[FFmpeg-devel] [PATCH 1/5 v2] lossless_videodsp: move shared functions from huffyuvdsp
James Almer
jamrial at gmail.com
Sun Jan 8 21:37:01 EET 2017
Several codecs other than huffyuv use them.
Signed-off-by: James Almer <jamrial at gmail.com>
---
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 i<mmsize-1
- RSHIFT m0, 1
- RSHIFT m1, 1
- RSHIFT m2, 1
-%endif
-%assign i i+1
-%endrep
- movu [dstq+wq], m7
- add wq, mmsize
- jl .loop
- movzx r2d, byte [dstq-1]
- mov [leftq], r2d
- movzx r2d, byte [topq-1]
- mov [left_topq], r2d
- RET
-%endmacro
-
-%if ARCH_X86_32
-INIT_MMX mmxext
-HFYU_MEDIAN
-%endif
-INIT_XMM sse2
-HFYU_MEDIAN
-
-
-%macro ADD_HFYU_LEFT_LOOP 2 ; %1 = dst_is_aligned, %2 = src_is_aligned
- add srcq, wq
- add dstq, wq
- neg wq
-%%.loop:
-%if %2
- mova m1, [srcq+wq]
-%else
- movu m1, [srcq+wq]
-%endif
- mova m2, m1
- psllw m1, 8
- paddb m1, m2
- mova m2, m1
- pshufb m1, m3
- paddb m1, m2
- pshufb m0, m5
- mova m2, m1
- pshufb m1, m4
- paddb m1, m2
-%if mmsize == 16
- mova m2, m1
- pshufb m1, m6
- paddb m1, m2
-%endif
- paddb m0, m1
-%if %1
- mova [dstq+wq], m0
-%else
- movq [dstq+wq], m0
- movhps [dstq+wq+8], m0
-%endif
- add wq, mmsize
- jl %%.loop
- mov eax, mmsize-1
- sub eax, wd
- movd m1, eax
- pshufb m0, m1
- movd eax, m0
- RET
-%endmacro
-
-; int ff_add_hfyu_left_pred(uint8_t *dst, const uint8_t *src, int w, int left)
-INIT_MMX ssse3
-cglobal add_hfyu_left_pred, 3,3,7, dst, src, w, left
-.skip_prologue:
- mova m5, [pb_7]
- mova m4, [pb_zzzz3333zzzzbbbb]
- mova m3, [pb_zz11zz55zz99zzdd]
- movd m0, leftm
- psllq m0, 56
- ADD_HFYU_LEFT_LOOP 1, 1
-
-INIT_XMM sse4
-cglobal add_hfyu_left_pred, 3,3,7, dst, src, w, left
- mova m5, [pb_15]
- mova m6, [pb_zzzzzzzz77777777]
- mova m4, [pb_zzzz3333zzzzbbbb]
- mova m3, [pb_zz11zz55zz99zzdd]
- movd m0, leftm
- pslldq m0, 15
- test srcq, 15
- jnz .src_unaligned
- test dstq, 15
- jnz .dst_unaligned
- ADD_HFYU_LEFT_LOOP 1, 1
-.dst_unaligned:
- ADD_HFYU_LEFT_LOOP 0, 1
-.src_unaligned:
- ADD_HFYU_LEFT_LOOP 0, 0
-
-%macro ADD_BYTES 0
-cglobal add_bytes, 3,4,2, dst, src, w, size
- mov sizeq, wq
- and sizeq, -2*mmsize
- jz .2
- add dstq, sizeq
- add srcq, sizeq
- neg sizeq
-.1:
- mova m0, [srcq + sizeq]
- mova m1, [srcq + sizeq + mmsize]
- paddb m0, [dstq + sizeq]
- paddb m1, [dstq + sizeq + mmsize]
- mova [dstq + sizeq], m0
- mova [dstq + sizeq + mmsize], m1
- add sizeq, 2*mmsize
- jl .1
-.2:
- and wq, 2*mmsize-1
- jz .end
- add dstq, wq
- add srcq, wq
- neg wq
-.3:
- mov sizeb, [srcq + wq]
- add [dstq + wq], sizeb
- inc wq
- jl .3
-.end:
- REP_RET
-%endmacro
-
-%if ARCH_X86_32
-INIT_MMX mmx
-ADD_BYTES
-%endif
-INIT_XMM sse2
-ADD_BYTES
-
; void add_hfyu_left_pred_bgr32(uint8_t *dst, const uint8_t *src,
; intptr_t w, uint8_t *left)
%macro LEFT_BGR32 0
diff --git a/libavcodec/x86/huffyuvdsp_init.c b/libavcodec/x86/huffyuvdsp_init.c
index 3ced3c0..fc87c38 100644
--- a/libavcodec/x86/huffyuvdsp_init.c
+++ b/libavcodec/x86/huffyuvdsp_init.c
@@ -25,93 +25,20 @@
#include "libavutil/x86/cpu.h"
#include "libavcodec/huffyuvdsp.h"
-void ff_add_bytes_mmx(uint8_t *dst, uint8_t *src, intptr_t w);
-void ff_add_bytes_sse2(uint8_t *dst, uint8_t *src, intptr_t w);
-
-void ff_add_hfyu_median_pred_mmxext(uint8_t *dst, const uint8_t *top,
- const uint8_t *diff, intptr_t w,
- int *left, int *left_top);
-void ff_add_hfyu_median_pred_sse2(uint8_t *dst, const uint8_t *top,
- const uint8_t *diff, intptr_t w,
- int *left, int *left_top);
-
-int ff_add_hfyu_left_pred_ssse3(uint8_t *dst, const uint8_t *src,
- intptr_t w, int left);
-int ff_add_hfyu_left_pred_sse4(uint8_t *dst, const uint8_t *src,
- intptr_t w, int left);
-
void ff_add_hfyu_left_pred_bgr32_mmx(uint8_t *dst, const uint8_t *src,
intptr_t w, uint8_t *left);
void ff_add_hfyu_left_pred_bgr32_sse2(uint8_t *dst, const uint8_t *src,
intptr_t w, uint8_t *left);
-#if HAVE_INLINE_ASM && HAVE_7REGS && ARCH_X86_32
-static void add_hfyu_median_pred_cmov(uint8_t *dst, const uint8_t *top,
- const uint8_t *diff, intptr_t w,
- int *left, int *left_top)
-{
- x86_reg w2 = -w;
- x86_reg x;
- int l = *left & 0xff;
- int tl = *left_top & 0xff;
- int t;
- __asm__ volatile (
- "mov %7, %3 \n"
- "1: \n"
- "movzbl (%3, %4), %2 \n"
- "mov %2, %k3 \n"
- "sub %b1, %b3 \n"
- "add %b0, %b3 \n"
- "mov %2, %1 \n"
- "cmp %0, %2 \n"
- "cmovg %0, %2 \n"
- "cmovg %1, %0 \n"
- "cmp %k3, %0 \n"
- "cmovg %k3, %0 \n"
- "mov %7, %3 \n"
- "cmp %2, %0 \n"
- "cmovl %2, %0 \n"
- "add (%6, %4), %b0 \n"
- "mov %b0, (%5, %4) \n"
- "inc %4 \n"
- "jl 1b \n"
- : "+&q"(l), "+&q"(tl), "=&r"(t), "=&q"(x), "+&r"(w2)
- : "r"(dst + w), "r"(diff + w), "rm"(top + w)
- );
- *left = l;
- *left_top = tl;
-}
-#endif
-
av_cold void ff_huffyuvdsp_init_x86(HuffYUVDSPContext *c)
{
int cpu_flags = av_get_cpu_flags();
-#if HAVE_INLINE_ASM && HAVE_7REGS && ARCH_X86_32
- if (cpu_flags & AV_CPU_FLAG_CMOV)
- c->add_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 i<mmsize-1
+ RSHIFT m0, 1
+ RSHIFT m1, 1
+ RSHIFT m2, 1
+%endif
+%assign i i+1
+%endrep
+ movu [dstq+wq], m7
+ add wq, mmsize
+ jl .loop
+ movzx r2d, byte [dstq-1]
+ mov [leftq], r2d
+ movzx r2d, byte [topq-1]
+ mov [left_topq], r2d
+ RET
+%endmacro
+
+%if ARCH_X86_32
+INIT_MMX mmxext
+MEDIAN_PRED
+%endif
+INIT_XMM sse2
+MEDIAN_PRED
+
+
+%macro ADD_LEFT_LOOP 2 ; %1 = dst_is_aligned, %2 = src_is_aligned
+ add srcq, wq
+ add dstq, wq
+ neg wq
+%%.loop:
+%if %2
+ mova m1, [srcq+wq]
+%else
+ movu m1, [srcq+wq]
+%endif
+ mova m2, m1
+ psllw m1, 8
+ paddb m1, m2
+ mova m2, m1
+ pshufb m1, m3
+ paddb m1, m2
+ pshufb m0, m5
+ mova m2, m1
+ pshufb m1, m4
+ paddb m1, m2
+%if mmsize == 16
+ mova m2, m1
+ pshufb m1, m6
+ paddb m1, m2
+%endif
+ paddb m0, m1
+%if %1
+ mova [dstq+wq], m0
+%else
+ movq [dstq+wq], m0
+ movhps [dstq+wq+8], m0
+%endif
+ add wq, mmsize
+ jl %%.loop
+ mov eax, mmsize-1
+ sub eax, wd
+ movd m1, eax
+ pshufb m0, m1
+ movd eax, m0
+ RET
+%endmacro
+
+; int ff_add_left_pred(uint8_t *dst, const uint8_t *src, int w, int left)
+INIT_MMX ssse3
+cglobal add_left_pred, 3,3,7, dst, src, w, left
+.skip_prologue:
+ mova m5, [pb_7]
+ mova m4, [pb_zzzz3333zzzzbbbb]
+ mova m3, [pb_zz11zz55zz99zzdd]
+ movd m0, leftm
+ psllq m0, 56
+ ADD_LEFT_LOOP 1, 1
+
+INIT_XMM sse4
+cglobal add_left_pred, 3,3,7, dst, src, w, left
+ mova m5, [pb_15]
+ mova m6, [pb_zzzzzzzz77777777]
+ mova m4, [pb_zzzz3333zzzzbbbb]
+ mova m3, [pb_zz11zz55zz99zzdd]
+ movd m0, leftm
+ pslldq m0, 15
+ test srcq, 15
+ jnz .src_unaligned
+ test dstq, 15
+ jnz .dst_unaligned
+ ADD_LEFT_LOOP 1, 1
+.dst_unaligned:
+ ADD_LEFT_LOOP 0, 1
+.src_unaligned:
+ ADD_LEFT_LOOP 0, 0
+
+%macro ADD_BYTES 0
+cglobal add_bytes, 3,4,2, dst, src, w, size
+ mov sizeq, wq
+ and sizeq, -2*mmsize
+ jz .2
+ add dstq, sizeq
+ add srcq, sizeq
+ neg sizeq
+.1:
+ mova m0, [srcq + sizeq]
+ mova m1, [srcq + sizeq + mmsize]
+ paddb m0, [dstq + sizeq]
+ paddb m1, [dstq + sizeq + mmsize]
+ mova [dstq + sizeq], m0
+ mova [dstq + sizeq + mmsize], m1
+ add sizeq, 2*mmsize
+ jl .1
+.2:
+ and wq, 2*mmsize-1
+ jz .end
+ add dstq, wq
+ add srcq, wq
+ neg wq
+.3:
+ mov sizeb, [srcq + wq]
+ add [dstq + wq], sizeb
+ inc wq
+ jl .3
+.end:
+ REP_RET
+%endmacro
+
+%if ARCH_X86_32
+INIT_MMX mmx
+ADD_BYTES
+%endif
+INIT_XMM sse2
+ADD_BYTES
+
%macro INT16_LOOP 2 ; %1 = a/u (aligned/unaligned), %2 = add/sub
movd m4, maskd
SPLATW m4, m4
@@ -86,9 +272,11 @@ SECTION .text
RET
%endmacro
+%if ARCH_X86_32
INIT_MMX mmx
cglobal add_int16, 4,4,5, dst, src, mask, w, tmp
INT16_LOOP a, add
+%endif
INIT_XMM sse2
cglobal add_int16, 4,4,5, dst, src, mask, w, tmp
@@ -100,9 +288,11 @@ cglobal add_int16, 4,4,5, dst, src, mask, w, tmp
.unaligned:
INT16_LOOP u, add
+%if ARCH_X86_32
INIT_MMX mmx
cglobal diff_int16, 5,5,5, dst, src1, src2, mask, w, tmp
INT16_LOOP a, sub
+%endif
INIT_XMM sse2
cglobal diff_int16, 5,5,5, dst, src1, src2, mask, w, tmp
diff --git a/libavcodec/x86/lossless_videodsp_init.c b/libavcodec/x86/lossless_videodsp_init.c
index 548d043..797d95a 100644
--- a/libavcodec/x86/lossless_videodsp_init.c
+++ b/libavcodec/x86/lossless_videodsp_init.c
@@ -18,10 +18,27 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "config.h"
+#include "libavutil/x86/asm.h"
#include "../lossless_videodsp.h"
#include "libavutil/pixdesc.h"
#include "libavutil/x86/cpu.h"
+void ff_add_bytes_mmx(uint8_t *dst, uint8_t *src, intptr_t w);
+void ff_add_bytes_sse2(uint8_t *dst, uint8_t *src, intptr_t w);
+
+void ff_add_median_pred_mmxext(uint8_t *dst, const uint8_t *top,
+ const uint8_t *diff, intptr_t w,
+ int *left, int *left_top);
+void ff_add_median_pred_sse2(uint8_t *dst, const uint8_t *top,
+ const uint8_t *diff, intptr_t w,
+ int *left, int *left_top);
+
+int ff_add_left_pred_ssse3(uint8_t *dst, const uint8_t *src,
+ intptr_t w, int left);
+int ff_add_left_pred_sse4(uint8_t *dst, const uint8_t *src,
+ intptr_t w, int left);
+
void ff_add_int16_mmx(uint16_t *dst, const uint16_t *src, unsigned mask, int w);
void ff_add_int16_sse2(uint16_t *dst, const uint16_t *src, unsigned mask, int w);
void ff_diff_int16_mmx (uint16_t *dst, const uint16_t *src1, const uint16_t *src2, unsigned mask, int w);
@@ -31,16 +48,66 @@ int ff_add_hfyu_left_pred_int16_sse4(uint16_t *dst, const uint16_t *src, unsigne
void ff_add_hfyu_median_pred_int16_mmxext(uint16_t *dst, const uint16_t *top, const uint16_t *diff, unsigned mask, int w, int *left, int *left_top);
void ff_sub_hfyu_median_pred_int16_mmxext(uint16_t *dst, const uint16_t *src1, const uint16_t *src2, unsigned mask, int w, int *left, int *left_top);
+#if HAVE_INLINE_ASM && HAVE_7REGS && ARCH_X86_32
+static void add_median_pred_cmov(uint8_t *dst, const uint8_t *top,
+ const uint8_t *diff, intptr_t w,
+ int *left, int *left_top)
+{
+ x86_reg w2 = -w;
+ x86_reg x;
+ int l = *left & 0xff;
+ int tl = *left_top & 0xff;
+ int t;
+ __asm__ volatile (
+ "mov %7, %3 \n"
+ "1: \n"
+ "movzbl (%3, %4), %2 \n"
+ "mov %2, %k3 \n"
+ "sub %b1, %b3 \n"
+ "add %b0, %b3 \n"
+ "mov %2, %1 \n"
+ "cmp %0, %2 \n"
+ "cmovg %0, %2 \n"
+ "cmovg %1, %0 \n"
+ "cmp %k3, %0 \n"
+ "cmovg %k3, %0 \n"
+ "mov %7, %3 \n"
+ "cmp %2, %0 \n"
+ "cmovl %2, %0 \n"
+ "add (%6, %4), %b0 \n"
+ "mov %b0, (%5, %4) \n"
+ "inc %4 \n"
+ "jl 1b \n"
+ : "+&q"(l), "+&q"(tl), "=&r"(t), "=&q"(x), "+&r"(w2)
+ : "r"(dst + w), "r"(diff + w), "rm"(top + w)
+ );
+ *left = l;
+ *left_top = tl;
+}
+#endif
void ff_llviddsp_init_x86(LLVidDSPContext *c, AVCodecContext *avctx)
{
int cpu_flags = av_get_cpu_flags();
const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(avctx->pix_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;
}
--
2.10.2
More information about the ffmpeg-devel
mailing list