static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
c->fragment.moof_offset = avio_tell(pb) - 8;
- av_dlog(c->fc, "moof offset %llx\n", c->fragment.moof_offset);
+ av_dlog(c->fc, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
return mov_read_default(c, pb, atom);
}
unsigned int color_start, color_count, color_end;
unsigned char r, g, b;
- st->codec->palctrl = av_malloc(sizeof(*st->codec->palctrl));
if (color_greyscale) {
int color_index, color_dec;
/* compute the greyscale palette */
color_dec = 256 / (color_count - 1);
for (j = 0; j < color_count; j++) {
r = g = b = color_index;
- st->codec->palctrl->palette[j] =
+ sc->palette[j] =
(r << 16) | (g << 8) | (b);
color_index -= color_dec;
if (color_index < 0)
r = color_table[j * 3 + 0];
g = color_table[j * 3 + 1];
b = color_table[j * 3 + 2];
- st->codec->palctrl->palette[j] =
+ sc->palette[j] =
(r << 16) | (g << 8) | (b);
}
} else {
avio_r8(pb);
b = avio_r8(pb);
avio_r8(pb);
- st->codec->palctrl->palette[j] =
+ sc->palette[j] =
(r << 16) | (g << 8) | (b);
}
}
}
- st->codec->palctrl->palette_changed = 1;
+ sc->has_palette = 1;
}
} else if(st->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
int bits_per_sample, flags;
av_strlcat(filename, ref->path + l + 1, 1024);
- if (!avio_open(pb, filename, URL_RDONLY))
+ if (!avio_open(pb, filename, AVIO_FLAG_READ))
return 0;
}
}
MOVFragment *frag = &c->fragment;
AVStream *st = NULL;
MOVStreamContext *sc;
+ MOVStts *ctts_data;
uint64_t offset;
int64_t dts;
int data_offset = 0;
flags = avio_rb24(pb);
entries = avio_rb32(pb);
av_dlog(c->fc, "flags 0x%x entries %d\n", flags, entries);
- if (flags & 0x001) data_offset = avio_rb32(pb);
- if (flags & 0x004) first_sample_flags = avio_rb32(pb);
- if (flags & 0x800) {
- MOVStts *ctts_data;
- if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
- return -1;
- ctts_data = av_realloc(sc->ctts_data,
- (entries+sc->ctts_count)*sizeof(*sc->ctts_data));
+
+ /* Always assume the presence of composition time offsets.
+ * Without this assumption, for instance, we cannot deal with a track in fragmented movies that meet the following.
+ * 1) in the initial movie, there are no samples.
+ * 2) in the first movie fragment, there is only one sample without composition time offset.
+ * 3) in the subsequent movie fragments, there are samples with composition time offset. */
+ if (!sc->ctts_count && sc->sample_count)
+ {
+ /* Complement ctts table if moov atom doesn't have ctts atom. */
+ ctts_data = av_malloc(sizeof(*sc->ctts_data));
if (!ctts_data)
return AVERROR(ENOMEM);
sc->ctts_data = ctts_data;
+ sc->ctts_data[sc->ctts_count].count = sc->sample_count;
+ sc->ctts_data[sc->ctts_count].duration = 0;
+ sc->ctts_count++;
}
+ if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
+ return -1;
+ ctts_data = av_realloc(sc->ctts_data,
+ (entries+sc->ctts_count)*sizeof(*sc->ctts_data));
+ if (!ctts_data)
+ return AVERROR(ENOMEM);
+ sc->ctts_data = ctts_data;
+
+ if (flags & 0x001) data_offset = avio_rb32(pb);
+ if (flags & 0x004) first_sample_flags = avio_rb32(pb);
dts = st->duration;
offset = frag->base_data_offset + data_offset;
distance = 0;
if (flags & 0x100) sample_duration = avio_rb32(pb);
if (flags & 0x200) sample_size = avio_rb32(pb);
if (flags & 0x400) sample_flags = avio_rb32(pb);
- if (flags & 0x800) {
- sc->ctts_data[sc->ctts_count].count = 1;
- sc->ctts_data[sc->ctts_count].duration = avio_rb32(pb);
- sc->ctts_count++;
- }
+ sc->ctts_data[sc->ctts_count].count = 1;
+ sc->ctts_data[sc->ctts_count].duration = (flags & 0x800) ? avio_rb32(pb) : 0;
+ sc->ctts_count++;
if ((keyframe = st->codec->codec_type == AVMEDIA_TYPE_AUDIO ||
(flags & 0x004 && !i && !sample_flags) || sample_flags & 0x2000000))
distance = 0;
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
MOVStreamContext *sc;
- int i, edit_count;
+ int i, edit_count, version;
if (c->fc->nb_streams < 1)
return 0;
sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
- avio_r8(pb); /* version */
+ version = avio_r8(pb); /* version */
avio_rb24(pb); /* flags */
edit_count = avio_rb32(pb); /* entries */
return -1;
for(i=0; i<edit_count; i++){
- int time;
- int duration = avio_rb32(pb); /* Track duration */
- time = avio_rb32(pb); /* Media time */
+ int64_t time;
+ int64_t duration;
+ if (version == 1) {
+ duration = avio_rb64(pb);
+ time = avio_rb64(pb);
+ } else {
+ duration = avio_rb32(pb); /* segment duration */
+ time = avio_rb32(pb); /* media time */
+ }
avio_rb32(pb); /* Media rate */
if (i == 0 && time >= -1) {
sc->time_offset = time != -1 ? time : -duration;
av_log(s, AV_LOG_ERROR, "moov atom not found\n");
return -1;
}
- av_dlog(mov->fc, "on_parse_exit_offset=%lld\n", avio_tell(pb));
+ av_dlog(mov->fc, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
if (pb->seekable && mov->chapter_track > 0)
mov_read_chapters(s);
mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX }) < 0 ||
s->pb->eof_reached)
return AVERROR_EOF;
- av_dlog(s, "read fragments, offset 0x%llx\n", avio_tell(s->pb));
+ av_dlog(s, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
goto retry;
}
sc = st->priv_data;
ret = av_get_packet(sc->pb, pkt, sample->size);
if (ret < 0)
return ret;
+ if (sc->has_palette) {
+ uint8_t *pal;
+
+ pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
+ if (!pal) {
+ av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
+ } else {
+ memcpy(pal, sc->palette, AVPALETTE_SIZE);
+ sc->has_palette = 0;
+ }
+ }
#if CONFIG_DV_DEMUXER
if (mov->dv_demux && sc->dv_audio_container) {
dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size);