libhb: prefer container color primaries, transfer, and matrix info over the stream ones.

This commit is contained in:
Damiano galassi 2022-04-19 13:14:57 +02:00
parent 01e3cfe1b6
commit 72b63d2ff5
No known key found for this signature in database
GPG Key ID: 5452E231DFDBCA11
4 changed files with 167 additions and 134 deletions

View File

@ -3901,6 +3901,9 @@ hb_title_t * hb_title_init( char * path, int index )
t->angle_count = 1;
t->geometry.par.num = 0;
t->geometry.par.den = 1;
t->color_prim = HB_COLR_PRI_UNDEF;
t->color_transfer = HB_COLR_TRA_UNDEF;
t->color_matrix = HB_COLR_MAT_UNDEF;
return t;
}

View File

@ -62,10 +62,6 @@ static void decavcodecClose( hb_work_object_t * );
static int decavcodecaInfo( hb_work_object_t *, hb_work_info_t * );
static int decavcodecaBSInfo( hb_work_object_t *, const hb_buffer_t *, hb_work_info_t * );
static int get_color_prim(int color_primaries, hb_geometry_t geometry, hb_rational_t rate);
static int get_color_transfer(int color_trc);
static int get_color_matrix(int colorspace, hb_geometry_t geometry);
hb_work_object_t hb_decavcodeca =
{
.id = WORK_DECAVCODEC,
@ -1989,128 +1985,6 @@ static void compute_frame_duration( hb_work_private_t *pv )
}
}
static int get_color_prim(int color_primaries, hb_geometry_t geometry, hb_rational_t rate)
{
switch (color_primaries)
{
case AVCOL_PRI_BT709:
return HB_COLR_PRI_BT709;
case AVCOL_PRI_BT470M:
return HB_COLR_PRI_BT470M;
case AVCOL_PRI_BT470BG:
return HB_COLR_PRI_EBUTECH;
case AVCOL_PRI_SMPTE170M:
case AVCOL_PRI_SMPTE240M:
return HB_COLR_PRI_SMPTEC;
case AVCOL_PRI_FILM:
return HB_COLR_PRI_FILM;
case AVCOL_PRI_SMPTE428:
return HB_COLR_PRI_SMPTE428;
case AVCOL_PRI_SMPTE431:
return HB_COLR_PRI_SMPTE431;
case AVCOL_PRI_SMPTE432:
return HB_COLR_PRI_SMPTE432;
case AVCOL_PRI_JEDEC_P22:
return HB_COLR_PRI_JEDEC_P22;
case AVCOL_PRI_BT2020:
return HB_COLR_PRI_BT2020;
default:
{
if ((geometry.width >= 1280 || geometry.height >= 720)||
(geometry.width > 720 && geometry.height > 576 ))
// ITU BT.709 HD content
return HB_COLR_PRI_BT709;
else if (rate.den == 1080000)
// ITU BT.601 DVD or SD TV content (PAL)
return HB_COLR_PRI_EBUTECH;
else
// ITU BT.601 DVD or SD TV content (NTSC)
return HB_COLR_PRI_SMPTEC;
}
}
}
static int get_color_transfer(int color_trc)
{
switch (color_trc)
{
case AVCOL_TRC_GAMMA22:
return HB_COLR_TRA_GAMMA22;
case AVCOL_TRC_GAMMA28:
return HB_COLR_TRA_GAMMA28;
case AVCOL_TRC_SMPTE170M:
return HB_COLR_TRA_SMPTE170M;
case AVCOL_TRC_LINEAR:
return HB_COLR_TRA_LINEAR;
case AVCOL_TRC_LOG:
return HB_COLR_TRA_LOG;
case AVCOL_TRC_LOG_SQRT:
return HB_COLR_TRA_LOG_SQRT;
case AVCOL_TRC_IEC61966_2_4:
return HB_COLR_TRA_IEC61966_2_4;
case AVCOL_TRC_BT1361_ECG:
return HB_COLR_TRA_BT1361_ECG;
case AVCOL_TRC_IEC61966_2_1:
return HB_COLR_TRA_IEC61966_2_1;
case AVCOL_TRC_SMPTE240M:
return HB_COLR_TRA_SMPTE240M;
case AVCOL_TRC_SMPTEST2084:
return HB_COLR_TRA_SMPTEST2084;
case AVCOL_TRC_ARIB_STD_B67:
return HB_COLR_TRA_ARIB_STD_B67;
case AVCOL_TRC_BT2020_10:
return HB_COLR_TRA_BT2020_10;
case AVCOL_TRC_BT2020_12:
return HB_COLR_TRA_BT2020_12;
default:
// ITU BT.601, BT.709, anything else
return HB_COLR_TRA_BT709;
}
}
static int get_color_matrix(int colorspace, hb_geometry_t geometry)
{
switch (colorspace)
{
case AVCOL_SPC_RGB:
return HB_COLR_MAT_RGB;
case AVCOL_SPC_BT709:
return HB_COLR_MAT_BT709;
case AVCOL_SPC_FCC:
return HB_COLR_MAT_FCC;
case AVCOL_SPC_BT470BG:
return HB_COLR_MAT_BT470BG;
case AVCOL_SPC_SMPTE170M:
return HB_COLR_MAT_SMPTE170M;
case AVCOL_SPC_SMPTE240M:
return HB_COLR_MAT_SMPTE240M;
case AVCOL_SPC_YCGCO:
return HB_COLR_MAT_YCGCO;
case AVCOL_SPC_BT2020_NCL:
return HB_COLR_MAT_BT2020_NCL;
case AVCOL_SPC_BT2020_CL:
return HB_COLR_MAT_BT2020_CL;
case AVCOL_SPC_CHROMA_DERIVED_NCL:
return HB_COLR_MAT_CD_NCL;
case AVCOL_SPC_CHROMA_DERIVED_CL:
return HB_COLR_MAT_CD_CL;
case AVCOL_SPC_ICTCP:
return HB_COLR_MAT_ICTCP;
default:
{
if ((geometry.width >= 1280 || geometry.height >= 720)||
(geometry.width > 720 && geometry.height > 576 ))
// ITU BT.709 HD content
return HB_COLR_MAT_BT709;
else
// ITU BT.601 DVD or SD TV content (PAL)
// ITU BT.601 DVD or SD TV content (NTSC)
return HB_COLR_MAT_SMPTE170M;
}
}
}
static int decavcodecvInfo( hb_work_object_t *w, hb_work_info_t *info )
{
hb_work_private_t *pv = w->private_data;
@ -2157,11 +2031,9 @@ static int decavcodecvInfo( hb_work_object_t *w, hb_work_info_t *info )
info->name = pv->context->codec->name;
info->pix_fmt = pv->context->pix_fmt;
info->color_prim = get_color_prim(pv->context->color_primaries,
info->geometry, info->rate);
info->color_transfer = get_color_transfer(pv->context->color_trc);
info->color_matrix = get_color_matrix(pv->context->colorspace,
info->geometry);
info->color_prim = pv->context->color_primaries;
info->color_transfer = pv->context->color_trc;
info->color_matrix = pv->context->colorspace;
info->color_range = pv->context->color_range;
info->chroma_location = pv->context->chroma_sample_location;

View File

@ -40,6 +40,10 @@ static void UpdateState1(hb_scan_t *scan, int title);
static void UpdateState2(hb_scan_t *scan, int title);
static void UpdateState3(hb_scan_t *scan, int preview);
static int get_color_prim(int color_primaries, hb_geometry_t geometry, hb_rational_t rate);
static int get_color_transfer(int color_trc);
static int get_color_matrix(int colorspace, hb_geometry_t geometry);
static const char *aspect_to_string(hb_rational_t *dar)
{
double aspect = (double)dar->num / dar->den;
@ -56,6 +60,128 @@ static const char *aspect_to_string(hb_rational_t *dar)
return arstr;
}
static int get_color_prim(int color_primaries, hb_geometry_t geometry, hb_rational_t rate)
{
switch (color_primaries)
{
case AVCOL_PRI_BT709:
return HB_COLR_PRI_BT709;
case AVCOL_PRI_BT470M:
return HB_COLR_PRI_BT470M;
case AVCOL_PRI_BT470BG:
return HB_COLR_PRI_EBUTECH;
case AVCOL_PRI_SMPTE170M:
case AVCOL_PRI_SMPTE240M:
return HB_COLR_PRI_SMPTEC;
case AVCOL_PRI_FILM:
return HB_COLR_PRI_FILM;
case AVCOL_PRI_SMPTE428:
return HB_COLR_PRI_SMPTE428;
case AVCOL_PRI_SMPTE431:
return HB_COLR_PRI_SMPTE431;
case AVCOL_PRI_SMPTE432:
return HB_COLR_PRI_SMPTE432;
case AVCOL_PRI_JEDEC_P22:
return HB_COLR_PRI_JEDEC_P22;
case AVCOL_PRI_BT2020:
return HB_COLR_PRI_BT2020;
default:
{
if ((geometry.width >= 1280 || geometry.height >= 720)||
(geometry.width > 720 && geometry.height > 576 ))
// ITU BT.709 HD content
return HB_COLR_PRI_BT709;
else if (rate.den == 1080000)
// ITU BT.601 DVD or SD TV content (PAL)
return HB_COLR_PRI_EBUTECH;
else
// ITU BT.601 DVD or SD TV content (NTSC)
return HB_COLR_PRI_SMPTEC;
}
}
}
static int get_color_transfer(int color_trc)
{
switch (color_trc)
{
case AVCOL_TRC_GAMMA22:
return HB_COLR_TRA_GAMMA22;
case AVCOL_TRC_GAMMA28:
return HB_COLR_TRA_GAMMA28;
case AVCOL_TRC_SMPTE170M:
return HB_COLR_TRA_SMPTE170M;
case AVCOL_TRC_LINEAR:
return HB_COLR_TRA_LINEAR;
case AVCOL_TRC_LOG:
return HB_COLR_TRA_LOG;
case AVCOL_TRC_LOG_SQRT:
return HB_COLR_TRA_LOG_SQRT;
case AVCOL_TRC_IEC61966_2_4:
return HB_COLR_TRA_IEC61966_2_4;
case AVCOL_TRC_BT1361_ECG:
return HB_COLR_TRA_BT1361_ECG;
case AVCOL_TRC_IEC61966_2_1:
return HB_COLR_TRA_IEC61966_2_1;
case AVCOL_TRC_SMPTE240M:
return HB_COLR_TRA_SMPTE240M;
case AVCOL_TRC_SMPTEST2084:
return HB_COLR_TRA_SMPTEST2084;
case AVCOL_TRC_ARIB_STD_B67:
return HB_COLR_TRA_ARIB_STD_B67;
case AVCOL_TRC_BT2020_10:
return HB_COLR_TRA_BT2020_10;
case AVCOL_TRC_BT2020_12:
return HB_COLR_TRA_BT2020_12;
default:
// ITU BT.601, BT.709, anything else
return HB_COLR_TRA_BT709;
}
}
static int get_color_matrix(int colorspace, hb_geometry_t geometry)
{
switch (colorspace)
{
case AVCOL_SPC_RGB:
return HB_COLR_MAT_RGB;
case AVCOL_SPC_BT709:
return HB_COLR_MAT_BT709;
case AVCOL_SPC_FCC:
return HB_COLR_MAT_FCC;
case AVCOL_SPC_BT470BG:
return HB_COLR_MAT_BT470BG;
case AVCOL_SPC_SMPTE170M:
return HB_COLR_MAT_SMPTE170M;
case AVCOL_SPC_SMPTE240M:
return HB_COLR_MAT_SMPTE240M;
case AVCOL_SPC_YCGCO:
return HB_COLR_MAT_YCGCO;
case AVCOL_SPC_BT2020_NCL:
return HB_COLR_MAT_BT2020_NCL;
case AVCOL_SPC_BT2020_CL:
return HB_COLR_MAT_BT2020_CL;
case AVCOL_SPC_CHROMA_DERIVED_NCL:
return HB_COLR_MAT_CD_NCL;
case AVCOL_SPC_CHROMA_DERIVED_CL:
return HB_COLR_MAT_CD_CL;
case AVCOL_SPC_ICTCP:
return HB_COLR_MAT_ICTCP;
default:
{
if ((geometry.width >= 1280 || geometry.height >= 720)||
(geometry.width > 720 && geometry.height > 576 ))
// ITU BT.709 HD content
return HB_COLR_MAT_BT709;
else
// ITU BT.601 DVD or SD TV content (PAL)
// ITU BT.601 DVD or SD TV content (NTSC)
return HB_COLR_MAT_SMPTE170M;
}
}
}
hb_thread_t * hb_scan_init( hb_handle_t * handle, volatile int * die,
const char * path, int title_index,
hb_title_set_t * title_set, int preview_count,
@ -1033,9 +1159,22 @@ skip_preview:
title->geometry.par.num = title->geometry.par.den = 1;
}
title->pix_fmt = vid_info.pix_fmt;
title->color_prim = vid_info.color_prim;
title->color_transfer = vid_info.color_transfer;
title->color_matrix = vid_info.color_matrix;
if (title->color_prim != HB_COLR_PRI_UNDEF ||
title->color_transfer != HB_COLR_TRA_UNDEF ||
title->color_matrix != HB_COLR_MAT_UNDEF)
{
title->color_prim = get_color_prim(title->color_prim, vid_info.geometry, vid_info.rate);
title->color_transfer = get_color_transfer(title->color_transfer);
title->color_matrix = get_color_matrix(title->color_matrix, vid_info.geometry);
}
else
{
title->color_prim = get_color_prim(vid_info.color_prim, vid_info.geometry, vid_info.rate);
title->color_transfer = get_color_transfer(vid_info.color_transfer);
title->color_matrix = get_color_matrix(vid_info.color_matrix, vid_info.geometry);
}
title->color_range = vid_info.color_range;
title->chroma_location = vid_info.chroma_location;

View File

@ -5231,6 +5231,25 @@ static int ffmpeg_open( hb_stream_t *stream, hb_title_t *title, int scan )
}
av_dict_free( &av_opts );
// Read the video track color info
// before it's overwritten with the stream info
// in avformat_find_stream_info
for (int i = 0; i < info_ic->nb_streams; ++i)
{
AVStream *st = info_ic->streams[i];
if ( st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
!(st->disposition & AV_DISPOSITION_ATTACHED_PIC) &&
avcodec_find_decoder(st->codecpar->codec_id))
{
AVCodecParameters *codecpar = st->codecpar;
title->color_prim = codecpar->color_primaries;
title->color_transfer = codecpar->color_trc;
title->color_matrix = codecpar->color_space;
title->color_range = codecpar->color_range;
}
}
if ( avformat_find_stream_info( info_ic, NULL ) < 0 )
goto fail;