Parse stss info in MOV files to get key frames patch by ("Brian Becker" <Brian dot Becker at palmone dot com>)
Originally committed as revision 2879 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
14284f78c5
commit
247d56f568
@ -220,6 +220,8 @@ typedef struct MOVStreamContext {
|
||||
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 @@ printf("track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
|
||||
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 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
|
||||
{ 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 @@ static void mov_free_stream_context(MOVStreamContext *sc)
|
||||
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 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
MOVContext *mov = (MOVContext *) s->priv_data;
|
||||
MOVStreamContext *sc;
|
||||
int64_t offset = 0x0FFFFFFFFFFFFFFFLL;
|
||||
int i;
|
||||
int i, a, b, m;
|
||||
int size;
|
||||
size = 0x0FFFFFFF;
|
||||
|
||||
@ -1718,6 +1749,27 @@ readchunk:
|
||||
}
|
||||
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
|
||||
/*
|
||||
printf("Packet (%d, %d, %ld) ", pkt->stream_index, st_id, pkt->size);
|
||||
|
Loading…
Reference in New Issue
Block a user