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