From patchwork Sun Jan 8 19:37:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 2124 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.89.21 with SMTP id n21csp6774477vsb; Sun, 8 Jan 2017 11:37:44 -0800 (PST) X-Received: by 10.223.145.5 with SMTP id j5mr8937820wrj.46.1483904264735; Sun, 08 Jan 2017 11:37:44 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id d75si458638wma.105.2017.01.08.11.37.44; Sun, 08 Jan 2017 11:37:44 -0800 (PST) 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=@gmail.com; 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; dmarc=fail (p=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 137D068A57F; Sun, 8 Jan 2017 21:37:35 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qk0-f193.google.com (mail-qk0-f193.google.com [209.85.220.193]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 03869680ABB for ; Sun, 8 Jan 2017 21:37:29 +0200 (EET) Received: by mail-qk0-f193.google.com with SMTP id a20so16572069qkc.3 for ; Sun, 08 Jan 2017 11:37:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=k6i+UFeeS3QXQP576giDd1flM2zJIHuIin9ZVELdi90=; b=CT5PZX5JEMQ/F5x8hJ58nqZer3ecrFwIkKgM3ujwdsvA3DND65VtgLpGgAnCP1+Aap 7oaMHLnPv1PjTdDG4YPmmJFf9j+Cq6bXI/QbNEmTzC1XEt2liILyT7I9dtheQZTJailC R3hsabygxYpcLDOQDoiuz2x2tdBD3y6fbRlIYviu9yb7sLxIv5nYX+IZdIg9yCbii2Cl RmSRJDej5Urj262697MbiSU5/0JbrL4YoifOIITUGrNPUSByKxm272MEnLndwokwp1HW uvo9E5JVhYyXIzrrEP6zw7EHdkqAGntvxgu44Xm43tQTc7Bf28DlpOW92YDcPKQglluR mjdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=k6i+UFeeS3QXQP576giDd1flM2zJIHuIin9ZVELdi90=; b=NuFytCvOxYgM/3Dkth9adqRE+N9iuIvO+dFJw5LioEoGbI/Olh1tsBobB7IwDsBTQo sMNY+ns5bv7h2s/TcT23vJC1lzBKtjeKy69mZDN+sSdGZLFk2pKPKQsCS1PWmVIh/KzG q5nojtHBF2o/7vbZtiYLzc83QAxMHJ7YehAi+uN2W5/fpdxBKOIAN3BBsjYyiDvniXi5 v+HsXD1t+wqXJpLCMxTUkVQOCn9BCMRrL/V3XcmteZdXP/M1dW1s17/7Q+Jhw3/aP7RO IgwcUS/sJmD06RsOVZtwpAFCMlJHVxWuRiiWpaM0h86Um42lPNnOIteyDKeJZyDsj84w JanQ== X-Gm-Message-State: AIkVDXKACEjP6tjTD5emNuKhM2EV6GoUdcS+lLyL48ag6N6QwFG69xckftKwqq9QbsslPA== X-Received: by 10.55.156.81 with SMTP id f78mr72154049qke.8.1483904253953; Sun, 08 Jan 2017 11:37:33 -0800 (PST) Received: from localhost.localdomain ([181.22.51.149]) by smtp.gmail.com with ESMTPSA id s65sm1872655qtd.2.2017.01.08.11.37.30 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 08 Jan 2017 11:37:33 -0800 (PST) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Sun, 8 Jan 2017 16:37:01 -0300 Message-Id: <20170108193701.6256-1-jamrial@gmail.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20170108152537.5468-2-jamrial@gmail.com> References: <20170108152537.5468-2-jamrial@gmail.com> Subject: [FFmpeg-devel] [PATCH 1/5 v2] lossless_videodsp: move shared functions from huffyuvdsp 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Several codecs other than huffyuv use them. Signed-off-by: James Almer --- Fixed the order of a couple asm constants that were crashing most related FATE tests. PPC changes still untested. configure | 8 +- libavcodec/huffyuvdec.c | 63 +++---- libavcodec/huffyuvdsp.c | 61 ------- libavcodec/huffyuvdsp.h | 7 - libavcodec/lagarith.c | 12 +- libavcodec/lossless_videodsp.c | 62 +++++++ libavcodec/lossless_videodsp.h | 9 + libavcodec/magicyuv.c | 22 ++- libavcodec/ppc/Makefile | 2 +- ...uvdsp_altivec.c => lossless_videodsp_altivec.c} | 4 +- libavcodec/utvideo.h | 4 +- libavcodec/utvideodec.c | 16 +- libavcodec/vble.c | 10 +- libavcodec/x86/huffyuvdsp.asm | 188 -------------------- libavcodec/x86/huffyuvdsp_init.c | 73 -------- libavcodec/x86/lossless_videodsp.asm | 190 +++++++++++++++++++++ libavcodec/x86/lossless_videodsp_init.c | 76 ++++++++- 17 files changed, 406 insertions(+), 401 deletions(-) rename libavcodec/ppc/{huffyuvdsp_altivec.c => lossless_videodsp_altivec.c} (93%) diff --git a/configure b/configure index 398e843..d393983 100755 --- a/configure +++ b/configure @@ -2440,10 +2440,10 @@ interplay_video_decoder_select="hpeldsp" jpegls_decoder_select="golomb mjpeg_decoder" jpegls_encoder_select="golomb" jv_decoder_select="blockdsp" -lagarith_decoder_select="huffyuvdsp" +lagarith_decoder_select="llviddsp" ljpeg_encoder_select="aandcttables idctdsp jpegtables mpegvideoenc" loco_decoder_select="golomb" -magicyuv_decoder_select="huffyuvdsp llviddsp" +magicyuv_decoder_select="llviddsp" mdec_decoder_select="blockdsp idctdsp mpegvideo" metasound_decoder_select="lsp mdct sinewin" mimic_decoder_select="blockdsp bswapdsp hpeldsp idctdsp" @@ -2533,9 +2533,9 @@ truespeech_decoder_select="bswapdsp" tscc_decoder_select="zlib" twinvq_decoder_select="mdct lsp sinewin" txd_decoder_select="texturedsp" -utvideo_decoder_select="bswapdsp huffyuvdsp" +utvideo_decoder_select="bswapdsp llviddsp" utvideo_encoder_select="bswapdsp huffman huffyuvencdsp" -vble_decoder_select="huffyuvdsp" +vble_decoder_select="llviddsp" vc1_decoder_select="blockdsp h263_decoder h264qpel intrax8 mpegvideo vc1dsp" vc1_qsv_decoder_deps="libmfx" vc1_qsv_decoder_select="qsvdec vc1_qsv_hwaccel" diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c index 7314519..1b4112c 100644 --- a/libavcodec/huffyuvdec.c +++ b/libavcodec/huffyuvdec.c @@ -36,6 +36,7 @@ #include "get_bits.h" #include "huffyuv.h" #include "huffyuvdsp.h" +#include "lossless_videodsp.h" #include "thread.h" #include "libavutil/imgutils.h" #include "libavutil/pixdesc.h" @@ -878,7 +879,7 @@ static void draw_slice(HYuvContext *s, AVFrame *frame, int y) static int left_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src, int w, int acc) { if (s->bps <= 8) { - return s->hdsp.add_hfyu_left_pred(dst, src, w, acc); + return s->llviddsp.add_left_pred(dst, src, w, acc); } else { return s->llviddsp.add_hfyu_left_pred_int16(( uint16_t *)dst, (const uint16_t *)src, s->n-1, w, acc); } @@ -887,7 +888,7 @@ static int left_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src, int static void add_bytes(HYuvContext *s, uint8_t *dst, uint8_t *src, int w) { if (s->bps <= 8) { - s->hdsp.add_bytes(dst, src, w); + s->llviddsp.add_bytes(dst, src, w); } else { s->llviddsp.add_int16((uint16_t*)dst, (const uint16_t*)src, s->n - 1, w); } @@ -896,7 +897,7 @@ static void add_bytes(HYuvContext *s, uint8_t *dst, uint8_t *src, int w) static void add_median_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src, const uint8_t *diff, int w, int *left, int *left_top) { if (s->bps <= 8) { - s->hdsp.add_hfyu_median_pred(dst, src, diff, w, left, left_top); + s->llviddsp.add_median_pred(dst, src, diff, w, left, left_top); } else { s->llviddsp.add_hfyu_median_pred_int16((uint16_t *)dst, (const uint16_t *)src, (const uint16_t *)diff, s->n-1, w, left, left_top); } @@ -1038,11 +1039,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, case LEFT: case PLANE: decode_422_bitstream(s, width - 2); - lefty = s->hdsp.add_hfyu_left_pred(p->data[0] + 2, s->temp[0], + lefty = s->llviddsp.add_left_pred(p->data[0] + 2, s->temp[0], width - 2, lefty); if (!(s->flags & AV_CODEC_FLAG_GRAY)) { - leftu = s->hdsp.add_hfyu_left_pred(p->data[1] + 1, s->temp[1], width2 - 1, leftu); - leftv = s->hdsp.add_hfyu_left_pred(p->data[2] + 1, s->temp[2], width2 - 1, leftv); + leftu = s->llviddsp.add_left_pred(p->data[1] + 1, s->temp[1], width2 - 1, leftu); + leftv = s->llviddsp.add_left_pred(p->data[2] + 1, s->temp[2], width2 - 1, leftv); } for (cy = y = 1; y < s->height; y++, cy++) { @@ -1053,11 +1054,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ydst = p->data[0] + p->linesize[0] * y; - lefty = s->hdsp.add_hfyu_left_pred(ydst, s->temp[0], + lefty = s->llviddsp.add_left_pred(ydst, s->temp[0], width, lefty); if (s->predictor == PLANE) { if (y > s->interlaced) - s->hdsp.add_bytes(ydst, ydst - fake_ystride, width); + s->llviddsp.add_bytes(ydst, ydst - fake_ystride, width); } y++; if (y >= s->height) @@ -1071,18 +1072,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, vdst = p->data[2] + p->linesize[2] * cy; decode_422_bitstream(s, width); - lefty = s->hdsp.add_hfyu_left_pred(ydst, s->temp[0], + lefty = s->llviddsp.add_left_pred(ydst, s->temp[0], width, lefty); if (!(s->flags & AV_CODEC_FLAG_GRAY)) { - leftu = s->hdsp.add_hfyu_left_pred(udst, s->temp[1], width2, leftu); - leftv = s->hdsp.add_hfyu_left_pred(vdst, s->temp[2], width2, leftv); + leftu = s->llviddsp.add_left_pred(udst, s->temp[1], width2, leftu); + leftv = s->llviddsp.add_left_pred(vdst, s->temp[2], width2, leftv); } if (s->predictor == PLANE) { if (cy > s->interlaced) { - s->hdsp.add_bytes(ydst, ydst - fake_ystride, width); + s->llviddsp.add_bytes(ydst, ydst - fake_ystride, width); if (!(s->flags & AV_CODEC_FLAG_GRAY)) { - s->hdsp.add_bytes(udst, udst - fake_ustride, width2); - s->hdsp.add_bytes(vdst, vdst - fake_vstride, width2); + s->llviddsp.add_bytes(udst, udst - fake_ustride, width2); + s->llviddsp.add_bytes(vdst, vdst - fake_vstride, width2); } } } @@ -1093,11 +1094,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, case MEDIAN: /* first line except first 2 pixels is left predicted */ decode_422_bitstream(s, width - 2); - lefty = s->hdsp.add_hfyu_left_pred(p->data[0] + 2, s->temp[0], + lefty = s->llviddsp.add_left_pred(p->data[0] + 2, s->temp[0], width - 2, lefty); if (!(s->flags & AV_CODEC_FLAG_GRAY)) { - leftu = s->hdsp.add_hfyu_left_pred(p->data[1] + 1, s->temp[1], width2 - 1, leftu); - leftv = s->hdsp.add_hfyu_left_pred(p->data[2] + 1, s->temp[2], width2 - 1, leftv); + leftu = s->llviddsp.add_left_pred(p->data[1] + 1, s->temp[1], width2 - 1, leftu); + leftv = s->llviddsp.add_left_pred(p->data[2] + 1, s->temp[2], width2 - 1, leftv); } cy = y = 1; @@ -1105,11 +1106,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, /* second line is left predicted for interlaced case */ if (s->interlaced) { decode_422_bitstream(s, width); - lefty = s->hdsp.add_hfyu_left_pred(p->data[0] + p->linesize[0], + lefty = s->llviddsp.add_left_pred(p->data[0] + p->linesize[0], s->temp[0], width, lefty); if (!(s->flags & AV_CODEC_FLAG_GRAY)) { - leftu = s->hdsp.add_hfyu_left_pred(p->data[1] + p->linesize[2], s->temp[1], width2, leftu); - leftv = s->hdsp.add_hfyu_left_pred(p->data[2] + p->linesize[1], s->temp[2], width2, leftv); + leftu = s->llviddsp.add_left_pred(p->data[1] + p->linesize[2], s->temp[1], width2, leftu); + leftv = s->llviddsp.add_left_pred(p->data[2] + p->linesize[1], s->temp[2], width2, leftv); } y++; cy++; @@ -1117,24 +1118,24 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, /* next 4 pixels are left predicted too */ decode_422_bitstream(s, 4); - lefty = s->hdsp.add_hfyu_left_pred(p->data[0] + fake_ystride, + lefty = s->llviddsp.add_left_pred(p->data[0] + fake_ystride, s->temp[0], 4, lefty); if (!(s->flags & AV_CODEC_FLAG_GRAY)) { - leftu = s->hdsp.add_hfyu_left_pred(p->data[1] + fake_ustride, s->temp[1], 2, leftu); - leftv = s->hdsp.add_hfyu_left_pred(p->data[2] + fake_vstride, s->temp[2], 2, leftv); + leftu = s->llviddsp.add_left_pred(p->data[1] + fake_ustride, s->temp[1], 2, leftu); + leftv = s->llviddsp.add_left_pred(p->data[2] + fake_vstride, s->temp[2], 2, leftv); } /* next line except the first 4 pixels is median predicted */ lefttopy = p->data[0][3]; decode_422_bitstream(s, width - 4); - s->hdsp.add_hfyu_median_pred(p->data[0] + fake_ystride + 4, + s->llviddsp.add_median_pred(p->data[0] + fake_ystride + 4, p->data[0] + 4, s->temp[0], width - 4, &lefty, &lefttopy); if (!(s->flags & AV_CODEC_FLAG_GRAY)) { lefttopu = p->data[1][1]; lefttopv = p->data[2][1]; - s->hdsp.add_hfyu_median_pred(p->data[1] + fake_ustride + 2, p->data[1] + 2, s->temp[1], width2 - 2, &leftu, &lefttopu); - s->hdsp.add_hfyu_median_pred(p->data[2] + fake_vstride + 2, p->data[2] + 2, s->temp[2], width2 - 2, &leftv, &lefttopv); + s->llviddsp.add_median_pred(p->data[1] + fake_ustride + 2, p->data[1] + 2, s->temp[1], width2 - 2, &leftu, &lefttopu); + s->llviddsp.add_median_pred(p->data[2] + fake_vstride + 2, p->data[2] + 2, s->temp[2], width2 - 2, &leftv, &lefttopv); } y++; cy++; @@ -1146,7 +1147,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, while (2 * cy > y) { decode_gray_bitstream(s, width); ydst = p->data[0] + p->linesize[0] * y; - s->hdsp.add_hfyu_median_pred(ydst, ydst - fake_ystride, + s->llviddsp.add_median_pred(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); y++; @@ -1162,12 +1163,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, udst = p->data[1] + p->linesize[1] * cy; vdst = p->data[2] + p->linesize[2] * cy; - s->hdsp.add_hfyu_median_pred(ydst, ydst - fake_ystride, + s->llviddsp.add_median_pred(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); if (!(s->flags & AV_CODEC_FLAG_GRAY)) { - s->hdsp.add_hfyu_median_pred(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu); - s->hdsp.add_hfyu_median_pred(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv); + s->llviddsp.add_median_pred(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu); + s->llviddsp.add_median_pred(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv); } } @@ -1210,7 +1211,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (s->bitstream_bpp != 32) left[A] = 0; if (y < s->height - 1 - s->interlaced) { - s->hdsp.add_bytes(p->data[0] + p->linesize[0] * y, + s->llviddsp.add_bytes(p->data[0] + p->linesize[0] * y, p->data[0] + p->linesize[0] * y + fake_ystride, 4 * width); } diff --git a/libavcodec/huffyuvdsp.c b/libavcodec/huffyuvdsp.c index e8a05f6..2adfc19 100644 --- a/libavcodec/huffyuvdsp.c +++ b/libavcodec/huffyuvdsp.c @@ -23,64 +23,6 @@ #include "mathops.h" #include "huffyuvdsp.h" -// 0x7f7f7f7f or 0x7f7f7f7f7f7f7f7f or whatever, depending on the cpu's native arithmetic size -#define pb_7f (~0UL / 255 * 0x7f) -#define pb_80 (~0UL / 255 * 0x80) - -static void add_bytes_c(uint8_t *dst, uint8_t *src, intptr_t w) -{ - long i; - - for (i = 0; i <= w - (int) sizeof(long); i += sizeof(long)) { - long a = *(long *) (src + i); - long b = *(long *) (dst + i); - *(long *) (dst + i) = ((a & pb_7f) + (b & pb_7f)) ^ ((a ^ b) & pb_80); - } - for (; i < w; i++) - dst[i + 0] += src[i + 0]; -} - -static void add_hfyu_median_pred_c(uint8_t *dst, const uint8_t *src1, - const uint8_t *diff, intptr_t w, - int *left, int *left_top) -{ - int i; - uint8_t l, lt; - - l = *left; - lt = *left_top; - - for (i = 0; i < w; i++) { - l = mid_pred(l, src1[i], (l + src1[i] - lt) & 0xFF) + diff[i]; - lt = src1[i]; - dst[i] = l; - } - - *left = l; - *left_top = lt; -} - -static int add_hfyu_left_pred_c(uint8_t *dst, const uint8_t *src, intptr_t w, - int acc) -{ - int i; - - for (i = 0; i < w - 1; i++) { - acc += src[i]; - dst[i] = acc; - i++; - acc += src[i]; - dst[i] = acc; - } - - for (; i < w; i++) { - acc += src[i]; - dst[i] = acc; - } - - return acc; -} - static void add_hfyu_left_pred_bgr32_c(uint8_t *dst, const uint8_t *src, intptr_t w, uint8_t *left) { @@ -107,9 +49,6 @@ static void add_hfyu_left_pred_bgr32_c(uint8_t *dst, const uint8_t *src, av_cold void ff_huffyuvdsp_init(HuffYUVDSPContext *c) { - c->add_bytes = add_bytes_c; - c->add_hfyu_median_pred = add_hfyu_median_pred_c; - c->add_hfyu_left_pred = add_hfyu_left_pred_c; c->add_hfyu_left_pred_bgr32 = add_hfyu_left_pred_bgr32_c; if (ARCH_X86) diff --git a/libavcodec/huffyuvdsp.h b/libavcodec/huffyuvdsp.h index db37728..eaad1af 100644 --- a/libavcodec/huffyuvdsp.h +++ b/libavcodec/huffyuvdsp.h @@ -35,13 +35,6 @@ #endif typedef struct HuffYUVDSPContext { - void (*add_bytes)(uint8_t *dst /* align 16 */, uint8_t *src /* align 16 */, - intptr_t w); - void (*add_hfyu_median_pred)(uint8_t *dst, const uint8_t *top, - const uint8_t *diff, intptr_t w, - int *left, int *left_top); - int (*add_hfyu_left_pred)(uint8_t *dst, const uint8_t *src, - intptr_t w, int left); void (*add_hfyu_left_pred_bgr32)(uint8_t *dst, const uint8_t *src, intptr_t w, uint8_t *left); } HuffYUVDSPContext; diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c index 93d1344..96a4b5c 100644 --- a/libavcodec/lagarith.c +++ b/libavcodec/lagarith.c @@ -30,8 +30,8 @@ #include "avcodec.h" #include "get_bits.h" #include "mathops.h" -#include "huffyuvdsp.h" #include "lagarithrac.h" +#include "lossless_videodsp.h" #include "thread.h" enum LagarithFrameType { @@ -50,7 +50,7 @@ enum LagarithFrameType { typedef struct LagarithContext { AVCodecContext *avctx; - HuffYUVDSPContext hdsp; + LLVidDSPContext llviddsp; int zeros; /**< number of consecutive zero bytes encountered */ int zeros_rem; /**< number of zero bytes remaining to output */ uint8_t *rgb_planes; @@ -260,7 +260,7 @@ static void lag_pred_line(LagarithContext *l, uint8_t *buf, if (!line) { /* Left prediction only for first line */ - L = l->hdsp.add_hfyu_left_pred(buf, buf, width, 0); + L = l->llviddsp.add_left_pred(buf, buf, width, 0); } else { /* Left pixel is actually prev_row[width] */ L = buf[width - stride - 1]; @@ -289,7 +289,7 @@ static void lag_pred_line_yuy2(LagarithContext *l, uint8_t *buf, L= buf[0]; if (is_luma) buf[0] = 0; - l->hdsp.add_hfyu_left_pred(buf, buf, width, 0); + l->llviddsp.add_left_pred(buf, buf, width, 0); if (is_luma) buf[0] = L; return; @@ -312,7 +312,7 @@ static void lag_pred_line_yuy2(LagarithContext *l, uint8_t *buf, } else { TL = buf[width - (2 * stride) - 1]; L = buf[width - stride - 1]; - l->hdsp.add_hfyu_median_pred(buf, buf - stride, buf, width, &L, &TL); + l->llviddsp.add_median_pred(buf, buf - stride, buf, width, &L, &TL); } } @@ -725,7 +725,7 @@ static av_cold int lag_decode_init(AVCodecContext *avctx) LagarithContext *l = avctx->priv_data; l->avctx = avctx; - ff_huffyuvdsp_init(&l->hdsp); + ff_llviddsp_init(&l->llviddsp, avctx); return 0; } diff --git a/libavcodec/lossless_videodsp.c b/libavcodec/lossless_videodsp.c index 231c25f..5440ce2 100644 --- a/libavcodec/lossless_videodsp.c +++ b/libavcodec/lossless_videodsp.c @@ -21,6 +21,64 @@ #include "lossless_videodsp.h" #include "libavcodec/mathops.h" +// 0x7f7f7f7f or 0x7f7f7f7f7f7f7f7f or whatever, depending on the cpu's native arithmetic size +#define pb_7f (~0UL / 255 * 0x7f) +#define pb_80 (~0UL / 255 * 0x80) + +static void add_bytes_c(uint8_t *dst, uint8_t *src, intptr_t w) +{ + long i; + + for (i = 0; i <= w - (int) sizeof(long); i += sizeof(long)) { + long a = *(long *) (src + i); + long b = *(long *) (dst + i); + *(long *) (dst + i) = ((a & pb_7f) + (b & pb_7f)) ^ ((a ^ b) & pb_80); + } + for (; i < w; i++) + dst[i + 0] += src[i + 0]; +} + +static void add_median_pred_c(uint8_t *dst, const uint8_t *src1, + const uint8_t *diff, intptr_t w, + int *left, int *left_top) +{ + int i; + uint8_t l, lt; + + l = *left; + lt = *left_top; + + for (i = 0; i < w; i++) { + l = mid_pred(l, src1[i], (l + src1[i] - lt) & 0xFF) + diff[i]; + lt = src1[i]; + dst[i] = l; + } + + *left = l; + *left_top = lt; +} + +static int add_left_pred_c(uint8_t *dst, const uint8_t *src, intptr_t w, + int acc) +{ + int i; + + for (i = 0; i < w - 1; i++) { + acc += src[i]; + dst[i] = acc; + i++; + acc += src[i]; + dst[i] = acc; + } + + for (; i < w; i++) { + acc += src[i]; + dst[i] = acc; + } + + return acc; +} + static void add_int16_c(uint16_t *dst, const uint16_t *src, unsigned mask, int w){ long i; unsigned long pw_lsb = (mask >> 1) * 0x0001000100010001ULL; @@ -117,6 +175,10 @@ static int add_hfyu_left_pred_int16_c(uint16_t *dst, const uint16_t *src, unsign void ff_llviddsp_init(LLVidDSPContext *c, AVCodecContext *avctx) { + c->add_bytes = add_bytes_c; + c->add_median_pred = add_median_pred_c; + c->add_left_pred = add_left_pred_c; + c->add_int16 = add_int16_c; c->diff_int16= diff_int16_c; c->add_hfyu_left_pred_int16 = add_hfyu_left_pred_int16_c; diff --git a/libavcodec/lossless_videodsp.h b/libavcodec/lossless_videodsp.h index 040902e..e8ba175 100644 --- a/libavcodec/lossless_videodsp.h +++ b/libavcodec/lossless_videodsp.h @@ -26,6 +26,14 @@ #include "libavutil/cpu.h" typedef struct LLVidDSPContext { + void (*add_bytes)(uint8_t *dst /* align 16 */, uint8_t *src /* align 16 */, + intptr_t w); + void (*add_median_pred)(uint8_t *dst, const uint8_t *top, + const uint8_t *diff, intptr_t w, + int *left, int *left_top); + int (*add_left_pred)(uint8_t *dst, const uint8_t *src, + intptr_t w, int left); + void (*add_int16)(uint16_t *dst/*align 16*/, const uint16_t *src/*align 16*/, unsigned mask, int w); void (*diff_int16)(uint16_t *dst/*align 16*/, const uint16_t *src1/*align 16*/, const uint16_t *src2/*align 1*/, unsigned mask, int w); @@ -36,5 +44,6 @@ typedef struct LLVidDSPContext { void ff_llviddsp_init(LLVidDSPContext *llviddsp, AVCodecContext *avctx); void ff_llviddsp_init_x86(LLVidDSPContext *llviddsp, AVCodecContext *avctx); +void ff_llviddsp_init_ppc(LLVidDSPContext *llviddsp, AVCodecContext *avctx); #endif //AVCODEC_LOSSLESS_VIDEODSP_H diff --git a/libavcodec/magicyuv.c b/libavcodec/magicyuv.c index 526df6f..4e78ff1 100644 --- a/libavcodec/magicyuv.c +++ b/libavcodec/magicyuv.c @@ -70,7 +70,6 @@ typedef struct MagicYUVContext { int (*huff_build)(VLC *vlc, uint8_t *len); int (*magy_decode_slice)(AVCodecContext *avctx, void *tdata, int j, int threadnr); - HuffYUVDSPContext hdsp; LLVidDSPContext llviddsp; } MagicYUVContext; @@ -353,24 +352,24 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, switch (pred) { case LEFT: dst = p->data[i] + j * sheight * stride; - s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); + s->llviddsp.add_left_pred(dst, dst, width, 0); dst += stride; if (interlaced) { - s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); + s->llviddsp.add_left_pred(dst, dst, width, 0); dst += stride; } for (k = 1 + interlaced; k < height; k++) { - s->hdsp.add_hfyu_left_pred(dst, dst, width, dst[-fake_stride]); + s->llviddsp.add_left_pred(dst, dst, width, dst[-fake_stride]); dst += stride; } break; case GRADIENT: dst = p->data[i] + j * sheight * stride; - s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); + s->llviddsp.add_left_pred(dst, dst, width, 0); left = lefttop = 0; dst += stride; if (interlaced) { - s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); + s->llviddsp.add_left_pred(dst, dst, width, 0); left = lefttop = 0; dst += stride; } @@ -390,15 +389,15 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, case MEDIAN: dst = p->data[i] + j * sheight * stride; lefttop = left = dst[0]; - s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); + s->llviddsp.add_left_pred(dst, dst, width, 0); dst += stride; if (interlaced) { lefttop = left = dst[0]; - s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); + s->llviddsp.add_left_pred(dst, dst, width, 0); dst += stride; } for (k = 1 + interlaced; k < height; k++) { - s->hdsp.add_hfyu_median_pred(dst, dst - fake_stride, + s->llviddsp.add_median_pred(dst, dst - fake_stride, dst, width, &left, &lefttop); lefttop = left = dst[0]; dst += stride; @@ -417,8 +416,8 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, uint8_t *r = p->data[2] + j * s->slice_height * p->linesize[2]; for (i = 0; i < height; i++) { - s->hdsp.add_bytes(b, g, width); - s->hdsp.add_bytes(r, g, width); + s->llviddsp.add_bytes(b, g, width); + s->llviddsp.add_bytes(r, g, width); b += p->linesize[0]; g += p->linesize[1]; r += p->linesize[2]; @@ -698,7 +697,6 @@ static int magy_init_thread_copy(AVCodecContext *avctx) static av_cold int magy_decode_init(AVCodecContext *avctx) { MagicYUVContext *s = avctx->priv_data; - ff_huffyuvdsp_init(&s->hdsp); ff_llviddsp_init(&s->llviddsp, avctx); return 0; } diff --git a/libavcodec/ppc/Makefile b/libavcodec/ppc/Makefile index 56a1398..ae774a0 100644 --- a/libavcodec/ppc/Makefile +++ b/libavcodec/ppc/Makefile @@ -10,8 +10,8 @@ OBJS-$(CONFIG_H264CHROMA) += ppc/h264chroma_init.o OBJS-$(CONFIG_H264DSP) += ppc/h264dsp.o ppc/hpeldsp_altivec.o OBJS-$(CONFIG_H264QPEL) += ppc/h264qpel.o OBJS-$(CONFIG_HPELDSP) += ppc/hpeldsp_altivec.o -OBJS-$(CONFIG_HUFFYUVDSP) += ppc/huffyuvdsp_altivec.o OBJS-$(CONFIG_IDCTDSP) += ppc/idctdsp.o +OBJS-$(CONFIG_LLVIDDSP) += ppc/lossless_videodsp_altivec.o OBJS-$(CONFIG_ME_CMP) += ppc/me_cmp.o OBJS-$(CONFIG_MPEGAUDIODSP) += ppc/mpegaudiodsp_altivec.o OBJS-$(CONFIG_MPEGVIDEO) += ppc/mpegvideo_altivec.o \ diff --git a/libavcodec/ppc/huffyuvdsp_altivec.c b/libavcodec/ppc/lossless_videodsp_altivec.c similarity index 93% rename from libavcodec/ppc/huffyuvdsp_altivec.c rename to libavcodec/ppc/lossless_videodsp_altivec.c index 6701524..e17abaa 100644 --- a/libavcodec/ppc/huffyuvdsp_altivec.c +++ b/libavcodec/ppc/lossless_videodsp_altivec.c @@ -30,7 +30,7 @@ #include "libavutil/ppc/cpu.h" #include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" -#include "libavcodec/huffyuvdsp.h" +#include "libavcodec/lossless_videodsp.h" #if HAVE_ALTIVEC static void add_bytes_altivec(uint8_t *dst, uint8_t *src, intptr_t w) @@ -51,7 +51,7 @@ static void add_bytes_altivec(uint8_t *dst, uint8_t *src, intptr_t w) } #endif /* HAVE_ALTIVEC */ -av_cold void ff_huffyuvdsp_init_ppc(HuffYUVDSPContext *c) +av_cold void ff_llviddsp_init_ppc(LLVidDSPContext *c, AVCodecContext *avctx) { #if HAVE_ALTIVEC if (!PPC_ALTIVEC(av_get_cpu_flags())) diff --git a/libavcodec/utvideo.h b/libavcodec/utvideo.h index 0d10865..3b2fe5f 100644 --- a/libavcodec/utvideo.h +++ b/libavcodec/utvideo.h @@ -30,8 +30,8 @@ #include "libavutil/common.h" #include "avcodec.h" #include "bswapdsp.h" -#include "huffyuvdsp.h" #include "huffyuvencdsp.h" +#include "lossless_videodsp.h" enum { PRED_NONE = 0, @@ -70,8 +70,8 @@ typedef struct UtvideoContext { const AVClass *class; AVCodecContext *avctx; BswapDSPContext bdsp; - HuffYUVDSPContext hdspdec; HuffYUVEncDSPContext hdsp; + LLVidDSPContext llviddsp; uint32_t frame_info_size, flags, frame_info; int planes; diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c index 23b8202..7d1d35b 100644 --- a/libavcodec/utvideodec.c +++ b/libavcodec/utvideodec.c @@ -396,7 +396,7 @@ static void restore_median_planar(UtvideoContext *c, uint8_t *src, int stride, // first line - left neighbour prediction bsrc[0] += 0x80; - c->hdspdec.add_hfyu_left_pred(bsrc, bsrc, width, 0); + c->llviddsp.add_left_pred(bsrc, bsrc, width, 0); bsrc += stride; if (slice_height <= 1) continue; @@ -413,7 +413,7 @@ static void restore_median_planar(UtvideoContext *c, uint8_t *src, int stride, bsrc += stride; // the rest of lines use continuous median prediction for (j = 2; j < slice_height; j++) { - c->hdspdec.add_hfyu_median_pred(bsrc, bsrc - stride, + c->llviddsp.add_median_pred(bsrc, bsrc - stride, bsrc, width, &A, &B); bsrc += stride; } @@ -446,8 +446,8 @@ static void restore_median_planar_il(UtvideoContext *c, uint8_t *src, int stride // first line - left neighbour prediction bsrc[0] += 0x80; - A = c->hdspdec.add_hfyu_left_pred(bsrc, bsrc, width, 0); - c->hdspdec.add_hfyu_left_pred(bsrc + stride, bsrc + stride, width, A); + A = c->llviddsp.add_left_pred(bsrc, bsrc, width, 0); + c->llviddsp.add_left_pred(bsrc + stride, bsrc + stride, width, A); bsrc += stride2; if (slice_height <= 1) continue; @@ -461,14 +461,14 @@ static void restore_median_planar_il(UtvideoContext *c, uint8_t *src, int stride C = B; A = bsrc[i]; } - c->hdspdec.add_hfyu_median_pred(bsrc + stride, bsrc - stride, + c->llviddsp.add_median_pred(bsrc + stride, bsrc - stride, bsrc + stride, width, &A, &B); bsrc += stride2; // the rest of lines use continuous median prediction for (j = 2; j < slice_height; j++) { - c->hdspdec.add_hfyu_median_pred(bsrc, bsrc - stride2, + c->llviddsp.add_median_pred(bsrc, bsrc - stride2, bsrc, width, &A, &B); - c->hdspdec.add_hfyu_median_pred(bsrc + stride, bsrc - stride, + c->llviddsp.add_median_pred(bsrc + stride, bsrc - stride, bsrc + stride, width, &A, &B); bsrc += stride2; } @@ -827,7 +827,7 @@ static av_cold int decode_init(AVCodecContext *avctx) c->avctx = avctx; ff_bswapdsp_init(&c->bdsp); - ff_huffyuvdsp_init(&c->hdspdec); + ff_llviddsp_init(&c->llviddsp, avctx); if (avctx->extradata_size >= 16) { av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d.%d.%d\n", diff --git a/libavcodec/vble.c b/libavcodec/vble.c index 032d9c2..7598d30 100644 --- a/libavcodec/vble.c +++ b/libavcodec/vble.c @@ -29,14 +29,14 @@ #define BITSTREAM_READER_LE #include "avcodec.h" #include "get_bits.h" -#include "huffyuvdsp.h" #include "internal.h" +#include "lossless_videodsp.h" #include "mathops.h" #include "thread.h" typedef struct VBLEContext { AVCodecContext *avctx; - HuffYUVDSPContext hdsp; + LLVidDSPContext llviddsp; int size; uint8_t *val; ///< This array first holds the lengths of vlc symbols and then their value. @@ -102,8 +102,8 @@ static void vble_restore_plane(VBLEContext *ctx, AVFrame *pic, if (i) { left = 0; left_top = dst[-stride]; - ctx->hdsp.add_hfyu_median_pred(dst, dst - stride, val, - width, &left, &left_top); + ctx->llviddsp.add_median_pred(dst, dst - stride, val, + width, &left, &left_top); } else { dst[0] = val[0]; for (j = 1; j < width; j++) @@ -185,7 +185,7 @@ static av_cold int vble_decode_init(AVCodecContext *avctx) /* Stash for later use */ ctx->avctx = avctx; - ff_huffyuvdsp_init(&ctx->hdsp); + ff_llviddsp_init(&ctx->llviddsp, avctx); avctx->pix_fmt = AV_PIX_FMT_YUV420P; avctx->bits_per_raw_sample = 8; diff --git a/libavcodec/x86/huffyuvdsp.asm b/libavcodec/x86/huffyuvdsp.asm index 0dbe598..0befd3b 100644 --- a/libavcodec/x86/huffyuvdsp.asm +++ b/libavcodec/x86/huffyuvdsp.asm @@ -22,196 +22,8 @@ %include "libavutil/x86/x86util.asm" -SECTION_RODATA -cextern pb_15 -pb_zzzzzzzz77777777: times 8 db -1 -pb_7: times 8 db 7 -pb_zzzz3333zzzzbbbb: db -1,-1,-1,-1,3,3,3,3,-1,-1,-1,-1,11,11,11,11 -pb_zz11zz55zz99zzdd: db -1,-1,1,1,-1,-1,5,5,-1,-1,9,9,-1,-1,13,13 - SECTION .text -; void ff_add_hfyu_median_pred_mmxext(uint8_t *dst, const uint8_t *top, -; const uint8_t *diff, int w, -; int *left, int *left_top) -%macro HFYU_MEDIAN 0 -cglobal add_hfyu_median_pred, 6,6,8, dst, top, diff, w, left, left_top - movu m0, [topq] - mova m2, m0 - movd m4, [left_topq] - LSHIFT m2, 1 - mova m1, m0 - por m4, m2 - movd m3, [leftq] - psubb m0, m4 ; t-tl - add dstq, wq - add topq, wq - add diffq, wq - neg wq - jmp .skip -.loop: - movu m4, [topq+wq] - mova m0, m4 - LSHIFT m4, 1 - por m4, m1 - mova m1, m0 ; t - psubb m0, m4 ; t-tl -.skip: - movu m2, [diffq+wq] -%assign i 0 -%rep mmsize - mova m4, m0 - paddb m4, m3 ; t-tl+l - mova m5, m3 - pmaxub m3, m1 - pminub m5, m1 - pminub m3, m4 - pmaxub m3, m5 ; median - paddb m3, m2 ; +residual -%if i==0 - mova m7, m3 - LSHIFT m7, mmsize-1 -%else - mova m6, m3 - RSHIFT m7, 1 - LSHIFT m6, mmsize-1 - por m7, m6 -%endif -%if iadd_hfyu_median_pred = add_hfyu_median_pred_cmov; -#endif - if (ARCH_X86_32 && EXTERNAL_MMX(cpu_flags)) { - c->add_bytes = ff_add_bytes_mmx; c->add_hfyu_left_pred_bgr32 = ff_add_hfyu_left_pred_bgr32_mmx; } - if (ARCH_X86_32 && EXTERNAL_MMXEXT(cpu_flags)) { - /* slower than cmov version on AMD */ - if (!(cpu_flags & AV_CPU_FLAG_3DNOW)) - c->add_hfyu_median_pred = ff_add_hfyu_median_pred_mmxext; - } - if (EXTERNAL_SSE2(cpu_flags)) { - c->add_bytes = ff_add_bytes_sse2; - c->add_hfyu_median_pred = ff_add_hfyu_median_pred_sse2; c->add_hfyu_left_pred_bgr32 = ff_add_hfyu_left_pred_bgr32_sse2; } - - if (EXTERNAL_SSSE3(cpu_flags)) { - c->add_hfyu_left_pred = ff_add_hfyu_left_pred_ssse3; - if (cpu_flags & AV_CPU_FLAG_SSE4) // not really SSE4, just slow on Conroe - c->add_hfyu_left_pred = ff_add_hfyu_left_pred_sse4; - } } diff --git a/libavcodec/x86/lossless_videodsp.asm b/libavcodec/x86/lossless_videodsp.asm index f06fcdf..a6ce5fe 100644 --- a/libavcodec/x86/lossless_videodsp.asm +++ b/libavcodec/x86/lossless_videodsp.asm @@ -24,13 +24,199 @@ SECTION_RODATA +cextern pb_15 +pb_zzzzzzzz77777777: times 8 db -1 +pb_7: times 8 db 7 pb_ef: times 8 db 14,15 pb_67: times 8 db 6, 7 +pb_zzzz3333zzzzbbbb: db -1,-1,-1,-1,3,3,3,3,-1,-1,-1,-1,11,11,11,11 +pb_zz11zz55zz99zzdd: db -1,-1,1,1,-1,-1,5,5,-1,-1,9,9,-1,-1,13,13 pb_zzzz2323zzzzabab: db -1,-1,-1,-1, 2, 3, 2, 3,-1,-1,-1,-1,10,11,10,11 pb_zzzzzzzz67676767: db -1,-1,-1,-1,-1,-1,-1,-1, 6, 7, 6, 7, 6, 7, 6, 7 SECTION .text +; void ff_add_median_pred_mmxext(uint8_t *dst, const uint8_t *top, +; const uint8_t *diff, int w, +; int *left, int *left_top) +%macro MEDIAN_PRED 0 +cglobal add_median_pred, 6,6,8, dst, top, diff, w, left, left_top + movu m0, [topq] + mova m2, m0 + movd m4, [left_topq] + LSHIFT m2, 1 + mova m1, m0 + por m4, m2 + movd m3, [leftq] + psubb m0, m4 ; t-tl + add dstq, wq + add topq, wq + add diffq, wq + neg wq + jmp .skip +.loop: + movu m4, [topq+wq] + mova m0, m4 + LSHIFT m4, 1 + por m4, m1 + mova m1, m0 ; t + psubb m0, m4 ; t-tl +.skip: + movu m2, [diffq+wq] +%assign i 0 +%rep mmsize + mova m4, m0 + paddb m4, m3 ; t-tl+l + mova m5, m3 + pmaxub m3, m1 + pminub m5, m1 + pminub m3, m4 + pmaxub m3, m5 ; median + paddb m3, m2 ; +residual +%if i==0 + mova m7, m3 + LSHIFT m7, mmsize-1 +%else + mova m6, m3 + RSHIFT m7, 1 + LSHIFT m6, mmsize-1 + por m7, m6 +%endif +%if ipix_fmt); - if (EXTERNAL_MMX(cpu_flags)) { +#if HAVE_INLINE_ASM && HAVE_7REGS && ARCH_X86_32 + if (cpu_flags & AV_CPU_FLAG_CMOV) + c->add_median_pred = add_median_pred_cmov; +#endif + + if (ARCH_X86_32 && EXTERNAL_MMX(cpu_flags)) { + c->add_bytes = ff_add_bytes_mmx; + c->add_int16 = ff_add_int16_mmx; c->diff_int16 = ff_diff_int16_mmx; } + + if (ARCH_X86_32 && EXTERNAL_MMXEXT(cpu_flags)) { + /* slower than cmov version on AMD */ + if (!(cpu_flags & AV_CPU_FLAG_3DNOW)) + c->add_median_pred = ff_add_median_pred_mmxext; + } if (EXTERNAL_MMXEXT(cpu_flags) && pix_desc && pix_desc->comp[0].depth<16) { c->add_hfyu_median_pred_int16 = ff_add_hfyu_median_pred_int16_mmxext; @@ -48,11 +115,18 @@ void ff_llviddsp_init_x86(LLVidDSPContext *c, AVCodecContext *avctx) } if (EXTERNAL_SSE2(cpu_flags)) { + c->add_bytes = ff_add_bytes_sse2; + c->add_median_pred = ff_add_median_pred_sse2; + c->add_int16 = ff_add_int16_sse2; c->diff_int16 = ff_diff_int16_sse2; } if (EXTERNAL_SSSE3(cpu_flags)) { + c->add_left_pred = ff_add_left_pred_ssse3; + if (cpu_flags & AV_CPU_FLAG_SSE4) // not really SSE4, just slow on Conroe + c->add_left_pred = ff_add_left_pred_sse4; + c->add_hfyu_left_pred_int16 = ff_add_hfyu_left_pred_int16_ssse3; }