aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/utils.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2009-09-16 00:59:15 +0000
committerMichael Niedermayer <michaelni@gmx.at>2009-09-16 00:59:15 +0000
commitddce56efc5976dbc4910a2e59bfd06f9f5f0ae4f (patch)
treeff93799ddcf1a45ee6204e6b8a73f2d695d9d2fa /libavformat/utils.c
parent42831b46ef03f00b86bf13c509a5e9b01b3fe457 (diff)
downloadffmpeg-ddce56efc5976dbc4910a2e59bfd06f9f5f0ae4f.tar.gz
Make packet interleaving in the muxer not scan through the whole
buffer when simply appending at the end works. Much faster if one stream ends prematurely. Fixes issue1379. Originally committed as revision 19870 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/utils.c')
-rw-r--r--libavformat/utils.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 0a88c80e5b..f7d929d66c 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2657,14 +2657,25 @@ void ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
pkt->destruct= NULL; // do not free original but only the copy
av_dup_packet(&this_pktl->pkt); // duplicate the packet if it uses non-alloced memory
+ if(!s->packet_buffer_end || compare(s, &s->packet_buffer_end->pkt, pkt)){
next_point = &s->packet_buffer;
while(*next_point){
if(compare(s, &(*next_point)->pkt, pkt))
break;
next_point= &(*next_point)->next;
}
+ }else{
+ next_point = &(s->packet_buffer_end->next);
+ assert(!*next_point);
+ }
this_pktl->next= *next_point;
+
+ if(!*next_point)
+ s->packet_buffer_end= this_pktl;
+
*next_point= this_pktl;
+
+ s->streams[pkt->stream_index]->num_in_packet_buffer++;
}
int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
@@ -2683,27 +2694,24 @@ int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush){
AVPacketList *pktl;
int stream_count=0;
- int streams[MAX_STREAMS];
+ int i;
if(pkt){
ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
}
- memset(streams, 0, sizeof(streams));
- pktl= s->packet_buffer;
- while(pktl){
-//av_log(s, AV_LOG_DEBUG, "show st:%d dts:%"PRId64"\n", pktl->pkt.stream_index, pktl->pkt.dts);
- if(streams[ pktl->pkt.stream_index ] == 0)
- stream_count++;
- streams[ pktl->pkt.stream_index ]++;
- pktl= pktl->next;
- }
+ for(i=0; i < s->nb_streams; i++)
+ stream_count+= !!s->streams[i]->num_in_packet_buffer;
if(stream_count && (s->nb_streams == stream_count || flush)){
pktl= s->packet_buffer;
*out= pktl->pkt;
s->packet_buffer= pktl->next;
+ if(!s->packet_buffer)
+ s->packet_buffer_end= NULL;
+
+ s->streams[out->stream_index]->num_in_packet_buffer--;
av_freep(&pktl);
return 1;
}else{