[FFmpeg-cvslog] Merge commit '5f0226668124aa7ae4db501ba7f4ace4c770f3d1'

Derek Buitenhuis git at videolan.org
Sun May 8 23:59:22 CEST 2016


ffmpeg | branch: master | Derek Buitenhuis <derek.buitenhuis at gmail.com> | Sun May  8 22:58:18 2016 +0100| [f3972b3b7dfaea254187c1f26c22b9b8761a9bf0] | committer: Derek Buitenhuis

Merge commit '5f0226668124aa7ae4db501ba7f4ace4c770f3d1'

* commit '5f0226668124aa7ae4db501ba7f4ace4c770f3d1':
  matroska: Support interlaced content correctly

Merged-by: Derek Buitenhuis <derek.buitenhuis at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=f3972b3b7dfaea254187c1f26c22b9b8761a9bf0
---

 libavformat/matroska.h    |   16 ++++++++++++++++
 libavformat/matroskadec.c |   31 +++++++++++++++++++++++++++++--
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/libavformat/matroska.h b/libavformat/matroska.h
index e97fe6b..e427c0e 100644
--- a/libavformat/matroska.h
+++ b/libavformat/matroska.h
@@ -119,6 +119,7 @@
 #define MATROSKA_ID_VIDEOPIXELCROPR 0x54DD
 #define MATROSKA_ID_VIDEODISPLAYUNIT 0x54B2
 #define MATROSKA_ID_VIDEOFLAGINTERLACED 0x9A
+#define MATROSKA_ID_VIDEOFIELDORDER 0x9D
 #define MATROSKA_ID_VIDEOSTEREOMODE 0x53B8
 #define MATROSKA_ID_VIDEOALPHAMODE 0x53C0
 #define MATROSKA_ID_VIDEOASPECTRATIO 0x54B3
