[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