diff options
author | Vittorio Giovara <vittorio.giovara@gmail.com> | 2014-10-22 14:36:32 +0100 |
---|---|---|
committer | Vittorio Giovara <vittorio.giovara@gmail.com> | 2014-10-27 18:21:35 +0000 |
commit | 090c67d586e3916f9acc49e010b6389d07f97153 (patch) | |
tree | 27b2e63a1eb1968bc03322ab17ab1a1762bc0de6 | |
parent | a6674d2e7771dbf7a4a5556f5e126be83cadac96 (diff) | |
download | ffmpeg-090c67d586e3916f9acc49e010b6389d07f97153.tar.gz |
matroskaenc: write correct Display{Width, Height} in stereo encoding
should be the raw amount of pixels (for example 3840x1080 for full HD side by
side) and the DisplayWidth/Height in pixels should be the amount of pixels for
one plane (1920x1080 for that full HD stream)."
So, move the aspect ratio check in the mkv_write_stereo_mode() function
and always write the embl when stereo format and/or aspect ration is set.
Also add a few comments to that function.
CC: libav-stable@libav.org
Found-by: Asan Usipov <asan.usipov@gmail.com>
-rw-r--r-- | libavformat/matroskaenc.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index ed6817099f..4ec474debc 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -629,6 +629,9 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, AVStream *st, int mode) { int i; + int display_width, display_height; + int h_width = 1, h_height = 1; + AVCodecContext *codec = st->codec; AVDictionaryEntry *tag; MatroskaVideoStereoModeType format = MATROSKA_VIDEO_STEREOMODE_TYPE_NB; @@ -643,6 +646,7 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, } } + // iterate to find the stereo3d side data for (i = 0; i < st->nb_side_data; i++) { AVPacketSideData sd = st->side_data[i]; if (sd.type == AV_PKT_DATA_STEREO3D) { @@ -656,11 +660,13 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, format = (stereo->flags & AV_STEREO3D_FLAG_INVERT) ? MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT : MATROSKA_VIDEO_STEREOMODE_TYPE_LEFT_RIGHT; + h_width = 2; break; case AV_STEREO3D_TOPBOTTOM: format = MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM; if (stereo->flags & AV_STEREO3D_FLAG_INVERT) format--; + h_height = 2; break; case AV_STEREO3D_CHECKERBOARD: format = MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_LR; @@ -671,11 +677,13 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, format = MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_LR; if (stereo->flags & AV_STEREO3D_FLAG_INVERT) format--; + h_height = 2; break; case AV_STEREO3D_COLUMNS: format = MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_LR; if (stereo->flags & AV_STEREO3D_FLAG_INVERT) format--; + h_width = 2; break; case AV_STEREO3D_FRAMESEQUENCE: format = MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_LR; @@ -688,14 +696,30 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, } } + // if webm, do not write unsupported modes if (mode == MODE_WEBM && (format > MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM && format != MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT)) format = MATROSKA_VIDEO_STEREOMODE_TYPE_NB; + // write StereoMode if format is valid if (format < MATROSKA_VIDEO_STEREOMODE_TYPE_NB) put_ebml_uint(pb, MATROSKA_ID_VIDEOSTEREOMODE, format); + // write DisplayWidth and DisplayHeight, they contain the size of + // a single source view and/or the display aspect ratio + display_width = codec->width / h_width; + display_height = codec->height / h_height; + if (st->sample_aspect_ratio.num) { + display_width *= av_q2d(st->sample_aspect_ratio); + put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYUNIT, 3); // DAR + } + if (st->sample_aspect_ratio.num || + format < MATROSKA_VIDEO_STEREOMODE_TYPE_NB) { + put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH, display_width); + put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, display_height); + } + return 0; } @@ -805,12 +829,6 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, if (ret < 0) return ret; - if (st->sample_aspect_ratio.num) { - int d_width = codec->width*av_q2d(st->sample_aspect_ratio); - put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , d_width); - put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, codec->height); - put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYUNIT, 3); - } end_ebml_master(pb, subinfo); break; |