]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/buffersrc.c
lavfi: move color filter to testsrc, factorize
[ffmpeg] / libavfilter / buffersrc.c
index b50a5e171556f244edfed14752e17fe5df12bf89..153ab6c0f71f11ad174a0669d4ac2ec0d6c7b7fa 100644 (file)
@@ -29,7 +29,6 @@
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
-#include "vsrc_buffer.h"
 #include "avcodec.h"
 
 #include "libavutil/audioconvert.h"
@@ -44,6 +43,7 @@ typedef struct {
     AVRational        time_base;     ///< time_base to set in the output link
     AVRational        frame_rate;    ///< frame_rate to set in the output link
     unsigned          nb_failed_requests;
+    unsigned          warning_limit;
 
     /* video only */
     int               w, h;
@@ -74,63 +74,6 @@ typedef struct {
         return AVERROR(EINVAL);\
     }
 
-static AVFilterBufferRef *copy_buffer_ref(AVFilterContext *ctx,
-                                          AVFilterBufferRef *ref)
-{
-    AVFilterLink *outlink = ctx->outputs[0];
-    AVFilterBufferRef *buf;
-    int channels;
-
-    switch (outlink->type) {
-
-    case AVMEDIA_TYPE_VIDEO:
-        buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
-                                        ref->video->w, ref->video->h);
-        if(!buf)
-            return NULL;
-        av_image_copy(buf->data, buf->linesize,
-                      (void*)ref->data, ref->linesize,
-                      ref->format, ref->video->w, ref->video->h);
-        break;
-
-    case AVMEDIA_TYPE_AUDIO:
-        buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE,
-                                        ref->audio->nb_samples);
-        if(!buf)
-            return NULL;
-        channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);
-        av_samples_copy(buf->extended_data, ref->buf->extended_data,
-                        0, 0, ref->audio->nb_samples,
-                        channels,
-                        ref->format);
-        break;
-
-    default:
-        return NULL;
-    }
-    avfilter_copy_buffer_ref_props(buf, ref);
-    return buf;
-}
-
-#if FF_API_VSRC_BUFFER_ADD_FRAME
-static int av_vsrc_buffer_add_frame_alt(AVFilterContext *buffer_filter, AVFrame *frame,
-                             int64_t pts, AVRational pixel_aspect)
-{
-    int64_t orig_pts = frame->pts;
-    AVRational orig_sar = frame->sample_aspect_ratio;
-    int ret;
-
-    frame->pts = pts;
-    frame->sample_aspect_ratio = pixel_aspect;
-    if ((ret = av_buffersrc_write_frame(buffer_filter, frame)) < 0)
-        return ret;
-    frame->pts = orig_pts;
-    frame->sample_aspect_ratio = orig_sar;
-
-    return 0;
-}
-#endif
-
 int av_buffersrc_add_frame(AVFilterContext *buffer_src,
                            const AVFrame *frame, int flags)
 {
@@ -140,16 +83,8 @@ int av_buffersrc_add_frame(AVFilterContext *buffer_src,
     if (!frame) /* NULL for EOF */
         return av_buffersrc_add_ref(buffer_src, NULL, flags);
 
-    switch (buffer_src->outputs[0]->type) {
-    case AVMEDIA_TYPE_VIDEO:
-        picref = avfilter_get_video_buffer_ref_from_frame(frame, AV_PERM_WRITE);
-        break;
-    case AVMEDIA_TYPE_AUDIO:
-        picref = avfilter_get_audio_buffer_ref_from_frame(frame, AV_PERM_WRITE);
-        break;
-    default:
-        return AVERROR(ENOSYS);
-    }
+    picref = avfilter_get_buffer_ref_from_frame(buffer_src->outputs[0]->type,
+                                                frame, AV_PERM_WRITE);
     if (!picref)
         return AVERROR(ENOMEM);
     ret = av_buffersrc_add_ref(buffer_src, picref, flags);
@@ -194,7 +129,7 @@ int av_buffersrc_add_ref(AVFilterContext *s, AVFilterBufferRef *buf, int flags)
         }
     }
     if (!(flags & AV_BUFFERSRC_FLAG_NO_COPY))
-        to_free = buf = copy_buffer_ref(s, buf);
+        to_free = buf = ff_copy_buffer_ref(s->outputs[0], buf);
     if(!buf)
         return -1;
 
@@ -203,14 +138,24 @@ int av_buffersrc_add_ref(AVFilterContext *s, AVFilterBufferRef *buf, int flags)
         return ret;
     }
     c->nb_failed_requests = 0;
+    if (c->warning_limit &&
+        av_fifo_size(c->fifo) / sizeof(buf) >= c->warning_limit) {
+        av_log(s, AV_LOG_WARNING,
+               "%d buffers queued in %s, something may be wrong.\n",
+               c->warning_limit,
+               (char *)av_x_if_null(s->name, s->filter->name));
+        c->warning_limit *= 10;
+    }
 
     return 0;
 }
 
