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