static int mov_read_chpl(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
{
int64_t start;
- int i, nb_chapters, str_len;
+ int i, nb_chapters, str_len, version;
char str[256+1];
if ((atom.size -= 5) < 0)
return 0;
- get_be32(pb); // version + flags
- get_be32(pb); // ???
+ version = get_byte(pb);
+ get_be24(pb);
+ if (version)
+ get_be32(pb); // ???
nb_chapters = get_byte(pb);
for (i = 0; i < nb_chapters; i++) {
a.size = get_be32(pb);
a.type = get_le32(pb);
}
+ dprintf(c->fc, "type: %08x '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
+ a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size);
total_size += 8;
- dprintf(c->fc, "type: %08x %.4s sz: %"PRIx64" %"PRIx64" %"PRIx64"\n",
- a.type, (char*)&a.type, a.size, atom.size, total_size);
if (a.size == 1) { /* 64 bit extended size */
a.size = get_be64(pb) - 8;
total_size += 8;
uint32_t size = get_be32(pb);
int64_t next = url_ftell(pb) + size - 4;
+ if (size < 12)
+ return -1;
+
dref->type = get_le32(pb);
get_be32(pb); // version + flags
dprintf(c->fc, "type %.4s size %d\n", (char*)&dref->type, size);
dprintf(fc, "Specific MPEG4 header len=%d\n", len);
if((uint64_t)len > (1<<30))
return -1;
+ av_free(st->codec->extradata);
st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata)
return AVERROR(ENOMEM);
st->codec->channels = cfg.channels;
if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4
st->codec->sample_rate = ff_mpa_freq_tab[cfg.sampling_index];
+ else if (cfg.ext_sample_rate)
+ st->codec->sample_rate = cfg.ext_sample_rate;
else
- st->codec->sample_rate = cfg.sample_rate; // ext sample rate ?
+ st->codec->sample_rate = cfg.sample_rate;
dprintf(fc, "mp4a config channels %d obj %d ext obj %d "
"sample rate %d ext sample rate %d\n", st->codec->channels,
cfg.object_type, cfg.ext_object_type,
return ff_mov_read_esds(c->fc, pb, atom);
}
+static int mov_read_dac3(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
+{
+ AVStream *st;
+ int ac3info, acmod, lfeon;
+
+ if (c->fc->nb_streams < 1)
+ return 0;
+ st = c->fc->streams[c->fc->nb_streams-1];
+
+ ac3info = get_be24(pb);
+ acmod = (ac3info >> 11) & 0x7;
+ lfeon = (ac3info >> 10) & 0x1;
+ st->codec->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
+
+ return 0;
+}
+
static int mov_read_pasp(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
{
const int num = get_be32(pb);
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- if (den != 0) {
- if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
- (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num))
- av_log(c->fc, AV_LOG_WARNING,
- "sample aspect ratio already set to %d:%d, overriding by 'pasp' atom\n",
- st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
+ if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
+ (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
+ av_log(c->fc, AV_LOG_WARNING,
+ "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
+ st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
+ num, den);
+ } else if (den != 0) {
st->sample_aspect_ratio.num = num;
st->sample_aspect_ratio.den = den;
}
return CODEC_ID_NONE;
}
-static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
+int ff_mov_read_stsd_entries(MOVContext *c, ByteIOContext *pb, int entries)
{
AVStream *st;
MOVStreamContext *sc;
- int j, entries, pseudo_stream_id;
+ int j, pseudo_stream_id;
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
sc = st->priv_data;
- get_byte(pb); /* version */
- get_be24(pb); /* flags */
-
- entries = get_be32(pb);
-
for(pseudo_stream_id=0; pseudo_stream_id<entries; pseudo_stream_id++) {
//Parsing Sample description table
enum CodecID id;
int dref_id = 1;
- MOVAtom a = { 0 };
+ MOVAtom a = { AV_RL32("stsd") };
int64_t start_pos = url_ftell(pb);
int size = get_be32(pb); /* size */
uint32_t format = get_le32(pb); /* data format */
st->codec->codec_tag = format;
id = ff_codec_get_id(codec_movaudio_tags, format);
if (id<=0 && ((format&0xFFFF) == 'm'+('s'<<8) || (format&0xFFFF) == 'T'+('S'<<8)))
- id = ff_codec_get_id(ff_codec_wav_tags, bswap_32(format)&0xFFFF);
+ id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format)&0xFFFF);
if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
return 0;
}
+static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
+{
+ int entries;
+
+ get_byte(pb); /* version */
+ get_be24(pb); /* flags */
+ entries = get_be32(pb);
+
+ return ff_mov_read_stsd_entries(c, pb, entries);
+}
+
static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
{
AVStream *st;
sc->pb = c->fc->pb;
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- if (st->codec->width != sc->width || st->codec->height != sc->height) {
- AVRational r = av_d2q(((double)st->codec->height * sc->width) /
- ((double)st->codec->width * sc->height), INT_MAX);
- if (st->sample_aspect_ratio.num)
- st->sample_aspect_ratio = av_mul_q(st->sample_aspect_ratio, r);
- else
- st->sample_aspect_ratio = r;
+ if (!st->sample_aspect_ratio.num &&
+ (st->codec->width != sc->width || st->codec->height != sc->height)) {
+ st->sample_aspect_ratio = av_d2q(((double)st->codec->height * sc->width) /
+ ((double)st->codec->width * sc->height), INT_MAX);
}
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
{ MKTAG('u','d','t','a'), mov_read_default },
{ MKTAG('w','a','v','e'), mov_read_wave },
{ MKTAG('e','s','d','s'), mov_read_esds },
+{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
{ MKTAG('c','m','o','v'), mov_read_cmov },
{ 0, NULL }
MOVContext *mov = s->priv_data;
ByteIOContext *pb = s->pb;
int err;
- MOVAtom atom = { 0 };
+ MOVAtom atom = { AV_RL32("root") };
mov->fc = s;
/* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
if (!sample) {
mov->found_mdat = 0;
if (!url_is_streamed(s->pb) ||
- mov_read_default(mov, s->pb, (MOVAtom){ 0, INT64_MAX }) < 0 ||
+ mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX }) < 0 ||
url_feof(s->pb))
return AVERROR_EOF;
dprintf(s, "read fragments, offset 0x%llx\n", url_ftell(s->pb));
sample = av_index_search_timestamp(st, timestamp, flags);
dprintf(s, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
+ if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
+ sample = 0;
if (sample < 0) /* not sure what to do */
return -1;
sc->current_sample = sample;