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
This commit is contained in:
@@ -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 {
|
|||||||
* 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,
|
|||||||
|
|
||||||
/*******************************************************/
|
/*******************************************************/
|
||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user