From patchwork Tue May 29 12:26:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Borsboom X-Patchwork-Id: 9151 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:11c:0:0:0:0:0 with SMTP id c28-v6csp3032133jad; Tue, 29 May 2018 05:26:28 -0700 (PDT) X-Google-Smtp-Source: ADUXVKL1oye1DshkrtFW7sHVThrQ4swh9bzUgbzIwdxpnLSeUYWyROdUQYGYvW7WgClP+XcW9K0x X-Received: by 2002:a1c:459a:: with SMTP id l26-v6mr13338271wmi.95.1527596788664; Tue, 29 May 2018 05:26:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527596788; cv=none; d=google.com; s=arc-20160816; b=MbER+GOyintgtowL1JpQiJnLZgRGjtAf9KlEN7hvCg0KbfwP8WxosyIKosVz46YBDq GqbL5gDXbKIlyq6qojZ28nY2fZgu410Yr1cLDVqBJWoDt1conzF4T2B6QyTVnSN8D4cw ylQ7ZW03sLoEXzjNzuxcn7KBQiMMtlYr7udl08/AZHXCGCjDp5cYJShdCYL4bJBvxUNi /OrIgoZ/COGpasB5BufCz7M6nP/W7fVDEa1xudw7yHv58Gwu90aUtOad3TEegW3oMTH1 vnZCBf71v08jznFiTuQOzwJUHCv1cmByl8+ADhg/LIzq5feRy5+vzc/JGYk2yu7ZAqa2 K0Zw== 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:in-reply-to:mime-version :user-agent:date:message-id:from:references:to:dkim-signature :delivered-to:arc-authentication-results; bh=v6NhdrVKv7qJVmQHRolALDKRKihyA6A91/PTwlIWS4k=; b=iGm/IYEHOA6PSSJdkKnFK60HihQlkze9fBtJkU/wQdfQ6gGetX/GcILlrlThRppgwK DHfDrI6ESOSbQERVOtju6mtJpEoMoc6TgNyTeTiGvNLDu81PjoTdSb49lFhyh7NrdWn6 Un2cwt9SYWPToE9aasdlSERK/eNjNwTa5sM+zX6WHPBDTR5orUM+8tkhEoehN8ivfn1U r7A0ypT8ri9MnIp03fkacgsmr+Cnk6i5jF3UJTSJRVYm5UpfRunUFNdSobY19/W0eUEi ot224vqbwzUYrcAWMOnNSBp7f3KLvQKZ6v+CiZ5B094DxfeIVcoRQ3km8C6GXjrlGq3S tGJA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@carpalis.nl header.s=default header.b=YBUZPOPM; 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 x187-v6si5106000wmb.215.2018.05.29.05.26.28; Tue, 29 May 2018 05:26:28 -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=YBUZPOPM; 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 8092068A34C; Tue, 29 May 2018 15:25:42 +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 06E93689818 for ; Tue, 29 May 2018 15:25:35 +0300 (EEST) Received: from [10.1.48.103] ([87.215.30.74]) (authenticated bits=0) by kyoto.xs4all.nl (8.14.7/8.14.7) with ESMTP id w4TCQHth024747 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 29 May 2018 14:26:18 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=carpalis.nl; s=default; t=1527596779; bh=7yiJ0p6bnud6AaJgh4Z/SRXodUZYjr0fZGfCUfpWstQ=; h=To:References:Subject:From:Date:In-Reply-To; b=YBUZPOPMt3dxNhSW1+EhyLeE30NhaqwymLDQtflZ2j8LpGKB+AUZj4dT2nyTQGJYU t4WE3hg7y/34ekQRxoh90n5dAF9OVfbrCANNIABC8xqelSk1EvjGma7xgEebzirL6A pzVG6gEXSg/t5lvbUKb7xcWnPNVwy/gM5VoAoZ9Utom8mRrI6JMdQ1R0A58/yeY64V Pn79CFXGCKbTlBJsBA3PHHwnxiAqpb9z7TnJjhKau2in/PhuLQHG5GUlVlS4G2mRv3 xKox0Osvtx8aVNQ8i+7i73cuJj4Hhm9kUMHElvBMKTDn5GD5JYOS63Z12KN0R/bXxV PDDDAnd3WBtWw== To: ffmpeg-devel@ffmpeg.org References: <85bd0478-73c1-100f-2376-ef24b12992b5@carpalis.nl> From: Jerome Borsboom Message-ID: Date: Tue, 29 May 2018 14:26:17 +0200 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 MIME-Version: 1.0 In-Reply-To: <85bd0478-73c1-100f-2376-ef24b12992b5@carpalis.nl> Content-Language: nl Subject: Re: [FFmpeg-devel] [PATCH v3] avcodec/vc1: fix out-of-bounds reference pixel replication 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" Out-of-bounds reference pixel replication should take into account the frame coding mode of the reference frame(s), not the frame coding mode of the current frame. Signed-off-by: Jerome Borsboom --- Even more corrections. The starting line must also be adjusted by one for an opposite refence field. libavcodec/vc1_mc.c | 668 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 385 insertions(+), 283 deletions(-) diff --git a/libavcodec/vc1_mc.c b/libavcodec/vc1_mc.c index 04b359204c..1b8d8799b3 100644 --- a/libavcodec/vc1_mc.c +++ b/libavcodec/vc1_mc.c @@ -179,12 +179,17 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) int i; uint8_t (*luty)[256], (*lutuv)[256]; int use_ic; + int interlace; + int linesize, uvlinesize; if ((!v->field_mode || (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && !v->s.last_picture.f->data[0]) return; + linesize = s->current_picture_ptr->f->linesize[0]; + uvlinesize = s->current_picture_ptr->f->linesize[1]; + mx = s->mv[dir][0][0]; my = s->mv[dir][0][1]; @@ -220,6 +225,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) luty = v->curr_luty; lutuv = v->curr_lutuv; use_ic = *v->curr_use_ic; + interlace = 1; } else { srcY = s->last_picture.f->data[0]; srcU = s->last_picture.f->data[1]; @@ -227,6 +233,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) luty = v->last_luty; lutuv = v->last_lutuv; use_ic = v->last_use_ic; + interlace = s->last_picture.f->interlaced_frame; } } else { srcY = s->next_picture.f->data[0]; @@ -235,6 +242,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) luty = v->next_luty; lutuv = v->next_lutuv; use_ic = v->next_use_ic; + interlace = s->next_picture.f->interlaced_frame; } if (!srcY || !srcU) { @@ -269,9 +277,9 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) srcV += uvsrc_y * s->uvlinesize + uvsrc_x; if (v->field_mode && v->ref_field_type[dir]) { - srcY += s->current_picture_ptr->f->linesize[0]; - srcU += s->current_picture_ptr->f->linesize[1]; - srcV += s->current_picture_ptr->f->linesize[2]; + srcY += linesize; + srcU += uvlinesize; + srcV += uvlinesize; } /* for grayscale we should not try to read from unknown area */ @@ -289,112 +297,105 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) const int k = 17 + s->mspel * 2; srcY -= s->mspel * (1 + s->linesize); - if (v->fcm == ILACE_FRAME) { - if (src_y - s->mspel & 1) { - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, - srcY, - 2 * s->linesize, - 2 * s->linesize, - k, - k + 1 >> 1, - src_x - s->mspel, - src_y - s->mspel >> 1, - s->h_edge_pos, - v_edge_pos + 1 >> 1); - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, - srcY + s->linesize, - 2 * s->linesize, - 2 * s->linesize, - k, - k >> 1, - src_x - s->mspel, - src_y - s->mspel + 1 >> 1, - s->h_edge_pos, - v_edge_pos >> 1); - } else { - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, - srcY, - 2 * s->linesize, - 2 * s->linesize, - k, - k + 1 >> 1, - src_x - s->mspel, - src_y - s->mspel >> 1, - s->h_edge_pos, - v_edge_pos >> 1); - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, - srcY + s->linesize, - 2 * s->linesize, - 2 * s->linesize, + if (interlace) { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, + srcY, + linesize << 1, + linesize << 1, + k, + v->field_mode ? k : k + 1 >> 1, + src_x - s->mspel, + src_y - s->mspel >> !v->field_mode, + s->h_edge_pos, + s->v_edge_pos >> 1); + if (!v->field_mode) + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize, + srcY + linesize, + linesize << 1, + linesize << 1, k, k >> 1, src_x - s->mspel, src_y - s->mspel + 1 >> 1, s->h_edge_pos, - v_edge_pos + 1 >> 1); - } + s->v_edge_pos >> 1); } else - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY, - s->linesize, s->linesize, - k, k, - src_x - s->mspel, src_y - s->mspel, - s->h_edge_pos, v_edge_pos); + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, + srcY, + linesize, + linesize, + k, + v->field_mode ? (k << 1) - 1 : k, + src_x - s->mspel, + v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[dir] : + src_y - s->mspel, + s->h_edge_pos, + s->v_edge_pos); srcY = s->sc.edge_emu_buffer; - if (v->fcm == ILACE_FRAME) { - if (uvsrc_y & 1) { - s->vdsp.emulated_edge_mc(ubuf, srcU, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 5, - uvsrc_x, uvsrc_y >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1); - s->vdsp.emulated_edge_mc(ubuf + s->uvlinesize, srcU + s->uvlinesize, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 4, - uvsrc_x, uvsrc_y + 1 >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1); - s->vdsp.emulated_edge_mc(vbuf, srcV, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 5, - uvsrc_x, uvsrc_y >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1); - s->vdsp.emulated_edge_mc(vbuf + s->uvlinesize, srcV + s->uvlinesize, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 4, - uvsrc_x, uvsrc_y + 1 >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1); - } else { - s->vdsp.emulated_edge_mc(ubuf, srcU, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 5, - uvsrc_x, uvsrc_y >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1); - s->vdsp.emulated_edge_mc(ubuf + s->uvlinesize, srcU + s->uvlinesize, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 4, - uvsrc_x, uvsrc_y + 1 >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1); - s->vdsp.emulated_edge_mc(vbuf, srcV, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 5, - uvsrc_x, uvsrc_y >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1); - s->vdsp.emulated_edge_mc(vbuf + s->uvlinesize, srcV + s->uvlinesize, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 4, - uvsrc_x, uvsrc_y + 1 >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1); + if (interlace) { + s->vdsp.emulated_edge_mc(ubuf, + srcU, + uvlinesize << 1, + uvlinesize << 1, + 9, + v->field_mode ? 9 : 5, + uvsrc_x, + uvsrc_y >> !v->field_mode, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); + s->vdsp.emulated_edge_mc(vbuf, + srcV, + uvlinesize << 1, + uvlinesize << 1, + 9, + v->field_mode ? 9 : 5, + uvsrc_x, + uvsrc_y >> !v->field_mode, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); + if (!v->field_mode) { + s->vdsp.emulated_edge_mc(ubuf + uvlinesize, + srcU + uvlinesize, + uvlinesize << 1, + uvlinesize << 1, + 9, + 4, + uvsrc_x, + uvsrc_y + 1 >> 1, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); + s->vdsp.emulated_edge_mc(vbuf + uvlinesize, + srcV + uvlinesize, + uvlinesize << 1, + uvlinesize << 1, + 9, + 4, + uvsrc_x, + uvsrc_y + 1 >> 1, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); } } else { - s->vdsp.emulated_edge_mc(ubuf, srcU, - s->uvlinesize, s->uvlinesize, - 8 + 1, 8 + 1, - uvsrc_x, uvsrc_y, - s->h_edge_pos >> 1, v_edge_pos >> 1); - s->vdsp.emulated_edge_mc(vbuf, srcV, - s->uvlinesize, s->uvlinesize, - 8 + 1, 8 + 1, - uvsrc_x, uvsrc_y, - s->h_edge_pos >> 1, v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(ubuf, + srcU, + uvlinesize, + uvlinesize, + 9, + v->field_mode ? 17 : 9, + uvsrc_x, + v->field_mode ? 2 * uvsrc_y + v->ref_field_type[dir] : uvsrc_y, + s->h_edge_pos >> 1, + s->v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(vbuf, + srcV, + uvlinesize, + uvlinesize, + 9, + v->field_mode ? 17 : 9, + uvsrc_x, + v->field_mode ? 2 * uvsrc_y + v->ref_field_type[dir] : uvsrc_y, + s->h_edge_pos >> 1, + s->v_edge_pos >> 1); } srcU = ubuf; srcV = vbuf; @@ -458,12 +459,16 @@ void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg) int v_edge_pos = s->v_edge_pos >> v->field_mode; uint8_t (*luty)[256]; int use_ic; + int interlace; + int linesize; if ((!v->field_mode || (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && !v->s.last_picture.f->data[0]) return; + linesize = s->current_picture_ptr->f->linesize[0]; + mx = s->mv[dir][n][0]; my = s->mv[dir][n][1]; @@ -472,15 +477,18 @@ void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg) srcY = s->current_picture.f->data[0]; luty = v->curr_luty; use_ic = *v->curr_use_ic; + interlace = 1; } else { srcY = s->last_picture.f->data[0]; luty = v->last_luty; use_ic = v->last_use_ic; + interlace = s->last_picture.f->interlaced_frame; } } else { srcY = s->next_picture.f->data[0]; luty = v->next_luty; use_ic = v->next_use_ic; + interlace = s->next_picture.f->interlaced_frame; } if (!srcY) { @@ -547,7 +555,7 @@ void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg) srcY += src_y * s->linesize + src_x; if (v->field_mode && v->ref_field_type[dir]) - srcY += s->current_picture_ptr->f->linesize[0]; + srcY += linesize; if (v->rangeredfrm || use_ic || s->h_edge_pos < 13 || v_edge_pos < 23 @@ -557,36 +565,40 @@ void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg) srcY -= s->mspel * (1 + (s->linesize << fieldmv)); /* check emulate edge stride and offset */ - if (v->fcm == ILACE_FRAME) { - if (src_y - (s->mspel << fieldmv) & 1) { - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY, - 2 * s->linesize, 2 * s->linesize, - k, (k << fieldmv) + 1 >> 1, - src_x - s->mspel, src_y - (s->mspel << fieldmv) >> 1, - s->h_edge_pos, v_edge_pos + 1 >> 1); - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, srcY + s->linesize, - 2 * s->linesize, 2 * s->linesize, - k, (k << fieldmv) >> 1, - src_x - s->mspel, src_y - (s->mspel << fieldmv) + 1 >> 1, - s->h_edge_pos, v_edge_pos >> 1); - } else { - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY, - 2 * s->linesize, 2 * s->linesize, - k, (k << fieldmv) + 1 >> 1, - src_x - s->mspel, src_y - (s->mspel << fieldmv) >> 1, - s->h_edge_pos, v_edge_pos >> 1); - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, srcY + s->linesize, - 2 * s->linesize, 2 * s->linesize, - k, (k << fieldmv) >> 1, - src_x - s->mspel, src_y - (s->mspel << fieldmv) + 1 >> 1, - s->h_edge_pos, v_edge_pos + 1 >> 1); - } + if (interlace) { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, + srcY, + linesize << 1, + linesize << 1, + k, + v->field_mode ? k : (k << fieldmv) + 1 >> 1, + src_x - s->mspel, + src_y - (s->mspel << fieldmv) >> !v->field_mode, + s->h_edge_pos, + s->v_edge_pos >> 1); + if (!v->field_mode && !fieldmv) + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize, + srcY + linesize, + linesize << 1, + linesize << 1, + k, + k >> 1, + src_x - s->mspel, + src_y - s->mspel + 1 >> 1, + s->h_edge_pos, + s->v_edge_pos >> 1); } else - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY, - s->linesize, s->linesize, - k, k, - src_x - s->mspel, src_y - s->mspel, - s->h_edge_pos, v_edge_pos); + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, + srcY, + linesize, + linesize, + k, + v->field_mode ? (k << 1) - 1 : k << fieldmv, + src_x - s->mspel, + v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[dir] : + src_y - (s->mspel << fieldmv), + s->h_edge_pos, + s->v_edge_pos); srcY = s->sc.edge_emu_buffer; /* if we deal with range reduction we need to scale source blocks */ if (v->rangeredfrm) { @@ -630,6 +642,8 @@ void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir) int v_edge_pos = s->v_edge_pos >> v->field_mode; uint8_t (*lutuv)[256]; int use_ic; + int interlace; + int uvlinesize; if (!v->field_mode && !v->s.last_picture.f->data[0]) return; @@ -654,6 +668,9 @@ void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir) return; s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx; s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty; + + uvlinesize = s->current_picture_ptr->f->linesize[1]; + uvmx = (tx + ((tx & 3) == 3)) >> 1; uvmy = (ty + ((ty & 3) == 3)) >> 1; @@ -685,17 +702,20 @@ void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir) srcV = s->current_picture.f->data[2]; lutuv = v->curr_lutuv; use_ic = *v->curr_use_ic; + interlace = 1; } else { srcU = s->last_picture.f->data[1]; srcV = s->last_picture.f->data[2]; lutuv = v->last_lutuv; use_ic = v->last_use_ic; + interlace = s->last_picture.f->interlaced_frame; } } else { srcU = s->next_picture.f->data[1]; srcV = s->next_picture.f->data[2]; lutuv = v->next_lutuv; use_ic = v->next_use_ic; + interlace = s->next_picture.f->interlaced_frame; } if (!srcU) { @@ -708,8 +728,8 @@ void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir) if (v->field_mode) { if (chroma_ref_type) { - srcU += s->current_picture_ptr->f->linesize[1]; - srcV += s->current_picture_ptr->f->linesize[2]; + srcU += uvlinesize; + srcV += uvlinesize; } } @@ -717,14 +737,71 @@ void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir) || s->h_edge_pos < 18 || v_edge_pos < 18 || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9 || (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9) { - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcU, - s->uvlinesize, s->uvlinesize, - 8 + 1, 8 + 1, uvsrc_x, uvsrc_y, - s->h_edge_pos >> 1, v_edge_pos >> 1); - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, srcV, - s->uvlinesize, s->uvlinesize, - 8 + 1, 8 + 1, uvsrc_x, uvsrc_y, - s->h_edge_pos >> 1, v_edge_pos >> 1); + if (interlace) { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, + srcU, + uvlinesize << 1, + uvlinesize << 1, + 9, + v->field_mode ? 9 : 5, + uvsrc_x, + uvsrc_y >> !v->field_mode, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, + srcV, + uvlinesize << 1, + uvlinesize << 1, + 9, + v->field_mode ? 9 : 5, + uvsrc_x, + uvsrc_y >> !v->field_mode, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); + if (!v->field_mode) { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + uvlinesize, + srcU + uvlinesize, + uvlinesize << 1, + uvlinesize << 1, + 9, + 4, + uvsrc_x, + uvsrc_y + 1 >> 1, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + uvlinesize, + srcV + uvlinesize, + uvlinesize << 1, + uvlinesize << 1, + 9, + 4, + uvsrc_x, + uvsrc_y + 1 >> 1, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); + } + } else { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, + srcU, + uvlinesize, + uvlinesize, + 9, + v->field_mode ? 17 : 9, + uvsrc_x, + v->field_mode ? 2 * uvsrc_y + chroma_ref_type : uvsrc_y, + s->h_edge_pos >> 1, + s->v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, + srcV, + uvlinesize, + uvlinesize, + 9, + v->field_mode ? 17 : 9, + uvsrc_x, + v->field_mode ? 2 * uvsrc_y + chroma_ref_type : uvsrc_y, + s->h_edge_pos >> 1, + s->v_edge_pos >> 1); + } srcU = s->sc.edge_emu_buffer; srcV = s->sc.edge_emu_buffer + 16; @@ -772,11 +849,15 @@ void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg) int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks int v_edge_pos = s->v_edge_pos >> 1; int use_ic; + int interlace; + int uvlinesize; uint8_t (*lutuv)[256]; if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) return; + uvlinesize = s->current_picture_ptr->f->linesize[1]; + for (i = 0; i < 4; i++) { int d = i < 2 ? dir: dir2; tx = s->mv[d][i][0]; @@ -803,11 +884,13 @@ void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg) srcV = s->next_picture.f->data[2]; lutuv = v->next_lutuv; use_ic = v->next_use_ic; + interlace = s->next_picture.f->interlaced_frame; } else { srcU = s->last_picture.f->data[1]; srcV = s->last_picture.f->data[2]; lutuv = v->last_lutuv; use_ic = v->last_use_ic; + interlace = s->last_picture.f->interlaced_frame; } if (!srcU) return; @@ -820,51 +903,70 @@ void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg) || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv) || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5 || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) { - if (v->fcm == ILACE_FRAME) { - if (uvsrc_y & 1) { - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcU, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 5, (5 << fieldmv) + 1 >> 1, uvsrc_x, uvsrc_y >> 1, - s->h_edge_pos >> 1, v_edge_pos + 1 >> 1); - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->uvlinesize, srcU + s->uvlinesize, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 5, (5 << fieldmv) >> 1, uvsrc_x, uvsrc_y + 1 >> 1, - s->h_edge_pos >> 1, v_edge_pos >> 1); - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, srcV, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 5, (5 << fieldmv) + 1 >> 1, uvsrc_x, uvsrc_y >> 1, - s->h_edge_pos >> 1, v_edge_pos + 1 >> 1); - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + s->uvlinesize, srcV + s->uvlinesize, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 5, (5 << fieldmv) >> 1, uvsrc_x, uvsrc_y + 1 >> 1, - s->h_edge_pos >> 1, v_edge_pos >> 1); - } else { - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcU, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 5, (5 << fieldmv) + 1 >> 1, uvsrc_x, uvsrc_y >> 1, - s->h_edge_pos >> 1, v_edge_pos >> 1); - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->uvlinesize, srcU + s->uvlinesize, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 5, (5 << fieldmv) >> 1, uvsrc_x, uvsrc_y + 1 >> 1, - s->h_edge_pos >> 1, v_edge_pos + 1 >> 1); - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, srcV, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 5, (5 << fieldmv) + 1 >> 1, uvsrc_x, uvsrc_y >> 1, - s->h_edge_pos >> 1, v_edge_pos >> 1); - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + s->uvlinesize, srcV + s->uvlinesize, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 5, (5 << fieldmv) + 1, uvsrc_x, uvsrc_y + 1 >> 1, - s->h_edge_pos >> 1, v_edge_pos + 1 >> 1); + if (interlace) { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, + srcU, + uvlinesize << 1, + uvlinesize << 1, + 5, + (5 << fieldmv) + 1 >> 1, + uvsrc_x, + uvsrc_y >> 1, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, + srcV, + uvlinesize << 1, + uvlinesize << 1, + 5, + (5 << fieldmv) + 1 >> 1, + uvsrc_x, + uvsrc_y >> 1, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); + if (!fieldmv) { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + uvlinesize, + srcU + uvlinesize, + uvlinesize << 1, + uvlinesize << 1, + 5, + 2, + uvsrc_x, + uvsrc_y + 1 >> 1, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + uvlinesize, + srcV + uvlinesize, + uvlinesize << 1, + uvlinesize << 1, + 5, + 2, + uvsrc_x, + uvsrc_y + 1 >> 1, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); } } else { - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcU, - s->uvlinesize, s->uvlinesize, - 5, 5, uvsrc_x, uvsrc_y, - s->h_edge_pos >> 1, v_edge_pos); - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, srcV, - s->uvlinesize, s->uvlinesize, - 5, 5, uvsrc_x, uvsrc_y, - s->h_edge_pos >> 1, v_edge_pos); + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, + srcU, + uvlinesize, + uvlinesize, + 5, + 5 << fieldmv, + uvsrc_x, + uvsrc_y, + s->h_edge_pos >> 1, + s->v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, + srcV, + uvlinesize, + uvlinesize, + 5, + 5 << fieldmv, + uvsrc_x, + uvsrc_y, + s->h_edge_pos >> 1, + s->v_edge_pos >> 1); } srcU = s->sc.edge_emu_buffer; srcV = s->sc.edge_emu_buffer + 16; @@ -907,10 +1009,15 @@ void ff_vc1_interp_mc(VC1Context *v) int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; int v_edge_pos = s->v_edge_pos >> v->field_mode; int use_ic = v->next_use_ic; + int interlace; + int linesize, uvlinesize; if (!v->field_mode && !v->s.next_picture.f->data[0]) return; + linesize = s->current_picture_ptr->f->linesize[0]; + uvlinesize = s->current_picture_ptr->f->linesize[1]; + mx = s->mv[1][0][0]; my = s->mv[1][0][1]; uvmx = (mx + ((mx & 3) == 3)) >> 1; @@ -927,6 +1034,8 @@ void ff_vc1_interp_mc(VC1Context *v) srcU = s->next_picture.f->data[1]; srcV = s->next_picture.f->data[2]; + interlace = s->next_picture.f->interlaced_frame; + src_x = s->mb_x * 16 + (mx >> 2); src_y = s->mb_y * 16 + (my >> 2); uvsrc_x = s->mb_x * 8 + (uvmx >> 2); @@ -954,9 +1063,9 @@ void ff_vc1_interp_mc(VC1Context *v) srcV += uvsrc_y * s->uvlinesize + uvsrc_x; if (v->field_mode && v->ref_field_type[1]) { - srcY += s->current_picture_ptr->f->linesize[0]; - srcU += s->current_picture_ptr->f->linesize[1]; - srcV += s->current_picture_ptr->f->linesize[2]; + srcY += linesize; + srcU += uvlinesize; + srcV += uvlinesize; } /* for grayscale we should not try to read from unknown area */ @@ -973,112 +1082,105 @@ void ff_vc1_interp_mc(VC1Context *v) const int k = 17 + s->mspel * 2; srcY -= s->mspel * (1 + s->linesize); - if (v->fcm == ILACE_FRAME) { - if (src_y - s->mspel & 1) { - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, - srcY, - 2 * s->linesize, - 2 * s->linesize, - k, - k + 1 >> 1, - src_x - s->mspel, - src_y - s->mspel >> 1, - s->h_edge_pos, - v_edge_pos + 1 >> 1); - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, - srcY + s->linesize, - 2 * s->linesize, - 2 * s->linesize, + if (interlace) { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, + srcY, + linesize << 1, + linesize << 1, + k, + v->field_mode ? k : (k + 1 >> 1), + src_x - s->mspel, + src_y - s->mspel >> !v->field_mode, + s->h_edge_pos, + s->v_edge_pos >> 1); + if (!v->field_mode) + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize, + srcY + linesize, + linesize << 1, + linesize << 1, k, k >> 1, src_x - s->mspel, src_y - s->mspel + 1 >> 1, s->h_edge_pos, - v_edge_pos >> 1); - } else { - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, - srcY, - 2 * s->linesize, - 2 * s->linesize, - k, - k + 1 >> 1, - src_x - s->mspel, - src_y - s->mspel >> 1, - s->h_edge_pos, - v_edge_pos >> 1); - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, - srcY + s->linesize, - 2 * s->linesize, - 2 * s->linesize, - k, - k >> 1, - src_x - s->mspel, - src_y - s->mspel + 1 >> 1, - s->h_edge_pos, - v_edge_pos + 1 >> 1); - } + s->v_edge_pos >> 1); } else - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY, - s->linesize, s->linesize, - k, k, - src_x - s->mspel, src_y - s->mspel, - s->h_edge_pos, v_edge_pos); + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, + srcY, + linesize, + linesize, + k, + v->field_mode ? (k << 1) - 1 : k, + src_x - s->mspel, + v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[1] : + src_y - s->mspel, + s->h_edge_pos, + s->v_edge_pos); srcY = s->sc.edge_emu_buffer; - if (v->fcm == ILACE_FRAME) { - if (uvsrc_y & 1) { - s->vdsp.emulated_edge_mc(ubuf, srcU, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 5, - uvsrc_x, uvsrc_y >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1); - s->vdsp.emulated_edge_mc(ubuf + s->uvlinesize, srcU + s->uvlinesize, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 4, - uvsrc_x, uvsrc_y + 1 >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1); - s->vdsp.emulated_edge_mc(vbuf, srcV, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 5, - uvsrc_x, uvsrc_y >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1); - s->vdsp.emulated_edge_mc(vbuf + s->uvlinesize, srcV + s->uvlinesize, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 4, - uvsrc_x, uvsrc_y + 1 >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1); - } else { - s->vdsp.emulated_edge_mc(ubuf, srcU, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 5, - uvsrc_x, uvsrc_y >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1); - s->vdsp.emulated_edge_mc(ubuf + s->uvlinesize, srcU + s->uvlinesize, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 4, - uvsrc_x, uvsrc_y + 1 >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1); - s->vdsp.emulated_edge_mc(vbuf, srcV, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 5, - uvsrc_x, uvsrc_y >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1); - s->vdsp.emulated_edge_mc(vbuf + s->uvlinesize, srcV + s->uvlinesize, - 2 * s->uvlinesize, 2 * s->uvlinesize, - 8 + 1, 4, - uvsrc_x, uvsrc_y + 1 >> 1, - s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1); + if (interlace) { + s->vdsp.emulated_edge_mc(ubuf, + srcU, + uvlinesize << 1, + uvlinesize << 1, + 9, + v->field_mode ? 9 : 5, + uvsrc_x, + uvsrc_y >> !v->field_mode, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); + s->vdsp.emulated_edge_mc(vbuf, + srcV, + uvlinesize << 1, + uvlinesize << 1, + 9, + v->field_mode ? 9 : 5, + uvsrc_x, + uvsrc_y >> !v->field_mode, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); + if (!v->field_mode) { + s->vdsp.emulated_edge_mc(ubuf + uvlinesize, + srcU + uvlinesize, + uvlinesize << 1, + uvlinesize << 1, + 9, + 4, + uvsrc_x, + uvsrc_y + 1 >> 1, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); + s->vdsp.emulated_edge_mc(vbuf + uvlinesize, + srcV + uvlinesize, + uvlinesize << 1, + uvlinesize << 1, + 9, + 4, + uvsrc_x, + uvsrc_y + 1 >> 1, + s->h_edge_pos >> 1, + s->v_edge_pos >> 2); } } else { - s->vdsp.emulated_edge_mc(ubuf, srcU, - s->uvlinesize, s->uvlinesize, - 8 + 1, 8 + 1, - uvsrc_x, uvsrc_y, - s->h_edge_pos >> 1, v_edge_pos >> 1); - s->vdsp.emulated_edge_mc(vbuf, srcV, - s->uvlinesize, s->uvlinesize, - 8 + 1, 8 + 1, - uvsrc_x, uvsrc_y, - s->h_edge_pos >> 1, v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(ubuf, + srcU, + uvlinesize, + uvlinesize, + 9, + v->field_mode ? 17 : 9, + uvsrc_x, + v->field_mode ? 2 * uvsrc_y + v->ref_field_type[1] : uvsrc_y, + s->h_edge_pos >> 1, + s->v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(vbuf, + srcV, + uvlinesize, + uvlinesize, + 9, + v->field_mode ? 17 : 9, + uvsrc_x, + v->field_mode ? 2 * uvsrc_y + v->ref_field_type[1] : uvsrc_y, + s->h_edge_pos >> 1, + s->v_edge_pos >> 1); } srcU = ubuf; srcV = vbuf;