[FFmpeg-cvslog] r19870 - in trunk/libavformat: avformat.h utils.c

michael subversion
Wed Sep 16 02:59:15 CEST 2009


Author: michael
Date: Wed Sep 16 02:59:15 2009
New Revision: 19870

Log:
Make packet interleaving in the muxer not scan throuh the whole
buffer when simply appending at the end works.
Much faster if one stream ends prematurely.
Fixes issue1379.

Modified:
   trunk/libavformat/avformat.h
   trunk/libavformat/utils.c

Modified: trunk/libavformat/avformat.h
==============================================================================
--- trunk/libavformat/avformat.h	Wed Sep 16 02:56:31 2009	(r19869)
+++ trunk/libavformat/avformat.h	Wed Sep 16 02:59:15 2009	(r19870)
@@ -450,6 +450,12 @@ typedef struct AVStream {
      */
 #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

Modified: trunk/libavformat/utils.c
==============================================================================
--- trunk/libavformat/utils.c	Wed Sep 16 02:56:31 2009	(r19869)
+++ trunk/libavformat/utils.c	Wed Sep 16 02:59:15 2009	(r19870)
@@ -2657,14 +2657,25 @@ void ff_interleave_add_packet(AVFormatCo
     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(AVFormatCo
 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{



More information about the ffmpeg-cvslog mailing list