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};