>From the specifications: "The pixel count of the track (PixelWidth/PixelHeight)
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 adapt the frame size appropriately when necessary.

CC: [email protected]
Found-by: Asan Usipov <[email protected]>
---
 libavformat/matroskaenc.c | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index f057c07..13e5f55 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -629,7 +629,9 @@ static int mkv_write_stereo_mode(AVFormatContext *s, 
AVIOContext *pb,
                                  AVStream *st, int mode)
 {
     int i;
+    int h_width = 1, h_height = 1;
     AVDictionaryEntry *tag;
+    AVCodecContext *codec = st->codec;
     MatroskaVideoStereoModeType format = MATROSKA_VIDEO_STEREOMODE_TYPE_NB;
 
     // convert metadata into proper side data and add it to the stream
@@ -656,26 +658,31 @@ 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;
                 if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
                     format--;
+                h_width = h_height = 2;
                 break;
             case AV_STEREO3D_LINES:
                 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;
@@ -693,9 +700,22 @@ static int mkv_write_stereo_mode(AVFormatContext *s, 
AVIOContext *pb,
          format != MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT))
         format = MATROSKA_VIDEO_STEREOMODE_TYPE_NB;
 
-    if (format < MATROSKA_VIDEO_STEREOMODE_TYPE_NB)
+    if (format < MATROSKA_VIDEO_STEREOMODE_TYPE_NB) {
         put_ebml_uint(pb, MATROSKA_ID_VIDEOSTEREOMODE, format);
 
+        // Write in DisplayWidth and DisplayHeight the size of a single view.
+        if (h_width > 1 || h_height > 1 || st->sample_aspect_ratio.num) {
+            int display_width  = codec->width  / h_width;
+            int 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
+            }
+            put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH,  display_width);
+            put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, display_height);
+        }
+    }
+
     return 0;
 }
 
@@ -805,12 +825,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;
 
-- 
1.9.3 (Apple Git-50)

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to