diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-11-30 00:21:00 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-12-01 03:53:13 +0100 |
commit | ec20fc15818598aaf83232db3df2c85b1752c49a (patch) | |
tree | 1842cab277a64ebdf52b612215617b4b98b5850a /libavformat/utils.c | |
parent | 31f9032b786c1788f6295f5d3fd07622229010b1 (diff) | |
download | ffmpeg-ec20fc15818598aaf83232db3df2c85b1752c49a.tar.gz |
lavf: allow grouping packets in chunks of a user specified size and duration.
This is similar to MP4Boxs -inter
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/utils.c')
-rw-r--r-- | libavformat/utils.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/libavformat/utils.c b/libavformat/utils.c index 5a4b364f47..1493f278ab 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3263,10 +3263,14 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt) return ret; } +#define CHUNK_START 0x1000 + int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt, int (*compare)(AVFormatContext *, AVPacket *, AVPacket *)) { AVPacketList **next_point, *this_pktl; + AVStream *st= s->streams[pkt->stream_index]; + int chunked= s->max_chunk_size || s->max_chunk_duration; this_pktl = av_mallocz(sizeof(AVPacketList)); if (!this_pktl) @@ -3276,16 +3280,34 @@ int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt, av_dup_packet(&this_pktl->pkt); // duplicate the packet if it uses non-alloced memory if(s->streams[pkt->stream_index]->last_in_packet_buffer){ - next_point = &(s->streams[pkt->stream_index]->last_in_packet_buffer->next); - }else + next_point = &(st->last_in_packet_buffer->next); + }else{ next_point = &s->packet_buffer; + } if(*next_point){ + if(chunked){ + uint64_t max= av_rescale_q(s->max_chunk_duration, AV_TIME_BASE_Q, st->time_base); + if( st->interleaver_chunk_size + pkt->size <= s->max_chunk_size-1U + && st->interleaver_chunk_duration + pkt->duration <= max-1U){ + st->interleaver_chunk_size += pkt->size; + st->interleaver_chunk_duration += pkt->duration; + goto next_non_null; + }else{ + st->interleaver_chunk_size = + st->interleaver_chunk_duration = 0; + this_pktl->pkt.flags |= CHUNK_START; + } + } + if(compare(s, &s->packet_buffer_end->pkt, pkt)){ - while(!compare(s, &(*next_point)->pkt, pkt)){ + while( *next_point + && ((chunked && !((*next_point)->pkt.flags&CHUNK_START)) + || !compare(s, &(*next_point)->pkt, pkt))){ next_point= &(*next_point)->next; } - goto next_non_null; + if(*next_point) + goto next_non_null; }else{ next_point = &(s->packet_buffer_end->next); } |