Commit 598fd2f9 authored by mru's avatar mru

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.

git-svn-id: file:///var/local/repositories/ffmpeg/trunk@14654 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent e0fbc3e4
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#define FFMPEG_AVFORMAT_H #define FFMPEG_AVFORMAT_H
#define LIBAVFORMAT_VERSION_MAJOR 52 #define LIBAVFORMAT_VERSION_MAJOR 52
#define LIBAVFORMAT_VERSION_MINOR 18 #define LIBAVFORMAT_VERSION_MINOR 19
#define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
...@@ -565,6 +565,9 @@ typedef struct AVFormatContext { ...@@ -565,6 +565,9 @@ typedef struct AVFormatContext {
* codec. * codec.
*/ */
struct AVPacketList *raw_packet_buffer; struct AVPacketList *raw_packet_buffer;
struct AVPacketList *raw_packet_buffer_end;
struct AVPacketList *packet_buffer_end;
} AVFormatContext; } AVFormatContext;
typedef struct AVPacketList { typedef struct AVPacketList {
......
...@@ -524,16 +524,17 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, ...@@ -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){ static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt,
AVPacketList *pktl; AVPacketList **plast_pktl){
AVPacketList **plast_pktl= packet_buffer; AVPacketList *pktl = av_mallocz(sizeof(AVPacketList));
while(*plast_pktl) plast_pktl= &(*plast_pktl)->next; //FIXME maybe maintain pointer to the last?
pktl = av_mallocz(sizeof(AVPacketList));
if (!pktl) if (!pktl)
return NULL; return NULL;
if (*packet_buffer)
(*plast_pktl)->next = pktl;
else
*packet_buffer = pktl;
/* add the packet in the buffered packet list */ /* add the packet in the buffered packet list */
*plast_pktl = pktl; *plast_pktl = pktl;
pktl->pkt= *pkt; pktl->pkt= *pkt;
...@@ -578,7 +579,7 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -578,7 +579,7 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
if(!pktl && st->codec->codec_id!=CODEC_ID_PROBE) if(!pktl && st->codec->codec_id!=CODEC_ID_PROBE)
return ret; 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){ if(st->codec->codec_id == CODEC_ID_PROBE){
AVProbeData *pd = &st->probe_data; AVProbeData *pd = &st->probe_data;
...@@ -1043,7 +1044,8 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) ...@@ -1043,7 +1044,8 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt)
return ret; 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); return AVERROR(ENOMEM);
}else{ }else{
assert(!s->packet_buffer); assert(!s->packet_buffer);
...@@ -2021,7 +2023,7 @@ int av_find_stream_info(AVFormatContext *ic) ...@@ -2021,7 +2023,7 @@ int av_find_stream_info(AVFormatContext *ic)
break; 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) { if(av_dup_packet(pkt) < 0) {
av_free(duration_error); av_free(duration_error);
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment