aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/utils.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-11-30 00:21:00 +0100
committerMichael Niedermayer <michaelni@gmx.at>2011-12-01 03:53:13 +0100
commitec20fc15818598aaf83232db3df2c85b1752c49a (patch)
tree1842cab277a64ebdf52b612215617b4b98b5850a /libavformat/utils.c
parent31f9032b786c1788f6295f5d3fd07622229010b1 (diff)
downloadffmpeg-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.c30
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);
}