| 70 | } |
| 71 | |
| 72 | static int iamf_read_header(AVFormatContext *s) |
| 73 | { |
| 74 | IAMFDemuxContext *const c = s->priv_data; |
| 75 | IAMFContext *const iamf = &c->iamf; |
| 76 | int ret; |
| 77 | |
| 78 | ret = ff_iamfdec_read_descriptors(iamf, s->pb, INT_MAX, s); |
| 79 | if (ret < 0) |
| 80 | return ret; |
| 81 | |
| 82 | for (int i = 0; i < iamf->nb_audio_elements; i++) { |
| 83 | IAMFAudioElement *audio_element = iamf->audio_elements[i]; |
| 84 | AVStreamGroup *stg = avformat_stream_group_create(s, AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT, NULL); |
| 85 | |
| 86 | if (!stg) |
| 87 | return AVERROR(ENOMEM); |
| 88 | |
| 89 | av_iamf_audio_element_free(&stg->params.iamf_audio_element); |
| 90 | stg->id = audio_element->audio_element_id; |
| 91 | /* Transfer ownership */ |
| 92 | stg->params.iamf_audio_element = audio_element->element; |
| 93 | audio_element->element = NULL; |
| 94 | |
| 95 | for (int j = 0; j < audio_element->nb_substreams; j++) { |
| 96 | IAMFSubStream *substream = &audio_element->substreams[j]; |
| 97 | AVStream *st = avformat_new_stream(s, NULL); |
| 98 | |
| 99 | if (!st) |
| 100 | return AVERROR(ENOMEM); |
| 101 | |
| 102 | ret = avformat_stream_group_add_stream(stg, st); |
| 103 | if (ret < 0) |
| 104 | return ret; |
| 105 | |
| 106 | ret = avcodec_parameters_copy(st->codecpar, substream->codecpar); |
| 107 | if (ret < 0) |
| 108 | return ret; |
| 109 | |
| 110 | if (!i && !j && audio_element->layers[0].substream_count == 1) |
| 111 | st->disposition |= AV_DISPOSITION_DEFAULT; |
| 112 | else if (audio_element->nb_layers > 1 || audio_element->layers[0].substream_count > 1) |
| 113 | st->disposition |= AV_DISPOSITION_DEPENDENT; |
| 114 | st->id = substream->audio_substream_id; |
| 115 | avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | for (int i = 0; i < iamf->nb_mix_presentations; i++) { |
| 120 | IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i]; |
| 121 | AVStreamGroup *stg = avformat_stream_group_create(s, AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION, NULL); |
| 122 | const AVIAMFMixPresentation *mix = mix_presentation->cmix; |
| 123 | |
| 124 | if (!stg) |
| 125 | return AVERROR(ENOMEM); |
| 126 | |
| 127 | av_iamf_mix_presentation_free(&stg->params.iamf_mix_presentation); |
| 128 | stg->id = mix_presentation->mix_presentation_id; |
| 129 | /* Transfer ownership */ |
nothing calls this directly
no test coverage detected