summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Ruggles <justin.ruggles@gmail.com>2011-12-05 11:49:38 -0500
committerJustin Ruggles <justin.ruggles@gmail.com>2011-12-05 11:54:24 -0500
commit9179f27c6431e36cf0ebd320fb2733f56969bb44 (patch)
tree868e802a6241ebc5398ac35708fd211248d87838
parent110d2af28e186d5ed120942f8b3d51acda59e341 (diff)
downloadffmpeg-9179f27c6431e36cf0ebd320fb2733f56969bb44.tar.gz
avconv: only allocate 1 AVFrame per input stream
This avoids allocating/freeing an AVFrame for each packet decode. It also simplifies error handling in transcode_audio() and transcode_video().
-rw-r--r--avconv.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/avconv.c b/avconv.c
index 787ca9c219..54aa89b117 100644
--- a/avconv.c
+++ b/avconv.c
@@ -145,6 +145,8 @@ typedef struct InputStream {
int discard; /* true if stream data should be discarded */
int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */
AVCodec *dec;
+ AVFrame *decoded_frame;
+ AVFrame *filtered_frame;
int64_t start; /* time when read started */
int64_t next_pts; /* synthetic pts for cases where pkt.pts
@@ -523,8 +525,11 @@ void exit_program(int ret)
for(i=0;i<nb_input_files;i++) {
av_close_input_file(input_files[i].ctx);
}
- for (i = 0; i < nb_input_streams; i++)
+ for (i = 0; i < nb_input_streams; i++) {
+ av_freep(&input_streams[i].decoded_frame);
+ av_freep(&input_streams[i].filtered_frame);
av_dict_free(&input_streams[i].opts);
+ }
if (vstats_file)
fclose(vstats_file);
@@ -1622,18 +1627,19 @@ static int transcode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
int bps = av_get_bytes_per_sample(ist->st->codec->sample_fmt);
int i, ret;
- if (!(decoded_frame = avcodec_alloc_frame()))
+ if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
return AVERROR(ENOMEM);
+ else
+ avcodec_get_frame_defaults(ist->decoded_frame);
+ decoded_frame = ist->decoded_frame;
ret = avcodec_decode_audio4(avctx, decoded_frame, got_output, pkt);
if (ret < 0) {
- av_freep(&decoded_frame);
return ret;
}
if (!*got_output) {
/* no audio frame */
- av_freep(&decoded_frame);
return ret;
}
@@ -1701,7 +1707,6 @@ static int transcode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
av_log(NULL, AV_LOG_FATAL,
"Audio volume adjustment on sample format %s is not supported.\n",
av_get_sample_fmt_name(ist->st->codec->sample_fmt));
- av_freep(&decoded_frame);
exit_program(1);
}
}
@@ -1716,7 +1721,6 @@ static int transcode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
do_audio_out(output_files[ost->file_index].ctx, ost, ist, decoded_frame);
}
- av_freep(&decoded_frame);
return ret;
}
@@ -1730,8 +1734,11 @@ static int transcode_video(InputStream *ist, AVPacket *pkt, int *got_output, int
int frame_available = 1;
#endif
- if (!(decoded_frame = avcodec_alloc_frame()))
+ if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
return AVERROR(ENOMEM);
+ else
+ avcodec_get_frame_defaults(ist->decoded_frame);
+ decoded_frame = ist->decoded_frame;
pkt->pts = *pkt_pts;
pkt->dts = ist->pts;
*pkt_pts = AV_NOPTS_VALUE;
@@ -1739,12 +1746,11 @@ static int transcode_video(InputStream *ist, AVPacket *pkt, int *got_output, int
ret = avcodec_decode_video2(ist->st->codec,
decoded_frame, got_output, pkt);
if (ret < 0)
- goto fail;
+ return ret;
quality = same_quant ? decoded_frame->quality : 0;
if (!*got_output) {
/* no picture yet */
- av_freep(&decoded_frame);
return ret;
}
ist->next_pts = ist->pts = guess_correct_pts(&ist->pts_ctx, decoded_frame->pkt_pts,
@@ -1778,10 +1784,12 @@ static int transcode_video(InputStream *ist, AVPacket *pkt, int *got_output, int
else
sar = ist->st->codec->sample_aspect_ratio;
av_vsrc_buffer_add_frame(ost->input_video_filter, decoded_frame, ist->pts, sar);
- if (!(filtered_frame = avcodec_alloc_frame())) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
+ if (!ist->filtered_frame && !(ist->filtered_frame = avcodec_alloc_frame())) {
+ av_free(buffer_to_free);
+ return AVERROR(ENOMEM);
+ } else
+ avcodec_get_frame_defaults(ist->filtered_frame);
+ filtered_frame = ist->filtered_frame;
frame_available = avfilter_poll_frame(ost->output_video_filter->inputs[0]);
}
while (frame_available) {
@@ -1805,13 +1813,10 @@ static int transcode_video(InputStream *ist, AVPacket *pkt, int *got_output, int
if (ost->picref)
avfilter_unref_buffer(ost->picref);
}
- av_freep(&filtered_frame);
#endif
}
-fail:
av_free(buffer_to_free);
- av_freep(&decoded_frame);
return ret;
}