Mercurial > libavformat.hg
changeset 5200:cd884511ec8b libavformat
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.
| author | michael |
|---|---|
| date | Wed, 16 Sep 2009 00:59:15 +0000 |
| parents | fc6e05b7709d |
| children | 12bd8561aed1 |
| files | avformat.h utils.c |
| diffstat | 2 files changed, 24 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/avformat.h Wed Sep 16 00:56:31 2009 +0000 +++ b/avformat.h Wed Sep 16 00:59:15 2009 +0000 @@ -450,6 +450,12 @@ */ #define MAX_PROBE_PACKETS 100 int probe_packets; + + /** + * Number of packets in packet_buffer for this stream when muxing. + * used internally, NOT PART OF PUBLIC API, dont read or write from outside of libav* + */ + int num_in_packet_buffer; } AVStream; #define AV_PROGRAM_RUNNING 1
--- a/utils.c Wed Sep 16 00:56:31 2009 +0000 +++ b/utils.c Wed Sep 16 00:59:15 2009 +0000 @@ -2657,14 +2657,25 @@ 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 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{
