Unified · Split
| @@ -50,6 +50,8 @@ typedef struct { · 49 unmodified lines | ||
| 50 | 50 | char *duration; ///< total duration of the generated video |
| 51 | 51 | AVRational sar; ///< sample aspect ratio |
| 52 | 52 | int nb_decimals; |
| 53 | + int draw_once; ///< draw only the first frame, always put out the same picture | |
| 54 | + AVFilterBufferRef *picref; ///< cached reference containing the painted picture | |
| 53 | 55 | |
| 54 | 56 | void (* fill_picture_fn)(AVFilterContext *ctx, AVFilterBufferRef *picref); |
| 55 | 57 | |
| @@ -123,6 +125,7 @@ static av_cold void uninit(AVFilterContext *ctx) · 67 unmodified lines | ||
| 123 | 125 | TestSourceContext *test = ctx->priv; |
| 124 | 126 | |
| 125 | 127 | av_opt_free(test); |
| 128 | + avfilter_unref_bufferp(&test->picref); | |
| 126 | 129 | } |
| 127 | 130 | |
| 128 | 131 | static int config_props(AVFilterLink *outlink) |
| @@ -140,25 +143,40 @@ static int config_props(AVFilterLink *outlink) · 11 unmodified lines | ||
| 140 | 143 | static int request_frame(AVFilterLink *outlink) |
| 141 | 144 | { |
| 142 | 145 | TestSourceContext *test = outlink->src->priv; |
| 143 | − AVFilterBufferRef *picref; | |
| 144 | − int ret; | |
| 146 | + AVFilterBufferRef *outpicref; | |
| 147 | + int ret = 0; | |
| 145 | 148 | |
| 146 | 149 | if (test->max_pts >= 0 && test->pts >= test->max_pts) |
| 147 | 150 | return AVERROR_EOF; |
| 148 | − picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, test->w, test->h); | |
| 149 | − if (!picref) | |
| 150 | − return AVERROR(ENOMEM); | |
| 151 | 151 | |
| 152 | − picref->pts = test->pts++; | |
| 153 | − picref->pos = -1; | |
| 154 | − picref->video->key_frame = 1; | |
| 155 | − picref->video->interlaced = 0; | |
| 156 | − picref->video->pict_type = AV_PICTURE_TYPE_I; | |
| 157 | − picref->video->sample_aspect_ratio = test->sar; | |
| 158 | − test->fill_picture_fn(outlink->src, picref); | |
| 152 | + if (test->draw_once) { | |
| 153 | + if (!test->picref) { | |
| 154 | + test->picref = | |
| 155 | + ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_PRESERVE|AV_PERM_REUSE, | |
| 156 | + test->w, test->h); | |
| 157 | + if (!test->picref) | |
| 158 | + return AVERROR(ENOMEM); | |
| 159 | + test->fill_picture_fn(outlink->src, test->picref); | |
| 160 | + } | |
| 161 | + outpicref = avfilter_ref_buffer(test->picref, ~AV_PERM_WRITE); | |
| 162 | + } else | |
| 163 | + outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, test->w, test->h); | |
| 164 | + | |
| 165 | + if (!outpicref) | |
| 166 | + return AVERROR(ENOMEM); | |
| 167 | + outpicref->pts = test->pts; | |
| 168 | + outpicref->pos = -1; | |
| 169 | + outpicref->video->key_frame = 1; | |
| 170 | + outpicref->video->interlaced = 0; | |
| 171 | + outpicref->video->pict_type = AV_PICTURE_TYPE_I; | |
| 172 | + outpicref->video->sample_aspect_ratio = test->sar; | |
| 173 | + if (!test->draw_once) | |
| 174 | + test->fill_picture_fn(outlink->src, outpicref); | |
| 175 | + | |
| 176 | + test->pts++; | |
| 159 | 177 | test->nb_frame++; |
| 160 | 178 | |
| 161 | − if ((ret = ff_start_frame(outlink, picref)) < 0 || | |
| 179 | + if ((ret = ff_start_frame(outlink, outpicref)) < 0 || | |
| 162 | 180 | (ret = ff_draw_slice(outlink, 0, test->h, 1)) < 0 || |
| 163 | 181 | (ret = ff_end_frame(outlink)) < 0) |
| 164 | 182 | return ret; |
| @@ -493,6 +511,7 @@ static av_cold int rgbtest_init(AVFilterContext *ctx, const char *args) · 328 unmodified lines | ||
| 493 | 511 | { |
| 494 | 512 | TestSourceContext *test = ctx->priv; |
| 495 | 513 | |
| 514 | + test->draw_once = 1; | |
| 496 | 515 | test->class = &rgbtestsrc_class; |
| 497 | 516 | test->fill_picture_fn = rgbtest_fill_picture; |
| 498 | 517 | return init(ctx, args); |