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