[PATCH 3/3] Make ffmpeg use the ffsrc defined in cmdutils.[hc] rather than the video buffer.
Stefano Sabatini
stefano.sabatini-lala
Mon Nov 1 19:31:44 CET 2010
Avoid an unnecessary memcpy, as the ffsrc filter is more strictly
coupled with the decoder.
---
cmdutils.c | 7 +++++
cmdutils.h | 1 +
ffmpeg.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++--------------
3 files changed, 64 insertions(+), 17 deletions(-)
diff --git a/cmdutils.c b/cmdutils.c
index 97f2ffb..940d82b 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -935,6 +935,12 @@ static int ffsrc_request_frame(AVFilterLink *outlink)
return 0;
}
+static int ffsrc_poll_frame(AVFilterLink *outlink)
+{
+ FFSrcContext *priv = outlink->src->priv;
+ return priv->poll_video_frame(outlink->src);
+}
+
static int ffsrc_query_formats(AVFilterContext *ctx)
{
FFSrcContext *priv = ctx->priv;
@@ -971,6 +977,7 @@ AVFilter ffsrc = {
.inputs = (AVFilterPad[]) {{ .name = NULL }},
.outputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
+ .poll_frame = ffsrc_poll_frame,
.request_frame = ffsrc_request_frame,
.config_props = ffsrc_config_props, },
{ .name = NULL }},
diff --git a/cmdutils.h b/cmdutils.h
index 4a21c50..a225c97 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -283,6 +283,7 @@ typedef struct {
AVStream *stream;
AVFrame *frame;
int (*get_video_frame)(AVFilterContext *, AVFrame *, int64_t *pts, int64_t *pos);
+ int (*poll_video_frame)(AVFilterContext *);
int use_dr1;
void *priv;
} FFSrcContext;
diff --git a/ffmpeg.c b/ffmpeg.c
index 27358f9..9b3ab69 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -302,6 +302,7 @@ typedef struct AVInputStream {
int64_t next_pts; /* synthetic pts for cases where pkt.pts
is not defined */
int64_t pts; /* current pts */
+ int64_t pos; /* current pos */
PtsCorrectionContext pts_ctx;
int is_start; /* is 1 at the start and after a discontinuity */
int showed_multi_packet_warning;
@@ -330,27 +331,57 @@ static struct termios oldtty;
#if CONFIG_AVFILTER
+static int ffsrc_get_video_frame(AVFilterContext *ctx, AVFrame *frame,
+ int64_t *pts, int64_t *pos)
+{
+ FFSrcContext *priv = ctx->priv;
+ AVInputStream *ist = priv->priv;
+
+ if (!ist->has_filter_frame) {
+ av_log(ctx, AV_LOG_ERROR,
+ "ffsrc_get_video_frame() called with no available frame!\n");
+ return AVERROR(EINVAL);
+ }
+
+ *pts = ist->pts;
+ *pos = ist->pos;
+ ist->has_filter_frame = 0;
+ *frame = *ist->filter_frame;
+ ist->filter_frame = NULL;
+ return 0;
+}
+
+static int ffsrc_poll_video_frame(AVFilterContext *ctx)
+{
+ FFSrcContext *priv = ctx->priv;
+ AVInputStream *ist = priv->priv;
+
+ return !!(ist->has_filter_frame);
+}
+
static int configure_filters(AVInputStream *ist, AVOutputStream *ost)
{
AVFilterContext *last_filter, *filter;
/** filter graph containing all filters including input & output */
AVCodecContext *codec = ost->st->codec;
AVCodecContext *icodec = ist->st->codec;
+ FFSrcContext ffsrc_ctx = {
+ .stream = ist->st,
+ .get_video_frame = ffsrc_get_video_frame,
+ .poll_video_frame = ffsrc_poll_video_frame,
+ .priv = ist,
+ };
FFSinkContext ffsink_ctx = { .pix_fmt = codec->pix_fmt };
char args[255];
int ret;
graph = av_mallocz(sizeof(AVFilterGraph));
- if ((ret = avfilter_open(&ist->input_video_filter, avfilter_get_by_name("buffer"), "src")) < 0)
+ if ((ret = avfilter_open(&ist->input_video_filter, &ffsrc, "src")) < 0)
return ret;
if ((ret = avfilter_open(&ist->output_video_filter, &ffsink, "out")) < 0)
return ret;
-
- snprintf(args, 255, "%d:%d:%d:%d:%d", ist->st->codec->width,
- ist->st->codec->height, ist->st->codec->pix_fmt,
- ist->st->time_base.num, ist->st->time_base.den);
- if ((ret = avfilter_init_filter(ist->input_video_filter, args, NULL)) < 0)
+ if ((ret = avfilter_init_filter(ist->input_video_filter, NULL, &ffsrc_ctx)) < 0)
return ret;
if ((ret = avfilter_init_filter(ist->output_video_filter, NULL, &ffsink_ctx)) < 0)
return ret;
@@ -1574,9 +1605,8 @@ static int output_packet(AVInputStream *ist, int ist_index,
#if CONFIG_AVFILTER
if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->input_video_filter) {
// add it to be filtered
- av_vsrc_buffer_add_frame(ist->input_video_filter, &picture,
- ist->pts,
- ist->st->codec->sample_aspect_ratio);
+ ist->has_filter_frame = 1;
+ ist->filter_frame = &picture;
}
#endif
@@ -1613,8 +1643,11 @@ static int output_packet(AVInputStream *ist, int ist_index,
AVRational ist_pts_tb;
if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->output_video_filter)
get_filtered_video_frame(ist->output_video_filter, &picture, &ist->picref, &ist_pts_tb);
- if (ist->picref)
+ if (ist->picref) {
+ ist->filter_frame = &picture;
ist->pts = ist->picref->pts;
+ ist->pos = ist->picref->pos;
+ }
#endif
for(i=0;i<nb_ostreams;i++) {
int frame_size;
@@ -2208,13 +2241,6 @@ static int transcode(AVFormatContext **output_files,
ost->resample_pix_fmt= icodec->pix_fmt;
ost->encoding_needed = 1;
ist->decoding_needed = 1;
-
-#if CONFIG_AVFILTER
- if (configure_filters(ist, ost)) {
- fprintf(stderr, "Error opening filters!\n");
- exit(1);
- }
-#endif
break;
case AVMEDIA_TYPE_SUBTITLE:
ost->encoding_needed = 1;
@@ -2313,6 +2339,19 @@ static int transcode(AVFormatContext **output_files,
}
}
+#if CONFIG_AVFILTER
+ for (i = 0; i < nb_ostreams; i++) {
+ ost = ost_table[i];
+ ist = ist_table[ost->source_index];
+
+ if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+ configure_filters(ist, ost) < 0) {
+ fprintf(stderr, "Error opening filters!\n");
+ exit(1);
+ }
+ }
+#endif
+
/* init pts */
for(i=0;i<nb_istreams;i++) {
AVStream *st;
--
1.7.1
--x+6KMIRAuhnl3hBn--
More information about the ffmpeg-devel
mailing list