GF_EXPORT GF_HEVCConfig *gf_odf_hevc_cfg_read_bs(GF_BitStream *bs, Bool is_shvc) { u32 i, count; GF_HEVCConfig *cfg = gf_odf_hevc_cfg_new(); cfg->configurationVersion = gf_bs_read_int(bs, 8); cfg->profile_space = gf_bs_read_int(bs, 2); cfg->tier_flag = gf_bs_read_int(bs, 1); cfg->profile_idc = gf_bs_read_int(bs, 5); cfg->general_profile_compatibility_flags = gf_bs_read_int(bs, 32); cfg->progressive_source_flag = gf_bs_read_int(bs, 1); cfg->interlaced_source_flag = gf_bs_read_int(bs, 1); cfg->non_packed_constraint_flag = gf_bs_read_int(bs, 1); cfg->frame_only_constraint_flag = gf_bs_read_int(bs, 1); /*only lowest 44 bits used*/ cfg->constraint_indicator_flags = gf_bs_read_long_int(bs, 44); cfg->level_idc = gf_bs_read_int(bs, 8); gf_bs_read_int(bs, 4); cfg->min_spatial_segmentation_idc = gf_bs_read_int(bs, 12); gf_bs_read_int(bs, 6); cfg->parallelismType = gf_bs_read_int(bs, 2); gf_bs_read_int(bs, 6); cfg->chromaFormat = gf_bs_read_int(bs, 2); gf_bs_read_int(bs, 5); cfg->luma_bit_depth = gf_bs_read_int(bs, 3) + 8; gf_bs_read_int(bs, 5); cfg->chroma_bit_depth = gf_bs_read_int(bs, 3) + 8; cfg->avgFrameRate = gf_bs_read_int(bs, 16); cfg->constantFrameRate = gf_bs_read_int(bs, 2); cfg->numTemporalLayers = gf_bs_read_int(bs, 3); cfg->temporalIdNested = gf_bs_read_int(bs, 1); cfg->nal_unit_size = 1 + gf_bs_read_int(bs, 2); if (is_shvc) { cfg->is_shvc = 1; cfg->complete_representation = gf_bs_read_int(bs, 1); cfg->non_hevc_base_layer = gf_bs_read_int(bs, 1); cfg->num_layers = 1 + gf_bs_read_int(bs, 6); cfg->scalability_mask = gf_bs_read_int(bs, 16); } count = gf_bs_read_int(bs, 8); for (i=0; i<count; i++) { u32 nalucount, j; GF_HEVCParamArray *ar; GF_SAFEALLOC(ar, GF_HEVCParamArray); ar->nalus = gf_list_new(); gf_list_add(cfg->param_array, ar); ar->array_completeness = gf_bs_read_int(bs, 1); gf_bs_read_int(bs, 1); ar->type = gf_bs_read_int(bs, 6); nalucount = gf_bs_read_int(bs, 16); for (j=0; j<nalucount; j++) { GF_AVCConfigSlot *sl; GF_SAFEALLOC(sl, GF_AVCConfigSlot ); sl->size = gf_bs_read_int(bs, 16); sl->data = (char *)gf_malloc(sizeof(char) * sl->size); gf_bs_read_data(bs, sl->data, sl->size); gf_list_add(ar->nalus, sl); } } return cfg; }
static GF_Err dc_gpac_video_write_config(VideoOutputFile *video_output_file, u32 *di, u32 track) { GF_Err ret; if (video_output_file->codec_ctx->codec_id == CODEC_ID_H264) { GF_AVCConfig *avccfg; avccfg = gf_odf_avc_cfg_new(); if (!avccfg) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create AVCConfig\n")); return GF_OUT_OF_MEM; } ret = avc_import_ffextradata(video_output_file->codec_ctx->extradata, video_output_file->codec_ctx->extradata_size, avccfg); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot parse AVC/H264 SPS/PPS\n")); gf_odf_avc_cfg_del(avccfg); return ret; } ret = gf_isom_avc_config_new(video_output_file->isof, track, avccfg, NULL, NULL, di); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_avc_config_new\n", gf_error_to_string(ret))); return ret; } gf_odf_avc_cfg_del(avccfg); //inband SPS/PPS if (video_output_file->muxer_type == GPAC_INIT_VIDEO_MUXER_AVC3) { ret = gf_isom_avc_set_inband_config(video_output_file->isof, track, 1); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_avc_set_inband_config\n", gf_error_to_string(ret))); return ret; } } } else if (!strcmp(video_output_file->codec_ctx->codec->name, "libx265")) { //FIXME CODEC_ID_HEVC would break on old releases GF_HEVCConfig *hevccfg = gf_odf_hevc_cfg_new(); if (!hevccfg) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create HEVCConfig\n")); return GF_OUT_OF_MEM; } ret = hevc_import_ffextradata(video_output_file->codec_ctx->extradata, video_output_file->codec_ctx->extradata_size, hevccfg); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot parse HEVC/H265 SPS/PPS\n")); gf_odf_hevc_cfg_del(hevccfg); return ret; } ret = gf_isom_hevc_config_new(video_output_file->isof, track, hevccfg, NULL, NULL, di); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_hevc_config_new\n", gf_error_to_string(ret))); return ret; } gf_odf_hevc_cfg_del(hevccfg); //inband SPS/PPS if (video_output_file->muxer_type == GPAC_INIT_VIDEO_MUXER_AVC3) { ret = gf_isom_hevc_set_inband_config(video_output_file->isof, track, 1); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_hevc_set_inband_config\n", gf_error_to_string(ret))); return ret; } } } return GF_OK; }