matroskadec_haali: parse color and mastering info
This commit is contained in:
parent
93b7986dde
commit
fa837fb9cc
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue