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_VORBIS , 0xDD },
00061 { CODEC_ID_DVD_SUBTITLE, 0xE0 },
00062 { CODEC_ID_QCELP , 0xE1 },
00063 { CODEC_ID_NONE , 0 },
00064 };
00065
00066 const AVCodecTag codec_movvideo_tags[] = {
00067
00068
00069 { CODEC_ID_RAWVIDEO, MKTAG('r', 'a', 'w', ' ') },
00070 { CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', '2') },
00071 { CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'U', 'I') },
00072 { CODEC_ID_RAWVIDEO, MKTAG('2', 'v', 'u', 'y') },
00073 { CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', 's') },
00074
00075 { CODEC_ID_RAWVIDEO, MKTAG('L', '5', '5', '5') },
00076 { CODEC_ID_RAWVIDEO, MKTAG('L', '5', '6', '5') },
00077 { CODEC_ID_RAWVIDEO, MKTAG('B', '5', '6', '5') },
00078 { CODEC_ID_RAWVIDEO, MKTAG('2', '4', 'B', 'G') },
00079 { CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 'A') },
00080 { CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 'A') },
00081 { CODEC_ID_RAWVIDEO, MKTAG('A', 'B', 'G', 'R') },
00082 { CODEC_ID_RAWVIDEO, MKTAG('b', '1', '6', 'g') },
00083 { CODEC_ID_RAWVIDEO, MKTAG('b', '4', '8', 'r') },
00084
00085 { CODEC_ID_R10K, MKTAG('R', '1', '0', 'k') },
00086 { CODEC_ID_R210, MKTAG('r', '2', '1', '0') },
00087 { CODEC_ID_V210, MKTAG('v', '2', '1', '0') },
00088
00089 { CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') },
00090 { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') },
00091 { CODEC_ID_MJPEG, MKTAG('A', 'V', 'D', 'J') },
00092
00093 { CODEC_ID_MJPEG, MKTAG('d', 'm', 'b', '1') },
00094 { CODEC_ID_MJPEGB, MKTAG('m', 'j', 'p', 'b') },
00095
00096 { CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') },
00097 { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') },
00098 { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', 'i') },
00099 { CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') },
00100
00101 { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
00102 { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') },
00103 { CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') },
00104 { CODEC_ID_MPEG4, MKTAG('3', 'I', 'V', '2') },
00105
00106 { CODEC_ID_H263, MKTAG('h', '2', '6', '3') },
00107 { CODEC_ID_H263, MKTAG('s', '2', '6', '3') },
00108
00109 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') },
00110 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') },
00111 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'p', 'p') },
00112 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'p') },
00113 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'n') },
00114 { CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', 'v') },
00115 { CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', '1') },
00116 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'q') },
00117 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'p') },
00118 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '1') },
00119 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '2') },
00120 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '4') },
00121 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '5') },
00122 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '6') },
00123 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '3') },
00124
00125 { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') },
00126 { CODEC_ID_RPZA, MKTAG('r', 'p', 'z', 'a') },
00127 { CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') },
00128 { CODEC_ID_8BPS, MKTAG('8', 'B', 'P', 'S') },
00129 { CODEC_ID_SMC, MKTAG('s', 'm', 'c', ' ') },
00130 { CODEC_ID_QTRLE, MKTAG('r', 'l', 'e', ' ') },
00131 { CODEC_ID_MSRLE, MKTAG('W', 'R', 'L', 'E') },
00132 { CODEC_ID_QDRAW, MKTAG('q', 'd', 'r', 'w') },
00133
00134 { CODEC_ID_RAWVIDEO, MKTAG('W', 'R', 'A', 'W') },
00135
00136 { CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
00137
00138 { CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', '1') },
00139 { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') },
00140 { CODEC_ID_MPEG2VIDEO, MKTAG('m', '2', 'v', '1') },
00141 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '1') },
00142 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') },
00143 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '3') },
00144 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '5') },
00145 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '6') },
00146 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '7') },
00147 { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '8') },
00148 { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'n') },
00149 { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'p') },
00150 { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'n') },
00151 { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'p') },
00152 { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'n') },
00153 { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'p') },
00154 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '4') },
00155 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '9') },
00156 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'a') },
00157 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'b') },
00158 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'c') },
00159 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'd') },
00160 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'e') },
00161 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'f') },
00162 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '1') },
00163 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '2') },
00164 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '3') },
00165 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '4') },
00166 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '5') },
00167 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '6') },
00168 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '7') },
00169 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '8') },
00170 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '9') },
00171 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'a') },
00172 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'b') },
00173 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'c') },
00174 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'd') },
00175 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'e') },
00176 { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'f') },
00177 { CODEC_ID_MPEG2VIDEO, MKTAG('A', 'V', 'm', 'p') },
00178
00179 { CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') },
00180
00181 { CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') },
00182 { CODEC_ID_TIFF, MKTAG('t', 'i', 'f', 'f') },
00183 { CODEC_ID_GIF, MKTAG('g', 'i', 'f', ' ') },
00184 { CODEC_ID_PNG, MKTAG('p', 'n', 'g', ' ') },
00185
00186 { CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') },
00187 { CODEC_ID_CAVS, MKTAG('a', 'v', 's', '2') },
00188
00189 { CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
00190 { CODEC_ID_DNXHD, MKTAG('A', 'V', 'd', 'n') },
00191 { CODEC_ID_RAWVIDEO, MKTAG('A', 'V', '1', 'x') },
00192 { CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'u', 'p') },
00193 { CODEC_ID_SGI, MKTAG('s', 'g', 'i', ' ') },
00194 { CODEC_ID_DPX, MKTAG('d', 'p', 'x', ' ') },
00195
00196 { CODEC_ID_NONE, 0 },
00197 };
00198
00199 const AVCodecTag codec_movaudio_tags[] = {
00200 { CODEC_ID_PCM_S32BE, MKTAG('i', 'n', '3', '2') },
00201 { CODEC_ID_PCM_S32LE, MKTAG('i', 'n', '3', '2') },
00202 { CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') },
00203 { CODEC_ID_PCM_S24LE, MKTAG('i', 'n', '2', '4') },
00204 { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') },
00205 { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') },
00206 { CODEC_ID_PCM_S16LE, MKTAG('l', 'p', 'c', 'm') },
00207 { CODEC_ID_PCM_F32BE, MKTAG('f', 'l', '3', '2') },
00208 { CODEC_ID_PCM_F32LE, MKTAG('f', 'l', '3', '2') },
00209 { CODEC_ID_PCM_F64BE, MKTAG('f', 'l', '6', '4') },
00210 { CODEC_ID_PCM_F64LE, MKTAG('f', 'l', '6', '4') },
00211 { CODEC_ID_PCM_S8, MKTAG('s', 'o', 'w', 't') },
00212 { CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') },
00213 { CODEC_ID_PCM_U8, MKTAG('N', 'O', 'N', 'E') },
00214 { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') },
00215 { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') },
00216
00217 { CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') },
00218
00219 { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') },
00220 { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') },
00221
00222 { CODEC_ID_MP1, MKTAG('.', 'm', 'p', '1') },
00223 { CODEC_ID_MP2, MKTAG('.', 'm', 'p', '2') },
00224
00225 { CODEC_ID_MP3, MKTAG('.', 'm', 'p', '3') },
00226 { CODEC_ID_MP3, 0x6D730055 },
00227
00228
00229
00230 { CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
00231 { CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') },
00232 { CODEC_ID_AC3, MKTAG('s', 'a', 'c', '3') },
00233
00234 { CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') },
00235 { CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') },
00236
00237 { CODEC_ID_GSM, MKTAG('a', 'g', 's', 'm') },
00238 { CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
00239
00240 { CODEC_ID_QCELP, MKTAG('Q','c','l','p') },
00241 { CODEC_ID_QCELP, MKTAG('Q','c','l','q') },
00242 { CODEC_ID_QCELP, MKTAG('s','q','c','p') },
00243
00244 { CODEC_ID_QDM2, MKTAG('Q', 'D', 'M', '2') },
00245
00246 { CODEC_ID_DVAUDIO, MKTAG('v', 'd', 'v', 'a') },
00247 { CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'c', 'a') },
00248
00249 { CODEC_ID_WMAV2, MKTAG('W', 'M', 'A', '2') },
00250
00251 { CODEC_ID_NONE, 0 },
00252 };
00253
00254 const AVCodecTag ff_codec_movsubtitle_tags[] = {
00255 { CODEC_ID_MOV_TEXT, MKTAG('t', 'e', 'x', 't') },
00256 { CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
00257 { CODEC_ID_NONE, 0 },
00258 };
00259
00260
00261
00262
00263
00264 static const char mov_mdhd_language_map[][4] = {
00265
00266 "eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor",
00267 "heb", "jpn", "ara", "fin", "gre", "ice", "mlt", "tur", "hr ", "chi",
00268 "urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav", "",
00269 "fo ", "", "rus", "chi", "", "iri", "alb", "ron", "ces", "slk",
00270 "slv", "yid", "sr ", "mac", "bul", "ukr", "bel", "uzb", "kaz", "aze",
00271
00272 "aze", "arm", "geo", "mol", "kir", "tgk", "tuk", "mon", "", "pus",
00273 "kur", "kas", "snd", "tib", "nep", "san", "mar", "ben", "asm", "guj",
00274 "pa ", "ori", "mal", "kan", "tam", "tel", "", "bur", "khm", "lao",
00275
00276 "vie", "ind", "tgl", "may", "may", "amh", "tir", "orm", "som", "swa",
00277
00278 "", "run", "", "mlg", "epo", "", "", "", "", "",
00279
00280 "", "", "", "", "", "", "", "", "", "",
00281 "", "", "", "", "", "", "", "", "", "",
00282 "", "", "", "", "", "", "", "", "wel", "baq",
00283 "cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav"
00284 };
00285
00286 int ff_mov_iso639_to_lang(const char lang[4], int mp4)
00287 {
00288 int i, code = 0;
00289
00290
00291 for (i = 0; lang[0] && !mp4 && i < FF_ARRAY_ELEMS(mov_mdhd_language_map); i++) {
00292 if (!strcmp(lang, mov_mdhd_language_map[i]))
00293 return i;
00294 }
00295
00296 if (!mp4)
00297 return -1;
00298
00299 if (lang[0] == '\0')
00300 lang = "und";
00301
00302 for (i = 0; i < 3; i++) {
00303 uint8_t c = lang[i];
00304 c -= 0x60;
00305 if (c > 0x1f)
00306 return -1;
00307 code <<= 5;
00308 code |= c;
00309 }
00310 return code;
00311 }
00312
00313 int ff_mov_lang_to_iso639(unsigned code, char to[4])
00314 {
00315 int i;
00316 memset(to, 0, 4);
00317
00318
00319 if (code > 138) {
00320 for (i = 2; i >= 0; i--) {
00321 to[i] = 0x60 + (code & 0x1f);
00322 code >>= 5;
00323 }
00324 return 1;
00325 }
00326
00327 if (code >= FF_ARRAY_ELEMS(mov_mdhd_language_map))
00328 return 0;
00329 if (!mov_mdhd_language_map[code][0])
00330 return 0;
00331 memcpy(to, mov_mdhd_language_map[code], 4);
00332 return 1;
00333 }
00334
00335 int ff_mp4_read_descr_len(ByteIOContext *pb)
00336 {
00337 int len = 0;
00338 int count = 4;
00339 while (count--) {
00340 int c = get_byte(pb);
00341 len = (len << 7) | (c & 0x7f);
00342 if (!(c & 0x80))
00343 break;
00344 }
00345 return len;
00346 }
00347
00348 int ff_mp4_read_descr(AVFormatContext *fc, ByteIOContext *pb, int *tag)
00349 {
00350 int len;
00351 *tag = get_byte(pb);
00352 len = ff_mp4_read_descr_len(pb);
00353 dprintf(fc, "MPEG4 description: tag=0x%02x len=%d\n", *tag, len);
00354 return len;
00355 }
00356
00357 static const AVCodecTag mp4_audio_types[] = {
00358 { CODEC_ID_MP3ON4, AOT_PS },
00359 { CODEC_ID_MP3ON4, AOT_L1 },
00360 { CODEC_ID_MP3ON4, AOT_L2 },
00361 { CODEC_ID_MP3ON4, AOT_L3 },
00362 { CODEC_ID_MP4ALS, AOT_ALS },
00363 { CODEC_ID_NONE, AOT_NULL },
00364 };
00365
00366 int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, ByteIOContext *pb)
00367 {
00368 int len, tag;
00369 int object_type_id = get_byte(pb);
00370 get_byte(pb);
00371 get_be24(pb);
00372 get_be32(pb);
00373 get_be32(pb);
00374
00375 st->codec->codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id);
00376 dprintf(fc, "esds object type id 0x%02x\n", object_type_id);
00377 len = ff_mp4_read_descr(fc, pb, &tag);
00378 if (tag == MP4DecSpecificDescrTag) {
00379 dprintf(fc, "Specific MPEG4 header len=%d\n", len);
00380 if((uint64_t)len > (1<<30))
00381 return -1;
00382 av_free(st->codec->extradata);
00383 st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
00384 if (!st->codec->extradata)
00385 return AVERROR(ENOMEM);
00386 get_buffer(pb, st->codec->extradata, len);
00387 st->codec->extradata_size = len;
00388 if (st->codec->codec_id == CODEC_ID_AAC) {
00389 MPEG4AudioConfig cfg;
00390 ff_mpeg4audio_get_config(&cfg, st->codec->extradata,
00391 st->codec->extradata_size);
00392 st->codec->channels = cfg.channels;
00393 if (cfg.object_type == 29 && cfg.sampling_index < 3)
00394 st->codec->sample_rate = ff_mpa_freq_tab[cfg.sampling_index];
00395 else if (cfg.ext_sample_rate)
00396 st->codec->sample_rate = cfg.ext_sample_rate;
00397 else
00398 st->codec->sample_rate = cfg.sample_rate;
00399 dprintf(fc, "mp4a config channels %d obj %d ext obj %d "
00400 "sample rate %d ext sample rate %d\n", st->codec->channels,
00401 cfg.object_type, cfg.ext_object_type,
00402 cfg.sample_rate, cfg.ext_sample_rate);
00403 if (!(st->codec->codec_id = ff_codec_get_id(mp4_audio_types,
00404 cfg.object_type)))
00405 st->codec->codec_id = CODEC_ID_AAC;
00406 }
00407 }
00408 return 0;
00409 }