diff --git a/libavformat/iamf.h b/libavformat/iamf.h index d88a24c435..0cb0902e86 100644 --- a/libavformat/iamf.h +++ b/libavformat/iamf.h @@ -86,6 +86,11 @@ typedef struct IAMFSubStream { } IAMFSubStream; typedef struct IAMFAudioElement { + const AVIAMFAudioElement *celement; + /** + * element backs celement iff the AVIAMFAudioElement + * is owned by this structure. + */ AVIAMFAudioElement *element; unsigned int audio_element_id; @@ -100,6 +105,11 @@ typedef struct IAMFAudioElement { } IAMFAudioElement; typedef struct IAMFMixPresentation { + const AVIAMFMixPresentation *cmix; + /** + * mix backs cmix iff the AVIAMFMixPresentation + * is owned by this structure. + */ AVIAMFMixPresentation *mix; unsigned int mix_presentation_id; diff --git a/libavformat/iamf_parse.c b/libavformat/iamf_parse.c index a6443f4f3d..50dfd1a6c2 100644 --- a/libavformat/iamf_parse.c +++ b/libavformat/iamf_parse.c @@ -651,6 +651,7 @@ static int audio_element_obu(void *s, IAMFContext *c, AVIOContext *pb, int len) ret = AVERROR(ENOMEM); goto fail; } + audio_element->celement = element; element->audio_element_type = audio_element_type; @@ -809,6 +810,7 @@ static int mix_presentation_obu(void *s, IAMFContext *c, AVIOContext *pb, int le ret = AVERROR(ENOMEM); goto fail; } + mix_presentation->cmix = mix; mix_presentation->count_label = ffio_read_leb(pbc); mix_presentation->language_label = av_calloc(mix_presentation->count_label, diff --git a/libavformat/iamf_writer.c b/libavformat/iamf_writer.c index 9a665dc002..e8a88b44c3 100644 --- a/libavformat/iamf_writer.c +++ b/libavformat/iamf_writer.c @@ -234,7 +234,7 @@ int ff_iamf_add_audio_element(IAMFContext *iamf, const AVStreamGroup *stg, void if (!audio_element) return AVERROR(ENOMEM); - audio_element->element = stg->params.iamf_audio_element; + audio_element->celement = stg->params.iamf_audio_element; audio_element->audio_element_id = stg->id; audio_element->codec_config_id = ret; @@ -329,11 +329,11 @@ int ff_iamf_add_mix_presentation(IAMFContext *iamf, const AVStreamGroup *stg, vo if (!mix_presentation) return AVERROR(ENOMEM); - mix_presentation->mix = stg->params.iamf_mix_presentation; + mix_presentation->cmix = stg->params.iamf_mix_presentation; mix_presentation->mix_presentation_id = stg->id; - for (int i = 0; i < mix_presentation->mix->nb_submixes; i++) { - const AVIAMFSubmix *submix = mix_presentation->mix->submixes[i]; + for (int i = 0; i < mix_presentation->cmix->nb_submixes; i++) { + const AVIAMFSubmix *submix = mix_presentation->cmix->submixes[i]; AVIAMFParamDefinition *param = submix->output_mix_config; IAMFParamDefinition *param_definition; @@ -465,7 +465,7 @@ static inline int rescale_rational(AVRational q, int b) static int scalable_channel_layout_config(const IAMFAudioElement *audio_element, AVIOContext *dyn_bc) { - const AVIAMFAudioElement *element = audio_element->element; + const AVIAMFAudioElement *element = audio_element->celement; uint8_t header[MAX_IAMF_OBU_HEADER_SIZE]; PutBitContext pb; @@ -503,7 +503,7 @@ static int scalable_channel_layout_config(const IAMFAudioElement *audio_element, static int ambisonics_config(const IAMFAudioElement *audio_element, AVIOContext *dyn_bc) { - const AVIAMFAudioElement *element = audio_element->element; + const AVIAMFAudioElement *element = audio_element->celement; AVIAMFLayer *layer = element->layers[0]; ffio_write_leb(dyn_bc, 0); // ambisonics_mode @@ -565,7 +565,7 @@ static int iamf_write_audio_element(const IAMFContext *iamf, const IAMFAudioElement *audio_element, AVIOContext *pb, void *log_ctx) { - const AVIAMFAudioElement *element = audio_element->element; + const AVIAMFAudioElement *element = audio_element->celement; const IAMFCodecConfig *codec_config = iamf->codec_configs[audio_element->codec_config_id]; uint8_t header[MAX_IAMF_OBU_HEADER_SIZE]; AVIOContext *dyn_bc; @@ -669,7 +669,7 @@ static int iamf_write_mixing_presentation(const IAMFContext *iamf, AVIOContext *pb, void *log_ctx) { uint8_t header[MAX_IAMF_OBU_HEADER_SIZE]; - const AVIAMFMixPresentation *mix = mix_presentation->mix; + const AVIAMFMixPresentation *mix = mix_presentation->cmix; const AVDictionaryEntry *tag = NULL; PutBitContext pbc; AVIOContext *dyn_bc; diff --git a/libavformat/iamfdec.c b/libavformat/iamfdec.c index 99622f697b..9b3f4c7429 100644 --- a/libavformat/iamfdec.c +++ b/libavformat/iamfdec.c @@ -232,7 +232,7 @@ static int parameter_block_obu(AVFormatContext *s, int len) case AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN: { AVIAMFReconGain *recon = subblock; const IAMFAudioElement *audio_element = param_definition->audio_element; - const AVIAMFAudioElement *element = audio_element->element; + const AVIAMFAudioElement *element = audio_element->celement; av_assert0(audio_element && element); for (int i = 0; i < element->nb_layers; i++) { @@ -403,7 +403,9 @@ static int iamf_read_header(AVFormatContext *s) av_iamf_audio_element_free(&stg->params.iamf_audio_element); stg->id = audio_element->audio_element_id; + /* Transfer ownership */ stg->params.iamf_audio_element = audio_element->element; + audio_element->element = NULL; for (int j = 0; j < audio_element->nb_substreams; j++) { IAMFSubStream *substream = &audio_element->substreams[j]; @@ -428,20 +430,22 @@ static int iamf_read_header(AVFormatContext *s) for (int i = 0; i < iamf->nb_mix_presentations; i++) { IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i]; AVStreamGroup *stg = avformat_stream_group_create(s, AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION, NULL); - const AVIAMFMixPresentation *mix = mix_presentation->mix; + const AVIAMFMixPresentation *mix = mix_presentation->cmix; if (!stg) return AVERROR(ENOMEM); av_iamf_mix_presentation_free(&stg->params.iamf_mix_presentation); stg->id = mix_presentation->mix_presentation_id; + /* Transfer ownership */ stg->params.iamf_mix_presentation = mix_presentation->mix; + mix_presentation->mix = NULL; for (int j = 0; j < mix->nb_submixes; j++) { - AVIAMFSubmix *sub_mix = mix->submixes[j]; + const AVIAMFSubmix *sub_mix = mix->submixes[j]; for (int k = 0; k < sub_mix->nb_elements; k++) { - AVIAMFSubmixElement *submix_element = sub_mix->elements[k]; + const AVIAMFSubmixElement *submix_element = sub_mix->elements[k]; AVStreamGroup *audio_element = NULL; for (int l = 0; l < s->nb_stream_groups; l++) @@ -467,16 +471,6 @@ static int iamf_read_header(AVFormatContext *s) static int iamf_read_close(AVFormatContext *s) { IAMFDemuxContext *const c = s->priv_data; - IAMFContext *const iamf = &c->iamf; - - for (int i = 0; i < iamf->nb_audio_elements; i++) { - IAMFAudioElement *audio_element = iamf->audio_elements[i]; - audio_element->element = NULL; - } - for (int i = 0; i < iamf->nb_mix_presentations; i++) { - IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i]; - mix_presentation->mix = NULL; - } ff_iamf_uninit_context(&c->iamf); diff --git a/libavformat/iamfenc.c b/libavformat/iamfenc.c index b588a507bb..b5572c79af 100644 --- a/libavformat/iamfenc.c +++ b/libavformat/iamfenc.c @@ -218,7 +218,7 @@ static int write_parameter_block(AVFormatContext *s, const AVIAMFParamDefinition } case AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN: { const AVIAMFReconGain *recon = subblock; - const AVIAMFAudioElement *audio_element = param_definition->audio_element->element; + const AVIAMFAudioElement *audio_element = param_definition->audio_element->celement; if (!param_definition->mode && param->constant_subblock_duration == 0) ffio_write_leb(dyn_bc, recon->subblock_duration); @@ -353,16 +353,6 @@ static void iamf_deinit(AVFormatContext *s) IAMFMuxContext *const c = s->priv_data; IAMFContext *const iamf = &c->iamf; - for (int i = 0; i < iamf->nb_audio_elements; i++) { - IAMFAudioElement *audio_element = iamf->audio_elements[i]; - audio_element->element = NULL; - } - - for (int i = 0; i < iamf->nb_mix_presentations; i++) { - IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i]; - mix_presentation->mix = NULL; - } - ff_iamf_uninit_context(iamf); return;