@@ -275,6 +276,21 @@ typedef enum {
 } MatroskaTrackEncodingCompAlgo;
 
 typedef enum {
+    MATROSKA_VIDEO_INTERLACE_FLAG_UNDETERMINED = 0,
+    MATROSKA_VIDEO_INTERLACE_FLAG_INTERLACED   = 1,
+    MATROSKA_VIDEO_INTERLACE_FLAG_PROGRESSIVE  = 2
+} MatroskaVideoInterlaceFlag;
+
+typedef enum {
+    MATROSKA_VIDEO_FIELDORDER_PROGRESSIVE  = 0,
+    MATROSKA_VIDEO_FIELDORDER_UNDETERMINED = 2,
+    MATROSKA_VIDEO_FIELDORDER_TT           = 1,
+    MATROSKA_VIDEO_FIELDORDER_BB           = 6,
+    MATROSKA_VIDEO_FIELDORDER_BT           = 9,
+    MATROSKA_VIDEO_FIELDORDER_TB           = 14,
+} MatroskaVideoFieldOrder;
+
+typedef enum {
   MATROSKA_VIDEO_STEREOMODE_TYPE_MONO               = 0,
   MATROSKA_VIDEO_STEREOMODE_TYPE_LEFT_RIGHT         = 1,
   MATROSKA_VIDEO_STEREOMODE_TYPE_BOTTOM_TOP         = 2,
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index fa301a7..1ef2001 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -168,6 +168,8 @@ typedef struct MatroskaTrackVideo {
     uint64_t pixel_width;
     uint64_t pixel_height;
     EbmlBin color_space;
+    uint64_t interlaced;
+    uint64_t field_order;
     uint64_t stereo_mode;
     uint64_t alpha_mode;
     MatroskaTrackVideoColor color;
@@ -434,7 +436,8 @@ static const EbmlSyntax matroska_track_video[] = {
     { MATROSKA_ID_VIDEOPIXELCROPL,     EBML_NONE },
     { MATROSKA_ID_VIDEOPIXELCROPR,     EBML_NONE },
     { MATROSKA_ID_VIDEODISPLAYUNIT,    EBML_NONE },
-    { MATROSKA_ID_VIDEOFLAGINTERLACED, EBML_NONE },
+    { MATROSKA_ID_VIDEOFLAGINTERLACED, EBML_UINT,  0, offsetof(MatroskaTrackVideo, interlaced),  { .u = MATROSKA_VIDEO_INTERLACE_FLAG_UNDETERMINED } },
+    { MATROSKA_ID_VIDEOFIELDORDER,     EBML_UINT,  0, offsetof(MatroskaTrackVideo, field_order), { .u = MATROSKA_VIDEO_FIELDORDER_UNDETERMINED } },
     { MATROSKA_ID_VIDEOSTEREOMODE,     EBML_UINT,  0, offsetof(MatroskaTrackVideo, stereo_mode), { .u = MATROSKA_VIDEO_STEREOMODE_TYPE_NB } },
     { MATROSKA_ID_VIDEOASPECTRATIO,    EBML_NONE },
     { 0 }
@@ -1749,7 +1752,28 @@ static int matroska_parse_flac(AVFormatContext *s,
     return 0;
 }
 
-static void mkv_stereo_mode_display_mul(int stereo_mode, int *h_width, int *h_height)
+static int mkv_field_order(int64_t field_order)
+{
+    switch (field_order) {
+    case MATROSKA_VIDEO_FIELDORDER_PROGRESSIVE:
+        return AV_FIELD_PROGRESSIVE;
+    case MATROSKA_VIDEO_FIELDORDER_UNDETERMINED:
+        return AV_FIELD_UNKNOWN;
+    case MATROSKA_VIDEO_FIELDORDER_TT:
+        return AV_FIELD_TT;
+    case MATROSKA_VIDEO_FIELDORDER_BB:
+        return AV_FIELD_BB;
+    case MATROSKA_VIDEO_FIELDORDER_BT:
+        return AV_FIELD_BT;
+    case MATROSKA_VIDEO_FIELDORDER_TB:
+        return AV_FIELD_TB;
+    default:
+        return AV_FIELD_UNKNOWN;
+    }
+}
+
+static void mkv_stereo_mode_display_mul(int stereo_mode,
+                                        int *h_width, int *h_height)
 {
     switch (stereo_mode) {
         case MATROSKA_VIDEO_STEREOMODE_TYPE_MONO:
@@ -2255,6 +2279,9 @@ static int matroska_parse_tracks(AVFormatContext *s)
             st->codecpar->width      = track->video.pixel_width;
             st->codecpar->height     = track->video.pixel_height;
 
+            if (track->video.interlaced == MATROSKA_VIDEO_INTERLACE_FLAG_INTERLACED)
+                st->codecpar->field_order = mkv_field_order(track->video.field_order);
+
             if (track->video.stereo_mode && track->video.stereo_mode < MATROSKA_VIDEO_STEREOMODE_TYPE_NB)
                 mkv_stereo_mode_display_mul(track->video.stereo_mode, &display_width_mul, &display_height_mul);
 


======================================================================

diff --cc libavformat/matroska.h
index e97fe6b,40402bc..e427c0e
--- a/libavformat/matroska.h
+++ b/libavformat/matroska.h
@@@ -119,38 -113,10 +119,39 @@@
  #define MATROSKA_ID_VIDEOPIXELCROPR 0x54DD
  #define MATROSKA_ID_VIDEODISPLAYUNIT 0x54B2
  #define MATROSKA_ID_VIDEOFLAGINTERLACED 0x9A
+ #define MATROSKA_ID_VIDEOFIELDORDER 0x9D
  #define MATROSKA_ID_VIDEOSTEREOMODE 0x53B8
 +#define MATROSKA_ID_VIDEOALPHAMODE 0x53C0
  #define MATROSKA_ID_VIDEOASPECTRATIO 0x54B3
  #define MATROSKA_ID_VIDEOCOLORSPACE 0x2EB524
 +#define MATROSKA_ID_VIDEOCOLOR 0x55B0
 +
 +#define MATROSKA_ID_VIDEOCOLORMATRIXCOEFF 0x55B1
 +#define MATROSKA_ID_VIDEOCOLORBITSPERCHANNEL 0x55B2
 +#define MATROSKA_ID_VIDEOCOLORCHROMASUBHORZ 0x55B3
 +#define MATROSKA_ID_VIDEOCOLORCHROMASUBVERT 0x55B4
 +#define MATROSKA_ID_VIDEOCOLORCBSUBHORZ 0x55B5
 +#define MATROSKA_ID_VIDEOCOLORCBSUBVERT 0x55B6
 +#define MATROSKA_ID_VIDEOCOLORCHROMASITINGHORZ 0x55B7
 +#define MATROSKA_ID_VIDEOCOLORCHROMASITINGVERT 0x55B8
 +#define MATROSKA_ID_VIDEOCOLORRANGE 0x55B9
 +#define MATROSKA_ID_VIDEOCOLORTRANSFERCHARACTERISTICS 0x55BA
 +
 +#define MATROSKA_ID_VIDEOCOLORPRIMARIES 0x55BB
 +#define MATROSKA_ID_VIDEOCOLORMAXCLL 0x55BC
 +#define MATROSKA_ID_VIDEOCOLORMAXFALL 0x55BD
 +
 +#define MATROSKA_ID_VIDEOCOLORMASTERINGMETA 0x55D0
 +#define MATROSKA_ID_VIDEOCOLOR_RX 0x55D1
 +#define MATROSKA_ID_VIDEOCOLOR_RY 0x55D2
 +#define MATROSKA_ID_VIDEOCOLOR_GX 0x55D3
 +#define MATROSKA_ID_VIDEOCOLOR_GY 0x55D4
 +#define MATROSKA_ID_VIDEOCOLOR_BX 0x55D5
 +#define MATROSKA_ID_VIDEOCOLOR_BY 0x55D6
 +#define MATROSKA_ID_VIDEOCOLOR_WHITEX 0x55D7
 +#define MATROSKA_ID_VIDEOCOLOR_WHITEY 0x55D8
 +#define MATROSKA_ID_VIDEOCOLOR_LUMINANCEMAX 0x55D9
 +#define MATROSKA_ID_VIDEOCOLOR_LUMINANCEMIN 0x55DA
  
  /* IDs in the trackaudio master */
  #define MATROSKA_ID_AUDIOSAMPLINGFREQ 0xB5
diff --cc libavformat/matroskadec.c
index fa301a7,978d56d..1ef2001
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@@ -167,10 -122,10 +167,12 @@@ typedef struct MatroskaTrackVideo 
      uint64_t display_height;
      uint64_t pixel_width;
      uint64_t pixel_height;
 -    uint64_t fourcc;
 +    EbmlBin color_space;
+     uint64_t interlaced;
+     uint64_t field_order;
      uint64_t stereo_mode;
 +    uint64_t alpha_mode;
 +    MatroskaTrackVideoColor color;
  } MatroskaTrackVideo;
  
  typedef struct MatroskaTrackAudio {
@@@ -1749,118 -1528,49 +1752,139 @@@ static int matroska_parse_flac(AVFormat
      return 0;
  }
  
- static void mkv_stereo_mode_display_mul(int stereo_mode, int *h_width, int *h_height)
+ static int mkv_field_order(int64_t field_order)
+ {
+     switch (field_order) {
+     case MATROSKA_VIDEO_FIELDORDER_PROGRESSIVE:
+         return AV_FIELD_PROGRESSIVE;
+     case MATROSKA_VIDEO_FIELDORDER_UNDETERMINED:
+         return AV_FIELD_UNKNOWN;
+     case MATROSKA_VIDEO_FIELDORDER_TT:
+         return AV_FIELD_TT;
+     case MATROSKA_VIDEO_FIELDORDER_BB:
+         return AV_FIELD_BB;
+     case MATROSKA_VIDEO_FIELDORDER_BT:
+         return AV_FIELD_BT;
+     case MATROSKA_VIDEO_FIELDORDER_TB:
+         return AV_FIELD_TB;
+     default:
+         return AV_FIELD_UNKNOWN;
+     }
+ }
+ 
+ static void mkv_stereo_mode_display_mul(int stereo_mode,
+                                         int *h_width, int *h_height)
  {
      switch (stereo_mode) {
 -    case MATROSKA_VIDEO_STEREOMODE_TYPE_MONO:
 -    case MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_RL:
 -    case MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_LR:
 -    case MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_RL:
 -    case MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_LR:
 -        break;
 -    case MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT:
 -    case MATROSKA_VIDEO_STEREOMODE_TYPE_LEFT_RIGHT:
 -    case MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_RL:
 -    case MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_LR:
 -        *h_width = 2;
 -        break;
 -    case MATROSKA_VIDEO_STEREOMODE_TYPE_BOTTOM_TOP:
 -    case MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM:
 -    case MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_RL:
 -    case MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_LR:
 -        *h_height = 2;
 -        break;
 +        case MATROSKA_VIDEO_STEREOMODE_TYPE_MONO:
 +        case MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_RL:
 +        case MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_LR:
 +        case MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_RL:
 +        case MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_LR:
 +            break;
 +        case MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT:
 +        case MATROSKA_VIDEO_STEREOMODE_TYPE_LEFT_RIGHT:
 +        case MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_RL:
 +        case MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_LR:
 +            *h_width = 2;
 +            break;
 +        case MATROSKA_VIDEO_STEREOMODE_TYPE_BOTTOM_TOP:
 +        case MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM:
 +        case MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_RL:
 +        case MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_LR:
 +            *h_height = 2;
 +            break;
 +    }
 +}
 +
 +static int mkv_parse_video_color(AVStream *st, const MatroskaTrack *track) {
 +    const MatroskaMasteringMeta* mastering_meta =
 +        &track->video.color.mastering_meta;
 +    // Mastering primaries are CIE 1931 coords, and must be > 0.
 +    const int has_mastering_primaries =
 +        mastering_meta->r_x > 0 && mastering_meta->r_y > 0 &&
 +        mastering_meta->g_x > 0 && mastering_meta->g_y > 0 &&
 +        mastering_meta->b_x > 0 && mastering_meta->b_y > 0 &&
 +        mastering_meta->white_x > 0 && mastering_meta->white_y > 0;
 +    const int has_mastering_luminance = mastering_meta->max_luminance > 0;
 +
 +    if (track->video.color.matrix_coefficients != AVCOL_SPC_RESERVED)
 +        st->codecpar->color_space = track->video.color.matrix_coefficients;
 +    if (track->video.color.primaries != AVCOL_PRI_RESERVED)
 +        st->codecpar->color_primaries = track->video.color.primaries;
 +    if (track->video.color.transfer_characteristics != AVCOL_TRC_RESERVED)
 +        st->codecpar->color_trc = track->video.color.transfer_characteristics;
 +    if (track->video.color.range != AVCOL_RANGE_UNSPECIFIED &&
 +        track->video.color.range <= AVCOL_RANGE_JPEG)
 +        st->codecpar->color_range = track->video.color.range;
 +
 +    if (has_mastering_primaries || has_mastering_luminance) {
 +        // Use similar rationals as other standards.
 +        const int chroma_den = 50000;
 +        const int luma_den = 10000;
 +        AVMasteringDisplayMetadata *metadata =
 +            (AVMasteringDisplayMetadata*) av_stream_new_side_data(
 +                st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
 +                sizeof(AVMasteringDisplayMetadata));
 +        if (!metadata) {
 +            return AVERROR(ENOMEM);
 +        }
 +        memset(metadata, 0, sizeof(AVMasteringDisplayMetadata));
 +        if (has_mastering_primaries) {
 +            metadata->display_primaries[0][0] = av_make_q(
 +                round(mastering_meta->r_x * chroma_den), chroma_den);
 +            metadata->display_primaries[0][1] = av_make_q(
 +                round(mastering_meta->r_y * chroma_den), chroma_den);
 +            metadata->display_primaries[1][0] = av_make_q(
 +                round(mastering_meta->g_x * chroma_den), chroma_den);
 +            metadata->display_primaries[1][1] = av_make_q(
 +                round(mastering_meta->g_y * chroma_den), chroma_den);
 +            metadata->display_primaries[2][0] = av_make_q(
 +                round(mastering_meta->b_x * chroma_den), chroma_den);
 +            metadata->display_primaries[2][1] = av_make_q(
 +                round(mastering_meta->b_y * chroma_den), chroma_den);
 +            metadata->white_point[0] = av_make_q(
 +                round(mastering_meta->white_x * chroma_den), chroma_den);
 +            metadata->white_point[1] = av_make_q(
 +                round(mastering_meta->white_y * chroma_den), chroma_den);
 +            metadata->has_primaries = 1;
 +        }
 +        if (has_mastering_luminance) {
 +            metadata->max_luminance = av_make_q(
 +                round(mastering_meta->max_luminance * luma_den), luma_den);
 +            metadata->min_luminance = av_make_q(
 +                round(mastering_meta->min_luminance * luma_den), luma_den);
 +            metadata->has_luminance = 1;
 +        }
      }
 +    return 0;
 +}
 +
 +static int get_qt_codec(MatroskaTrack *track, uint32_t *fourcc, enum AVCodecID *codec_id)
 +{
 +    const AVCodecTag *codec_tags;
 +
 +    codec_tags = track->type == MATROSKA_TRACK_TYPE_VIDEO ?
 +            ff_codec_movvideo_tags : ff_codec_movaudio_tags;
 +
 +    /* Normalize noncompliant private data that starts with the fourcc
 +     * by expanding/shifting the data by 4 bytes and storing the data
 +     * size at the start. */
 +    if (ff_codec_get_id(codec_tags, AV_RL32(track->codec_priv.data))) {
 +        uint8_t *p = av_realloc(track->codec_priv.data,
 +                                track->codec_priv.size + 4);
 +        if (!p)
 +            return AVERROR(ENOMEM);
 +        memmove(p + 4, p, track->codec_priv.size);
 +        track->codec_priv.data = p;
 +        track->codec_priv.size += 4;
 +        AV_WB32(track->codec_priv.data, track->codec_priv.size);
 +    }
 +
 +    *fourcc = AV_RL32(track->codec_priv.data + 4);
 +    *codec_id = ff_codec_get_id(codec_tags, *fourcc);
 +
 +    return 0;
  }
  
  static int matroska_parse_tracks(AVFormatContext *s)



More information about the ffmpeg-cvslog mailing list