|
|
|
@ -1102,6 +1102,35 @@ static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOVAtom atom) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int mov_read_stps(MOVContext *c, ByteIOContext *pb, MOVAtom atom) |
|
|
|
|
{ |
|
|
|
|
AVStream *st; |
|
|
|
|
MOVStreamContext *sc; |
|
|
|
|
unsigned i, entries; |
|
|
|
|
|
|
|
|
|
if (c->fc->nb_streams < 1) |
|
|
|
|
return 0; |
|
|
|
|
st = c->fc->streams[c->fc->nb_streams-1]; |
|
|
|
|
sc = st->priv_data; |
|
|
|
|
|
|
|
|
|
get_be32(pb); // version + flags
|
|
|
|
|
|
|
|
|
|
entries = get_be32(pb); |
|
|
|
|
if (entries >= UINT_MAX / sizeof(*sc->stps_data)) |
|
|
|
|
return -1; |
|
|
|
|
sc->stps_data = av_malloc(entries * sizeof(*sc->stps_data)); |
|
|
|
|
if (!sc->stps_data) |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
sc->stps_count = entries; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < entries; i++) { |
|
|
|
|
sc->stps_data[i] = get_be32(pb); |
|
|
|
|
//dprintf(c->fc, "stps %d\n", sc->stps_data[i]);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOVAtom atom) |
|
|
|
|
{ |
|
|
|
|
AVStream *st = c->fc->streams[c->fc->nb_streams-1]; |
|
|
|
@ -1300,6 +1329,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st) |
|
|
|
|
unsigned int stts_index = 0; |
|
|
|
|
unsigned int stsc_index = 0; |
|
|
|
|
unsigned int stss_index = 0; |
|
|
|
|
unsigned int stps_index = 0; |
|
|
|
|
unsigned int i, j; |
|
|
|
|
|
|
|
|
|
/* adjust first dts according to edit list */ |
|
|
|
@ -1320,7 +1350,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st) |
|
|
|
|
sc->stts_count == 1 && sc->stts_data[0].duration == 1)) { |
|
|
|
|
unsigned int current_sample = 0; |
|
|
|
|
unsigned int stts_sample = 0; |
|
|
|
|
unsigned int keyframe, sample_size; |
|
|
|
|
unsigned int sample_size; |
|
|
|
|
unsigned int distance = 0; |
|
|
|
|
int key_off = sc->keyframes && sc->keyframes[0] == 1; |
|
|
|
|
|
|
|
|
@ -1334,16 +1364,23 @@ static void mov_build_index(MOVContext *mov, AVStream *st) |
|
|
|
|
i + 1 == sc->stsc_data[stsc_index + 1].first) |
|
|
|
|
stsc_index++; |
|
|
|
|
for (j = 0; j < sc->stsc_data[stsc_index].count; j++) { |
|
|
|
|
int keyframe = 0; |
|
|
|
|
if (current_sample >= sc->sample_count) { |
|
|
|
|
av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
keyframe = !sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index]; |
|
|
|
|
if (keyframe) { |
|
|
|
|
distance = 0; |
|
|
|
|
|
|
|
|
|
if (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index]) { |
|
|
|
|
keyframe = 1; |
|
|
|
|
if (stss_index + 1 < sc->keyframe_count) |
|
|
|
|
stss_index++; |
|
|
|
|
} else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) { |
|
|
|
|
keyframe = 1; |
|
|
|
|
if (stps_index + 1 < sc->stps_count) |
|
|
|
|
stps_index++; |
|
|
|
|
} |
|
|
|
|
if (keyframe) |
|
|
|
|
distance = 0; |
|
|
|
|
sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample]; |
|
|
|
|
if(sc->pseudo_stream_id == -1 || |
|
|
|
|
sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) { |
|
|
|
@ -1492,6 +1529,7 @@ static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOVAtom atom) |
|
|
|
|
av_freep(&sc->sample_sizes); |
|
|
|
|
av_freep(&sc->keyframes); |
|
|
|
|
av_freep(&sc->stts_data); |
|
|
|
|
av_freep(&sc->stps_data); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
@ -1861,6 +1899,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { |
|
|
|
|
{ MKTAG('p','a','s','p'), mov_read_pasp }, |
|
|
|
|
{ MKTAG('s','t','b','l'), mov_read_default }, |
|
|
|
|
{ MKTAG('s','t','c','o'), mov_read_stco }, |
|
|
|
|
{ MKTAG('s','t','p','s'), mov_read_stps }, |
|
|
|
|
{ MKTAG('s','t','s','c'), mov_read_stsc }, |
|
|
|
|
{ MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */ |
|
|
|
|
{ MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */ |
|
|
|
|