FFmpeg
Loading...
Searching...
No Matches
iamfdec.c
Go to the documentation of this file.
1/*
2 * Immersive Audio Model and Formats demuxer
3 * Copyright (c) 2023 James Almer <jamrial@gmail.com>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include "libavutil/avassert.h"
24#include "avformat.h"
25#include "demux.h"
26#include "iamf.h"
27#include "iamf_reader.h"
28#include "iamf_parse.h"
29#include "internal.h"
30
31//return < 0 if we need more data
32static int get_score(const uint8_t *buf, int buf_size, enum IAMF_OBU_Type type, int *seq)
33{
35 if (buf_size < 4 || AV_RB32(buf) != MKBETAG('i','a','m','f'))
36 return 0;
37 *seq = 1;
38 return -1;
39 }
41 return *seq ? -1 : 0;
43 return *seq ? AVPROBE_SCORE_EXTENSION + 1 : 0;
44 return 0;
45}
46
47static int iamf_probe(const AVProbeData *p)
48{
49 unsigned obu_size;
51 int seq = 0, cnt = 0, start_pos;
52 int ret;
53
54 while (1) {
55 int size = ff_iamf_parse_obu_header(p->buf + cnt, p->buf_size - cnt,
56 &obu_size, &start_pos, &type,
57 NULL, NULL);
58 if (size < 0)
59 return 0;
60
61 ret = get_score(p->buf + cnt + start_pos,
62 p->buf_size - cnt - start_pos,
63 type, &seq);
64 if (ret >= 0)
65 return ret;
66
67 cnt += FFMIN(size, p->buf_size - cnt);
68 }
69 return 0;
70}
71
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];
85
86 if (!stg)
87 return AVERROR(ENOMEM);
88
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];
98
99 if (!st)
100 return AVERROR(ENOMEM);
101
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)
112 else if (audio_element->nb_layers > 1 || audio_element->layers[0].substream_count > 1)
114 st->id = substream->audio_substream_id;
116 }
117 }
118
119 for (int i = 0; i < iamf->nb_mix_presentations; i++) {
120 IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
122 const AVIAMFMixPresentation *mix = mix_presentation->cmix;
123
124 if (!stg)
125 return AVERROR(ENOMEM);
126
128 stg->id = mix_presentation->mix_presentation_id;
129 /* Transfer ownership */
130 stg->params.iamf_mix_presentation = mix_presentation->mix;
131 mix_presentation->mix = NULL;
132
133 for (int j = 0; j < mix->nb_submixes; j++) {
134 const AVIAMFSubmix *sub_mix = mix->submixes[j];
135
136 for (int k = 0; k < sub_mix->nb_elements; k++) {
137 const AVIAMFSubmixElement *submix_element = sub_mix->elements[k];
138 AVStreamGroup *audio_element = NULL;
139
140 for (int l = 0; l < s->nb_stream_groups; l++)
141 if (s->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
142 s->stream_groups[l]->id == submix_element->audio_element_id) {
143 audio_element = s->stream_groups[l];
144 break;
145 }
146 av_assert0(audio_element);
147
148 for (int l = 0; l < audio_element->nb_streams; l++) {
149 ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
150 if (ret < 0 && ret != AVERROR(EEXIST))
151 return ret;
152 }
153 }
154 }
155 }
156
157 if (!s->nb_streams)
158 return AVERROR_INVALIDDATA;
159
160 return 0;
161}
162
164{
165 IAMFDemuxContext *const c = s->priv_data;
166 int ret;
167
168 ret = ff_iamf_read_packet(s, c, s->pb, INT_MAX, 0, pkt);
169 if (ret < 0)
170 return ret;
171
172 return 0;
173}
174
176{
177 IAMFDemuxContext *const c = s->priv_data;
178
180
181 return 0;
182}
183
185 .p.name = "iamf",
186 .p.long_name = NULL_IF_CONFIG_SMALL("Raw Immersive Audio Model and Formats"),
187 .p.extensions = "iamf",
189 .priv_data_size = sizeof(IAMFDemuxContext),
190 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
195};
const FFInputFormat ff_iamf_demuxer
Definition iamfdec.c:184
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:834
Main libavformat public API header.
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition avformat.h:1149
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition avformat.h:1148
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition avformat.h:506
#define AV_DISPOSITION_DEPENDENT
The stream is intended to be mixed with another stream before presentation.
Definition avformat.h:727
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition avformat.h:481
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition avformat.h:496
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition avformat.h:499
#define AVFMT_NOTIMESTAMPS
Format does not need / have any timestamps.
Definition avformat.h:498
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition avformat.h:639
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
static int read_probe(const AVProbeData *p)
Definition cdg.c:30
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Definition codec_par.c:107
#define NULL
Definition coverity.c:32
#define FF_INFMT_FLAG_INIT_CLEANUP
For an FFInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition demux.h:35
static AVPacket * pkt
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
AVStreamGroup * avformat_stream_group_create(AVFormatContext *s, enum AVStreamGroupParamsType type, AVDictionary **options)
Add a new empty stream group to a media file.
Definition options.c:470
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
Add an already allocated stream to a stream group.
Definition options.c:558
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition iamf.c:338
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition iamf.c:536
cl_device_type type
int ff_iamf_parse_obu_header(const uint8_t *buf, int buf_size, unsigned *obu_size, int *start_pos, enum IAMF_OBU_Type *type, unsigned *skip_samples, unsigned *discard_padding)
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
void ff_iamf_read_deinit(IAMFDemuxContext *c)
static int get_score(const uint8_t *buf, int buf_size, enum IAMF_OBU_Type type, int *seq)
Definition iamfdec.c:32
static int iamf_probe(const AVProbeData *p)
Definition iamfdec.c:47
static int iamf_read_header(AVFormatContext *s)
Definition iamfdec.c:72
static int iamf_read_close(AVFormatContext *s)
Definition iamfdec.c:175
static int iamf_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition iamfdec.c:163
#define AV_RB32(p)
static int mix(int c0, int c1)
Definition 4xm.c:717
IAMF_OBU_Type
Definition iamf.h:37
@ IAMF_OBU_IA_AUDIO_FRAME
Definition iamf.h:43
@ IAMF_OBU_IA_SEQUENCE_HEADER
Definition iamf.h:63
@ IAMF_OBU_IA_TEMPORAL_DELIMITER
Definition iamf.h:42
@ IAMF_OBU_IA_CODEC_CONFIG
Definition iamf.h:38
@ IAMF_OBU_IA_AUDIO_FRAME_ID17
Definition iamf.h:61
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
static av_cold int read_close(AVFormatContext *ctx)
Definition libcdio.c:143
#define FFMIN(a, b)
Definition macros.h:49
#define MKBETAG(a, b, c, d)
Definition macros.h:56
int sample_rate
The number of audio samples per second.
Definition codec_par.h:213
Format I/O context.
Definition avformat.h:1333
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition iamf.h:616
Submix element as defined in section 3.7 of IAMF.
Definition iamf.h:449
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition iamf.h:455
Submix layout as defined in section 3.7 of IAMF.
Definition iamf.h:559
unsigned int nb_elements
Number of elements in the submix.
Definition iamf.h:575
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition iamf.h:568
This structure stores compressed data.
Definition packet.h:580
This structure contains the data a format has to probe a file.
Definition avformat.h:471
union AVStreamGroup::@166361102046003066253145020066347265153020354020 params
Group type-specific parameters.
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition avformat.h:1193
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition avformat.h:1221
struct AVIAMFAudioElement * iamf_audio_element
Definition avformat.h:1192
int64_t id
Group type-specific group ID.
Definition avformat.h:1178
AVStream ** streams
A list of streams in the group.
Definition avformat.h:1234
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
int id
Format-specific stream ID.
Definition avformat.h:778
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition avformat.h:835
IAMFLayer * layers
Definition iamf.h:103
unsigned int audio_element_id
Definition iamf.h:96
unsigned int nb_layers
Definition iamf.h:104
AVIAMFAudioElement * element
element backs celement iff the AVIAMFAudioElement is owned by this structure.
Definition iamf.h:95
unsigned int nb_substreams
Definition iamf.h:99
IAMFSubStream * substreams
Definition iamf.h:98
int nb_mix_presentations
Definition iamf.h:134
IAMFMixPresentation ** mix_presentations
Definition iamf.h:133
IAMFAudioElement ** audio_elements
Definition iamf.h:131
int nb_audio_elements
Definition iamf.h:132
unsigned int substream_count
Definition iamf.h:78
AVIAMFMixPresentation * mix
mix backs cmix iff the AVIAMFMixPresentation is owned by this structure.
Definition iamf.h:113
const AVIAMFMixPresentation * cmix
Definition iamf.h:108
unsigned int mix_presentation_id
Definition iamf.h:114
AVCodecParameters * codecpar
Definition iamf.h:86
unsigned int audio_substream_id
Definition iamf.h:83
int size
static double c[64]