1 /*
2 * AV3A Parser
3 *
4 * Copyright (c) 2024 Shuai Liu <cqliushuai@outlook.com>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <stdio.h>
24 #include <stdint.h>
25 #include "libavutil/intreadwrite.h"
26 #include "parser.h"
27 #include "get_bits.h"
28 #include "av3a.h"
29
30 typedef struct {
31 int16_t audio_codec_id;
32 int16_t nn_type;
33 int16_t frame_size;
34 int16_t resolution;
35 int32_t sample_rate;
36 int64_t bit_rate;
37
38 int16_t content_type;
39 int16_t channel_number_index;
40 int16_t nb_channels;
41 int16_t nb_objects;
42 int16_t total_channels;
43 } Av3aParseContext;
44
ff_av3a_header_parse(const uint8_t * buf,const int buf_size,AATFHeaderInfo * hdf)45 static int ff_av3a_header_parse(const uint8_t *buf, const int buf_size, AATFHeaderInfo *hdf)
46 {
47 int ret;
48 GetBitContext gb;
49 int64_t soundbed_bitrate = 0L;
50 int64_t object_bitrate = 0L;
51
52 hdf->nb_channels = 0;
53 hdf->nb_objects = 0;
54
55 if ((!buf) || (!hdf)) {
56 return AVERROR(ENOMEM);
57 }
58
59 if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0) {
60 return ret;
61 }
62
63 hdf->sync_word = get_bits(&gb, 12);
64 if (hdf->sync_word != AV3A_AUDIO_SYNC_WORD) {
65 return AVERROR_INVALIDDATA;
66 }
67
68 hdf->audio_codec_id = get_bits(&gb, 4);
69 if (hdf->audio_codec_id != AV3A_LOSSY_CODEC_ID) {
70 return AVERROR_INVALIDDATA;
71 }
72
73 skip_bits(&gb, 1); /* skip anc_data 1 bit */
74
75 hdf->nn_type = get_bits(&gb, 3);
76 if ((hdf->nn_type > AV3A_LC_NN_TYPE) || (hdf->nn_type < AV3A_BASELINE_NN_TYPE)) {
77 return AVERROR_INVALIDDATA;
78 }
79
80 hdf->coding_profile = get_bits(&gb, 3);
81
82 hdf->sampling_frequency_index = get_bits(&gb, 4);
83 if ((hdf->sampling_frequency_index >= AV3A_FS_TABLE_SIZE) || (hdf->sampling_frequency_index < 0)) {
84 return AVERROR_INVALIDDATA;
85 }
86 hdf->sampling_rate = ff_av3a_sampling_rate_table[hdf->sampling_frequency_index];
87
88 skip_bits(&gb, 8); /* skip CRC 8 bits */
89
90 if (hdf->coding_profile == AV3A_BASE_PROFILE) {
91 hdf->content_type = AV3A_CHANNEL_BASED_TYPE;
92 hdf->channel_number_index = get_bits(&gb, 7);
93 if ((hdf->channel_number_index > CHANNEL_CONFIG_MC_7_1_4) ||
94 (hdf->channel_number_index == CHANNEL_CONFIG_MC_10_2) ||
95 (hdf->channel_number_index == CHANNEL_CONFIG_MC_22_2) ||
96 (hdf->channel_number_index < CHANNEL_CONFIG_MONO)) {
97 return AVERROR_INVALIDDATA;
98 }
99 hdf->nb_channels = ff_av3a_channels_map_table[hdf->channel_number_index].channels;
100 } else if (hdf->coding_profile == AV3A_OBJECT_METADATA_PROFILE) {
101 hdf->soundbed_type = get_bits(&gb, 2);
102 if (hdf->soundbed_type == 0) {
103 hdf->content_type = AV3A_OBJECT_BASED_TYPE;
104 hdf->object_channel_number = get_bits(&gb, 7);
105 if (hdf->object_channel_number < 0) {
106 return AVERROR_INVALIDDATA;
107 }
108 hdf->nb_objects = hdf->object_channel_number + 1;
109
110 hdf->bitrate_index_per_channel = get_bits(&gb, 4);
111 if ((hdf->bitrate_index_per_channel >= AV3A_BITRATE_TABLE_SIZE) || (hdf->bitrate_index_per_channel < 0)) {
112 return AVERROR_INVALIDDATA;
113 }
114 object_bitrate = ff_av3a_bitrate_map_table[CHANNEL_CONFIG_MONO].bitrate_table[hdf->bitrate_index_per_channel];
115 hdf->total_bitrate = object_bitrate * hdf->nb_objects;
116 } else if (hdf->soundbed_type == 1) {
117 hdf->content_type = AV3A_CHANNEL_OBJECT_TYPE;
118 hdf->channel_number_index = get_bits(&gb, 7);
119 if ((hdf->channel_number_index > CHANNEL_CONFIG_MC_7_1_4) ||
120 (hdf->channel_number_index == CHANNEL_CONFIG_MC_10_2) ||
121 (hdf->channel_number_index == CHANNEL_CONFIG_MC_22_2) ||
122 (hdf->channel_number_index < CHANNEL_CONFIG_STEREO)) {
123 return AVERROR_INVALIDDATA;
124 }
125
126 hdf->bitrate_index = get_bits(&gb, 4);
127 if ((hdf->bitrate_index >= AV3A_BITRATE_TABLE_SIZE) || (hdf->bitrate_index < 0)) {
128 return AVERROR_INVALIDDATA;
129 }
130 hdf->nb_channels = ff_av3a_channels_map_table[hdf->channel_number_index].channels;
131 soundbed_bitrate = ff_av3a_bitrate_map_table[hdf->channel_number_index].bitrate_table[hdf->bitrate_index];
132
133 hdf->object_channel_number = get_bits(&gb, 7);
134 if (hdf->object_channel_number < 0) {
135 return AVERROR_INVALIDDATA;
136 }
137 hdf->bitrate_index_per_channel = get_bits(&gb, 4);
138 if ((hdf->bitrate_index_per_channel >= AV3A_BITRATE_TABLE_SIZE) || (hdf->bitrate_index_per_channel < 0)) {
139 return AVERROR_INVALIDDATA;
140 }
141 hdf->nb_objects = hdf->object_channel_number + 1;
142 object_bitrate = ff_av3a_bitrate_map_table[CHANNEL_CONFIG_MONO].bitrate_table[hdf->bitrate_index_per_channel];
143 hdf->total_bitrate = soundbed_bitrate + (object_bitrate * hdf->nb_objects);
144 } else {
145 return AVERROR_INVALIDDATA;
146 }
147 } else if (hdf->coding_profile == AV3A_AMBISONIC_PROFILE) {
148 hdf->content_type = AV3A_AMBISONIC_TYPE;
149 hdf->order = get_bits(&gb, 4);
150 hdf->hoa_order = hdf->order + 1;
151
152 switch (hdf->hoa_order) {
153 case AV3A_AMBISONIC_FIRST_ORDER:
154 hdf->channel_number_index = CHANNEL_CONFIG_HOA_ORDER1;
155 break;
156 case AV3A_AMBISONIC_SECOND_ORDER:
157 hdf->channel_number_index = CHANNEL_CONFIG_HOA_ORDER2;
158 break;
159 case AV3A_AMBISONIC_THIRD_ORDER:
160 hdf->channel_number_index = CHANNEL_CONFIG_HOA_ORDER3;
161 break;
162 default:
163 return AVERROR_INVALIDDATA;
164 }
165 hdf->nb_channels = ff_av3a_channels_map_table[hdf->channel_number_index].channels;
166 } else {
167 return AVERROR_INVALIDDATA;
168 }
169 hdf->total_channels = hdf->nb_channels + hdf->nb_objects;
170
171 hdf->resolution_index = get_bits(&gb, 2);
172 if ((hdf->resolution_index >= AV3A_RESOLUTION_TABLE_SIZE) || (hdf->resolution_index < 0)) {
173 return AVERROR_INVALIDDATA;
174 }
175 hdf->resolution = ff_av3a_sample_format_map_table[hdf->resolution_index].resolution;
176 hdf->sample_format = ff_av3a_sample_format_map_table[hdf->resolution_index].sample_format;
177
178 if (hdf->coding_profile != AV3A_OBJECT_METADATA_PROFILE) {
179 hdf->bitrate_index = get_bits(&gb, 4);
180 if ((hdf->bitrate_index >= AV3A_BITRATE_TABLE_SIZE) || (hdf->bitrate_index < 0)) {
181 return AVERROR_INVALIDDATA;
182 }
183 hdf->total_bitrate = ff_av3a_bitrate_map_table[hdf->channel_number_index].bitrate_table[hdf->bitrate_index];
184 }
185
186 skip_bits(&gb, 8); /* skip CRC 8 bits */
187
188 return 0;
189 }
190
raw_av3a_parse(AVCodecParserContext * s,AVCodecContext * avctx,const uint8_t ** poutbuf,int32_t * poutbuf_size,const uint8_t * buf,int32_t buf_size)191 static int raw_av3a_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf,
192 int32_t *poutbuf_size, const uint8_t *buf, int32_t buf_size)
193 {
194 int ret = 0;
195 AATFHeaderInfo hdf;
196
197 if ((!s) || (!avctx) || (!buf) || (buf_size < (AV3A_MAX_NBYTES_HEADER + 7))) {
198 *poutbuf = NULL;
199 *poutbuf_size = 0;
200 return buf_size;
201 }
202
203 if ((ret = ff_av3a_header_parse(buf, AV3A_MAX_NBYTES_HEADER + 7, &hdf)) < 0) {
204 *poutbuf = NULL;
205 *poutbuf_size = 0;
206 return buf_size;
207 }
208
209 avctx->codec_id = AV_CODEC_ID_AVS3DA;
210 avctx->frame_size = AV3A_AUDIO_FRAME_SIZE;
211 avctx->bits_per_raw_sample = hdf.resolution;
212 avctx->sample_rate = hdf.sampling_rate;
213 avctx->bit_rate = hdf.total_bitrate;
214
215 avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
216 avctx->ch_layout.nb_channels = hdf.total_channels;
217
218 *poutbuf = buf;
219 *poutbuf_size = buf_size;
220
221 return buf_size;
222 }
223
224 const AVCodecParser ff_av3a_parser = {
225 .codec_ids = { AV_CODEC_ID_AVS3DA },
226 .priv_data_size = sizeof(Av3aParseContext),
227 .parser_parse = raw_av3a_parse,
228 };