1
0
Fork 0

matroskadec_haali: parse color and mastering info

This commit is contained in:
Hendrik Leppkes 2016-11-18 15:07:31 +01:00
parent f3c286b364
commit 6ccbf6d4c5
Signed by: hendrik
GPG Key ID: 846079A4B0A7C1B5
3 changed files with 192 additions and 0 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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];