+#ifdef FF_API_BUFFERSRC_BUFFER
 int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf)
 {
     return av_buffersrc_add_ref(s, buf, AV_BUFFERSRC_FLAG_NO_COPY);
 }
+#endif
 
 unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src)
 {
@@ -219,7 +164,7 @@ unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src)
 
 #define OFFSET(x) offsetof(BufferSourceContext, x)
 #define V AV_OPT_FLAG_VIDEO_PARAM
-static const AVOption video_options[] = {
+static const AVOption buffer_options[] = {
     { "time_base",      NULL, OFFSET(time_base),           AV_OPT_TYPE_RATIONAL,   { 0 }, 0, INT_MAX, V },
     { "frame_rate",     NULL, OFFSET(frame_rate),          AV_OPT_TYPE_RATIONAL,   { 0 }, 0, INT_MAX, V },
     { "video_size",     NULL, OFFSET(w),                   AV_OPT_TYPE_IMAGE_SIZE,           .flags = V },
@@ -230,21 +175,15 @@ static const AVOption video_options[] = {
 };
 #undef V
 
-static const AVClass vbuffer_class = {
-    .class_name = "vbuffer source",
-    .item_name  = av_default_item_name,
-    .option     = video_options,
-    .version    = LIBAVUTIL_VERSION_INT,
-    .category   = AV_CLASS_CATEGORY_FILTER,
-};
+AVFILTER_DEFINE_CLASS(buffer);
 
-static av_cold int init_video(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init_video(AVFilterContext *ctx, const char *args)
 {
     BufferSourceContext *c = ctx->priv;
     char pix_fmt_str[128], sws_param[256] = "", *colon, *equal;
     int ret, n = 0;
 
-    c->class = &vbuffer_class;
+    c->class = &buffer_class;
 
     if (!args) {
         av_log(ctx, AV_LOG_ERROR, "Arguments required\n");
@@ -256,7 +195,7 @@ static av_cold int init_video(AVFilterContext *ctx, const char *args, void *opaq
         av_opt_set_defaults(c);
         ret = av_set_options_string(c, args, "=", ":");
         if (ret < 0) {
-            av_log(ctx, AV_LOG_ERROR, "Error parsing options string: %s.\n", args);
+            av_log(ctx, AV_LOG_ERROR, "Error parsing options string: %s\n", args);
             goto fail;
         }
     } else {
@@ -267,7 +206,7 @@ static av_cold int init_video(AVFilterContext *ctx, const char *args, void *opaq
         ret = AVERROR(EINVAL);
         goto fail;
     }
-    av_log(ctx, AV_LOG_WARNING, "Flat options syntax is deprecated, use key=value pairs.\n");
+    av_log(ctx, AV_LOG_WARNING, "Flat options syntax is deprecated, use key=value pairs\n");
 
     if ((ret = ff_parse_pixel_format(&c->pix_fmt, pix_fmt_str, ctx)) < 0)
         goto fail;
@@ -283,10 +222,11 @@ static av_cold int init_video(AVFilterContext *ctx, const char *args, void *opaq
         goto fail;
     }
 
-    av_log(ctx, AV_LOG_INFO, "w:%d h:%d pixfmt:%s tb:%d/%d fr:%d/%d sar:%d/%d sws_param:%s\n",
+    av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s tb:%d/%d fr:%d/%d sar:%d/%d sws_param:%s\n",
            c->w, c->h, av_pix_fmt_descriptors[c->pix_fmt].name,
            c->time_base.num, c->time_base.den, c->frame_rate.num, c->frame_rate.den,
            c->pixel_aspect.num, c->pixel_aspect.den, (char *)av_x_if_null(c->sws_param, ""));
+    c->warning_limit = 100;
     return 0;
 
 fail:
@@ -295,7 +235,7 @@ fail:
 }
 
 #define A AV_OPT_FLAG_AUDIO_PARAM
-static const AVOption audio_options[] = {
+static const AVOption abuffer_options[] = {
     { "time_base",      NULL, OFFSET(time_base),           AV_OPT_TYPE_RATIONAL, { 0 }, 0, INT_MAX, A },
     { "sample_rate",    NULL, OFFSET(sample_rate),         AV_OPT_TYPE_INT,      { 0 }, 0, INT_MAX, A },
     { "sample_fmt",     NULL, OFFSET(sample_fmt_str),      AV_OPT_TYPE_STRING,             .flags = A },
@@ -303,15 +243,9 @@ static const AVOption audio_options[] = {
     { NULL },
 };
 
-static const AVClass abuffer_class = {
-    .class_name = "abuffer source",
-    .item_name  = av_default_item_name,
-    .option     = audio_options,
-    .version    = LIBAVUTIL_VERSION_INT,
-    .category   = AV_CLASS_CATEGORY_FILTER,
-};
+AVFILTER_DEFINE_CLASS(abuffer);
 
-static av_cold int init_audio(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init_audio(AVFilterContext *ctx, const char *args)
 {
     BufferSourceContext *s = ctx->priv;
     int ret = 0;
@@ -320,13 +254,13 @@ static av_cold int init_audio(AVFilterContext *ctx, const char *args, void *opaq
     av_opt_set_defaults(s);
 
     if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string: %s.\n", args);
+        av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
         goto fail;
     }
 
     s->sample_fmt = av_get_sample_fmt(s->sample_fmt_str);
     if (s->sample_fmt == AV_SAMPLE_FMT_NONE) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid sample format %s.\n",
+        av_log(ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n",
                s->sample_fmt_str);
         ret = AVERROR(EINVAL);
         goto fail;
@@ -334,7 +268,7 @@ static av_cold int init_audio(AVFilterContext *ctx, const char *args, void *opaq
 
     s->channel_layout = av_get_channel_layout(s->channel_layout_str);
     if (!s->channel_layout) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid channel layout %s.\n",
+        av_log(ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n",
                s->channel_layout_str);
         ret = AVERROR(EINVAL);
         goto fail;
@@ -348,9 +282,11 @@ static av_cold int init_audio(AVFilterContext *ctx, const char *args, void *opaq
     if (!s->time_base.num)
         s->time_base = (AVRational){1, s->sample_rate};
 
-    av_log(ctx, AV_LOG_VERBOSE, "tb:%d/%d samplefmt:%s samplerate: %d "
-           "ch layout:%s\n", s->time_base.num, s->time_base.den, s->sample_fmt_str,
+    av_log(ctx, AV_LOG_VERBOSE,
+           "tb:%d/%d samplefmt:%s samplerate:%d chlayout:%s\n",
+           s->time_base.num, s->time_base.den, s->sample_fmt_str,
            s->sample_rate, s->channel_layout_str);
+    s->warning_limit = 100;
 
 fail:
     av_opt_free(s);
@@ -426,6 +362,7 @@ static int request_frame(AVFilterLink *link)
 {
     BufferSourceContext *c = link->src->priv;
     AVFilterBufferRef *buf;
+    int ret = 0;
 
     if (!av_fifo_size(c->fifo)) {
         if (c->eof)
@@ -437,20 +374,20 @@ static int request_frame(AVFilterLink *link)
 
     switch (link->type) {
     case AVMEDIA_TYPE_VIDEO:
-        ff_start_frame(link, avfilter_ref_buffer(buf, ~0));
-        ff_draw_slice(link, 0, link->h, 1);
-        ff_end_frame(link);
+        if ((ret = ff_start_frame(link, buf)) < 0 ||
+            (ret = ff_draw_slice(link, 0, link->h, 1)) < 0 ||
+            (ret = ff_end_frame(link)) < 0)
+            return ret;
         break;
     case AVMEDIA_TYPE_AUDIO:
-        ff_filter_samples(link, avfilter_ref_buffer(buf, ~0));
+        ret = ff_filter_samples(link, buf);
         break;
     default:
+        avfilter_unref_bufferp(&buf);
         return AVERROR(EINVAL);
     }
 
-    avfilter_unref_buffer(buf);
-
-    return 0;
+    return ret;
 }
 
 static int poll_frame(AVFilterLink *link)
@@ -471,13 +408,13 @@ AVFilter avfilter_vsrc_buffer = {
     .init      = init_video,
     .uninit    = uninit,
 
-    .inputs    = (AVFilterPad[]) {{ .name = NULL }},
-    .outputs   = (AVFilterPad[]) {{ .name            = "default",
-                                    .type            = AVMEDIA_TYPE_VIDEO,
-                                    .request_frame   = request_frame,
-                                    .poll_frame      = poll_frame,
-                                    .config_props    = config_props, },
-                                  { .name = NULL}},
+    .inputs    = (const AVFilterPad[]) {{ .name = NULL }},
+    .outputs   = (const AVFilterPad[]) {{ .name            = "default",
+                                          .type            = AVMEDIA_TYPE_VIDEO,
+                                          .request_frame   = request_frame,
+                                          .poll_frame      = poll_frame,
+                                          .config_props    = config_props, },
+                                        { .name = NULL}},
 };
 
 AVFilter avfilter_asrc_abuffer = {
@@ -489,11 +426,11 @@ AVFilter avfilter_asrc_abuffer = {
     .init      = init_audio,
     .uninit    = uninit,
 
-    .inputs    = (AVFilterPad[]) {{ .name = NULL }},
-    .outputs   = (AVFilterPad[]) {{ .name            = "default",
-                                    .type            = AVMEDIA_TYPE_AUDIO,
-                                    .request_frame   = request_frame,
-                                    .poll_frame      = poll_frame,
-                                    .config_props    = config_props, },
-                                  { .name = NULL}},
+    .inputs    = (const AVFilterPad[]) {{ .name = NULL }},
+    .outputs   = (const AVFilterPad[]) {{ .name            = "default",
+                                          .type            = AVMEDIA_TYPE_AUDIO,
+                                          .request_frame   = request_frame,
+                                          .poll_frame      = poll_frame,
+                                          .config_props    = config_props, },
+                                        { .name = NULL}},
 };