mirror of
https://github.com/gpac/gpac.git
synced 2026-01-12 00:05:22 +08:00
extract color info from avc/hevc/av1 config when exporting to mov - cf #1319
This commit is contained in:
@@ -910,6 +910,121 @@ GF_Err gf_media_make_psp(GF_ISOFile *mp4)
|
||||
return GF_OK;
|
||||
}
|
||||
|
||||
static GF_Err gf_media_get_color_info(GF_ISOFile *file, u32 track, u32 sampleDescriptionIndex, u32 *colour_type, u16 *colour_primaries, u16 *transfer_characteristics, u16 *matrix_coefficients, Bool *full_range_flag)
|
||||
{
|
||||
#ifndef GPAC_DISABLE_AV_PARSERS
|
||||
u32 stype = gf_isom_get_media_subtype(file, track, sampleDescriptionIndex);
|
||||
if ((stype==GF_ISOM_SUBTYPE_AVC_H264)
|
||||
|| (stype==GF_ISOM_SUBTYPE_AVC2_H264)
|
||||
|| (stype==GF_ISOM_SUBTYPE_AVC3_H264)
|
||||
|| (stype==GF_ISOM_SUBTYPE_AVC4_H264)
|
||||
) {
|
||||
AVCState avc;
|
||||
GF_AVCConfig *avcc = gf_isom_avc_config_get(file, track, sampleDescriptionIndex);
|
||||
u32 i;
|
||||
s32 idx;
|
||||
GF_NALUFFParam *slc;
|
||||
|
||||
memset(&avc, 0, sizeof(AVCState));
|
||||
avc.sps_active_idx = -1;
|
||||
|
||||
i=0;
|
||||
while ((slc = (GF_NALUFFParam *)gf_list_enum(avcc->sequenceParameterSets, &i))) {
|
||||
idx = gf_avc_read_sps(slc->data, slc->size, &avc, 0, NULL);
|
||||
|
||||
if (idx<0) continue;
|
||||
if (! avc.sps[idx].vui_parameters_present_flag )
|
||||
continue;
|
||||
|
||||
*colour_type = avc.sps[idx].vui.video_format;
|
||||
*colour_primaries = avc.sps[idx].vui.colour_primaries;
|
||||
*transfer_characteristics = avc.sps[idx].vui.transfer_characteristics;
|
||||
*matrix_coefficients = avc.sps[idx].vui.matrix_coefficients;
|
||||
*full_range_flag = avc.sps[idx].vui.video_full_range_flag;
|
||||
break;
|
||||
}
|
||||
gf_odf_avc_cfg_del(avcc);
|
||||
return GF_OK;
|
||||
}
|
||||
if ((stype==GF_ISOM_SUBTYPE_HEV1)
|
||||
|| (stype==GF_ISOM_SUBTYPE_HEV2)
|
||||
|| (stype==GF_ISOM_SUBTYPE_HVC1)
|
||||
|| (stype==GF_ISOM_SUBTYPE_HVC2)
|
||||
|| (stype==GF_ISOM_SUBTYPE_LHV1)
|
||||
|| (stype==GF_ISOM_SUBTYPE_LHE1)
|
||||
) {
|
||||
HEVCState hvc;
|
||||
GF_HEVCConfig *hvcc = gf_isom_hevc_config_get(file, track, sampleDescriptionIndex);
|
||||
u32 i;
|
||||
GF_NALUFFParamArray *pa;
|
||||
|
||||
memset(&hvc, 0, sizeof(HEVCState));
|
||||
hvc.sps_active_idx = -1;
|
||||
|
||||
i=0;
|
||||
while ((pa = (GF_NALUFFParamArray *)gf_list_enum(hvcc->param_array, &i))) {
|
||||
GF_NALUFFParam *slc;
|
||||
u32 j;
|
||||
s32 idx;
|
||||
if (pa->type != GF_HEVC_NALU_SEQ_PARAM) continue;
|
||||
|
||||
j=0;
|
||||
while ((slc = (GF_NALUFFParam *)gf_list_enum(pa->nalus, &j))) {
|
||||
idx = gf_hevc_read_sps(slc->data, slc->size, &hvc);
|
||||
|
||||
if (idx<0) continue;
|
||||
if (! hvc.sps[idx].vui_parameters_present_flag)
|
||||
continue;
|
||||
|
||||
*colour_type = hvc.sps[idx].video_format;
|
||||
*colour_primaries = hvc.sps[idx].colour_primaries;
|
||||
*transfer_characteristics = hvc.sps[idx].transfer_characteristic;
|
||||
*matrix_coefficients = hvc.sps[idx].matrix_coeffs;
|
||||
*full_range_flag = hvc.sps[idx].video_full_range_flag;
|
||||
gf_odf_hevc_cfg_del(hvcc);
|
||||
return GF_OK;
|
||||
}
|
||||
}
|
||||
gf_odf_hevc_cfg_del(hvcc);
|
||||
return GF_OK;
|
||||
}
|
||||
if (stype==GF_ISOM_SUBTYPE_AV01) {
|
||||
AV1State av1;
|
||||
|
||||
gf_av1_init_state(&av1);
|
||||
av1.config = gf_isom_av1_config_get(file, track, sampleDescriptionIndex);
|
||||
if (av1.config) {
|
||||
u32 i;
|
||||
for (i=0; i<gf_list_count(av1.config->obu_array); i++) {
|
||||
GF_BitStream *bs;
|
||||
ObuType obu_type;
|
||||
u32 hdr_size;
|
||||
u64 obu_size;
|
||||
GF_AV1_OBUArrayEntry *obu = gf_list_get(av1.config->obu_array, i);
|
||||
bs = gf_bs_new(obu->obu, (u32) obu->obu_length, GF_BITSTREAM_READ);
|
||||
gf_av1_parse_obu(bs, &obu_type, &obu_size, &hdr_size, &av1);
|
||||
gf_bs_del(bs);
|
||||
|
||||
if (av1.color_description_present_flag) {
|
||||
*colour_type = 0;
|
||||
*colour_primaries = av1.color_primaries;
|
||||
*transfer_characteristics = av1.transfer_characteristics;
|
||||
*matrix_coefficients = av1.matrix_coefficients;
|
||||
*full_range_flag = av1.color_range;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (av1.config) gf_odf_av1_cfg_del(av1.config);
|
||||
gf_av1_reset_state(&av1, GF_TRUE);
|
||||
return GF_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
return GF_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
GF_EXPORT
|
||||
GF_Err gf_media_check_qt_prores(GF_ISOFile *mp4)
|
||||
{
|
||||
@@ -1050,6 +1165,8 @@ GF_Err gf_media_check_qt_prores(GF_ISOFile *mp4)
|
||||
gf_bs_del(bs);
|
||||
}
|
||||
gf_isom_sample_del(&s);
|
||||
} else {
|
||||
e = gf_media_get_color_info(mp4, video_tk, 1, &colour_type, &colour_primaries, &transfer_characteristics, &matrix_coefficients, &full_range_flag);
|
||||
}
|
||||
if (!colour_primaries) {
|
||||
GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[ProRes] No color info present in visual track, defaulting to BT709\n"));
|
||||
@@ -1057,7 +1174,7 @@ GF_Err gf_media_check_qt_prores(GF_ISOFile *mp4)
|
||||
transfer_characteristics = 1;
|
||||
matrix_coefficients = 1;
|
||||
} else {
|
||||
GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[ProRes] No color info present in visual track, extracting from first ProRes frame\n"));
|
||||
GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[ProRes] No color info present in visual track, extracting from %s\n", prores_type ? "first ProRes frame" : "sample description"));
|
||||
}
|
||||
gf_isom_set_visual_color_info(mp4, video_tk, 1, GF_4CC('n','c','l','c'), colour_primaries, transfer_characteristics, matrix_coefficients, GF_FALSE, NULL, 0);
|
||||
} else if (e) {
|
||||
|
||||
Reference in New Issue
Block a user