From patchwork Wed Jun 20 11:11:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Borsboom X-Patchwork-Id: 9450 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:11c:0:0:0:0:0 with SMTP id c28-v6csp618997jad; Wed, 20 Jun 2018 04:11:30 -0700 (PDT) X-Google-Smtp-Source: ADUXVKK+HozyheT0TEdHYGb0HxWfZngLJpaaFaAEulY2KNDUTmgUcMTjnEFcWAluqwSz/k1WCl6d X-Received: by 2002:adf:e881:: with SMTP id d1-v6mr18089448wrm.43.1529493090239; Wed, 20 Jun 2018 04:11:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529493090; cv=none; d=google.com; s=arc-20160816; b=kY9egGcIKBf7Oheo/5MtG8qcAH+ejjxAmcNE9vKgItmF6Kl6LnyXH7cGPs7RX5SLAn h+7XWr2YpYT3KBRFFfSdJIY4o0Zf5TrJQ3YnG8qmgkUnXKJIVZwi72QS90FVGrXAXVvv OYufLzy22nqQcpa82mvnOJRnZn09tVgwoU3ueqb0tpN5LivH54AvUqRa/dSNaBxFgezr vw0yRdYZgdnLCsA1NjiaZMz/OXnjZ/mm/g8WVZLSbvCiZv1ECLRhdnCwSB9R+/kG3O75 /9P6QPZY5lc3GIyjX0kRtyRAJ8Wo5sLyfa83Yo034ugh+8HNtAhh6l1q53NYfjesfpAf tqLw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:content-language:mime-version:user-agent:date :message-id:from:to:dkim-signature:delivered-to :arc-authentication-results; bh=vi+ZR+03BIFBL0bdoUd1Ki8XdI3CQ77cuuT2IuYcy3E=; b=KlBPIHJzFx9iP7nvWIXs5M8MgC1CvvjxgHl/7ajHNy3fiu1TUzcV/S2P4Sg5CuQvsC RMLMl8h0kDQApPGYebIw/uuCM+nHndSAovCV9Eatw8CAaOMmesup1OtYT8h4tJvGTVWy i2WBMbwESQBUrUIgh1WdrdOvcbD2S9WmVdH5PmdryLafpb3ipJ6a0OuvjVTzFK5QBSvo 11EavJhstpHtAnqU708ZStbyhyI2Q+7zZ/GLX8Zd0LnS59/F/zVzMDFtJoiQnxzu5+j8 fuRw3VbhWA1CoHruTMHjvIY2m4kp6Rwy91oY4M8e3izPvPsx2cHKu0+Ap9dqBuJ6K/xa KhGA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@carpalis.nl header.s=default header.b=biH9mpNN; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id e194-v6si2363107wmf.221.2018.06.20.04.11.29; Wed, 20 Jun 2018 04:11:30 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@carpalis.nl header.s=default header.b=biH9mpNN; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6FD0B68A40D; Wed, 20 Jun 2018 14:10:21 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from kyoto.xs4all.nl (kyoto.xs4all.nl [83.161.153.34]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E962768A402 for ; Wed, 20 Jun 2018 14:10:15 +0300 (EEST) Received: from [10.1.50.50] ([87.215.30.74]) (authenticated bits=0) by kyoto.xs4all.nl (8.14.7/8.14.7) with ESMTP id w5KBB7aC027032 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 20 Jun 2018 13:11:08 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=carpalis.nl; s=default; t=1529493068; bh=2ecrAr3cyrPfGSFKIN0TV00Iyr/wV/Zw3AXPtf66tfg=; h=To:From:Subject:Date; b=biH9mpNN8b88JKAPPgl9KZTUG4YMxRU3RnM9DsxZ4scVv1ct5SbBA/2mwM3ZU8gvk 5cPs20YYSu0qdbiWXl+wYmiYuJKa9Q85po5lNRmDbNFFx6PlFVgS9kD4hJH3jwMVlG kOp87AbldAe3ZXwtuWI03fJhHyAnEJCLnMYxS+eTPMCXlkDDMauUkRxliCAs68rI9N 5gkUdS6HLrJgXASqTQNWLPVjLmZ8ln92gIlb5iEcQQlFuMdefF7q1QmATB2otbjJVs CpUTdss3NKAWiYvjPBzIJAZrlL+dQYgUARtxVcwg9BRADSMmhtc3Do3RkOWl5bnMJN FJnZkkMKRxghw== To: ffmpeg-devel@ffmpeg.org From: Jerome Borsboom Message-ID: <9fd6a3e1-e50b-e85c-59db-97b1914668c9@carpalis.nl> Date: Wed, 20 Jun 2018 13:11:07 +0200 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 MIME-Version: 1.0 Content-Language: nl Subject: [FFmpeg-devel] [PATCH 3/3] avcodec/vc1: fix overlap filter for frame interlaced pictures X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" The overlap filter is not correct for vertical edges in frame interlaced I and P pictures. When filtering macroblocks with different FIELDTX values, we have to match the lines at both sides of the vertical border. In addition, we have to use the correct rounding values, depending on the line we are filtering. Signed-off-by: Jerome Borsboom --- libavcodec/mips/vc1dsp_mmi.c | 15 ++++---- libavcodec/vc1_loopfilter.c | 86 ++++++++++++++++++++++++++++++++++++-------- libavcodec/vc1dsp.c | 15 ++++---- libavcodec/vc1dsp.h | 2 +- 4 files changed, 91 insertions(+), 27 deletions(-) diff --git a/libavcodec/mips/vc1dsp_mmi.c b/libavcodec/mips/vc1dsp_mmi.c index 01e7f9f32c..ec2fdca987 100644 --- a/libavcodec/mips/vc1dsp_mmi.c +++ b/libavcodec/mips/vc1dsp_mmi.c @@ -1019,12 +1019,13 @@ void ff_vc1_h_overlap_mmi(uint8_t *src, int stride) } } -void ff_vc1_h_s_overlap_mmi(int16_t *left, int16_t *right) +void ff_vc1_h_s_overlap_mmi(int16_t *left, int16_t *right, int left_stride, int right_stride, int flags) { int i; int a, b, c, d; int d1, d2; - int rnd1 = 4, rnd2 = 3; + int rnd1 = flags & 2 ? 3 : 4; + int rnd2 = 7 - rnd1; for (i = 0; i < 8; i++) { a = left[6]; b = left[7]; @@ -1038,10 +1039,12 @@ void ff_vc1_h_s_overlap_mmi(int16_t *left, int16_t *right) right[0] = ((c << 3) + d2 + rnd1) >> 3; right[1] = ((d << 3) + d1 + rnd2) >> 3; - right += 8; - left += 8; - rnd2 = 7 - rnd2; - rnd1 = 7 - rnd1; + right += right_stride; + left += left_stride; + if (flags & 1) { + rnd2 = 7 - rnd2; + rnd1 = 7 - rnd1; + } } } diff --git a/libavcodec/vc1_loopfilter.c b/libavcodec/vc1_loopfilter.c index 5d5630db67..d43fa5b3ae 100644 --- a/libavcodec/vc1_loopfilter.c +++ b/libavcodec/vc1_loopfilter.c @@ -32,25 +32,74 @@ #include "vc1dsp.h" static av_always_inline void vc1_h_overlap_filter(VC1Context *v, int16_t (*left_block)[64], - int16_t (*right_block)[64], int block_num) + int16_t (*right_block)[64], int left_fieldtx, + int right_fieldtx, int block_num) { - if (block_num > 3) - v->vc1dsp.vc1_h_s_overlap(left_block[block_num], right_block[block_num]); - else if (block_num & 1) - v->vc1dsp.vc1_h_s_overlap(right_block[block_num - 1], right_block[block_num]); - else - v->vc1dsp.vc1_h_s_overlap(left_block[block_num + 1], right_block[block_num]); + switch (block_num) { + case 0: + v->vc1dsp.vc1_h_s_overlap(left_block[2], + right_block[0], + left_fieldtx ^ right_fieldtx ? 16 - 8 * left_fieldtx : 8, + left_fieldtx ^ right_fieldtx ? 16 - 8 * right_fieldtx : 8, + left_fieldtx || right_fieldtx ? 0 : 1); + break; + + case 1: + v->vc1dsp.vc1_h_s_overlap(right_block[0], + right_block[2], + 8, + 8, + right_fieldtx ? 0 : 1); + break; + + case 2: + v->vc1dsp.vc1_h_s_overlap(!left_fieldtx && right_fieldtx ? left_block[2] + 8 : left_block[3], + left_fieldtx && !right_fieldtx ? right_block[0] + 8 : right_block[1], + left_fieldtx ^ right_fieldtx ? 16 - 8 * left_fieldtx : 8, + left_fieldtx ^ right_fieldtx ? 16 - 8 * right_fieldtx : 8, + left_fieldtx || right_fieldtx ? 2 : 1); + break; + + case 3: + v->vc1dsp.vc1_h_s_overlap(right_block[1], + right_block[3], + 8, + 8, + right_fieldtx ? 2 : 1); + break; + + case 4: + case 5: + v->vc1dsp.vc1_h_s_overlap(left_block[block_num], right_block[block_num], 8, 8, 1); + break; + } } static av_always_inline void vc1_v_overlap_filter(VC1Context *v, int16_t (*top_block)[64], int16_t (*bottom_block)[64], int block_num) { - if (block_num > 3) + switch (block_num) { + case 0: + v->vc1dsp.vc1_v_s_overlap(top_block[1], bottom_block[0]); + break; + + case 1: + v->vc1dsp.vc1_v_s_overlap(top_block[3], bottom_block[2]); + break; + + case 2: + v->vc1dsp.vc1_v_s_overlap(bottom_block[0], bottom_block[1]); + break; + + case 3: + v->vc1dsp.vc1_v_s_overlap(bottom_block[2], bottom_block[3]); + break; + + case 4: + case 5: v->vc1dsp.vc1_v_s_overlap(top_block[block_num], bottom_block[block_num]); - else if (block_num & 2) - v->vc1dsp.vc1_v_s_overlap(bottom_block[block_num - 2], bottom_block[block_num]); - else - v->vc1dsp.vc1_v_s_overlap(top_block[block_num + 2], bottom_block[block_num]); + break; + } } void ff_vc1_i_overlap_filter(VC1Context *v) @@ -82,7 +131,11 @@ void ff_vc1_i_overlap_filter(VC1Context *v) (v->condover == CONDOVER_ALL || (v->over_flags_plane[mb_pos] && ((i & 5) == 1 || v->over_flags_plane[mb_pos - 1]))))) - vc1_h_overlap_filter(v, s->mb_x ? left_blk : cur_blk, cur_blk, i); + vc1_h_overlap_filter(v, + s->mb_x ? left_blk : cur_blk, cur_blk, + v->fcm == ILACE_FRAME && s->mb_x && v->fieldtx_plane[mb_pos - 1], + v->fcm == ILACE_FRAME && v->fieldtx_plane[mb_pos], + i); } if (v->fcm != ILACE_FRAME) @@ -110,6 +163,7 @@ void ff_vc1_p_overlap_filter(VC1Context *v) MpegEncContext *s = &v->s; int16_t (*topleft_blk)[64], (*top_blk)[64], (*left_blk)[64], (*cur_blk)[64]; int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6; + int mb_pos = s->mb_x + s->mb_y * s->mb_stride; int i; topleft_blk = v->block[v->topleft_blk_idx]; @@ -122,7 +176,11 @@ void ff_vc1_p_overlap_filter(VC1Context *v) continue; if (v->mb_type[0][s->block_index[i]] && v->mb_type[0][s->block_index[i] - 1]) - vc1_h_overlap_filter(v, s->mb_x ? left_blk : cur_blk, cur_blk, i); + vc1_h_overlap_filter(v, + s->mb_x ? left_blk : cur_blk, cur_blk, + v->fcm == ILACE_FRAME && s->mb_x && v->fieldtx_plane[mb_pos - 1], + v->fcm == ILACE_FRAME && v->fieldtx_plane[mb_pos], + i); } if (v->fcm != ILACE_FRAME) diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c index 9239a4a1f5..778b811f1a 100644 --- a/libavcodec/vc1dsp.c +++ b/libavcodec/vc1dsp.c @@ -107,12 +107,13 @@ static void vc1_v_s_overlap_c(int16_t *top, int16_t *bottom) } } -static void vc1_h_s_overlap_c(int16_t *left, int16_t *right) +static void vc1_h_s_overlap_c(int16_t *left, int16_t *right, int left_stride, int right_stride, int flags) { int i; int a, b, c, d; int d1, d2; - int rnd1 = 4, rnd2 = 3; + int rnd1 = flags & 2 ? 3 : 4; + int rnd2 = 7 - rnd1; for (i = 0; i < 8; i++) { a = left[6]; b = left[7]; @@ -126,10 +127,12 @@ static void vc1_h_s_overlap_c(int16_t *left, int16_t *right) right[0] = ((c << 3) + d2 + rnd1) >> 3; right[1] = ((d << 3) + d1 + rnd2) >> 3; - right += 8; - left += 8; - rnd2 = 7 - rnd2; - rnd1 = 7 - rnd1; + right += right_stride; + left += left_stride; + if (flags & 1) { + rnd2 = 7 - rnd2; + rnd1 = 7 - rnd1; + } } } diff --git a/libavcodec/vc1dsp.h b/libavcodec/vc1dsp.h index 16b3528a75..75db62b1b4 100644 --- a/libavcodec/vc1dsp.h +++ b/libavcodec/vc1dsp.h @@ -45,7 +45,7 @@ typedef struct VC1DSPContext { void (*vc1_v_overlap)(uint8_t *src, int stride); void (*vc1_h_overlap)(uint8_t *src, int stride); void (*vc1_v_s_overlap)(int16_t *top, int16_t *bottom); - void (*vc1_h_s_overlap)(int16_t *left, int16_t *right); + void (*vc1_h_s_overlap)(int16_t *left, int16_t *right, int left_stride, int right_stride, int flags); void (*vc1_v_loop_filter4)(uint8_t *src, int stride, int pq); void (*vc1_h_loop_filter4)(uint8_t *src, int stride, int pq); void (*vc1_v_loop_filter8)(uint8_t *src, int stride, int pq);