Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHendrik Leppkes <h.leppkes@gmail.com>2016-11-18 17:07:31 +0300
committerHendrik Leppkes <h.leppkes@gmail.com>2017-08-04 20:18:34 +0300
commit851687d17f7819ce2b8acd06e66c8e24d7da6924 (patch)
tree4d5ef8cdf671b631d6f5e0bc0944747f4de1dc3a
parent333a44b8bb0f9ba8befff76e49423e741c576468 (diff)
matroskadec_haali: parse color and mastering info
-rw-r--r--libavformat/MatroskaParser.c88
-rw-r--r--libavformat/MatroskaParser.h27
-rw-r--r--libavformat/matroskadec_haali.c77
3 files changed, 192 insertions, 0 deletions
diff --git a/libavformat/MatroskaParser.c b/libavformat/MatroskaParser.c
index 497581cc1c..173c2e1c20 100644
--- a/libavformat/MatroskaParser.c
+++ b/libavformat/MatroskaParser.c
@@ -1190,6 +1190,84 @@ out:
ENDFOR(mf);
}
+static void parseVideoColourInfo(MatroskaFile *mf,ulonglong toplen,struct TrackInfo *ti) {
+ FOREACH(mf,toplen)
+ case 0x55b1:
+ ti->AV.Video.Colour.MatrixCoefficients = readUInt(mf,(unsigned)len);
+ break;
+ case 0x55b2:
+ ti->AV.Video.Colour.BitsPerChannel = readUInt(mf,(unsigned)len);
+ break;
+ case 0x55b3:
+ ti->AV.Video.Colour.ChromaSubsamplingHorz = readUInt(mf,(unsigned)len);
+ break;
+ case 0x55b4:
+ ti->AV.Video.Colour.ChromaSubsamplingVert = readUInt(mf,(unsigned)len);
+ break;
+ case 0x55b5:
+ ti->AV.Video.Colour.CbSubsamplingHorz = readUInt(mf,(unsigned)len);
+ break;
+ case 0x55b6:
+ ti->AV.Video.Colour.CbSubsamplingVert = readUInt(mf,(unsigned)len);
+ break;
+ case 0x55b7:
+ ti->AV.Video.Colour.ChromaSitingHorz = readUInt(mf,(unsigned)len);
+ break;
+ case 0x55b8:
+ ti->AV.Video.Colour.ChromaSitingVert = readUInt(mf,(unsigned)len);
+ break;
+ case 0x55b9:
+ ti->AV.Video.Colour.Range = readUInt(mf,(unsigned)len);
+ break;
+ case 0x55ba:
+ ti->AV.Video.Colour.TransferCharacteristics = readUInt(mf,(unsigned)len);
+ break;
+ case 0x55bb:
+ ti->AV.Video.Colour.Primaries = readUInt(mf,(unsigned)len);
+ break;
+ case 0x55bc:
+ ti->AV.Video.Colour.MaxCLL = readUInt(mf,(unsigned)len);
+ break;
+ case 0x55bd:
+ ti->AV.Video.Colour.MaxFALL = readUInt(mf,(unsigned)len);
+ break;
+ case 0x55d0:
+ FOREACH(mf,len)
+ case 0x55d1:
+ ti->AV.Video.Colour.MasteringMetadata.PrimaryRChromaticityX = readFloat(mf,(unsigned)len);
+ break;
+ case 0x55d2:
+ ti->AV.Video.Colour.MasteringMetadata.PrimaryRChromaticityY = readFloat(mf,(unsigned)len);
+ break;
+ case 0x55d3:
+ ti->AV.Video.Colour.MasteringMetadata.PrimaryGChromaticityX = readFloat(mf,(unsigned)len);
+ break;
+ case 0x55d4:
+ ti->AV.Video.Colour.MasteringMetadata.PrimaryGChromaticityY = readFloat(mf,(unsigned)len);
+ break;
+ case 0x55d5:
+ ti->AV.Video.Colour.MasteringMetadata.PrimaryBChromaticityX = readFloat(mf,(unsigned)len);
+ break;
+ case 0x55d6:
+ ti->AV.Video.Colour.MasteringMetadata.PrimaryBChromaticityY = readFloat(mf,(unsigned)len);
+ break;
+ case 0x55d7:
+ ti->AV.Video.Colour.MasteringMetadata.WhitePointChromaticityX = readFloat(mf,(unsigned)len);
+ break;
+ case 0x55d8:
+ ti->AV.Video.Colour.MasteringMetadata.WhitePointChromaticityY = readFloat(mf,(unsigned)len);
+ break;
+ case 0x55d9:
+ ti->AV.Video.Colour.MasteringMetadata.LuminanceMax = readFloat(mf,(unsigned)len);
+ break;
+ case 0x55da:
+ ti->AV.Video.Colour.MasteringMetadata.LuminanceMin = readFloat(mf,(unsigned)len);
+ break;
+ ENDFOR(mf);
+ break;
+ ENDFOR(mf);
+}
+
static void parseVideoInfo(MatroskaFile *mf,ulonglong toplen,struct TrackInfo *ti) {
ulonglong v;
char dW = 0, dH = 0;
@@ -1272,6 +1350,9 @@ static void parseVideoInfo(MatroskaFile *mf,ulonglong toplen,struct TrackInfo *t
case 0x2fb523: // GammaValue
ti->AV.Video.GammaValue = readFloat(mf,(unsigned)len);
break;
+ case 0x55b0: // Colour
+ parseVideoColourInfo(mf,len,ti);
+ break;
ENDFOR(mf);
// DisplayWidth/Height defaults don't apply for DisplayUnit != 0
@@ -1368,6 +1449,13 @@ static void parseTrackEntry(MatroskaFile *mf,ulonglong toplen) {
if (v<1 || v>254)
errorjmp(mf,"Invalid track type: %d",(int)v);
t.Type = (unsigned char)v;
+
+ // Load type-dependent defaults
+ if (t.Type == TT_VIDEO) {
+ t.AV.Video.Colour.MatrixCoefficients = 2;
+ t.AV.Video.Colour.TransferCharacteristics = 2;
+ t.AV.Video.Colour.Primaries = 2;
+ }
break;
case 0xb9: // Enabled
t.Enabled = readUInt(mf,(unsigned)len)!=0;
diff --git a/libavformat/MatroskaParser.h b/libavformat/MatroskaParser.h
index 7d04dd080f..fa7fbe6189 100644
--- a/libavformat/MatroskaParser.h
+++ b/libavformat/MatroskaParser.h
@@ -150,6 +150,33 @@ struct TrackInfo {
unsigned int CropL, CropT, CropR, CropB;
unsigned int ColourSpace;
MKFLOAT GammaValue;
+ struct {
+ unsigned int MatrixCoefficients;
+ unsigned int BitsPerChannel;
+ unsigned int ChromaSubsamplingHorz;
+ unsigned int ChromaSubsamplingVert;
+ unsigned int CbSubsamplingHorz;
+ unsigned int CbSubsamplingVert;
+ unsigned int ChromaSitingHorz;
+ unsigned int ChromaSitingVert;
+ unsigned int Range;
+ unsigned int TransferCharacteristics;
+ unsigned int Primaries;
+ unsigned int MaxCLL;
+ unsigned int MaxFALL;
+ struct {
+ float PrimaryRChromaticityX;
+ float PrimaryRChromaticityY;
+ float PrimaryGChromaticityX;
+ float PrimaryGChromaticityY;
+ float PrimaryBChromaticityX;
+ float PrimaryBChromaticityY;
+ float WhitePointChromaticityX;
+ float WhitePointChromaticityY;
+ float LuminanceMax;
+ float LuminanceMin;
+ } MasteringMetadata;
+ } Colour;
unsigned int Interlaced:1;
} Video;
diff --git a/libavformat/matroskadec_haali.c b/libavformat/matroskadec_haali.c
index 377d402003..4a83348ef1 100644
--- a/libavformat/matroskadec_haali.c
+++ b/libavformat/matroskadec_haali.c
@@ -36,6 +36,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
#include "libavutil/dict.h"
+#include "libavutil/mastering_display_metadata.h"
#if CONFIG_ZLIB
#include <zlib.h>
#endif
@@ -1055,6 +1056,79 @@ static int get_qt_codec(TrackInfo *track, uint32_t *fourcc, enum AVCodecID *code
return 0;
}
+static int mkv_parse_video_color(AVStream *st, TrackInfo *info)
+{
+ // Mastering primaries are CIE 1931 coords, and must be > 0.
+ const int has_mastering_primaries =
+ info->AV.Video.Colour.MasteringMetadata.PrimaryRChromaticityX > 0 && info->AV.Video.Colour.MasteringMetadata.PrimaryRChromaticityY > 0 &&
+ info->AV.Video.Colour.MasteringMetadata.PrimaryGChromaticityX > 0 && info->AV.Video.Colour.MasteringMetadata.PrimaryGChromaticityY > 0 &&
+ info->AV.Video.Colour.MasteringMetadata.PrimaryBChromaticityX > 0 && info->AV.Video.Colour.MasteringMetadata.PrimaryBChromaticityY > 0 &&
+ info->AV.Video.Colour.MasteringMetadata.WhitePointChromaticityX > 0 && info->AV.Video.Colour.MasteringMetadata.WhitePointChromaticityY > 0;
+ const int has_mastering_luminance = info->AV.Video.Colour.MasteringMetadata.LuminanceMax > 0;
+
+ if (info->AV.Video.Colour.MatrixCoefficients != AVCOL_SPC_RESERVED)
+ st->codecpar->color_space = info->AV.Video.Colour.MatrixCoefficients;
+ if (info->AV.Video.Colour.Primaries != AVCOL_PRI_RESERVED &&
+ info->AV.Video.Colour.Primaries != AVCOL_PRI_RESERVED0)
+ st->codecpar->color_primaries = info->AV.Video.Colour.Primaries;
+ if (info->AV.Video.Colour.TransferCharacteristics != AVCOL_TRC_RESERVED &&
+ info->AV.Video.Colour.TransferCharacteristics != AVCOL_TRC_RESERVED0)
+ st->codecpar->color_trc = info->AV.Video.Colour.TransferCharacteristics;
+ if (info->AV.Video.Colour.Range != AVCOL_RANGE_UNSPECIFIED &&
+ info->AV.Video.Colour.Range <= AVCOL_RANGE_JPEG)
+ st->codecpar->color_range = info->AV.Video.Colour.Range;
+ if (info->AV.Video.Colour.ChromaSitingHorz != MATROSKA_COLOUR_CHROMASITINGHORZ_UNDETERMINED &&
+ info->AV.Video.Colour.ChromaSitingVert != MATROSKA_COLOUR_CHROMASITINGVERT_UNDETERMINED &&
+ info->AV.Video.Colour.ChromaSitingHorz < MATROSKA_COLOUR_CHROMASITINGHORZ_NB &&
+ info->AV.Video.Colour.ChromaSitingVert < MATROSKA_COLOUR_CHROMASITINGVERT_NB) {
+ st->codecpar->chroma_location =
+ avcodec_chroma_pos_to_enum((info->AV.Video.Colour.ChromaSitingHorz - 1) << 7,
+ (info->AV.Video.Colour.ChromaSitingVert - 1) << 7);
+ }
+
+ 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(info->AV.Video.Colour.MasteringMetadata.PrimaryRChromaticityX * chroma_den), chroma_den);
+ metadata->display_primaries[0][1] = av_make_q(
+ round(info->AV.Video.Colour.MasteringMetadata.PrimaryRChromaticityY * chroma_den), chroma_den);
+ metadata->display_primaries[1][0] = av_make_q(
+ round(info->AV.Video.Colour.MasteringMetadata.PrimaryGChromaticityX * chroma_den), chroma_den);
+ metadata->display_primaries[1][1] = av_make_q(
+ round(info->AV.Video.Colour.MasteringMetadata.PrimaryGChromaticityY * chroma_den), chroma_den);
+ metadata->display_primaries[2][0] = av_make_q(
+ round(info->AV.Video.Colour.MasteringMetadata.PrimaryBChromaticityX * chroma_den), chroma_den);
+ metadata->display_primaries[2][1] = av_make_q(
+ round(info->AV.Video.Colour.MasteringMetadata.PrimaryBChromaticityY * chroma_den), chroma_den);
+ metadata->white_point[0] = av_make_q(
+ round(info->AV.Video.Colour.MasteringMetadata.WhitePointChromaticityX * chroma_den), chroma_den);
+ metadata->white_point[1] = av_make_q(
+ round(info->AV.Video.Colour.MasteringMetadata.WhitePointChromaticityY * chroma_den), chroma_den);
+ metadata->has_primaries = 1;
+ }
+ if (has_mastering_luminance) {
+ metadata->max_luminance = av_make_q(
+ round(info->AV.Video.Colour.MasteringMetadata.LuminanceMax * luma_den), luma_den);
+ metadata->min_luminance = av_make_q(
+ round(info->AV.Video.Colour.MasteringMetadata.LuminanceMin * luma_den), luma_den);
+ metadata->has_luminance = 1;
+ }
+ }
+
+ return 0;
+}
+
static int mkv_read_header(AVFormatContext *s)
{
MatroskaDemuxContext *ctx = (MatroskaDemuxContext *)s->priv_data;
@@ -1275,6 +1349,9 @@ static int mkv_read_header(AVFormatContext *s)
return ret;
}
+ ret = mkv_parse_video_color(st, info);
+ if (ret < 0)
+ return ret;
// if we have virtual track, mark the real tracks
/*for (j=0; j < track->operation.combine_planes.nb_elem; j++) {
char buf[32];