00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "avformat.h"
00027 #include "internal.h"
00028 #include "isom.h"
00029 #include "riff.h"
00030 #include "libavcodec/mpeg4audio.h"
00031 #include "libavcodec/mpegaudiodata.h"
00032
00033
00034
00035 const AVCodecTag ff_mp4_obj_type[] = {
00036 { CODEC_ID_MOV_TEXT , 0x08 },
00037 { CODEC_ID_MPEG4 , 0x20 },
00038 { CODEC_ID_H264 , 0x21 },
00039 { CODEC_ID_AAC , 0x40 },
00040 { CODEC_ID_MP4ALS , 0x40 },
00041 { CODEC_ID_MPEG2VIDEO, 0x61 },
00042 { CODEC_ID_MPEG2VIDEO, 0x60 },
00043 { CODEC_ID_MPEG2VIDEO, 0x62 },
00044 { CODEC_ID_MPEG2VIDEO, 0x63 },
00045 { CODEC_ID_MPEG2VIDEO, 0x64 },
00046 { CODEC_ID_MPEG2VIDEO, 0x65 },
00047 { CODEC_ID_AAC , 0x66 },
00048 { CODEC_ID_AAC , 0x67 },
00049 { CODEC_ID_AAC , 0x68 },
00050 { CODEC_ID_MP3 , 0x69 },
00051 { CODEC_ID_MP2 , 0x69 },
00052 { CODEC_ID_MPEG1VIDEO, 0x6A },
00053 { CODEC_ID_MP3 , 0x6B },
00054 { CODEC_ID_MJPEG , 0x6C },
00055 { CODEC_ID_PNG , 0x6D },
00056 { CODEC_ID_JPEG2000 , 0x6E },
00057 { CODEC_ID_VC1 , 0xA3 },
00058 { CODEC_ID_DIRAC , 0xA4 },
00059 { CODEC_ID_AC3 , 0xA5 },
00060 { CODEC_ID_DTS , 0xA9 },
00061 { CODEC_ID_VORBIS , 0xDD },
00062 { CODEC_ID_DVD_SUBTITLE, 0xE0 },
00063 { CODEC_ID_QCELP , 0xE1 },
00064 { CODEC_ID_MPEG4SYSTEMS, 0x01 },
00065 { CODEC_ID_MPEG4SYSTEMS, 0x02 },
00066 { CODEC_ID_NONE , 0 },
00067 };
00068
00069 const AVCodecTag ff_codec_movvideo_tags[] = {
00070
00071
00072 { CODEC_ID_RAWVIDEO, MKTAG('r', 'a', 'w', ' ') },
00073 { CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', '2') },
00074 { CODEC_ID_RAWVIDEO, MKTAG('2', 'v', 'u', 'y') },
00075 { CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', 's') },
00076
00077 { CODEC_ID_RAWVIDEO, MKTAG('L', '5', '5', '5') },
00078 { CODEC_ID_RAWVIDEO, MKTAG('L', '5', '6', '5') },
00079 { CODEC_ID_RAWVIDEO, MKTAG('B', '5', '6', '5') },
00080 { CODEC_ID_RAWVIDEO, MKTAG('2', '4', 'B', 'G') },
00081 { CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 'A') },
00082 { CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 'A') },
00083 { CODEC_ID_RAWVIDEO, MKTAG('A', 'B', 'G', 'R') },
00084 { CODEC_ID_RAWVIDEO, MKTAG('b', '1', '6', 'g') },
00085 { CODEC_ID_RAWVIDEO, MKTAG('b', '4', '8', 'r') },
00086 { CODEC_ID_RAWVIDEO, MKTAG('D', 'V', 'O', 'O') },
00087
00088 { CODEC_ID_R10K, MKTAG('R', '1', '0', 'k') },
00089 { CODEC_ID_R10K, MKTAG('R', '1', '0', 'g') },
00090 { CODEC_ID_R210, MKTAG('r', '2', '1', '0') },
00091 { CODEC_ID_AVUI, MKTAG('A', 'V', 'U', 'I') },
00092 { CODEC_ID_AVRP, MKTAG('A', 'V', 'r', 'p') },
00093 { CODEC_ID_AVRP, MKTAG('S', 'U', 'D', 'S') },
00094 { CODEC_ID_V210, MKTAG('v', '2', '1', '0') },
00095 { CODEC_ID_V308, MKTAG('v', '3', '0', '8') },
00096 { CODEC_ID_V408, MKTAG('v', '4', '0', '8') },
00097 { CODEC_ID_V410, MKTAG('v', '4', '1', '0') },
00098 { CODEC_ID_Y41P, MKTAG('Y', '4', '1', 'P') },
00099 { CODEC_ID_YUV4, MKTAG('y', 'u', 'v', '4') },
00100
00101 { CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') },
00102 { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') },
00103 { CODEC_ID_MJPEG, MKTAG('A', 'V', 'D', 'J') },
00104
00105 { CODEC_ID_MJPEG, MKTAG('d', 'm', 'b', '1') },
00106 { CODEC_ID_MJPEGB, MKTAG('m', 'j', 'p', 'b') },
00107
00108 { CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') },
00109 { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') },
00110 { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', 'i') },
00111 { CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') },
00112
00113 { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
00114 { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') },
00115 { CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') },
00116 { CODEC_ID_MPEG4, MKTAG('3', 'I', 'V', '2') },
00117
00118 { CODEC_ID_H263, MKTAG('h', '2', '6', '3') },
00119 { CODEC_ID_H263, MKTAG('s', '2', '6', '3') },
00120
00121 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') },
00122 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') },
00123 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'p', 'p') },
00124 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'p') },
00125 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'n') },
00126 { CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', 'v') },
00127 { CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', '1') },
00128 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'q') },
00129 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'p') },
00130 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '1') },
00131 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '2') },
00132 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '4') },
00133 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '5') },
00134 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '6') },
00135 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '3') },
00136
00137 { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') },
00138 { CODEC_ID_RPZA, MKTAG('r', 'p', 'z', 'a') },
00139 { CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') },
00140 { CODEC_ID_8BPS, MKTAG('8', 'B', 'P', 'S') },
00141 { CODEC_ID_SMC, MKTAG('s', 'm', 'c', ' ') },
00142 { CODEC_ID_QTRLE, MKTAG('r', 'l', 'e', ' ') },
00143 { CODEC_ID_MSRLE, MKTAG('W', 'R', 'L', 'E') },
00144 { CODEC_ID_QDRAW, MKTAG('q', 'd', 'r', 'w') },
00145
00146 { CODEC_ID_RAWVIDEO, MKTAG('W', 'R', 'A', 'W') },
00147
00148 { CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
00149 { CODEC_ID_H264, MKTAG('a', 'i', '5', 'p') },
00150 { CODEC_ID_H264, MKTAG('a', 'i', '5', 'q') },
00151 { CODEC_ID_H264, MKTAG('a', 'i', '5', '2') },
00152 { CODEC_ID_H264, MKTAG('a', 'i', '5', '3') },
00153 { CODEC_ID_H264, MKTAG('a', 'i', '5', '5') },
00154 { CODEC_ID_H264, MKTAG('a', 'i', '5', '6') },
00155 { CODEC_ID_H264, MKTAG('a', 'i', '1', 'p') },
00156 { CODEC_ID_H264, MKTAG('a', 'i', '1', 'q') },
00157 { CODEC_ID_H264, MKTAG('a', 'i', '1', '2') },
00158 { CODEC_ID_H264, MKTAG('a', 'i', '1', '3') },
00159 { CODEC_ID_H264, MKTAG('a', 'i', '1', '5') },
00160 { CODEC_ID_H264, MKTAG('a', 'i', '1', '6') },
00161
00162 { CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', '1') },
00163 { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') },
00164 { CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', ' ') },
00165 { CODEC_ID_MPEG2VIDEO, MKTAG('m', '2', 'v', '1') },
00166 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '1') },
00167 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') },
00168 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '3') },
00169 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '4') },
00170 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '5') },
00171 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '6') },
00172 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '7') },
00173 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '8') },
00174 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '9') },
00175 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', 'a') },
00176 { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'n') },
00177 { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'p') },
00178 { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'n') },
00179 { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'p') },
00180 { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'n') },
00181 { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'p') },
00182 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '4') },
00183 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '5') },
00184 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '9') },
00185 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'a') },
00186 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'b') },
00187 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'c') },
00188 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'd') },
00189 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'e') },
00190 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'f') },
00191 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '1') },
00192 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '2') },
00193 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '3') },
00194 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '4') },
00195 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '5') },
00196 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '6') },
00197 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '7') },
00198 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '8') },
00199 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '9') },
00200 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'a') },
00201 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'b') },
00202 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'c') },
00203 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'd') },
00204 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'e') },
00205 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'f') },
00206 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', 'd') },
00207 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', '2') },
00208 { CODEC_ID_MPEG2VIDEO, MKTAG('A', 'V', 'm', 'p') },
00209
00210 { CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') },
00211
00212 { CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') },
00213 { CODEC_ID_TIFF, MKTAG('t', 'i', 'f', 'f') },
00214 { CODEC_ID_GIF, MKTAG('g', 'i', 'f', ' ') },
00215 { CODEC_ID_PNG, MKTAG('p', 'n', 'g', ' ') },
00216
00217 { CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') },
00218 { CODEC_ID_CAVS, MKTAG('a', 'v', 's', '2') },
00219
00220 { CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
00221 { CODEC_ID_DNXHD, MKTAG('A', 'V', 'd', 'n') },
00222
00223 { CODEC_ID_MSMPEG4V3, MKTAG('3', 'I', 'V', 'D') },
00224 { CODEC_ID_RAWVIDEO, MKTAG('A', 'V', '1', 'x') },
00225 { CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'u', 'p') },
00226 { CODEC_ID_SGI, MKTAG('s', 'g', 'i', ' ') },
00227 { CODEC_ID_DPX, MKTAG('d', 'p', 'x', ' ') },
00228 { CODEC_ID_EXR, MKTAG('e', 'x', 'r', ' ') },
00229
00230 { CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'h') },
00231 { CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'n') },
00232 { CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 's') },
00233 { CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'o') },
00234 { CODEC_ID_PRORES, MKTAG('a', 'p', '4', 'h') },
00235 { CODEC_ID_FLIC, MKTAG('f', 'l', 'i', 'c') },
00236
00237 { CODEC_ID_NONE, 0 },
00238 };
00239
00240 const AVCodecTag ff_codec_movaudio_tags[] = {
00241 { CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
00242 { CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') },
00243 { CODEC_ID_AC3, MKTAG('s', 'a', 'c', '3') },
00244 { CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') },
00245 { CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
00246 { CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') },
00247 { CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') },
00248 { CODEC_ID_DTS, MKTAG('d', 't', 's', 'c') },
00249 { CODEC_ID_DTS, MKTAG('d', 't', 's', 'h') },
00250 { CODEC_ID_DTS, MKTAG('d', 't', 's', 'l') },
00251 { CODEC_ID_DTS, MKTAG('D', 'T', 'S', ' ') },
00252 { CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') },
00253 { CODEC_ID_DVAUDIO, MKTAG('v', 'd', 'v', 'a') },
00254 { CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'c', 'a') },
00255 { CODEC_ID_GSM, MKTAG('a', 'g', 's', 'm') },
00256 { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') },
00257 { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') },
00258 { CODEC_ID_MP1, MKTAG('.', 'm', 'p', '1') },
00259 { CODEC_ID_MP2, MKTAG('.', 'm', 'p', '2') },
00260 { CODEC_ID_MP3, MKTAG('.', 'm', 'p', '3') },
00261 { CODEC_ID_MP3, 0x6D730055 },
00262 { CODEC_ID_NELLYMOSER, MKTAG('n', 'm', 'o', 's') },
00263 { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') },
00264 { CODEC_ID_PCM_F32BE, MKTAG('f', 'l', '3', '2') },
00265 { CODEC_ID_PCM_F32LE, MKTAG('f', 'l', '3', '2') },
00266 { CODEC_ID_PCM_F64BE, MKTAG('f', 'l', '6', '4') },
00267 { CODEC_ID_PCM_F64LE, MKTAG('f', 'l', '6', '4') },
00268 { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') },
00269 { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') },
00270 { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') },
00271 { CODEC_ID_PCM_S16LE, MKTAG('l', 'p', 'c', 'm') },
00272 { CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') },
00273 { CODEC_ID_PCM_S24LE, MKTAG('i', 'n', '2', '4') },
00274 { CODEC_ID_PCM_S32BE, MKTAG('i', 'n', '3', '2') },
00275 { CODEC_ID_PCM_S32LE, MKTAG('i', 'n', '3', '2') },
00276 { CODEC_ID_PCM_S8, MKTAG('s', 'o', 'w', 't') },
00277 { CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') },
00278 { CODEC_ID_PCM_U8, MKTAG('N', 'O', 'N', 'E') },
00279 { CODEC_ID_QCELP, MKTAG('Q', 'c', 'l', 'p') },
00280 { CODEC_ID_QCELP, MKTAG('Q', 'c', 'l', 'q') },
00281 { CODEC_ID_QCELP, MKTAG('s', 'q', 'c', 'p') },
00282 { CODEC_ID_QDM2, MKTAG('Q', 'D', 'M', '2') },
00283 { CODEC_ID_QDMC, MKTAG('Q', 'D', 'M', 'C') },
00284 { CODEC_ID_SPEEX, MKTAG('s', 'p', 'e', 'x') },
00285 { CODEC_ID_WMAV2, MKTAG('W', 'M', 'A', '2') },
00286 { CODEC_ID_NONE, 0 },
00287 };
00288
00289 const AVCodecTag ff_codec_movsubtitle_tags[] = {
00290 { CODEC_ID_MOV_TEXT, MKTAG('t', 'e', 'x', 't') },
00291 { CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
00292 { CODEC_ID_EIA_608, MKTAG('c', '6', '0', '8') },
00293 { CODEC_ID_NONE, 0 },
00294 };
00295
00296
00297
00298
00299
00300 static const char mov_mdhd_language_map[][4] = {
00301
00302 "eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor",
00303 "heb", "jpn", "ara", "fin", "gre", "ice", "mlt", "tur", "hr ", "chi",
00304 "urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav", "",
00305 "fo ", "", "rus", "chi", "", "iri", "alb", "ron", "ces", "slk",
00306 "slv", "yid", "sr ", "mac", "bul", "ukr", "bel", "uzb", "kaz", "aze",
00307
00308 "aze", "arm", "geo", "mol", "kir", "tgk", "tuk", "mon", "", "pus",
00309 "kur", "kas", "snd", "tib", "nep", "san", "mar", "ben", "asm", "guj",
00310 "pa ", "ori", "mal", "kan", "tam", "tel", "", "bur", "khm", "lao",
00311
00312 "vie", "ind", "tgl", "may", "may", "amh", "tir", "orm", "som", "swa",
00313
00314 "", "run", "", "mlg", "epo", "", "", "", "", "",
00315
00316 "", "", "", "", "", "", "", "", "", "",
00317 "", "", "", "", "", "", "", "", "", "",
00318 "", "", "", "", "", "", "", "", "wel", "baq",
00319 "cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav"
00320 };
00321
00322 int ff_mov_iso639_to_lang(const char lang[4], int mp4)
00323 {
00324 int i, code = 0;
00325
00326
00327 for (i = 0; lang[0] && !mp4 && i < FF_ARRAY_ELEMS(mov_mdhd_language_map); i++) {
00328 if (!strcmp(lang, mov_mdhd_language_map[i]))
00329 return i;
00330 }
00331
00332 if (!mp4)
00333 return -1;
00334
00335 if (lang[0] == '\0')
00336 lang = "und";
00337
00338 for (i = 0; i < 3; i++) {
00339 uint8_t c = lang[i];
00340 c -= 0x60;
00341 if (c > 0x1f)
00342 return -1;
00343 code <<= 5;
00344 code |= c;
00345 }
00346 return code;
00347 }
00348
00349 int ff_mov_lang_to_iso639(unsigned code, char to[4])
00350 {
00351 int i;
00352 memset(to, 0, 4);
00353
00354
00355 if (code >= 0x400 && code != 0x7fff) {
00356 for (i = 2; i >= 0; i--) {
00357 to[i] = 0x60 + (code & 0x1f);
00358 code >>= 5;
00359 }
00360 return 1;
00361 }
00362
00363 if (code >= FF_ARRAY_ELEMS(mov_mdhd_language_map))
00364 return 0;
00365 if (!mov_mdhd_language_map[code][0])
00366 return 0;
00367 memcpy(to, mov_mdhd_language_map[code], 4);
00368 return 1;
00369 }
00370
00371 int ff_mp4_read_descr_len(AVIOContext *pb)
00372 {
00373 int len = 0;
00374 int count = 4;
00375 while (count--) {
00376 int c = avio_r8(pb);
00377 len = (len << 7) | (c & 0x7f);
00378 if (!(c & 0x80))
00379 break;
00380 }
00381 return len;
00382 }
00383
00384 int ff_mp4_read_descr(AVFormatContext *fc, AVIOContext *pb, int *tag)
00385 {
00386 int len;
00387 *tag = avio_r8(pb);
00388 len = ff_mp4_read_descr_len(pb);
00389 av_dlog(fc, "MPEG4 description: tag=0x%02x len=%d\n", *tag, len);
00390 return len;
00391 }
00392
00393 void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id)
00394 {
00395 int flags;
00396 if (es_id) *es_id = avio_rb16(pb);
00397 else avio_rb16(pb);
00398 flags = avio_r8(pb);
00399 if (flags & 0x80)
00400 avio_rb16(pb);
00401 if (flags & 0x40) {
00402 int len = avio_r8(pb);
00403 avio_skip(pb, len);
00404 }
00405 if (flags & 0x20)
00406 avio_rb16(pb);
00407 }
00408
00409 static const AVCodecTag mp4_audio_types[] = {
00410 { CODEC_ID_MP3ON4, AOT_PS },
00411 { CODEC_ID_MP3ON4, AOT_L1 },
00412 { CODEC_ID_MP3ON4, AOT_L2 },
00413 { CODEC_ID_MP3ON4, AOT_L3 },
00414 { CODEC_ID_MP4ALS, AOT_ALS },
00415 { CODEC_ID_NONE, AOT_NULL },
00416 };
00417
00418 int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb)
00419 {
00420 int len, tag;
00421 int object_type_id = avio_r8(pb);
00422 avio_r8(pb);
00423 avio_rb24(pb);
00424 avio_rb32(pb);
00425 avio_rb32(pb);
00426
00427 st->codec->codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id);
00428 av_dlog(fc, "esds object type id 0x%02x\n", object_type_id);
00429 len = ff_mp4_read_descr(fc, pb, &tag);
00430 if (tag == MP4DecSpecificDescrTag) {
00431 av_dlog(fc, "Specific MPEG4 header len=%d\n", len);
00432 if (!len || (uint64_t)len > (1<<30))
00433 return -1;
00434 av_free(st->codec->extradata);
00435 st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
00436 if (!st->codec->extradata)
00437 return AVERROR(ENOMEM);
00438 avio_read(pb, st->codec->extradata, len);
00439 st->codec->extradata_size = len;
00440 if (st->codec->codec_id == CODEC_ID_AAC) {
00441 MPEG4AudioConfig cfg;
00442 avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,
00443 st->codec->extradata_size * 8, 1);
00444 st->codec->channels = cfg.channels;
00445 if (cfg.object_type == 29 && cfg.sampling_index < 3)
00446 st->codec->sample_rate = avpriv_mpa_freq_tab[cfg.sampling_index];
00447 else if (cfg.ext_sample_rate)
00448 st->codec->sample_rate = cfg.ext_sample_rate;
00449 else
00450 st->codec->sample_rate = cfg.sample_rate;
00451 av_dlog(fc, "mp4a config channels %d obj %d ext obj %d "
00452 "sample rate %d ext sample rate %d\n", st->codec->channels,
00453 cfg.object_type, cfg.ext_object_type,
00454 cfg.sample_rate, cfg.ext_sample_rate);
00455 if (!(st->codec->codec_id = ff_codec_get_id(mp4_audio_types,
00456 cfg.object_type)))
00457 st->codec->codec_id = CODEC_ID_AAC;
00458 }
00459 }
00460 return 0;
00461 }
00462
00463 typedef struct MovChannelLayout {
00464 int64_t channel_layout;
00465 uint32_t layout_tag;
00466 } MovChannelLayout;
00467
00468 static const MovChannelLayout mov_channel_layout[] = {
00469 { AV_CH_LAYOUT_MONO, (100<<16) | 1},
00470 { AV_CH_LAYOUT_STEREO, (101<<16) | 2},
00471 { AV_CH_LAYOUT_STEREO, (102<<16) | 2},
00472 { AV_CH_LAYOUT_2_1, (131<<16) | 3},
00473 { AV_CH_LAYOUT_QUAD, (132<<16) | 4},
00474 { AV_CH_LAYOUT_2_2, (132<<16) | 4},
00475 { AV_CH_LAYOUT_QUAD, (108<<16) | 4},
00476 { AV_CH_LAYOUT_SURROUND, (113<<16) | 3},
00477 { AV_CH_LAYOUT_4POINT0, (115<<16) | 4},
00478 { AV_CH_LAYOUT_5POINT0_BACK, (117<<16) | 5},
00479 { AV_CH_LAYOUT_5POINT0, (117<<16) | 5},
00480 { AV_CH_LAYOUT_5POINT1_BACK, (121<<16) | 6},
00481 { AV_CH_LAYOUT_5POINT1, (121<<16) | 6},
00482 { AV_CH_LAYOUT_7POINT1, (128<<16) | 8},
00483 { AV_CH_LAYOUT_7POINT1_WIDE, (126<<16) | 8},
00484 { AV_CH_LAYOUT_5POINT1_BACK|AV_CH_LAYOUT_STEREO_DOWNMIX, (130<<16) | 8},
00485 { AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY, (133<<16) | 3},
00486 { AV_CH_LAYOUT_2_1|AV_CH_LOW_FREQUENCY, (134<<16) | 4},
00487 { AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY, (135<<16) | 4},
00488 { AV_CH_LAYOUT_2_2|AV_CH_LOW_FREQUENCY, (135<<16) | 4},
00489 { AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY, (136<<16) | 4},
00490 { AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY, (137<<16) | 5},
00491 { 0, 0},
00492 };
00493
00494 void ff_mov_read_chan(AVFormatContext *s, int64_t size, AVCodecContext *codec)
00495 {
00496 uint32_t layout_tag;
00497 AVIOContext *pb = s->pb;
00498 const MovChannelLayout *layouts = mov_channel_layout;
00499 layout_tag = avio_rb32(pb);
00500 size -= 4;
00501 if (layout_tag == 0) {
00502
00503 av_log_ask_for_sample(s, "Unimplemented container channel layout.\n");
00504 avio_skip(pb, size);
00505 return;
00506 }
00507 if (layout_tag == 0x10000) {
00508 codec->channel_layout = avio_rb32(pb);
00509 size -= 4;
00510 avio_skip(pb, size);
00511 return;
00512 }
00513 while (layouts->channel_layout) {
00514 if (layout_tag == layouts->layout_tag) {
00515 codec->channel_layout = layouts->channel_layout;
00516 break;
00517 }
00518 layouts++;
00519 }
00520 if (!codec->channel_layout)
00521 av_log(s, AV_LOG_WARNING, "Unknown container channel layout.\n");
00522 avio_skip(pb, size);
00523 }
00524
00525 void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout)
00526 {
00527 const MovChannelLayout *layouts;
00528 uint32_t layout_tag = 0;
00529
00530 for (layouts = mov_channel_layout; layouts->channel_layout; layouts++)
00531 if (channel_layout == layouts->channel_layout) {
00532 layout_tag = layouts->layout_tag;
00533 break;
00534 }
00535
00536 if (layout_tag) {
00537 avio_wb32(pb, layout_tag);
00538 avio_wb32(pb, 0);
00539 } else {
00540 avio_wb32(pb, 0x10000);
00541 avio_wb32(pb, channel_layout);
00542 }
00543 avio_wb32(pb, 0);
00544 }
00545