changeset 3698:b7e347127897 libavformat

Maintain pointer to end of AVFormatContext.packet_buffer list This changes add_to_pktbuf() to maintain a pointer to the last entry in the list, avoiding a linear walk-through on each call. Before this change, add_to_pktbuf() could take a significant amount of time (10% of total decoding time), even with input files of several minutes. After the change, the time spent in this function is barely measurable with oprofile.
author mru
date Wed, 06 Aug 2008 22:17:38 +0000
parents c458ae91b0f9
children 76b7a9f5cef4
files avformat.h utils.c
diffstat 2 files changed, 16 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/avformat.h	Wed Aug 06 08:34:35 2008 +0000
+++ b/avformat.h	Wed Aug 06 22:17:38 2008 +0000
@@ -22,7 +22,7 @@
 #define FFMPEG_AVFORMAT_H
 
 #define LIBAVFORMAT_VERSION_MAJOR 52
-#define LIBAVFORMAT_VERSION_MINOR 18
+#define LIBAVFORMAT_VERSION_MINOR 19
 #define LIBAVFORMAT_VERSION_MICRO  0
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
@@ -565,6 +565,9 @@
      * codec.
      */
     struct AVPacketList *raw_packet_buffer;
+    struct AVPacketList *raw_packet_buffer_end;
+
+    struct AVPacketList *packet_buffer_end;
 } AVFormatContext;
 
 typedef struct AVPacketList {
--- a/utils.c	Wed Aug 06 08:34:35 2008 +0000
+++ b/utils.c	Wed Aug 06 22:17:38 2008 +0000
@@ -524,16 +524,17 @@
 
 /*******************************************************/
 
-static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt){
-    AVPacketList *pktl;
-    AVPacketList **plast_pktl= packet_buffer;
-
-    while(*plast_pktl) plast_pktl= &(*plast_pktl)->next; //FIXME maybe maintain pointer to the last?
-
-    pktl = av_mallocz(sizeof(AVPacketList));
+static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt,
+                               AVPacketList **plast_pktl){
+    AVPacketList *pktl = av_mallocz(sizeof(AVPacketList));
     if (!pktl)
         return NULL;
 
+    if (*packet_buffer)
+        (*plast_pktl)->next = pktl;
+    else
+        *packet_buffer = pktl;
+
     /* add the packet in the buffered packet list */
     *plast_pktl = pktl;
     pktl->pkt= *pkt;
@@ -578,7 +579,7 @@
         if(!pktl && st->codec->codec_id!=CODEC_ID_PROBE)
             return ret;
 
-        add_to_pktbuf(&s->raw_packet_buffer, pkt);
+        add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end);
 
         if(st->codec->codec_id == CODEC_ID_PROBE){
             AVProbeData *pd = &st->probe_data;
@@ -1043,7 +1044,8 @@
                     return ret;
             }
 
-            if(av_dup_packet(add_to_pktbuf(&s->packet_buffer, pkt)) < 0)
+            if(av_dup_packet(add_to_pktbuf(&s->packet_buffer, pkt,
+                                           &s->packet_buffer_end)) < 0)
                 return AVERROR(ENOMEM);
         }else{
             assert(!s->packet_buffer);
@@ -2021,7 +2023,7 @@
             break;
         }
 
-        pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1);
+        pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end);
         if(av_dup_packet(pkt) < 0) {
             av_free(duration_error);
             return AVERROR(ENOMEM);