Commit d7806238 authored by Christophe GISQUET's avatar Christophe GISQUET Committed by Janne Grunau

rv34: Intra 16x16 handling

Extract processing of intra 16x16 blocks from intra macroblock
processing.
Also implement a function performing inverse transform and block
reconstruction for DC-only blocks in 1 pass instead of 2.
parent 3eeb7557
This diff is collapsed.
......@@ -32,7 +32,7 @@
* @{
*/
static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block)
static av_always_inline void rv34_row_transform(int temp[16], const DCTELEM *block)
{
int i;
......@@ -72,6 +72,32 @@ static void rv34_inv_transform_c(DCTELEM *block){
}
}
/**
* Real Video 3.0/4.0 inverse transform + sample reconstruction
* Code is almost the same as in SVQ3, only scaling is different.
*/
static void rv34_idct_add_c(uint8_t *dst, int stride, const DCTELEM *block){
int temp[16];
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
int i;
rv34_row_transform(temp, block);
for(i = 0; i < 4; i++){
const int z0 = 13*(temp[4*0+i] + temp[4*2+i]) + 0x200;
const int z1 = 13*(temp[4*0+i] - temp[4*2+i]) + 0x200;
const int z2 = 7* temp[4*1+i] - 17*temp[4*3+i];
const int z3 = 17* temp[4*1+i] + 7*temp[4*3+i];
dst[0] = cm[ dst[0] + ( (z0 + z3) >> 10 ) ];
dst[1] = cm[ dst[1] + ( (z1 + z2) >> 10 ) ];
dst[2] = cm[ dst[2] + ( (z1 - z2) >> 10 ) ];
dst[3] = cm[ dst[3] + ( (z0 - z3) >> 10 ) ];
dst += stride;
}
}
/**
* RealVideo 3.0/4.0 inverse transform for DC block
*
......@@ -97,6 +123,22 @@ static void rv34_inv_transform_noround_c(DCTELEM *block){
}
}
static void rv34_idct_dc_add_c(uint8_t *dst, int stride, int dc)
{
const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
int i, j;
cm += (13*13*dc + 0x200) >> 10;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
dst[j] = cm[ dst[j] ];
dst += stride;
}
}
static void rv34_inv_transform_dc_c(DCTELEM *block)
{
DCTELEM dc = (13 * 13 * block[0] + 0x200) >> 10;
......@@ -126,6 +168,9 @@ av_cold void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp) {
c->rv34_inv_transform_dc_tab[0] = rv34_inv_transform_dc_c;
c->rv34_inv_transform_dc_tab[1] = rv34_inv_transform_dc_noround_c;
c->rv34_idct_add = rv34_idct_add_c;
c->rv34_idct_dc_add = rv34_idct_dc_add_c;
if (HAVE_NEON)
ff_rv34dsp_init_neon(c, dsp);
if (HAVE_MMX)
......
......@@ -36,6 +36,11 @@ typedef void (*rv40_weight_func)(uint8_t *dst/*align width (8 or 16)*/,
typedef void (*rv34_inv_transform_func)(DCTELEM *block);
typedef void (*rv34_idct_add_func)(uint8_t *dst, int stride,
const DCTELEM *block);
typedef void (*rv34_idct_dc_add_func)(uint8_t *dst, int stride,
int dc);
typedef void (*rv40_weak_loop_filter_func)(uint8_t *src, int stride,
int filter_p1, int filter_q1,
int alpha, int beta,
......@@ -57,6 +62,8 @@ typedef struct RV34DSPContext {
rv40_weight_func rv40_weight_pixels_tab[2];
rv34_inv_transform_func rv34_inv_transform_tab[2];
void (*rv34_inv_transform_dc_tab[2])(DCTELEM *block);
rv34_idct_add_func rv34_idct_add;
rv34_idct_dc_add_func rv34_idct_dc_add;
rv40_weak_loop_filter_func rv40_weak_loop_filter[2];
rv40_strong_loop_filter_func rv40_strong_loop_filter[2];
rv40_loop_filter_strength_func rv40_loop_filter_strength[2];
......
......@@ -35,21 +35,84 @@ SECTION .text
sar %1, 10
%endmacro
%macro rv34_idct_dequant4x4_dc 1
cglobal rv34_idct_dequant4x4_%1_mmx2, 1, 2, 0
%macro rv34_idct 1
cglobal rv34_idct_%1_mmx2, 1, 2, 0
movsx r1, word [r0]
IDCT_DC r1
movd mm0, r1
pshufw mm0, mm0, 0
movq [r0+ 0], mm0
movq [r0+16], mm0
movq [r0+32], mm0
movq [r0+48], mm0
movd m0, r1
pshufw m0, m0, 0
movq [r0+ 0], m0
movq [r0+16], m0
movq [r0+32], m0
movq [r0+48], m0
REP_RET
%endmacro
INIT_MMX
%define IDCT_DC IDCT_DC_ROUND
rv34_idct_dequant4x4_dc dc
rv34_idct dc
%define IDCT_DC IDCT_DC_NOROUND
rv34_idct_dequant4x4_dc dc_noround
rv34_idct dc_noround
; ff_rv34_idct_dc_add_mmx(uint8_t *dst, int stride, int dc);
cglobal rv34_idct_dc_add_mmx, 3, 3
; calculate DC
IDCT_DC_ROUND r2
pxor m1, m1
movd m0, r2
psubw m1, m0
packuswb m0, m0
packuswb m1, m1
punpcklbw m0, m0
punpcklbw m1, m1
punpcklwd m0, m0
punpcklwd m1, m1
; add DC
lea r2, [r0+r1*2]
movh m2, [r0]
movh m3, [r0+r1]
movh m4, [r2]
movh m5, [r2+r1]
paddusb m2, m0
paddusb m3, m0
paddusb m4, m0
paddusb m5, m0
psubusb m2, m1
psubusb m3, m1
psubusb m4, m1
psubusb m5, m1
movh [r0], m2
movh [r0+r1], m3
movh [r2], m4
movh [r2+r1], m5
RET
; ff_rv34_idct_dc_add_sse4(uint8_t *dst, int stride, int dc);
INIT_XMM
cglobal rv34_idct_dc_add_sse4, 3, 3, 6
; load data
IDCT_DC_ROUND r2
pxor m1, m1
; calculate DC
movd m0, r2
lea r2, [r0+r1*2]
movd m2, [r0]
movd m3, [r0+r1]
pshuflw m0, m0, 0
movd m4, [r2]
movd m5, [r2+r1]
punpcklqdq m0, m0
punpckldq m2, m3
punpckldq m4, m5
punpcklbw m2, m1
punpcklbw m4, m1
paddw m2, m0
paddw m4, m0
packuswb m2, m4
movd [r0], m2
pextrd [r0+r1], m2, 1
pextrd [r2], m2, 2
pextrd [r2+r1], m2, 3
RET
......@@ -24,17 +24,23 @@
#include "libavcodec/dsputil.h"
#include "libavcodec/rv34dsp.h"
void ff_rv34_idct_dequant4x4_dc_mmx2(DCTELEM *block);
void ff_rv34_idct_dequant4x4_dc_noround_mmx2(DCTELEM *block);
void ff_rv34_idct_dc_mmx2(DCTELEM *block);
void ff_rv34_idct_dc_noround_mmx2(DCTELEM *block);
void ff_rv34_idct_dc_add_mmx(uint8_t *dst, int stride, int dc);
void ff_rv34_idct_dc_add_sse4(uint8_t *dst, int stride, int dc);
av_cold void ff_rv34dsp_init_x86(RV34DSPContext* c, DSPContext *dsp)
{
#if HAVE_YASM
int mm_flags = av_get_cpu_flags();
if (mm_flags & AV_CPU_FLAG_MMX)
c->rv34_idct_dc_add = ff_rv34_idct_dc_add_mmx;
if (mm_flags & AV_CPU_FLAG_MMX2) {
c->rv34_inv_transform_dc_tab[0] = ff_rv34_idct_dequant4x4_dc_mmx2;
c->rv34_inv_transform_dc_tab[1] = ff_rv34_idct_dequant4x4_dc_noround_mmx2;
c->rv34_inv_transform_dc_tab[0] = ff_rv34_idct_dc_mmx2;
c->rv34_inv_transform_dc_tab[1] = ff_rv34_idct_dc_noround_mmx2;
}
if (mm_flags & AV_CPU_FLAG_SSE4)
c->rv34_idct_dc_add = ff_rv34_idct_dc_add_sse4;
#endif
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment