[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