return 0;
}
+static int mov_read_custom_metadata(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ char key[1024]={0}, data[1024]={0};
+ int i;
+ AVStream *st;
+ MOVStreamContext *sc;
+
+ if (c->fc->nb_streams < 1)
+ return 0;
+ st = c->fc->streams[c->fc->nb_streams-1];
+ sc = st->priv_data;
+
+ if (atom.size <= 8) return 0;
+
+ for (i = 0; i < 3; i++) { // Parse up to three sub-atoms looking for name and data.
+ int data_size = avio_rb32(pb);
+ int tag = avio_rl32(pb);
+ int str_size = 0, skip_size = 0;
+ char *target = NULL;
+
+ switch (tag) {
+ case MKTAG('n','a','m','e'):
+ avio_rb32(pb); // version/flags
+ str_size = skip_size = data_size - 12;
+ atom.size -= 12;
+ target = key;
+ break;
+ case MKTAG('d','a','t','a'):
+ avio_rb32(pb); // version/flags
+ avio_rb32(pb); // reserved (zero)
+ str_size = skip_size = data_size - 16;
+ atom.size -= 16;
+ target = data;
+ break;
+ default:
+ skip_size = data_size - 8;
+ str_size = 0;
+ break;
+ }
+
+ if (target) {
+ str_size = FFMIN3(sizeof(data)-1, str_size, atom.size);
+ avio_read(pb, target, str_size);
+ target[str_size] = 0;
+ }
+ atom.size -= skip_size;
+
+ // If we didn't read the full data chunk for the sub-atom, skip to the end of it.
+ if (skip_size > str_size) avio_skip(pb, skip_size - str_size);
+ }
+
+ if (*key && *data) {
+ if (strcmp(key, "iTunSMPB") == 0) {
+ int priming, remainder, samples;
+ if(sscanf(data, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
+ if(priming>0 && priming<16384)
+ sc->start_pad = priming;
+ return 1;
+ }
+ }
+ if (strcmp(key, "cdec") == 0) {
+// av_dict_set(&st->metadata, key, data, 0);
+ return 1;
+ }
+ }
+ return 0;
+}
+
static const uint32_t mac_to_unicode[128] = {
0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
AVPacket pkt;
AVStream *st;
MOVStreamContext *sc;
- enum CodecID id;
+ enum AVCodecID id;
int ret;
switch (type) {
- case 0xd: id = CODEC_ID_MJPEG; break;
- case 0xe: id = CODEC_ID_PNG; break;
- case 0x1b: id = CODEC_ID_BMP; break;
+ case 0xd: id = AV_CODEC_ID_MJPEG; break;
+ case 0xe: id = AV_CODEC_ID_PNG; break;
+ case 0x1b: id = AV_CODEC_ID_BMP; break;
default:
av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
avio_skip(pb, len);
uint32_t data_type = 0, str_size;
int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
+ if (c->itunes_metadata && atom.type == MKTAG('-','-','-','-'))
+ return mov_read_custom_metadata(c, pb, atom);
+
switch (atom.type) {
case MKTAG(0xa9,'n','a','m'): key = "title"; break;
case MKTAG(0xa9,'a','u','t'):
else if (type == MKTAG('s','o','u','n'))
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
else if (type == MKTAG('m','1','a',' '))
- st->codec->codec_id = CODEC_ID_MP2;
+ st->codec->codec_id = AV_CODEC_ID_MP2;
else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
if (atom.size < 16)
return 0;
- ff_mov_read_chan(c->fc, st, atom.size - 4);
+ ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
return 0;
}
av_dlog(c->fc, "enda %d\n", little_endian);
if (little_endian == 1) {
switch (st->codec->codec_id) {
- case CODEC_ID_PCM_S24BE:
- st->codec->codec_id = CODEC_ID_PCM_S24LE;
+ case AV_CODEC_ID_PCM_S24BE:
+ st->codec->codec_id = AV_CODEC_ID_PCM_S24LE;
break;
- case CODEC_ID_PCM_S32BE:
- st->codec->codec_id = CODEC_ID_PCM_S32LE;
+ case AV_CODEC_ID_PCM_S32BE:
+ st->codec->codec_id = AV_CODEC_ID_PCM_S32LE;
break;
- case CODEC_ID_PCM_F32BE:
- st->codec->codec_id = CODEC_ID_PCM_F32LE;
+ case AV_CODEC_ID_PCM_F32BE:
+ st->codec->codec_id = AV_CODEC_ID_PCM_F32LE;
break;
- case CODEC_ID_PCM_F64BE:
- st->codec->codec_id = CODEC_ID_PCM_F64LE;
+ case AV_CODEC_ID_PCM_F64BE:
+ st->codec->codec_id = AV_CODEC_ID_PCM_F64LE;
break;
default:
break;
/* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
- enum CodecID codec_id)
+ enum AVCodecID codec_id)
{
AVStream *st;
uint64_t size;
/* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
- return mov_read_extradata(c, pb, atom, CODEC_ID_ALAC);
+ return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
}
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
- return mov_read_extradata(c, pb, atom, CODEC_ID_AVS);
+ return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
}
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
- return mov_read_extradata(c, pb, atom, CODEC_ID_JPEG2000);
+ return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
}
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
- return mov_read_extradata(c, pb, atom, CODEC_ID_AVUI);
+ return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
}
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
- return mov_read_extradata(c, pb, atom, CODEC_ID_SVQ3);
+ return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
}
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if ((uint64_t)atom.size > (1<<30))
return AVERROR_INVALIDDATA;
- if (st->codec->codec_id == CODEC_ID_QDM2 || st->codec->codec_id == CODEC_ID_QDMC) {
+ if (st->codec->codec_id == AV_CODEC_ID_QDM2 || st->codec->codec_id == AV_CODEC_ID_QDMC) {
// pass all frma atom to codec, needed at least for QDMC and QDM2
av_free(st->codec->extradata);
st->codec->extradata_size = 0;
* Compute codec id for 'lpcm' tag.
* See CoreAudioTypes and AudioStreamBasicDescription at Apple.
*/
-enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
+enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
{
if (flags & 1) { // floating point
if (flags & 2) { // big endian
- if (bps == 32) return CODEC_ID_PCM_F32BE;
- else if (bps == 64) return CODEC_ID_PCM_F64BE;
+ if (bps == 32) return AV_CODEC_ID_PCM_F32BE;
+ else if (bps == 64) return AV_CODEC_ID_PCM_F64BE;
} else {
- if (bps == 32) return CODEC_ID_PCM_F32LE;
- else if (bps == 64) return CODEC_ID_PCM_F64LE;
+ if (bps == 32) return AV_CODEC_ID_PCM_F32LE;
+ else if (bps == 64) return AV_CODEC_ID_PCM_F64LE;
}
} else {
if (flags & 2) {
if (bps == 8)
// signed integer
- if (flags & 4) return CODEC_ID_PCM_S8;
- else return CODEC_ID_PCM_U8;
- else if (bps == 16) return CODEC_ID_PCM_S16BE;
- else if (bps == 24) return CODEC_ID_PCM_S24BE;
- else if (bps == 32) return CODEC_ID_PCM_S32BE;
+ if (flags & 4) return AV_CODEC_ID_PCM_S8;
+ else return AV_CODEC_ID_PCM_U8;
+ else if (bps == 16) return AV_CODEC_ID_PCM_S16BE;
+ else if (bps == 24) return AV_CODEC_ID_PCM_S24BE;
+ else if (bps == 32) return AV_CODEC_ID_PCM_S32BE;
} else {
if (bps == 8)
- if (flags & 4) return CODEC_ID_PCM_S8;
- else return CODEC_ID_PCM_U8;
- else if (bps == 16) return CODEC_ID_PCM_S16LE;
- else if (bps == 24) return CODEC_ID_PCM_S24LE;
- else if (bps == 32) return CODEC_ID_PCM_S32LE;
+ if (flags & 4) return AV_CODEC_ID_PCM_S8;
+ else return AV_CODEC_ID_PCM_U8;
+ else if (bps == 16) return AV_CODEC_ID_PCM_S16LE;
+ else if (bps == 24) return AV_CODEC_ID_PCM_S24LE;
+ else if (bps == 32) return AV_CODEC_ID_PCM_S32LE;
}
}
- return CODEC_ID_NONE;
+ return AV_CODEC_ID_NONE;
}
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
for (pseudo_stream_id=0; pseudo_stream_id<entries; pseudo_stream_id++) {
//Parsing Sample description table
- enum CodecID id;
+ enum AVCodecID id;
int dref_id = 1;
MOVAtom a = { AV_RL32("stsd") };
int64_t start_pos = avio_tell(pb);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
else if (st->codec->codec_type == AVMEDIA_TYPE_DATA ||
(st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE &&
- st->codec->codec_id == CODEC_ID_NONE)){
+ st->codec->codec_id == AV_CODEC_ID_NONE)){
id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
if (id > 0)
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
color_index = 255;
color_dec = 256 / (color_count - 1);
for (j = 0; j < color_count; j++) {
- if (id == CODEC_ID_CINEPAK){
+ if (id == AV_CODEC_ID_CINEPAK){
r = g = b = color_count - 1 - color_index;
}else
r = g = b = color_index;
}
switch (st->codec->codec_id) {
- case CODEC_ID_PCM_S8:
- case CODEC_ID_PCM_U8:
+ case AV_CODEC_ID_PCM_S8:
+ case AV_CODEC_ID_PCM_U8:
if (st->codec->bits_per_coded_sample == 16)
- st->codec->codec_id = CODEC_ID_PCM_S16BE;
+ st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
break;
- case CODEC_ID_PCM_S16LE:
- case CODEC_ID_PCM_S16BE:
+ case AV_CODEC_ID_PCM_S16LE:
+ case AV_CODEC_ID_PCM_S16BE:
if (st->codec->bits_per_coded_sample == 8)
- st->codec->codec_id = CODEC_ID_PCM_S8;
+ st->codec->codec_id = AV_CODEC_ID_PCM_S8;
else if (st->codec->bits_per_coded_sample == 24)
st->codec->codec_id =
- st->codec->codec_id == CODEC_ID_PCM_S16BE ?
- CODEC_ID_PCM_S24BE : CODEC_ID_PCM_S24LE;
+ st->codec->codec_id == AV_CODEC_ID_PCM_S16BE ?
+ AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
break;
/* set values for old format before stsd version 1 appeared */
- case CODEC_ID_MACE3:
+ case AV_CODEC_ID_MACE3:
sc->samples_per_frame = 6;
sc->bytes_per_frame = 2*st->codec->channels;
break;
- case CODEC_ID_MACE6:
+ case AV_CODEC_ID_MACE6:
sc->samples_per_frame = 6;
sc->bytes_per_frame = 1*st->codec->channels;
break;
- case CODEC_ID_ADPCM_IMA_QT:
+ case AV_CODEC_ID_ADPCM_IMA_QT:
sc->samples_per_frame = 64;
sc->bytes_per_frame = 34*st->codec->channels;
break;
- case CODEC_ID_GSM:
+ case AV_CODEC_ID_GSM:
sc->samples_per_frame = 160;
sc->bytes_per_frame = 33;
break;
/* special codec parameters handling */
switch (st->codec->codec_id) {
#if CONFIG_DV_DEMUXER
- case CODEC_ID_DVAUDIO:
+ case AV_CODEC_ID_DVAUDIO:
c->dv_fctx = avformat_alloc_context();
c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
if (!c->dv_demux) {
return AVERROR(ENOMEM);
}
sc->dv_audio_container = 1;
- st->codec->codec_id = CODEC_ID_PCM_S16LE;
+ st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
break;
#endif
/* no ifdef since parameters are always those */
- case CODEC_ID_QCELP:
+ case AV_CODEC_ID_QCELP:
// force sample rate for qcelp when not stored in mov
if (st->codec->codec_tag != MKTAG('Q','c','l','p'))
st->codec->sample_rate = 8000;
st->codec->channels= 1; /* really needed */
break;
- case CODEC_ID_AMR_NB:
+ case AV_CODEC_ID_AMR_NB:
st->codec->channels= 1; /* really needed */
/* force sample rate for amr, stsd in 3gp does not store sample rate */
st->codec->sample_rate = 8000;
break;
- case CODEC_ID_AMR_WB:
+ case AV_CODEC_ID_AMR_WB:
st->codec->channels = 1;
st->codec->sample_rate = 16000;
break;
- case CODEC_ID_MP2:
- case CODEC_ID_MP3:
+ case AV_CODEC_ID_MP2:
+ case AV_CODEC_ID_MP3:
st->codec->codec_type = AVMEDIA_TYPE_AUDIO; /* force type after stsd for m1a hdlr */
st->need_parsing = AVSTREAM_PARSE_FULL;
break;
- case CODEC_ID_GSM:
- case CODEC_ID_ADPCM_MS:
- case CODEC_ID_ADPCM_IMA_WAV:
- case CODEC_ID_ILBC:
+ case AV_CODEC_ID_GSM:
+ case AV_CODEC_ID_ADPCM_MS:
+ case AV_CODEC_ID_ADPCM_IMA_WAV:
+ case AV_CODEC_ID_ILBC:
st->codec->block_align = sc->bytes_per_frame;
break;
- case CODEC_ID_ALAC:
+ case AV_CODEC_ID_ALAC:
if (st->codec->extradata_size == 36) {
st->codec->channels = AV_RB8 (st->codec->extradata+21);
st->codec->sample_rate = AV_RB32(st->codec->extradata+32);
}
break;
- case CODEC_ID_AC3:
+ case AV_CODEC_ID_AC3:
st->need_parsing = AVSTREAM_PARSE_FULL;
break;
- case CODEC_ID_MPEG1VIDEO:
+ case AV_CODEC_ID_MPEG1VIDEO:
st->need_parsing = AVSTREAM_PARSE_FULL;
break;
- case CODEC_ID_VC1:
+ case AV_CODEC_ID_VC1:
st->need_parsing = AVSTREAM_PARSE_FULL;
break;
default:
sc->ctts_data[i].count = count;
sc->ctts_data[i].duration= duration;
+ av_dlog(c->fc, "count=%d, duration=%d\n",
+ count, duration);
+
if (FFABS(duration) > (1<<28) && i+2<entries) {
av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
av_freep(&sc->ctts_data);
switch (st->codec->codec_id) {
#if CONFIG_H261_DECODER
- case CODEC_ID_H261:
+ case AV_CODEC_ID_H261:
#endif
#if CONFIG_H263_DECODER
- case CODEC_ID_H263:
+ case AV_CODEC_ID_H263:
#endif
#if CONFIG_MPEG4_DECODER
- case CODEC_ID_MPEG4:
+ case AV_CODEC_ID_MPEG4:
#endif
st->codec->width = 0; /* let decoder init width/height */
st->codec->height= 0;
if (avio_rl32(pb) != MKTAG('d','c','o','m'))
return AVERROR_INVALIDDATA;
if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
- av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !");
+ av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
return AVERROR_INVALIDDATA;
}
avio_rb32(pb); /* cmvd atom */
if (atom.size < 16)
return 0;
avio_skip(pb, 4);
- ff_mov_read_chan(c->fc,c->fc->streams[0], atom.size - 4);
+ ff_mov_read_chan(c->fc, pb, c->fc->streams[0], atom.size - 4);
return 0;
}
static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('A','C','L','R'), mov_read_avid },
{ MKTAG('A','P','R','G'), mov_read_avid },
+{ MKTAG('A','A','L','P'), mov_read_avid },
{ MKTAG('A','R','E','S'), mov_read_avid },
{ MKTAG('a','v','s','s'), mov_read_avss },
{ MKTAG('c','h','p','l'), mov_read_chpl },
left = a.size - avio_tell(pb) + start_pos;
if (left > 0) /* skip garbage at atom end */
avio_skip(pb, left);
+ else if(left < 0) {
+ av_log(c->fc, AV_LOG_DEBUG, "undoing overread of %"PRId64" in '%.4s'\n", -left, (char*)&a.type);
+ avio_seek(pb, left, SEEK_CUR);
+ }
}
total_size += a.size;
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
MOVStreamContext *sc = st->priv_data;
- if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->codec_id == CODEC_ID_AAC) {
- sc->start_pad = 2112;
+ if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->codec_id == AV_CODEC_ID_AAC) {
+ if(!sc->start_pad)
+ sc->start_pad = 1024;
st->skip_samples = sc->start_pad;
}
}