]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/vsrc_testsrc.c
avio: add a destructor for AVIOContext
[ffmpeg] / libavfilter / vsrc_testsrc.c
index 632bd278ac46008fa1f545b13cb794016e1c3f86..5bd458c99705371f09f4f20931c7e2abdae279da 100644 (file)
 #include "internal.h"
 #include "video.h"
 
-typedef struct {
+typedef struct TestSourceContext {
     const AVClass *class;
     int h, w;
     unsigned int nb_frame;
-    AVRational time_base;
+    AVRational time_base, frame_rate;
     int64_t pts, max_pts;
     char *size;                 ///< video frame size
     char *rate;                 ///< video frame rate
     char *duration;             ///< total duration of the generated video
     AVRational sar;             ///< sample aspect ratio
 
-    void (* fill_picture_fn)(AVFilterContext *ctx, AVFilterBufferRef *picref);
+    void (* fill_picture_fn)(AVFilterContext *ctx, AVFrame *frame);
 
     /* only used by rgbtest */
     int rgba_map[4];
 } TestSourceContext;
 
 #define OFFSET(x) offsetof(TestSourceContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
 
 static const AVOption testsrc_options[] = {
-    { "size",     "set video size",     OFFSET(size),     AV_OPT_TYPE_STRING, {.str = "320x240"}},
-    { "s",        "set video size",     OFFSET(size),     AV_OPT_TYPE_STRING, {.str = "320x240"}},
-    { "rate",     "set video rate",     OFFSET(rate),     AV_OPT_TYPE_STRING, {.str = "25"},    },
-    { "r",        "set video rate",     OFFSET(rate),     AV_OPT_TYPE_STRING, {.str = "25"},    },
-    { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_STRING, {.str = NULL},    },
-    { "sar",      "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl = 1},  0, INT_MAX },
+    { "size",     "set video size",     OFFSET(size),     AV_OPT_TYPE_STRING, {.str = "320x240"},     .flags = FLAGS },
+    { "s",        "set video size",     OFFSET(size),     AV_OPT_TYPE_STRING, {.str = "320x240"},     .flags = FLAGS },
+    { "rate",     "set video rate",     OFFSET(rate),     AV_OPT_TYPE_STRING, {.str = "25"},          .flags = FLAGS },
+    { "r",        "set video rate",     OFFSET(rate),     AV_OPT_TYPE_STRING, {.str = "25"},          .flags = FLAGS },
+    { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_STRING, {.str = NULL},          .flags = FLAGS },
+    { "sar",      "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl = 1},  0, INT_MAX, FLAGS },
     { NULL },
 };
 
-static av_cold int init_common(AVFilterContext *ctx, const char *args)
+static av_cold int init_common(AVFilterContext *ctx)
 {
     TestSourceContext *test = ctx->priv;
-    AVRational frame_rate_q;
     int64_t duration = -1;
     int ret = 0;
 
-    av_opt_set_defaults(test);
-
-    if ((ret = (av_set_options_string(test, args, "=", ":"))) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
-        return ret;
-    }
-
     if ((ret = av_parse_video_size(&test->w, &test->h, test->size)) < 0) {
         av_log(ctx, AV_LOG_ERROR, "Invalid frame size: '%s'\n", test->size);
         return ret;
     }
 
-    if ((ret = av_parse_video_rate(&frame_rate_q, test->rate)) < 0 ||
-        frame_rate_q.den <= 0 || frame_rate_q.num <= 0) {
+    if ((ret = av_parse_video_rate(&test->frame_rate, test->rate)) < 0) {
         av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", test->rate);
         return ret;
     }
@@ -101,15 +93,14 @@ static av_cold int init_common(AVFilterContext *ctx, const char *args)
         return ret;
     }
 
-    test->time_base.num = frame_rate_q.den;
-    test->time_base.den = frame_rate_q.num;
+    test->time_base = av_inv_q(test->frame_rate);
     test->max_pts = duration >= 0 ?
         av_rescale_q(duration, AV_TIME_BASE_Q, test->time_base) : -1;
     test->nb_frame = 0;
     test->pts = 0;
 
     av_log(ctx, AV_LOG_DEBUG, "size:%dx%d rate:%d/%d duration:%f sar:%d/%d\n",
-           test->w, test->h, frame_rate_q.num, frame_rate_q.den,
+           test->w, test->h, test->frame_rate.num, test->frame_rate.den,
            duration < 0 ? -1 : test->max_pts * av_q2d(test->time_base),
            test->sar.num, test->sar.den);
     return 0;
@@ -122,7 +113,8 @@ static int config_props(AVFilterLink *outlink)
     outlink->w = test->w;
     outlink->h = test->h;
     outlink->sample_aspect_ratio = test->sar;
-    outlink->time_base = test->time_base;
+    outlink->frame_rate = test->frame_rate;
+    outlink->time_base  = test->time_base;
 
     return 0;
 }
@@ -130,24 +122,23 @@ static int config_props(AVFilterLink *outlink)
 static int request_frame(AVFilterLink *outlink)
 {
     TestSourceContext *test = outlink->src->priv;
-    AVFilterBufferRef *picref;
+    AVFrame *frame;
 
     if (test->max_pts >= 0 && test->pts > test->max_pts)
         return AVERROR_EOF;
-    picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, test->w, test->h);
-    if (!picref)
+    frame = ff_get_video_buffer(outlink, test->w, test->h);
+    if (!frame)
         return AVERROR(ENOMEM);
 
-    picref->pts = test->pts++;
-    picref->pos = -1;
-    picref->video->key_frame = 1;
-    picref->video->interlaced = 0;
-    picref->video->pict_type = AV_PICTURE_TYPE_I;
-    picref->video->pixel_aspect = test->sar;
+    frame->pts                 = test->pts++;
+    frame->key_frame           = 1;
+    frame->interlaced_frame    = 0;
+    frame->pict_type           = AV_PICTURE_TYPE_I;
+    frame->sample_aspect_ratio = test->sar;
     test->nb_frame++;
-    test->fill_picture_fn(outlink->src, picref);
+    test->fill_picture_fn(outlink->src, frame);
 
-    return ff_filter_frame(outlink, picref);
+    return ff_filter_frame(outlink, frame);
 }
 
 #if CONFIG_TESTSRC_FILTER
@@ -200,7 +191,7 @@ static void draw_digit(int digit, uint8_t *dst, unsigned dst_linesize,
 #define LEFT_BOT_VBAR  16
 #define RIGHT_TOP_VBAR 32
 #define RIGHT_BOT_VBAR 64
-    struct {
+    struct segments {
         int x, y, w, h;
     } segments[] = {
         { 1,  0, 5, 1 }, /* TOP_HBAR */
@@ -235,7 +226,7 @@ static void draw_digit(int digit, uint8_t *dst, unsigned dst_linesize,
 
 #define GRADIENT_SIZE (6 * 256)
 
-static void test_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
+static void test_fill_picture(AVFilterContext *ctx, AVFrame *frame)
 {
     TestSourceContext *test = ctx->priv;
     uint8_t *p, *p0;
@@ -249,9 +240,9 @@ static void test_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
     int seg_size;
     int second;
     int i;
-    uint8_t *data = picref->data[0];
-    int width  = picref->video->w;
-    int height = picref->video->h;
+    uint8_t *data = frame->data[0];
+    int width  = frame->width;
+    int height = frame->height;
 
     /* draw colored bars and circle */
     radius = (width + height) / 4;
@@ -281,11 +272,11 @@ static void test_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
         }
         quad0 += dquad_y;
         dquad_y += 2;
-        p0 += picref->linesize[0];
+        p0 += frame->linesize[0];
     }
 
     /* draw sliding color line */
-    p = data + picref->linesize[0] * height * 3/4;
+    p = data + frame->linesize[0] * height * 3/4;
     grad = (256 * test->nb_frame * test->time_base.num / test->time_base.den) %
         GRADIENT_SIZE;
     rgrad = 0;
@@ -314,8 +305,8 @@ static void test_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
             grad -= GRADIENT_SIZE;
     }
     for (y = height / 8; y > 0; y--) {
-        memcpy(p, p - picref->linesize[0], 3 * width);
-        p += picref->linesize[0];
+        memcpy(p, p - frame->linesize[0], 3 * width);
+        p += frame->linesize[0];
     }
 
     /* draw digits */
@@ -324,10 +315,10 @@ static void test_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
         second = test->nb_frame * test->time_base.num / test->time_base.den;
         x = width - (width - seg_size * 64) / 2;
         y = (height - seg_size * 13) / 2;
-        p = data + (x*3 + y * picref->linesize[0]);
+        p = data + (x*3 + y * frame->linesize[0]);
         for (i = 0; i < 8; i++) {
             p -= 3 * 8 * seg_size;
-            draw_digit(second % 10, p, picref->linesize[0], seg_size);
+            draw_digit(second % 10, p, frame->linesize[0], seg_size);
             second /= 10;
             if (second == 0)
                 break;
@@ -335,13 +326,12 @@ static void test_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
     }
 }
 
-static av_cold int test_init(AVFilterContext *ctx, const char *args)
+static av_cold int test_init(AVFilterContext *ctx)
 {
     TestSourceContext *test = ctx->priv;
 
-    test->class = &testsrc_class;
     test->fill_picture_fn = test_fill_picture;
-    return init_common(ctx, args);
+    return init_common(ctx);
 }
 
 static int test_query_formats(AVFilterContext *ctx)
@@ -363,10 +353,11 @@ static const AVFilterPad avfilter_vsrc_testsrc_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vsrc_testsrc = {
+AVFilter ff_vsrc_testsrc = {
     .name          = "testsrc",
     .description   = NULL_IF_CONFIG_SMALL("Generate test pattern."),
     .priv_size     = sizeof(TestSourceContext),
+    .priv_class    = &testsrc_class,
     .init          = test_init,
 
     .query_formats = test_query_formats,
@@ -427,13 +418,13 @@ static void rgbtest_put_pixel(uint8_t *dst, int dst_linesize,
     }
 }
 
-static void rgbtest_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
+static void rgbtest_fill_picture(AVFilterContext *ctx, AVFrame *frame)
 {
     TestSourceContext *test = ctx->priv;
-    int x, y, w = picref->video->w, h = picref->video->h;
+    int x, y, w = frame->width, h = frame->height;
 
     for (y = 0; y < h; y++) {
-         for (x = 0; x < picref->video->w; x++) {
+         for (x = 0; x < w; x++) {
              int c = 256*x/w;
              int r = 0, g = 0, b = 0;
 
@@ -441,19 +432,18 @@ static void rgbtest_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref
              else if (3*y < 2*h) g = c;
              else                b = c;
 
-             rgbtest_put_pixel(picref->data[0], picref->linesize[0], x, y, r, g, b,
+             rgbtest_put_pixel(frame->data[0], frame->linesize[0], x, y, r, g, b,
                                ctx->outputs[0]->format, test->rgba_map);
          }
      }
 }
 
-static av_cold int rgbtest_init(AVFilterContext *ctx, const char *args)
+static av_cold int rgbtest_init(AVFilterContext *ctx)
 {
     TestSourceContext *test = ctx->priv;
 
-    test->class = &rgbtestsrc_class;
     test->fill_picture_fn = rgbtest_fill_picture;
-    return init_common(ctx, args);
+    return init_common(ctx);
 }
 
 static int rgbtest_query_formats(AVFilterContext *ctx)
@@ -496,10 +486,11 @@ static const AVFilterPad avfilter_vsrc_rgbtestsrc_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vsrc_rgbtestsrc = {
+AVFilter ff_vsrc_rgbtestsrc = {
     .name          = "rgbtestsrc",
     .description   = NULL_IF_CONFIG_SMALL("Generate RGB test pattern."),
     .priv_size     = sizeof(TestSourceContext),
+    .priv_class    = &rgbtestsrc_class,
     .init          = rgbtest_init,
 
     .query_formats = rgbtest_query_formats,