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