Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * ISO Media common code | ||
3 | * Copyright (c) 2001 Fabrice Bellard | ||
4 | * Copyright (c) 2002 Francois Revol <revol@free.fr> | ||
5 | * Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr> | ||
6 | * | ||
7 | * This file is part of FFmpeg. | ||
8 | * | ||
9 | * FFmpeg is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU Lesser General Public | ||
11 | * License as published by the Free Software Foundation; either | ||
12 | * version 2.1 of the License, or (at your option) any later version. | ||
13 | * | ||
14 | * FFmpeg is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * Lesser General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU Lesser General Public | ||
20 | * License along with FFmpeg; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
22 | */ | ||
23 | |||
24 | #include "avformat.h" | ||
25 | #include "demux.h" | ||
26 | #include "internal.h" | ||
27 | #include "isom.h" | ||
28 | #include "libavcodec/mpeg4audio.h" | ||
29 | #include "libavcodec/mpegaudiodata.h" | ||
30 | #include "libavutil/channel_layout.h" | ||
31 | |||
32 | /* http://www.mp4ra.org */ | ||
33 | /* ordered by muxing preference */ | ||
34 | const AVCodecTag ff_mp4_obj_type[] = { | ||
35 | { AV_CODEC_ID_MOV_TEXT , 0x08 }, | ||
36 | { AV_CODEC_ID_MPEG4 , 0x20 }, | ||
37 | { AV_CODEC_ID_H264 , 0x21 }, | ||
38 | { AV_CODEC_ID_HEVC , 0x23 }, | ||
39 | { AV_CODEC_ID_VVC , 0x33 }, | ||
40 | { AV_CODEC_ID_AAC , 0x40 }, | ||
41 | { AV_CODEC_ID_MP4ALS , 0x40 }, /* 14496-3 ALS */ | ||
42 | { AV_CODEC_ID_MPEG2VIDEO , 0x61 }, /* MPEG-2 Main */ | ||
43 | { AV_CODEC_ID_MPEG2VIDEO , 0x60 }, /* MPEG-2 Simple */ | ||
44 | { AV_CODEC_ID_MPEG2VIDEO , 0x62 }, /* MPEG-2 SNR */ | ||
45 | { AV_CODEC_ID_MPEG2VIDEO , 0x63 }, /* MPEG-2 Spatial */ | ||
46 | { AV_CODEC_ID_MPEG2VIDEO , 0x64 }, /* MPEG-2 High */ | ||
47 | { AV_CODEC_ID_MPEG2VIDEO , 0x65 }, /* MPEG-2 422 */ | ||
48 | { AV_CODEC_ID_AAC , 0x66 }, /* MPEG-2 AAC Main */ | ||
49 | { AV_CODEC_ID_AAC , 0x67 }, /* MPEG-2 AAC Low */ | ||
50 | { AV_CODEC_ID_AAC , 0x68 }, /* MPEG-2 AAC SSR */ | ||
51 | { AV_CODEC_ID_MP3 , 0x69 }, /* 13818-3 */ | ||
52 | { AV_CODEC_ID_MP2 , 0x69 }, /* 11172-3 */ | ||
53 | { AV_CODEC_ID_MPEG1VIDEO , 0x6A }, /* 11172-2 */ | ||
54 | { AV_CODEC_ID_MP3 , 0x6B }, /* 11172-3 */ | ||
55 | { AV_CODEC_ID_MJPEG , 0x6C }, /* 10918-1 */ | ||
56 | { AV_CODEC_ID_PNG , 0x6D }, | ||
57 | { AV_CODEC_ID_JPEG2000 , 0x6E }, /* 15444-1 */ | ||
58 | { AV_CODEC_ID_VC1 , 0xA3 }, | ||
59 | { AV_CODEC_ID_DIRAC , 0xA4 }, | ||
60 | { AV_CODEC_ID_AC3 , 0xA5 }, | ||
61 | { AV_CODEC_ID_EAC3 , 0xA6 }, | ||
62 | { AV_CODEC_ID_DTS , 0xA9 }, /* mp4ra.org */ | ||
63 | { AV_CODEC_ID_OPUS , 0xAD }, /* mp4ra.org */ | ||
64 | { AV_CODEC_ID_VP9 , 0xB1 }, /* mp4ra.org */ | ||
65 | { AV_CODEC_ID_TSCC2 , 0xD0 }, /* nonstandard, camtasia uses it */ | ||
66 | { AV_CODEC_ID_EVRC , 0xD1 }, /* nonstandard, pvAuthor uses it */ | ||
67 | { AV_CODEC_ID_VORBIS , 0xDD }, /* nonstandard, gpac uses it */ | ||
68 | { AV_CODEC_ID_DVD_SUBTITLE, 0xE0 }, /* nonstandard, see unsupported-embedded-subs-2.mp4 */ | ||
69 | { AV_CODEC_ID_QCELP , 0xE1 }, | ||
70 | { AV_CODEC_ID_MPEG4SYSTEMS, 0x01 }, | ||
71 | { AV_CODEC_ID_MPEG4SYSTEMS, 0x02 }, | ||
72 | { AV_CODEC_ID_NONE , 0 }, | ||
73 | }; | ||
74 | |||
75 | const AVCodecTag ff_codec_movsubtitle_tags[] = { | ||
76 | { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'e', 'x', 't') }, | ||
77 | { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') }, | ||
78 | { AV_CODEC_ID_EIA_608, MKTAG('c', '6', '0', '8') }, | ||
79 | { AV_CODEC_ID_NONE, 0 }, | ||
80 | }; | ||
81 | |||
82 | const AVCodecTag ff_codec_movdata_tags[] = { | ||
83 | { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') }, | ||
84 | { AV_CODEC_ID_NONE, 0 }, | ||
85 | }; | ||
86 | |||
87 | /* map numeric codes from mdhd atom to ISO 639 */ | ||
88 | /* cf. QTFileFormat.pdf p253, qtff.pdf p205 */ | ||
89 | /* http://developer.apple.com/documentation/mac/Text/Text-368.html */ | ||
90 | /* deprecated by putting the code as 3*5 bits ASCII */ | ||
91 | static const char mov_mdhd_language_map[][4] = { | ||
92 | "eng", /* 0 English */ | ||
93 | "fra", /* 1 French */ | ||
94 | "ger", /* 2 German */ | ||
95 | "ita", /* 3 Italian */ | ||
96 | "dut", /* 4 Dutch */ | ||
97 | "sve", /* 5 Swedish */ | ||
98 | "spa", /* 6 Spanish */ | ||
99 | "dan", /* 7 Danish */ | ||
100 | "por", /* 8 Portuguese */ | ||
101 | "nor", /* 9 Norwegian */ | ||
102 | "heb", /* 10 Hebrew */ | ||
103 | "jpn", /* 11 Japanese */ | ||
104 | "ara", /* 12 Arabic */ | ||
105 | "fin", /* 13 Finnish */ | ||
106 | "gre", /* 14 Greek */ | ||
107 | "ice", /* 15 Icelandic */ | ||
108 | "mlt", /* 16 Maltese */ | ||
109 | "tur", /* 17 Turkish */ | ||
110 | "hr ", /* 18 Croatian */ | ||
111 | "chi", /* 19 Traditional Chinese */ | ||
112 | "urd", /* 20 Urdu */ | ||
113 | "hin", /* 21 Hindi */ | ||
114 | "tha", /* 22 Thai */ | ||
115 | "kor", /* 23 Korean */ | ||
116 | "lit", /* 24 Lithuanian */ | ||
117 | "pol", /* 25 Polish */ | ||
118 | "hun", /* 26 Hungarian */ | ||
119 | "est", /* 27 Estonian */ | ||
120 | "lav", /* 28 Latvian */ | ||
121 | "smi", /* 29 Sami */ | ||
122 | "fo ", /* 30 Faroese */ | ||
123 | "per", /* 31 Farsi */ | ||
124 | "rus", /* 32 Russian */ | ||
125 | "chi", /* 33 Simplified Chinese */ | ||
126 | "", /* 34 Flemish */ | ||
127 | "iri", /* 35 Irish */ | ||
128 | "alb", /* 36 Albanian */ | ||
129 | "ron", /* 37 Romanian */ | ||
130 | "ces", /* 38 Czech */ | ||
131 | "slk", /* 39 Slovak */ | ||
132 | "slv", /* 40 Slovenian */ | ||
133 | "yid", /* 41 Yiddish */ | ||
134 | "sr ", /* 42 Serbian */ | ||
135 | "mac", /* 43 Macedonian */ | ||
136 | "bul", /* 44 Bulgarian */ | ||
137 | "ukr", /* 45 Ukrainian */ | ||
138 | "bel", /* 46 Belarusian */ | ||
139 | "uzb", /* 47 Uzbek */ | ||
140 | "kaz", /* 48 Kazakh */ | ||
141 | "aze", /* 49 Azerbaijani */ | ||
142 | "aze", /* 50 AzerbaijanAr */ | ||
143 | "arm", /* 51 Armenian */ | ||
144 | "geo", /* 52 Georgian */ | ||
145 | "mol", /* 53 Moldavian */ | ||
146 | "kir", /* 54 Kirghiz */ | ||
147 | "tgk", /* 55 Tajiki */ | ||
148 | "tuk", /* 56 Turkmen */ | ||
149 | "mon", /* 57 Mongolian */ | ||
150 | "", /* 58 MongolianCyr */ | ||
151 | "pus", /* 59 Pashto */ | ||
152 | "kur", /* 60 Kurdish */ | ||
153 | "kas", /* 61 Kashmiri */ | ||
154 | "snd", /* 62 Sindhi */ | ||
155 | "tib", /* 63 Tibetan */ | ||
156 | "nep", /* 64 Nepali */ | ||
157 | "san", /* 65 Sanskrit */ | ||
158 | "mar", /* 66 Marathi */ | ||
159 | "ben", /* 67 Bengali */ | ||
160 | "asm", /* 68 Assamese */ | ||
161 | "guj", /* 69 Gujarati */ | ||
162 | "pa ", /* 70 Punjabi */ | ||
163 | "ori", /* 71 Oriya */ | ||
164 | "mal", /* 72 Malayalam */ | ||
165 | "kan", /* 73 Kannada */ | ||
166 | "tam", /* 74 Tamil */ | ||
167 | "tel", /* 75 Telugu */ | ||
168 | "sin", /* 76 Sinhala */ | ||
169 | "bur", /* 77 Burmese */ | ||
170 | "khm", /* 78 Khmer */ | ||
171 | "lao", /* 79 Lao */ | ||
172 | "vie", /* 80 Vietnamese */ | ||
173 | "ind", /* 81 Indonesian */ | ||
174 | "tgl", /* 82 Tagalog */ | ||
175 | "may", /* 83 MalayRoman */ | ||
176 | "may", /* 84 MalayArabic */ | ||
177 | "amh", /* 85 Amharic */ | ||
178 | "tir", /* 86 Galla */ | ||
179 | "orm", /* 87 Oromo */ | ||
180 | "som", /* 88 Somali */ | ||
181 | "swa", /* 89 Swahili */ | ||
182 | "kin", /* 90 Kinyarwanda */ | ||
183 | "run", /* 91 Rundi */ | ||
184 | "nya", /* 92 Nyanja */ | ||
185 | "mlg", /* 93 Malagasy */ | ||
186 | "epo", /* 94 Esperanto */ | ||
187 | "", /* 95 */ | ||
188 | "", /* 96 */ | ||
189 | "", /* 97 */ | ||
190 | "", /* 98 */ | ||
191 | "", /* 99 */ | ||
192 | "", /* 100 */ | ||
193 | "", /* 101 */ | ||
194 | "", /* 102 */ | ||
195 | "", /* 103 */ | ||
196 | "", /* 104 */ | ||
197 | "", /* 105 */ | ||
198 | "", /* 106 */ | ||
199 | "", /* 107 */ | ||
200 | "", /* 108 */ | ||
201 | "", /* 109 */ | ||
202 | "", /* 110 */ | ||
203 | "", /* 111 */ | ||
204 | "", /* 112 */ | ||
205 | "", /* 113 */ | ||
206 | "", /* 114 */ | ||
207 | "", /* 115 */ | ||
208 | "", /* 116 */ | ||
209 | "", /* 117 */ | ||
210 | "", /* 118 */ | ||
211 | "", /* 119 */ | ||
212 | "", /* 120 */ | ||
213 | "", /* 121 */ | ||
214 | "", /* 122 */ | ||
215 | "", /* 123 */ | ||
216 | "", /* 124 */ | ||
217 | "", /* 125 */ | ||
218 | "", /* 126 */ | ||
219 | "", /* 127 */ | ||
220 | "wel", /* 128 Welsh */ | ||
221 | "baq", /* 129 Basque */ | ||
222 | "cat", /* 130 Catalan */ | ||
223 | "lat", /* 131 Latin */ | ||
224 | "que", /* 132 Quechua */ | ||
225 | "grn", /* 133 Guarani */ | ||
226 | "aym", /* 134 Aymara */ | ||
227 | "tat", /* 135 Tatar */ | ||
228 | "uig", /* 136 Uighur */ | ||
229 | "dzo", /* 137 Dzongkha */ | ||
230 | "jav", /* 138 JavaneseRom */ | ||
231 | }; | ||
232 | |||
233 | 321 | int ff_mov_iso639_to_lang(const char lang[4], int mp4) | |
234 | { | ||
235 | 321 | int i, code = 0; | |
236 | |||
237 | /* old way, only for QT? */ | ||
238 |
5/6✓ Branch 0 taken 21866 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21710 times.
✓ Branch 3 taken 156 times.
✓ Branch 4 taken 21555 times.
✓ Branch 5 taken 155 times.
|
21866 | for (i = 0; lang[0] && !mp4 && i < FF_ARRAY_ELEMS(mov_mdhd_language_map); i++) { |
239 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 21545 times.
|
21555 | if (!strcmp(lang, mov_mdhd_language_map[i])) |
240 | 10 | return i; | |
241 | } | ||
242 | /* XXX:can we do that in mov too? */ | ||
243 |
2/2✓ Branch 0 taken 155 times.
✓ Branch 1 taken 156 times.
|
311 | if (!mp4) |
244 | 155 | return -1; | |
245 | /* handle undefined as such */ | ||
246 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 156 times.
|
156 | if (lang[0] == '\0') |
247 | ✗ | lang = "und"; | |
248 | /* 5 bits ASCII */ | ||
249 |
2/2✓ Branch 0 taken 468 times.
✓ Branch 1 taken 156 times.
|
624 | for (i = 0; i < 3; i++) { |
250 | 468 | uint8_t c = lang[i]; | |
251 | 468 | c -= 0x60; | |
252 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 468 times.
|
468 | if (c > 0x1f) |
253 | ✗ | return -1; | |
254 | 468 | code <<= 5; | |
255 | 468 | code |= c; | |
256 | } | ||
257 | 156 | return code; | |
258 | } | ||
259 | |||
260 | 692 | int ff_mov_lang_to_iso639(unsigned code, char to[4]) | |
261 | { | ||
262 | int i; | ||
263 | 692 | memset(to, 0, 4); | |
264 | /* is it the mangled iso code? */ | ||
265 | /* see http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt */ | ||
266 |
4/4✓ Branch 0 taken 487 times.
✓ Branch 1 taken 205 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 172 times.
|
692 | if (code >= 0x400 && code != 0x7fff) { |
267 |
2/2✓ Branch 0 taken 945 times.
✓ Branch 1 taken 315 times.
|
1260 | for (i = 2; i >= 0; i--) { |
268 | 945 | to[i] = 0x60 + (code & 0x1f); | |
269 | 945 | code >>= 5; | |
270 | } | ||
271 | 315 | return 1; | |
272 | } | ||
273 | /* old fashion apple lang code */ | ||
274 |
2/2✓ Branch 0 taken 172 times.
✓ Branch 1 taken 205 times.
|
377 | if (code >= FF_ARRAY_ELEMS(mov_mdhd_language_map)) |
275 | 172 | return 0; | |
276 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 205 times.
|
205 | if (!mov_mdhd_language_map[code][0]) |
277 | ✗ | return 0; | |
278 | 205 | memcpy(to, mov_mdhd_language_map[code], 4); | |
279 | 205 | return 1; | |
280 | } | ||
281 | |||
282 | 994 | int ff_mp4_read_descr_len(AVIOContext *pb) | |
283 | { | ||
284 | 994 | int len = 0; | |
285 | 994 | int count = 4; | |
286 |
1/2✓ Branch 0 taken 2421 times.
✗ Branch 1 not taken.
|
2421 | while (count--) { |
287 | 2421 | int c = avio_r8(pb); | |
288 | 2421 | len = (len << 7) | (c & 0x7f); | |
289 |
2/2✓ Branch 0 taken 994 times.
✓ Branch 1 taken 1427 times.
|
2421 | if (!(c & 0x80)) |
290 | 994 | break; | |
291 | } | ||
292 | 994 | return len; | |
293 | } | ||
294 | |||
295 | 454 | int ff_mp4_read_descr(void *logctx, AVIOContext *pb, int *tag) | |
296 | { | ||
297 | int len; | ||
298 | 454 | *tag = avio_r8(pb); | |
299 | 454 | len = ff_mp4_read_descr_len(pb); | |
300 | 454 | av_log(logctx, AV_LOG_TRACE, "MPEG-4 description: tag=0x%02x len=%d\n", *tag, len); | |
301 | 454 | return len; | |
302 | } | ||
303 | |||
304 | 150 | void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id) | |
305 | { | ||
306 | int flags; | ||
307 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 150 times.
|
150 | if (es_id) *es_id = avio_rb16(pb); |
308 | 150 | else avio_rb16(pb); | |
309 | 150 | flags = avio_r8(pb); | |
310 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 150 times.
|
150 | if (flags & 0x80) //streamDependenceFlag |
311 | ✗ | avio_rb16(pb); | |
312 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 150 times.
|
150 | if (flags & 0x40) { //URL_Flag |
313 | ✗ | int len = avio_r8(pb); | |
314 | ✗ | avio_skip(pb, len); | |
315 | } | ||
316 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 150 times.
|
150 | if (flags & 0x20) //OCRstreamFlag |
317 | ✗ | avio_rb16(pb); | |
318 | 150 | } | |
319 | |||
320 | static const AVCodecTag mp4_audio_types[] = { | ||
321 | { AV_CODEC_ID_MP3ON4, AOT_PS }, /* old mp3on4 draft */ | ||
322 | { AV_CODEC_ID_MP3ON4, AOT_L1 }, /* layer 1 */ | ||
323 | { AV_CODEC_ID_MP3ON4, AOT_L2 }, /* layer 2 */ | ||
324 | { AV_CODEC_ID_MP3ON4, AOT_L3 }, /* layer 3 */ | ||
325 | { AV_CODEC_ID_MP4ALS, AOT_ALS }, /* MPEG-4 ALS */ | ||
326 | { AV_CODEC_ID_NONE, AOT_NULL }, | ||
327 | }; | ||
328 | |||
329 | 150 | int ff_mp4_read_dec_config_descr(void *logctx, AVStream *st, AVIOContext *pb) | |
330 | { | ||
331 | enum AVCodecID codec_id; | ||
332 | int len, tag; | ||
333 | int ret; | ||
334 | 150 | int object_type_id = avio_r8(pb); | |
335 | 150 | avio_r8(pb); /* stream type */ | |
336 | 150 | avio_rb24(pb); /* buffer size db */ | |
337 | 150 | avio_rb32(pb); /* rc_max_rate */ | |
338 | |||
339 | 150 | st->codecpar->bit_rate = avio_rb32(pb); /* avg bitrate */ | |
340 | |||
341 | 150 | codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id); | |
342 |
1/2✓ Branch 0 taken 150 times.
✗ Branch 1 not taken.
|
150 | if (codec_id) |
343 | 150 | st->codecpar->codec_id = codec_id; | |
344 | 150 | av_log(logctx, AV_LOG_TRACE, "esds object type id 0x%02x\n", object_type_id); | |
345 | 150 | len = ff_mp4_read_descr(logctx, pb, &tag); | |
346 |
2/2✓ Branch 0 taken 149 times.
✓ Branch 1 taken 1 times.
|
150 | if (tag == MP4DecSpecificDescrTag) { |
347 | 149 | av_log(logctx, AV_LOG_TRACE, "Specific MPEG-4 header len=%d\n", len); | |
348 | /* As per 14496-3:2009 9.D.2.2, No decSpecificInfo is defined | ||
349 | for MPEG-1 Audio or MPEG-2 Audio; MPEG-2 AAC excluded. */ | ||
350 |
2/4✓ Branch 0 taken 149 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 149 times.
|
149 | if (object_type_id == 0x69 || object_type_id == 0x6b) |
351 | ✗ | return 0; | |
352 |
2/4✓ Branch 0 taken 149 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 149 times.
|
149 | if (!len || (uint64_t)len > (1<<30)) |
353 | ✗ | return AVERROR_INVALIDDATA; | |
354 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 149 times.
|
149 | if ((ret = ff_get_extradata(logctx, st->codecpar, pb, len)) < 0) |
355 | ✗ | return ret; | |
356 |
2/2✓ Branch 0 taken 123 times.
✓ Branch 1 taken 26 times.
|
149 | if (st->codecpar->codec_id == AV_CODEC_ID_AAC) { |
357 | 123 | MPEG4AudioConfig cfg = {0}; | |
358 | 123 | ret = avpriv_mpeg4audio_get_config2(&cfg, st->codecpar->extradata, | |
359 | 123 | st->codecpar->extradata_size, 1, logctx); | |
360 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
|
123 | if (ret < 0) |
361 | ✗ | return ret; | |
362 |
2/2✓ Branch 0 taken 50 times.
✓ Branch 1 taken 73 times.
|
123 | if (cfg.channels != st->codecpar->ch_layout.nb_channels) { |
363 | 50 | av_channel_layout_uninit(&st->codecpar->ch_layout); | |
364 | 50 | st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; | |
365 | 50 | st->codecpar->ch_layout.nb_channels = cfg.channels; | |
366 | } | ||
367 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
123 | if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4 |
368 | ✗ | st->codecpar->sample_rate = ff_mpa_freq_tab[cfg.sampling_index]; | |
369 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 95 times.
|
123 | else if (cfg.ext_sample_rate) |
370 | 28 | st->codecpar->sample_rate = cfg.ext_sample_rate; | |
371 | else | ||
372 | 95 | st->codecpar->sample_rate = cfg.sample_rate; | |
373 | 123 | av_log(logctx, AV_LOG_TRACE, "mp4a config channels %d obj %d ext obj %d " | |
374 | "sample rate %d ext sample rate %d\n", cfg.channels, | ||
375 | cfg.object_type, cfg.ext_object_type, | ||
376 | cfg.sample_rate, cfg.ext_sample_rate); | ||
377 |
2/2✓ Branch 0 taken 116 times.
✓ Branch 1 taken 7 times.
|
123 | if (!(st->codecpar->codec_id = ff_codec_get_id(mp4_audio_types, |
378 | 123 | cfg.object_type))) | |
379 | 116 | st->codecpar->codec_id = AV_CODEC_ID_AAC; | |
380 | } | ||
381 | } | ||
382 | 150 | return 0; | |
383 | } | ||
384 | |||
385 | typedef struct MovChannelLayout { | ||
386 | int64_t channel_layout; | ||
387 | uint32_t layout_tag; | ||
388 | } MovChannelLayout; | ||
389 | |||
390 | static const MovChannelLayout mov_channel_layout[] = { | ||
391 | { AV_CH_LAYOUT_MONO, (100<<16) | 1}, // kCAFChannelLayoutTag_Mono | ||
392 | { AV_CH_LAYOUT_STEREO, (101<<16) | 2}, // kCAFChannelLayoutTag_Stereo | ||
393 | { AV_CH_LAYOUT_STEREO, (102<<16) | 2}, // kCAFChannelLayoutTag_StereoHeadphones | ||
394 | { AV_CH_LAYOUT_2_1, (131<<16) | 3}, // kCAFChannelLayoutTag_ITU_2_1 | ||
395 | { AV_CH_LAYOUT_QUAD, (132<<16) | 4}, // kCAFChannelLayoutTag_ITU_2_2 | ||
396 | { AV_CH_LAYOUT_2_2, (132<<16) | 4}, // kCAFChannelLayoutTag_ITU_2_2 | ||
397 | { AV_CH_LAYOUT_QUAD, (108<<16) | 4}, // kCAFChannelLayoutTag_Quadraphonic | ||
398 | { AV_CH_LAYOUT_SURROUND, (113<<16) | 3}, // kCAFChannelLayoutTag_MPEG_3_0_A | ||
399 | { AV_CH_LAYOUT_4POINT0, (115<<16) | 4}, // kCAFChannelLayoutTag_MPEG_4_0_A | ||
400 | { AV_CH_LAYOUT_5POINT0_BACK, (117<<16) | 5}, // kCAFChannelLayoutTag_MPEG_5_0_A | ||
401 | { AV_CH_LAYOUT_5POINT0, (117<<16) | 5}, // kCAFChannelLayoutTag_MPEG_5_0_A | ||
402 | { AV_CH_LAYOUT_5POINT1_BACK, (121<<16) | 6}, // kCAFChannelLayoutTag_MPEG_5_1_A | ||
403 | { AV_CH_LAYOUT_5POINT1, (121<<16) | 6}, // kCAFChannelLayoutTag_MPEG_5_1_A | ||
404 | { AV_CH_LAYOUT_7POINT1, (128<<16) | 8}, // kCAFChannelLayoutTag_MPEG_7_1_C | ||
405 | { AV_CH_LAYOUT_7POINT1_WIDE, (126<<16) | 8}, // kCAFChannelLayoutTag_MPEG_7_1_A | ||
406 | { AV_CH_LAYOUT_5POINT1_BACK|AV_CH_LAYOUT_STEREO_DOWNMIX, (130<<16) | 8}, // kCAFChannelLayoutTag_SMPTE_DTV | ||
407 | { AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY, (133<<16) | 3}, // kCAFChannelLayoutTag_DVD_4 | ||
408 | { AV_CH_LAYOUT_2_1|AV_CH_LOW_FREQUENCY, (134<<16) | 4}, // kCAFChannelLayoutTag_DVD_5 | ||
409 | { AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY, (135<<16) | 4}, // kCAFChannelLayoutTag_DVD_6 | ||
410 | { AV_CH_LAYOUT_2_2|AV_CH_LOW_FREQUENCY, (135<<16) | 4}, // kCAFChannelLayoutTag_DVD_6 | ||
411 | { AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY, (136<<16) | 4}, // kCAFChannelLayoutTag_DVD_10 | ||
412 | { AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY, (137<<16) | 5}, // kCAFChannelLayoutTag_DVD_11 | ||
413 | { 0, 0}, | ||
414 | }; | ||
415 | |||
416 | 8 | void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout) | |
417 | { | ||
418 | const MovChannelLayout *layouts; | ||
419 | 8 | uint32_t layout_tag = 0; | |
420 | |||
421 |
2/2✓ Branch 0 taken 33 times.
✓ Branch 1 taken 1 times.
|
34 | for (layouts = mov_channel_layout; layouts->channel_layout; layouts++) |
422 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 26 times.
|
33 | if (channel_layout == layouts->channel_layout) { |
423 | 7 | layout_tag = layouts->layout_tag; | |
424 | 7 | break; | |
425 | } | ||
426 | |||
427 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
|
8 | if (layout_tag) { |
428 | 7 | avio_wb32(pb, layout_tag); // mChannelLayoutTag | |
429 | 7 | avio_wb32(pb, 0); // mChannelBitmap | |
430 | } else { | ||
431 | 1 | avio_wb32(pb, 0x10000); // kCAFChannelLayoutTag_UseChannelBitmap | |
432 | 1 | avio_wb32(pb, channel_layout); | |
433 | } | ||
434 | 8 | avio_wb32(pb, 0); // mNumberChannelDescriptions | |
435 | 8 | } | |
436 | |||
437 | static const struct MP4TrackKindValueMapping dash_role_map[] = { | ||
438 | { AV_DISPOSITION_HEARING_IMPAIRED|AV_DISPOSITION_CAPTIONS, | ||
439 | "caption" }, | ||
440 | { AV_DISPOSITION_COMMENT, | ||
441 | "commentary" }, | ||
442 | { AV_DISPOSITION_VISUAL_IMPAIRED|AV_DISPOSITION_DESCRIPTIONS, | ||
443 | "description" }, | ||
444 | { AV_DISPOSITION_DUB, | ||
445 | "dub" }, | ||
446 | { AV_DISPOSITION_FORCED, | ||
447 | "forced-subtitle" }, | ||
448 | { 0, NULL } | ||
449 | }; | ||
450 | |||
451 | const struct MP4TrackKindMapping ff_mov_track_kind_table[] = { | ||
452 | { "urn:mpeg:dash:role:2011", dash_role_map }, | ||
453 | { 0, NULL } | ||
454 | }; | ||
455 |