History

avfilter/vf_tinterlace: support full-range YUV

This filter, when used in the "pad" mode, currently makes the distinction between limited and full range solely by testing for YUVJ pixel formats at link setup time. This is deprecated and should be improved to perform the detection based on the per-frame metadata. In order to make this distinction based on color range metadata, which is only known at the time of filtering frames, for simplicity, we simply allocate two copies of the "black" frame - one for limited range and the other for full range metadata. This could be done more dynamically (e.g. as-needed or simply by blitting the appropriate pixel value directly), but this change is relatively simple and preserves the structure of the existing code. This commit actually fixes a bug in FATE - the new output is correct for the first time. The previous md5 ref was of a frame that incorrectly combined full-range pixel data with limited-range black fields. The corresponding result has been updated.

Niklas Haas committed 3 years ago

Commit a69b0871 parent 8e2f61e3 files · +20 −10Browse files

Showing the changes to libavfilter (2 of 3 files). Show all

Unified · Split

2 files
  1. libavfilter/tinterlace.h +1 −1
  2. libavfilter/vf_tinterlace.c +18 −8
libavfilter/tinterlace.h+1−1
@@ -70,7 +70,7 @@ typedef struct TInterlaceContext { · 69 unmodified lines
70 int vsub; ///< chroma vertical subsampling70 int vsub; ///< chroma vertical subsampling
71 AVFrame *cur;71 AVFrame *cur;
72 AVFrame *next;72 AVFrame *next;
73 uint8_t *black_data[4]; ///< buffer used to fill padded lines73 uint8_t *black_data[2][4]; ///< buffer used to fill padded lines (limited/full)
74 int black_linesize[4];74 int black_linesize[4];
75 FFDrawContext draw;75 FFDrawContext draw;
76 FFDrawColor color;76 FFDrawColor color;
libavfilter/vf_tinterlace.c+18−8
@@ -201,7 +201,8 @@ static av_cold void uninit(AVFilterContext *ctx) · 200 unmodified lines
201 201
202 av_frame_free(&tinterlace->cur );202 av_frame_free(&tinterlace->cur );
203 av_frame_free(&tinterlace->next);203 av_frame_free(&tinterlace->next);
204 av_freep(&tinterlace->black_data[0]);204 av_freep(&tinterlace->black_data[0][0]);
205 av_freep(&tinterlace->black_data[1][0]);
205}206}
206 207
207static int config_out_props(AVFilterLink *outlink)208static int config_out_props(AVFilterLink *outlink)
@@ -225,14 +226,22 @@ static int config_out_props(AVFilterLink *outlink) · 17 unmodified lines
225 int ret;226 int ret;
226 ff_draw_init(&tinterlace->draw, outlink->format, 0);227 ff_draw_init(&tinterlace->draw, outlink->format, 0);
227 ff_draw_color(&tinterlace->draw, &tinterlace->color, black);228 ff_draw_color(&tinterlace->draw, &tinterlace->color, black);
228 if (ff_fmt_is_in(outlink->format, full_scale_yuvj_pix_fmts))229 /* limited range */
229 tinterlace->color.comp[0].u8[0] = 0;230 if (!ff_fmt_is_in(outlink->format, full_scale_yuvj_pix_fmts)) {
230 ret = av_image_alloc(tinterlace->black_data, tinterlace->black_linesize,231 ret = av_image_alloc(tinterlace->black_data[0], tinterlace->black_linesize,
232 outlink->w, outlink->h, outlink->format, 16);
233 if (ret < 0)
234 return ret;
235 ff_fill_rectangle(&tinterlace->draw, &tinterlace->color, tinterlace->black_data[0],
236 tinterlace->black_linesize, 0, 0, outlink->w, outlink->h);
237 }
238 /* full range */
239 tinterlace->color.comp[0].u8[0] = 0;
240 ret = av_image_alloc(tinterlace->black_data[1], tinterlace->black_linesize,
231 outlink->w, outlink->h, outlink->format, 16);241 outlink->w, outlink->h, outlink->format, 16);
232 if (ret < 0)242 if (ret < 0)
233 return ret;243 return ret;
234 244 ff_fill_rectangle(&tinterlace->draw, &tinterlace->color, tinterlace->black_data[1],
235 ff_fill_rectangle(&tinterlace->draw, &tinterlace->color, tinterlace->black_data,
236 tinterlace->black_linesize, 0, 0, outlink->w, outlink->h);245 tinterlace->black_linesize, 0, 0, outlink->w, outlink->h);
237 }246 }
238 if (tinterlace->flags & (TINTERLACE_FLAG_VLPF | TINTERLACE_FLAG_CVLPF)247 if (tinterlace->flags & (TINTERLACE_FLAG_VLPF | TINTERLACE_FLAG_CVLPF)
@@ -360,7 +369,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) · 121 unmodified lines
360 AVFilterLink *outlink = ctx->outputs[0];369 AVFilterLink *outlink = ctx->outputs[0];
361 TInterlaceContext *tinterlace = ctx->priv;370 TInterlaceContext *tinterlace = ctx->priv;
362 AVFrame *cur, *next, *out;371 AVFrame *cur, *next, *out;
363 int field, tff, ret;372 int field, tff, full, ret;
364 373
365 av_frame_free(&tinterlace->cur);374 av_frame_free(&tinterlace->cur);
366 tinterlace->cur = tinterlace->next;375 tinterlace->cur = tinterlace->next;
@@ -418,6 +427,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) · 51 unmodified lines
418 out->sample_aspect_ratio = av_mul_q(cur->sample_aspect_ratio, av_make_q(2, 1));427 out->sample_aspect_ratio = av_mul_q(cur->sample_aspect_ratio, av_make_q(2, 1));
419 428
420 field = (1 + outlink->frame_count_in) & 1 ? FIELD_UPPER : FIELD_LOWER;429 field = (1 + outlink->frame_count_in) & 1 ? FIELD_UPPER : FIELD_LOWER;
430 full = out->color_range == AVCOL_RANGE_JPEG || ff_fmt_is_in(out->format, full_scale_yuvj_pix_fmts);
421 /* copy upper and lower fields */431 /* copy upper and lower fields */
422 copy_picture_field(tinterlace, out->data, out->linesize,432 copy_picture_field(tinterlace, out->data, out->linesize,
423 (const uint8_t **)cur->data, cur->linesize,433 (const uint8_t **)cur->data, cur->linesize,
@@ -425,7 +435,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) · 1 unmodified line
425 FIELD_UPPER_AND_LOWER, 1, field, tinterlace->flags);435 FIELD_UPPER_AND_LOWER, 1, field, tinterlace->flags);
426 /* pad with black the other field */436 /* pad with black the other field */
427 copy_picture_field(tinterlace, out->data, out->linesize,437 copy_picture_field(tinterlace, out->data, out->linesize,
428 (const uint8_t **)tinterlace->black_data, tinterlace->black_linesize,438 (const uint8_t **)tinterlace->black_data[full], tinterlace->black_linesize,
429 inlink->format, inlink->w, inlink->h,439 inlink->format, inlink->w, inlink->h,
430 FIELD_UPPER_AND_LOWER, 1, !field, tinterlace->flags);440 FIELD_UPPER_AND_LOWER, 1, !field, tinterlace->flags);
431 break;441 break;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t