summaryrefslogtreecommitdiff
path: root/libavformat/utils.c
diff options
context:
space:
mode:
authorMåns Rullgård <mans@mansr.com>2008-08-06 22:17:38 +0000
committerMåns Rullgård <mans@mansr.com>2008-08-06 22:17:38 +0000
commit5c5b1731b77c6988debf975a5fd0a91936df013b (patch)
tree815be7b7833a50d3a0447d6b1f90fda897bd2be2 /libavformat/utils.c
parentb888abe1be9f0b3c75273c28e9a7b58fe47d5ec4 (diff)
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. Originally committed as revision 14654 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/utils.c')
-rw-r--r--libavformat/utils.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/libavformat/utils.c b/libavformat/utils.c
index d1647d2a06..1d96d3c5d4 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -524,16 +524,17 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
/*******************************************************/
-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 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
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 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt)
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 @@ int av_find_stream_info(AVFormatContext *ic)
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);