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
7070 int vsub; ///< chroma vertical subsampling
7171 AVFrame *cur;
7272 AVFrame *next;
73− uint8_t *black_data[4]; ///< buffer used to fill padded lines
73+ uint8_t *black_data[2][4]; ///< buffer used to fill padded lines (limited/full)
7474 int black_linesize[4];
7575 FFDrawContext draw;
7676 FFDrawColor color;
libavfilter/vf_tinterlace.c+18−8
@@ -201,7 +201,8 @@ static av_cold void uninit(AVFilterContext *ctx) · 200 unmodified lines
201201
202202 av_frame_free(&tinterlace->cur );
203203 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]);
205206 }
206207
207208 static int config_out_props(AVFilterLink *outlink)
@@ -225,14 +226,22 @@ static int config_out_props(AVFilterLink *outlink) · 17 unmodified lines
225226 int ret;
226227 ff_draw_init(&tinterlace->draw, outlink->format, 0);
227228 ff_draw_color(&tinterlace->draw, &tinterlace->color, black);
228− if (ff_fmt_is_in(outlink->format, full_scale_yuvj_pix_fmts))
229− tinterlace->color.comp[0].u8[0] = 0;
230− ret = av_image_alloc(tinterlace->black_data, tinterlace->black_linesize,
229+ /* limited range */
230+ if (!ff_fmt_is_in(outlink->format, full_scale_yuvj_pix_fmts)) {
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,
231241 outlink->w, outlink->h, outlink->format, 16);
232242 if (ret < 0)
233243 return ret;
234−
235− ff_fill_rectangle(&tinterlace->draw, &tinterlace->color, tinterlace->black_data,
244+ ff_fill_rectangle(&tinterlace->draw, &tinterlace->color, tinterlace->black_data[1],
236245 tinterlace->black_linesize, 0, 0, outlink->w, outlink->h);
237246 }
238247 if (tinterlace->flags & (TINTERLACE_FLAG_VLPF | TINTERLACE_FLAG_CVLPF)
@@ -360,7 +369,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) · 121 unmodified lines
360369 AVFilterLink *outlink = ctx->outputs[0];
361370 TInterlaceContext *tinterlace = ctx->priv;
362371 AVFrame *cur, *next, *out;
363− int field, tff, ret;
372+ int field, tff, full, ret;
364373
365374 av_frame_free(&tinterlace->cur);
366375 tinterlace->cur = tinterlace->next;
@@ -418,6 +427,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) · 51 unmodified lines
418427 out->sample_aspect_ratio = av_mul_q(cur->sample_aspect_ratio, av_make_q(2, 1));
419428
420429 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);
421431 /* copy upper and lower fields */
422432 copy_picture_field(tinterlace, out->data, out->linesize,
423433 (const uint8_t **)cur->data, cur->linesize,
@@ -425,7 +435,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) · 1 unmodified line
425435 FIELD_UPPER_AND_LOWER, 1, field, tinterlace->flags);
426436 /* pad with black the other field */
427437 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,
429439 inlink->format, inlink->w, inlink->h,
430440 FIELD_UPPER_AND_LOWER, 1, !field, tinterlace->flags);
431441 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