| 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 | 332 | int ff_mov_iso639_to_lang(const char lang[4], int mp4) | |
| 234 | { | ||
| 235 | 332 | int i, code = 0; | |
| 236 | |||
| 237 | /* old way, only for QT? */ | ||
| 238 |
5/6✓ Branch 0 taken 21877 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21712 times.
✓ Branch 3 taken 165 times.
✓ Branch 4 taken 21557 times.
✓ Branch 5 taken 155 times.
|
21877 | for (i = 0; lang[0] && !mp4 && i < FF_ARRAY_ELEMS(mov_mdhd_language_map); i++) { |
| 239 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 21545 times.
|
21557 | if (!strcmp(lang, mov_mdhd_language_map[i])) |
| 240 | 12 | return i; | |
| 241 | } | ||
| 242 | /* XXX:can we do that in mov too? */ | ||
| 243 |
2/2✓ Branch 0 taken 155 times.
✓ Branch 1 taken 165 times.
|
320 | if (!mp4) |
| 244 | 155 | return -1; | |
| 245 | /* handle undefined as such */ | ||
| 246 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 165 times.
|
165 | if (lang[0] == '\0') |
| 247 | ✗ | lang = "und"; | |
| 248 | /* 5 bits ASCII */ | ||
| 249 |
2/2✓ Branch 0 taken 495 times.
✓ Branch 1 taken 165 times.
|
660 | for (i = 0; i < 3; i++) { |
| 250 | 495 | uint8_t c = lang[i]; | |
| 251 | 495 | c -= 0x60; | |
| 252 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 495 times.
|
495 | if (c > 0x1f) |
| 253 | ✗ | return -1; | |
| 254 | 495 | code <<= 5; | |
| 255 | 495 | code |= c; | |
| 256 | } | ||
| 257 | 165 | return code; | |
| 258 | } | ||
| 259 | |||
| 260 | 714 | int ff_mov_lang_to_iso639(unsigned code, char to[4]) | |
| 261 | { | ||
| 262 | int i; | ||
| 263 | 714 | 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 504 times.
✓ Branch 1 taken 210 times.
✓ Branch 2 taken 332 times.
✓ Branch 3 taken 172 times.
|
714 | if (code >= 0x400 && code != 0x7fff) { |
| 267 |
2/2✓ Branch 0 taken 996 times.
✓ Branch 1 taken 332 times.
|
1328 | for (i = 2; i >= 0; i--) { |
| 268 | 996 | to[i] = 0x60 + (code & 0x1f); | |
| 269 | 996 | code >>= 5; | |
| 270 | } | ||
| 271 | 332 | return 1; | |
| 272 | } | ||
| 273 | /* old fashion apple lang code */ | ||
| 274 |
2/2✓ Branch 0 taken 172 times.
✓ Branch 1 taken 210 times.
|
382 | if (code >= FF_ARRAY_ELEMS(mov_mdhd_language_map)) |
| 275 | 172 | return 0; | |
| 276 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
|
210 | if (!mov_mdhd_language_map[code][0]) |
| 277 | ✗ | return 0; | |
| 278 | 210 | memcpy(to, mov_mdhd_language_map[code], 4); | |
| 279 | 210 | return 1; | |
| 280 | } | ||
| 281 | |||
| 282 | 1012 | int ff_mp4_read_descr_len(AVIOContext *pb) | |
| 283 | { | ||
| 284 | 1012 | int len = 0; | |
| 285 | 1012 | int count = 4; | |
| 286 |
1/2✓ Branch 0 taken 2493 times.
✗ Branch 1 not taken.
|
2493 | while (count--) { |
| 287 | 2493 | int c = avio_r8(pb); | |
| 288 | 2493 | len = (len << 7) | (c & 0x7f); | |
| 289 |
2/2✓ Branch 0 taken 1012 times.
✓ Branch 1 taken 1481 times.
|
2493 | if (!(c & 0x80)) |
| 290 | 1012 | break; | |
| 291 | } | ||
| 292 | 1012 | return len; | |
| 293 | } | ||
| 294 | |||
| 295 | 472 | int ff_mp4_read_descr(void *logctx, AVIOContext *pb, int *tag) | |
| 296 | { | ||
| 297 | int len; | ||
| 298 | 472 | *tag = avio_r8(pb); | |
| 299 | 472 | len = ff_mp4_read_descr_len(pb); | |
| 300 | 472 | av_log(logctx, AV_LOG_TRACE, "MPEG-4 description: tag=0x%02x len=%d\n", *tag, len); | |
| 301 | 472 | return len; | |
| 302 | } | ||
| 303 | |||
| 304 | 156 | 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 156 times.
|
156 | if (es_id) *es_id = avio_rb16(pb); |
| 308 | 156 | else avio_rb16(pb); | |
| 309 | 156 | flags = avio_r8(pb); | |
| 310 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 156 times.
|
156 | if (flags & 0x80) //streamDependenceFlag |
| 311 | ✗ | avio_rb16(pb); | |
| 312 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 156 times.
|
156 | 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 156 times.
|
156 | if (flags & 0x20) //OCRstreamFlag |
| 317 | ✗ | avio_rb16(pb); | |
| 318 | 156 | } | |
| 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 | 156 | 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 | 156 | int object_type_id = avio_r8(pb); | |
| 335 | 156 | avio_r8(pb); /* stream type */ | |
| 336 | 156 | avio_rb24(pb); /* buffer size db */ | |
| 337 | 156 | avio_rb32(pb); /* rc_max_rate */ | |
| 338 | |||
| 339 | 156 | st->codecpar->bit_rate = avio_rb32(pb); /* avg bitrate */ | |
| 340 | |||
| 341 | 156 | codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id); | |
| 342 |
1/2✓ Branch 0 taken 156 times.
✗ Branch 1 not taken.
|
156 | if (codec_id) |
| 343 | 156 | st->codecpar->codec_id = codec_id; | |
| 344 | 156 | av_log(logctx, AV_LOG_TRACE, "esds object type id 0x%02x\n", object_type_id); | |
| 345 | 156 | len = ff_mp4_read_descr(logctx, pb, &tag); | |
| 346 |
2/2✓ Branch 0 taken 151 times.
✓ Branch 1 taken 5 times.
|
156 | if (tag == MP4DecSpecificDescrTag) { |
| 347 | 151 | 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 151 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 151 times.
|
151 | if (object_type_id == 0x69 || object_type_id == 0x6b) |
| 351 | ✗ | return 0; | |
| 352 |
2/4✓ Branch 0 taken 151 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 151 times.
|
151 | if (!len || (uint64_t)len > (1<<30)) |
| 353 | ✗ | return AVERROR_INVALIDDATA; | |
| 354 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 151 times.
|
151 | if ((ret = ff_get_extradata(logctx, st->codecpar, pb, len)) < 0) |
| 355 | ✗ | return ret; | |
| 356 |
2/2✓ Branch 0 taken 125 times.
✓ Branch 1 taken 26 times.
|
151 | if (st->codecpar->codec_id == AV_CODEC_ID_AAC) { |
| 357 | 125 | MPEG4AudioConfig cfg = {0}; | |
| 358 | 125 | ret = avpriv_mpeg4audio_get_config2(&cfg, st->codecpar->extradata, | |
| 359 | 125 | st->codecpar->extradata_size, 1, logctx); | |
| 360 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 125 times.
|
125 | if (ret < 0) |
| 361 | ✗ | return ret; | |
| 362 |
2/2✓ Branch 0 taken 52 times.
✓ Branch 1 taken 73 times.
|
125 | if (cfg.channels != st->codecpar->ch_layout.nb_channels) { |
| 363 | 52 | av_channel_layout_uninit(&st->codecpar->ch_layout); | |
| 364 | 52 | st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; | |
| 365 | 52 | st->codecpar->ch_layout.nb_channels = cfg.channels; | |
| 366 | } | ||
| 367 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 125 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
125 | 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 97 times.
|
125 | else if (cfg.ext_sample_rate) |
| 370 | 28 | st->codecpar->sample_rate = cfg.ext_sample_rate; | |
| 371 | else | ||
| 372 | 97 | st->codecpar->sample_rate = cfg.sample_rate; | |
| 373 | 125 | 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 118 times.
✓ Branch 1 taken 7 times.
|
125 | if (!(st->codecpar->codec_id = ff_codec_get_id(mp4_audio_types, |
| 378 | 125 | cfg.object_type))) | |
| 379 | 118 | st->codecpar->codec_id = AV_CODEC_ID_AAC; | |
| 380 | } | ||
| 381 | } | ||
| 382 | 156 | 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_2POINT1, (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_3POINT1, (136<<16) | 4}, // kCAFChannelLayoutTag_DVD_10 | ||
| 412 | { AV_CH_LAYOUT_4POINT1, (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 |