[FFmpeg-devel] [PATCH] avfilter/src_movie: add code to test old get/release buffer

Michael Niedermayer michaelni at gmx.at
Wed Mar 19 04:50:52 CET 2014


Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
 libavfilter/src_movie.c |   75 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 72 insertions(+), 3 deletions(-)

diff --git a/libavfilter/src_movie.c b/libavfilter/src_movie.c
index 82bcc56..163ee67 100644
--- a/libavfilter/src_movie.c
+++ b/libavfilter/src_movie.c
@@ -47,6 +47,8 @@
 typedef struct {
     AVStream *st;
     int done;
+    int get_seq;
+    int free_count;
 } MovieStream;
 
 typedef struct {
@@ -68,6 +70,9 @@ typedef struct {
     int max_stream_index; /**< max stream # actually used for output */
     MovieStream *st; /**< array of all streams, one per output */
     int *out_index; /**< stream number -> output number map, or -1 */
+
+    int refcounted;
+    int debug_buffers;
 } MovieContext;
 
 #define OFFSET(x) offsetof(MovieContext, x)
@@ -84,6 +89,8 @@ static const AVOption movie_options[]= {
     { "streams",      "set streams",             OFFSET(stream_specs), AV_OPT_TYPE_STRING, {.str =  0},  CHAR_MAX, CHAR_MAX, FLAGS },
     { "s",            "set streams",             OFFSET(stream_specs), AV_OPT_TYPE_STRING, {.str =  0},  CHAR_MAX, CHAR_MAX, FLAGS },
     { "loop",         "set loop count",          OFFSET(loop_count),   AV_OPT_TYPE_INT,    {.i64 =  1},  0,        INT_MAX, FLAGS },
+    { "refcounted",   "select new/old API",      OFFSET(refcounted),   AV_OPT_TYPE_INT,    {.i64 =  1},  0,        1, FLAGS },
+    { "debug_buffers","debug buffers",           OFFSET(debug_buffers),AV_OPT_TYPE_INT,    {.i64 =  0},  0,        1, FLAGS },
     { NULL },
 };
 
@@ -155,8 +162,6 @@ static int open_stream(void *log, MovieStream *st)
         return AVERROR(EINVAL);
     }
 
-    st->st->codec->refcounted_frames = 1;
-
     if ((ret = avcodec_open2(st->st->codec, codec, NULL)) < 0) {
         av_log(log, AV_LOG_ERROR, "Failed to open codec\n");
         return ret;
@@ -188,6 +193,57 @@ static int guess_channel_layout(MovieStream *st, int st_index, void *log_ctx)
     return 0;
 }
 
+typedef struct FrameCtx {
+    AVFrame *frame;
+    int seq;
+} FrameCtx;
+
+static int get_buffer(AVCodecContext *avctx, AVFrame *frame)
+{
+    int width = avctx->width;
+    int height= avctx->height;
+    FrameCtx *frame_ctx;
+    MovieStream *mst = avctx->opaque;
+
+    avcodec_align_dimensions(avctx, &width, &height);
+
+    frame_ctx = av_mallocz(sizeof(FrameCtx));
+    frame_ctx->frame = av_frame_alloc();
+    if (!frame_ctx || !frame_ctx->frame)
+        return AVERROR(ENOMEM);
+
+    frame_ctx->frame->width  = width;
+    frame_ctx->frame->height = height;
+    frame_ctx->frame->format = avctx->pix_fmt;
+
+    if (av_frame_get_buffer(frame_ctx->frame, 1) < 0) {
+        av_log(avctx, AV_LOG_INFO, "av_frame_get_buffer failed\n");
+        return -1;
+    }
+
+    frame_ctx->seq = (mst->get_seq++);
+
+    frame->opaque = frame_ctx;
+    memcpy(frame->data    , frame_ctx->frame->data    , sizeof(frame->data));
+    memcpy(frame->linesize, frame_ctx->frame->linesize, sizeof(frame->linesize));
+    //FIXME frame width/height/format
+    av_log(avctx, AV_LOG_INFO, "get_buffer seq: %d\n", frame_ctx->seq);
+
+    return 0;
+}
+
+static void release_buffer(AVCodecContext *avctx, AVFrame *frame)
+{
+    FrameCtx *frame_ctx = frame->opaque;
+    MovieStream *mst = avctx->opaque;
+
+    av_log(avctx, AV_LOG_INFO,  "release_buffer seq: %d\n", frame_ctx->seq);
+    av_assert0(frame_ctx->seq >= 0);
+    frame_ctx->seq = -1;
+    memset(frame->data, 0, sizeof(frame->data));
+    mst->free_count ++;
+}
+
 static av_cold int movie_common_init(AVFilterContext *ctx)
 {
     MovieContext *movie = ctx->priv;
@@ -295,6 +351,12 @@ static av_cold int movie_common_init(AVFilterContext *ctx)
         pad.config_props  = movie_config_output_props;
         pad.request_frame = movie_request_frame;
         ff_insert_outpad(ctx, i, &pad);
+        movie->st[i].st->codec->refcounted_frames = movie->refcounted;
+        if (pad.type == AVMEDIA_TYPE_VIDEO && movie->debug_buffers) {
+            movie->st[i].st->codec->get_buffer     = get_buffer;
+            movie->st[i].st->codec->release_buffer = release_buffer;
+            movie->st[i].st->codec->opaque = &movie->st[i];
+        }
         ret = open_stream(ctx, &movie->st[i]);
         if (ret < 0)
             return ret;
@@ -323,11 +385,18 @@ static av_cold void movie_uninit(AVFilterContext *ctx)
         if (movie->st[i].st)
             avcodec_close(movie->st[i].st->codec);
     }
-    av_freep(&movie->st);
     av_freep(&movie->out_index);
     av_frame_free(&movie->frame);
     if (movie->format_ctx)
         avformat_close_input(&movie->format_ctx);
+    if (movie->debug_buffers) {
+        for (i = 0; i < ctx->nb_outputs; i++) {
+            MovieStream *mst = &movie->st[i];
+            if (mst->get_seq != mst->free_count)
+                av_log(ctx, AV_LOG_ERROR, "stream %d, %d buffers allocated, %d buffers freed\n", i, mst->get_seq, mst->free_count);
+        }
+    }
+    av_freep(&movie->st);
 }
 
 static int movie_query_formats(AVFilterContext *ctx)
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list