Mercurial > libavformat.hg
changeset 383:1674ed5ca2f0 libavformat
Parse stss info in MOV files to get key frames patch by ("Brian Becker" <Brian dot Becker at palmone dot com>)
author | michael |
---|---|
date | Sat, 13 Mar 2004 21:02:26 +0000 |
parents | 37a29b5200d8 |
children | 9479dac25620 |
files | mov.c |
diffstat | 1 files changed, 54 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/mov.c Sat Mar 13 17:30:37 2004 +0000 +++ b/mov.c Sat Mar 13 21:02:26 2004 +0000 @@ -220,6 +220,8 @@ long sample_size; long sample_count; long *sample_sizes; + long keyframe_count; + long *keyframes; int time_scale; long current_sample; long left_in_chunk; /* how many samples before next chunk */ @@ -1102,6 +1104,34 @@ return 0; } +static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) +{ + AVStream *st = c->fc->streams[c->fc->nb_streams-1]; + MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; + int entries, i; + + print_atom("stss", atom); + + get_byte(pb); /* version */ + get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ + + entries = get_be32(pb); + sc->keyframe_count = entries; +#ifdef DEBUG + av_log(NULL, AV_LOG_DEBUG, "keyframe_count = %ld\n", sc->keyframe_count); +#endif + sc->keyframes = (long*) av_malloc(entries * sizeof(long)); + if (!sc->keyframes) + return -1; + for(i=0; i<entries; i++) { + sc->keyframes[i] = get_be32(pb); +#ifdef DEBUG +/* av_log(NULL, AV_LOG_DEBUG, "keyframes[]=%ld\n", sc->keyframes[i]); */ +#endif + } + return 0; +} + static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) { AVStream *st = c->fc->streams[c->fc->nb_streams-1]; @@ -1409,7 +1439,7 @@ { MKTAG( 's', 't', 's', 'c' ), mov_read_stsc }, { MKTAG( 's', 't', 's', 'd' ), mov_read_stsd }, /* sample description */ { MKTAG( 's', 't', 's', 'h' ), mov_read_default }, -{ MKTAG( 's', 't', 's', 's' ), mov_read_leaf }, /* sync sample */ +{ MKTAG( 's', 't', 's', 's' ), mov_read_stss }, /* sync sample */ { MKTAG( 's', 't', 's', 'z' ), mov_read_stsz }, /* sample size */ { MKTAG( 's', 't', 't', 's' ), mov_read_stts }, { MKTAG( 't', 'k', 'h', 'd' ), mov_read_tkhd }, /* track header */ @@ -1455,6 +1485,7 @@ av_free(sc->chunk_offsets); av_free(sc->sample_to_chunk); av_free(sc->sample_sizes); + av_free(sc->keyframes); av_free(sc->header_data); av_free(sc); } @@ -1583,7 +1614,7 @@ MOVContext *mov = (MOVContext *) s->priv_data; MOVStreamContext *sc; int64_t offset = 0x0FFFFFFFFFFFFFFFLL; - int i; + int i, a, b, m; int size; size = 0x0FFFFFFF; @@ -1717,6 +1748,27 @@ get_buffer(&s->pb, pkt->data, pkt->size); } pkt->stream_index = sc->ffindex; + + // If the keyframes table exists, mark any samples that are in the table as key frames. + // If no table exists, treat very sample as a key frame. + if (sc->keyframes) { + a = 0; + b = sc->keyframe_count - 1; + + while (a < b) { + m = (a + b + 1) >> 1; + if (sc->keyframes[m] > sc->current_sample) { + b = m - 1; + } else { + a = m; + } + } + + if (sc->keyframes[a] == sc->current_sample) + pkt->flags |= PKT_FLAG_KEY; + } + else + pkt->flags |= PKT_FLAG_KEY; #ifdef DEBUG /*