mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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.
This commit is contained in:
parent
3eeb755763
commit
d78062386e
@ -982,15 +982,6 @@ static void rv34_pred_4x4_block(RV34DecContext *r, uint8_t *dst, int stride, int
|
|||||||
r->h.pred4x4[itype](dst, prev, stride);
|
r->h.pred4x4[itype](dst, prev, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** add_pixels_clamped for 4x4 block */
|
|
||||||
static void rv34_add_4x4_block(uint8_t *dst, int stride, DCTELEM block[64], int off)
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
for(y = 0; y < 4; y++)
|
|
||||||
for(x = 0; x < 4; x++)
|
|
||||||
dst[x + y*stride] = av_clip_uint8(dst[x + y*stride] + block[off + x+y*8]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int adjust_pred16(int itype, int up, int left)
|
static inline int adjust_pred16(int itype, int up, int left)
|
||||||
{
|
{
|
||||||
if(!up && !left)
|
if(!up && !left)
|
||||||
@ -1007,15 +998,20 @@ static inline int adjust_pred16(int itype, int up, int left)
|
|||||||
return itype;
|
return itype;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int cbp, int is16)
|
static void rv34_output_i16x16(RV34DecContext *r, int8_t *intra_types, int cbp)
|
||||||
{
|
{
|
||||||
MpegEncContext *s = &r->s;
|
LOCAL_ALIGNED_16(DCTELEM, block16, [64]);
|
||||||
DSPContext *dsp = &s->dsp;
|
MpegEncContext *s = &r->s;
|
||||||
int i, j;
|
DSPContext *dsp = &s->dsp;
|
||||||
uint8_t *Y, *U, *V;
|
GetBitContext *gb = &s->gb;
|
||||||
int itype;
|
int q_dc = rv34_qscale_tab[ r->luma_dc_quant_i[s->qscale] ],
|
||||||
int avail[6*8] = {0};
|
q_ac = rv34_qscale_tab[s->qscale];
|
||||||
int idx;
|
uint8_t *dst = s->dest[0];
|
||||||
|
DCTELEM *ptr = s->block[0];
|
||||||
|
int avail[6*8] = {0};
|
||||||
|
int i, j, itype, has_ac;
|
||||||
|
|
||||||
|
memset(block16, 0, 64 * sizeof(*block16));
|
||||||
|
|
||||||
// Set neighbour information.
|
// Set neighbour information.
|
||||||
if(r->avail_cache[1])
|
if(r->avail_cache[1])
|
||||||
@ -1031,52 +1027,142 @@ static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int c
|
|||||||
if(r->avail_cache[9])
|
if(r->avail_cache[9])
|
||||||
avail[24] = avail[32] = 1;
|
avail[24] = avail[32] = 1;
|
||||||
|
|
||||||
Y = s->dest[0];
|
has_ac = rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0, q_dc, q_dc, q_ac);
|
||||||
U = s->dest[1];
|
if(has_ac)
|
||||||
V = s->dest[2];
|
r->rdsp.rv34_inv_transform_tab[1](block16);
|
||||||
if(!is16){
|
else
|
||||||
for(j = 0; j < 4; j++){
|
r->rdsp.rv34_inv_transform_dc_tab[1](block16);
|
||||||
idx = 9 + j*8;
|
|
||||||
for(i = 0; i < 4; i++, cbp >>= 1, Y += 4, idx++){
|
|
||||||
rv34_pred_4x4_block(r, Y, s->linesize, ittrans[intra_types[i]], avail[idx-8], avail[idx-1], avail[idx+7], avail[idx-7]);
|
|
||||||
avail[idx] = 1;
|
|
||||||
if(cbp & 1)
|
|
||||||
rv34_add_4x4_block(Y, s->linesize, s->block[(i>>1)+(j&2)], (i&1)*4+(j&1)*32);
|
|
||||||
}
|
|
||||||
Y += s->linesize * 4 - 4*4;
|
|
||||||
intra_types += r->intra_types_stride;
|
|
||||||
}
|
|
||||||
intra_types -= r->intra_types_stride * 4;
|
|
||||||
fill_rectangle(r->avail_cache + 6, 2, 2, 4, 0, 4);
|
|
||||||
for(j = 0; j < 2; j++){
|
|
||||||
idx = 6 + j*4;
|
|
||||||
for(i = 0; i < 2; i++, cbp >>= 1, idx++){
|
|
||||||
rv34_pred_4x4_block(r, U + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*r->intra_types_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]);
|
|
||||||
rv34_pred_4x4_block(r, V + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*r->intra_types_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]);
|
|
||||||
r->avail_cache[idx] = 1;
|
|
||||||
if(cbp & 0x01)
|
|
||||||
rv34_add_4x4_block(U + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[4], i*4+j*32);
|
|
||||||
if(cbp & 0x10)
|
|
||||||
rv34_add_4x4_block(V + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[5], i*4+j*32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
itype = ittrans16[intra_types[0]];
|
|
||||||
itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
|
|
||||||
r->h.pred16x16[itype](Y, s->linesize);
|
|
||||||
dsp->add_pixels_clamped(s->block[0], Y, s->linesize);
|
|
||||||
dsp->add_pixels_clamped(s->block[1], Y + 8, s->linesize);
|
|
||||||
Y += s->linesize * 8;
|
|
||||||
dsp->add_pixels_clamped(s->block[2], Y, s->linesize);
|
|
||||||
dsp->add_pixels_clamped(s->block[3], Y + 8, s->linesize);
|
|
||||||
|
|
||||||
itype = ittrans16[intra_types[0]];
|
itype = ittrans16[intra_types[0]];
|
||||||
if(itype == PLANE_PRED8x8) itype = DC_PRED8x8;
|
itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
|
||||||
itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
|
r->h.pred16x16[itype](dst, s->linesize);
|
||||||
r->h.pred8x8[itype](U, s->uvlinesize);
|
|
||||||
dsp->add_pixels_clamped(s->block[4], U, s->uvlinesize);
|
dsp->clear_block(ptr);
|
||||||
r->h.pred8x8[itype](V, s->uvlinesize);
|
for(j = 0; j < 4; j++){
|
||||||
dsp->add_pixels_clamped(s->block[5], V, s->uvlinesize);
|
for(i = 0; i < 4; i++, cbp >>= 1){
|
||||||
|
int dc = block16[i + j*8];
|
||||||
|
|
||||||
|
if(cbp & 1){
|
||||||
|
has_ac = rv34_decode_block(ptr, gb, r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac);
|
||||||
|
}else
|
||||||
|
has_ac = 0;
|
||||||
|
|
||||||
|
if(has_ac){
|
||||||
|
ptr[0] = dc;
|
||||||
|
r->rdsp.rv34_idct_add(dst+4*i, s->linesize, ptr);
|
||||||
|
dsp->clear_block(ptr);
|
||||||
|
}else
|
||||||
|
r->rdsp.rv34_idct_dc_add(dst+4*i, s->linesize, dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += 4*s->linesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
itype = ittrans16[intra_types[0]];
|
||||||
|
if(itype == PLANE_PRED8x8) itype = DC_PRED8x8;
|
||||||
|
itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
|
||||||
|
|
||||||
|
q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
|
||||||
|
q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];
|
||||||
|
|
||||||
|
for(j = 1; j < 3; j++){
|
||||||
|
dst = s->dest[j];
|
||||||
|
r->h.pred8x8[itype](dst, s->uvlinesize);
|
||||||
|
for(i = 0; i < 4; i++, cbp >>= 1){
|
||||||
|
uint8_t *pdst;
|
||||||
|
if(!(cbp & 1)) continue;
|
||||||
|
pdst = dst + (i&1)*4 + (i&2)*2*s->uvlinesize;
|
||||||
|
|
||||||
|
has_ac = rv34_decode_block(ptr, gb, r->cur_vlcs, r->chroma_vlc, 1, q_dc, q_ac, q_ac);
|
||||||
|
if(has_ac){
|
||||||
|
r->rdsp.rv34_idct_add(pdst, s->uvlinesize, ptr);
|
||||||
|
dsp->clear_block(ptr);
|
||||||
|
}else{
|
||||||
|
r->rdsp.rv34_idct_dc_add(pdst, s->uvlinesize, ptr[0]);
|
||||||
|
ptr[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rv34_output_intra(RV34DecContext *r, int8_t *intra_types, int cbp)
|
||||||
|
{
|
||||||
|
MpegEncContext *s = &r->s;
|
||||||
|
DSPContext *dsp = &s->dsp;
|
||||||
|
GetBitContext *gb = &s->gb;
|
||||||
|
DCTELEM *ptr = s->block[0];
|
||||||
|
uint8_t *dst = s->dest[0];
|
||||||
|
int avail[6*8] = {0};
|
||||||
|
int i, j, k;
|
||||||
|
int idx, has_ac;
|
||||||
|
int q_ac, q_dc;
|
||||||
|
|
||||||
|
// Set neighbour information.
|
||||||
|
if(r->avail_cache[1])
|
||||||
|
avail[0] = 1;
|
||||||
|
if(r->avail_cache[2])
|
||||||
|
avail[1] = avail[2] = 1;
|
||||||
|
if(r->avail_cache[3])
|
||||||
|
avail[3] = avail[4] = 1;
|
||||||
|
if(r->avail_cache[4])
|
||||||
|
avail[5] = 1;
|
||||||
|
if(r->avail_cache[5])
|
||||||
|
avail[8] = avail[16] = 1;
|
||||||
|
if(r->avail_cache[9])
|
||||||
|
avail[24] = avail[32] = 1;
|
||||||
|
|
||||||
|
q_ac = rv34_qscale_tab[s->qscale];
|
||||||
|
for(j = 0; j < 4; j++){
|
||||||
|
idx = 9 + j*8;
|
||||||
|
for(i = 0; i < 4; i++, cbp >>= 1, dst += 4, idx++){
|
||||||
|
rv34_pred_4x4_block(r, dst, s->linesize, ittrans[intra_types[i]], avail[idx-8], avail[idx-1], avail[idx+7], avail[idx-7]);
|
||||||
|
avail[idx] = 1;
|
||||||
|
if(!(cbp & 1)) continue;
|
||||||
|
|
||||||
|
has_ac = rv34_decode_block(ptr, gb, r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac);
|
||||||
|
if(has_ac){
|
||||||
|
r->rdsp.rv34_idct_add(dst, s->linesize, ptr);
|
||||||
|
dsp->clear_block(ptr);
|
||||||
|
}else{
|
||||||
|
r->rdsp.rv34_idct_dc_add(dst, s->linesize, ptr[0]);
|
||||||
|
ptr[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst += s->linesize * 4 - 4*4;
|
||||||
|
intra_types += r->intra_types_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
intra_types -= r->intra_types_stride * 4;
|
||||||
|
|
||||||
|
q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
|
||||||
|
q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];
|
||||||
|
|
||||||
|
for(k = 0; k < 2; k++){
|
||||||
|
dst = s->dest[1+k];
|
||||||
|
fill_rectangle(r->avail_cache + 6, 2, 2, 4, 0, 4);
|
||||||
|
|
||||||
|
for(j = 0; j < 2; j++){
|
||||||
|
int* acache = r->avail_cache + 6 + j*4;
|
||||||
|
for(i = 0; i < 2; i++, cbp >>= 1, acache++){
|
||||||
|
int itype = ittrans[intra_types[i*2+j*2*r->intra_types_stride]];
|
||||||
|
rv34_pred_4x4_block(r, dst+4*i, s->uvlinesize, itype, acache[-4], acache[-1], !i && !j, acache[-3]);
|
||||||
|
acache[0] = 1;
|
||||||
|
|
||||||
|
if(!(cbp&1)) continue;
|
||||||
|
|
||||||
|
has_ac = rv34_decode_block(ptr, gb, r->cur_vlcs, r->chroma_vlc, 1, q_dc, q_ac, q_ac);
|
||||||
|
if(has_ac){
|
||||||
|
r->rdsp.rv34_idct_add(dst + 4*i, s->uvlinesize, ptr);
|
||||||
|
dsp->clear_block(ptr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r->rdsp.rv34_idct_dc_add(dst + 4*i, s->uvlinesize, ptr[0]);
|
||||||
|
ptr[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += 4*s->uvlinesize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1185,6 +1271,12 @@ static int rv34_decode_inter_macroblock(RV34DecContext *r, int8_t *intra_types)
|
|||||||
if(cbp == -1)
|
if(cbp == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos])){
|
||||||
|
if(r->is16) rv34_output_i16x16(r, intra_types, cbp);
|
||||||
|
else rv34_output_intra(r, intra_types, cbp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(r->is16){
|
if(r->is16){
|
||||||
int luma_dc_quant = r->block_type == RV34_MB_P_MIX16x16
|
int luma_dc_quant = r->block_type == RV34_MB_P_MIX16x16
|
||||||
? r->luma_dc_quant_p[s->qscale]
|
? r->luma_dc_quant_p[s->qscale]
|
||||||
@ -1243,10 +1335,7 @@ static int rv34_decode_inter_macroblock(RV34DecContext *r, int8_t *intra_types)
|
|||||||
else
|
else
|
||||||
r->rdsp.rv34_inv_transform_dc_tab[0](ptr);
|
r->rdsp.rv34_inv_transform_dc_tab[0](ptr);
|
||||||
}
|
}
|
||||||
if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos]))
|
rv34_apply_differences(r, cbp2);
|
||||||
rv34_output_macroblock(r, intra_types, cbp2, r->is16);
|
|
||||||
else
|
|
||||||
rv34_apply_differences(r, cbp2);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1254,12 +1343,7 @@ static int rv34_decode_inter_macroblock(RV34DecContext *r, int8_t *intra_types)
|
|||||||
static int rv34_decode_intra_macroblock(RV34DecContext *r, int8_t *intra_types)
|
static int rv34_decode_intra_macroblock(RV34DecContext *r, int8_t *intra_types)
|
||||||
{
|
{
|
||||||
MpegEncContext *s = &r->s;
|
MpegEncContext *s = &r->s;
|
||||||
GetBitContext *gb = &s->gb;
|
int cbp, dist;
|
||||||
int cbp, cbp2;
|
|
||||||
int q_dc, q_ac, has_ac;
|
|
||||||
int i, blknum, blkoff;
|
|
||||||
LOCAL_ALIGNED_16(DCTELEM, block16, [64]);
|
|
||||||
int dist;
|
|
||||||
int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
|
int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
|
||||||
|
|
||||||
// Calculate which neighbours are available. Maybe it's worth optimizing too.
|
// Calculate which neighbours are available. Maybe it's worth optimizing too.
|
||||||
@ -1278,74 +1362,21 @@ static int rv34_decode_intra_macroblock(RV34DecContext *r, int8_t *intra_types)
|
|||||||
r->avail_cache[1] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride - 1];
|
r->avail_cache[1] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride - 1];
|
||||||
|
|
||||||
s->qscale = r->si.quant;
|
s->qscale = r->si.quant;
|
||||||
cbp = cbp2 = rv34_decode_intra_mb_header(r, intra_types);
|
cbp = rv34_decode_intra_mb_header(r, intra_types);
|
||||||
r->cbp_luma [mb_pos] = cbp;
|
r->cbp_luma [mb_pos] = cbp;
|
||||||
r->cbp_chroma[mb_pos] = cbp >> 16;
|
r->cbp_chroma[mb_pos] = cbp >> 16;
|
||||||
r->deblock_coefs[mb_pos] = 0xFFFF;
|
r->deblock_coefs[mb_pos] = 0xFFFF;
|
||||||
s->current_picture_ptr->f.qscale_table[mb_pos] = s->qscale;
|
s->current_picture_ptr->f.qscale_table[mb_pos] = s->qscale;
|
||||||
|
|
||||||
if(cbp == -1)
|
if(cbp == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(r->is16){
|
if(r->is16){
|
||||||
int luma_dc_quant = r->block_type == RV34_MB_P_MIX16x16
|
rv34_output_i16x16(r, intra_types, cbp);
|
||||||
? r->luma_dc_quant_p[s->qscale]
|
return 0;
|
||||||
: r->luma_dc_quant_i[s->qscale];
|
|
||||||
q_dc = rv34_qscale_tab[luma_dc_quant];
|
|
||||||
q_ac = rv34_qscale_tab[s->qscale];
|
|
||||||
s->dsp.clear_block(block16);
|
|
||||||
if (rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0, q_dc, q_dc, q_ac))
|
|
||||||
r->rdsp.rv34_inv_transform_tab[1](block16);
|
|
||||||
else
|
|
||||||
r->rdsp.rv34_inv_transform_dc_tab[1](block16);
|
|
||||||
|
|
||||||
q_ac = rv34_qscale_tab[s->qscale];
|
|
||||||
for(i = 0; i < 16; i++, cbp >>= 1){
|
|
||||||
DCTELEM *ptr;
|
|
||||||
blknum = ((i & 2) >> 1) + ((i & 8) >> 2);
|
|
||||||
blkoff = ((i & 1) << 2) + ((i & 4) << 3);
|
|
||||||
ptr = s->block[blknum] + blkoff;
|
|
||||||
if(cbp & 1)
|
|
||||||
has_ac = rv34_decode_block(ptr, gb, r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac);
|
|
||||||
else
|
|
||||||
has_ac = 0;
|
|
||||||
ptr[0] = block16[(i & 3) | ((i & 0xC) << 1)];
|
|
||||||
if(has_ac)
|
|
||||||
r->rdsp.rv34_inv_transform_tab[0](ptr);
|
|
||||||
else
|
|
||||||
r->rdsp.rv34_inv_transform_dc_tab[0](ptr);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
q_ac = rv34_qscale_tab[s->qscale];
|
|
||||||
for(i = 0; i < 16; i++, cbp >>= 1){
|
|
||||||
DCTELEM *ptr;
|
|
||||||
if(!(cbp & 1)) continue;
|
|
||||||
blknum = ((i & 2) >> 1) + ((i & 8) >> 2);
|
|
||||||
blkoff = ((i & 1) << 2) + ((i & 4) << 3);
|
|
||||||
ptr = s->block[blknum] + blkoff;
|
|
||||||
has_ac = rv34_decode_block(ptr, gb, r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac);
|
|
||||||
if(has_ac)
|
|
||||||
r->rdsp.rv34_inv_transform_tab[0](ptr);
|
|
||||||
else
|
|
||||||
r->rdsp.rv34_inv_transform_dc_tab[0](ptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
|
rv34_output_intra(r, intra_types, cbp);
|
||||||
q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];
|
|
||||||
for(; i < 24; i++, cbp >>= 1){
|
|
||||||
DCTELEM *ptr;
|
|
||||||
if(!(cbp & 1)) continue;
|
|
||||||
blknum = ((i & 4) >> 2) + 4;
|
|
||||||
blkoff = ((i & 1) << 2) + ((i & 2) << 4);
|
|
||||||
ptr = s->block[blknum] + blkoff;
|
|
||||||
if (rv34_decode_block(ptr, gb, r->cur_vlcs, r->chroma_vlc, 1, q_dc, q_ac, q_ac))
|
|
||||||
r->rdsp.rv34_inv_transform_tab[0](ptr);
|
|
||||||
else
|
|
||||||
r->rdsp.rv34_inv_transform_dc_tab[0](ptr);
|
|
||||||
}
|
|
||||||
rv34_output_macroblock(r, intra_types, cbp2, r->is16);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
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
|
* 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)
|
static void rv34_inv_transform_dc_c(DCTELEM *block)
|
||||||
{
|
{
|
||||||
DCTELEM dc = (13 * 13 * block[0] + 0x200) >> 10;
|
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[0] = rv34_inv_transform_dc_c;
|
||||||
c->rv34_inv_transform_dc_tab[1] = rv34_inv_transform_dc_noround_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)
|
if (HAVE_NEON)
|
||||||
ff_rv34dsp_init_neon(c, dsp);
|
ff_rv34dsp_init_neon(c, dsp);
|
||||||
if (HAVE_MMX)
|
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_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,
|
typedef void (*rv40_weak_loop_filter_func)(uint8_t *src, int stride,
|
||||||
int filter_p1, int filter_q1,
|
int filter_p1, int filter_q1,
|
||||||
int alpha, int beta,
|
int alpha, int beta,
|
||||||
@ -57,6 +62,8 @@ typedef struct RV34DSPContext {
|
|||||||
rv40_weight_func rv40_weight_pixels_tab[2];
|
rv40_weight_func rv40_weight_pixels_tab[2];
|
||||||
rv34_inv_transform_func rv34_inv_transform_tab[2];
|
rv34_inv_transform_func rv34_inv_transform_tab[2];
|
||||||
void (*rv34_inv_transform_dc_tab[2])(DCTELEM *block);
|
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_weak_loop_filter_func rv40_weak_loop_filter[2];
|
||||||
rv40_strong_loop_filter_func rv40_strong_loop_filter[2];
|
rv40_strong_loop_filter_func rv40_strong_loop_filter[2];
|
||||||
rv40_loop_filter_strength_func rv40_loop_filter_strength[2];
|
rv40_loop_filter_strength_func rv40_loop_filter_strength[2];
|
||||||
|
@ -35,21 +35,84 @@ SECTION .text
|
|||||||
sar %1, 10
|
sar %1, 10
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
%macro rv34_idct_dequant4x4_dc 1
|
%macro rv34_idct 1
|
||||||
cglobal rv34_idct_dequant4x4_%1_mmx2, 1, 2, 0
|
cglobal rv34_idct_%1_mmx2, 1, 2, 0
|
||||||
movsx r1, word [r0]
|
movsx r1, word [r0]
|
||||||
IDCT_DC r1
|
IDCT_DC r1
|
||||||
movd mm0, r1
|
movd m0, r1
|
||||||
pshufw mm0, mm0, 0
|
pshufw m0, m0, 0
|
||||||
movq [r0+ 0], mm0
|
movq [r0+ 0], m0
|
||||||
movq [r0+16], mm0
|
movq [r0+16], m0
|
||||||
movq [r0+32], mm0
|
movq [r0+32], m0
|
||||||
movq [r0+48], mm0
|
movq [r0+48], m0
|
||||||
REP_RET
|
REP_RET
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
INIT_MMX
|
INIT_MMX
|
||||||
%define IDCT_DC IDCT_DC_ROUND
|
%define IDCT_DC IDCT_DC_ROUND
|
||||||
rv34_idct_dequant4x4_dc dc
|
rv34_idct dc
|
||||||
%define IDCT_DC IDCT_DC_NOROUND
|
%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/dsputil.h"
|
||||||
#include "libavcodec/rv34dsp.h"
|
#include "libavcodec/rv34dsp.h"
|
||||||
|
|
||||||
void ff_rv34_idct_dequant4x4_dc_mmx2(DCTELEM *block);
|
void ff_rv34_idct_dc_mmx2(DCTELEM *block);
|
||||||
void ff_rv34_idct_dequant4x4_dc_noround_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)
|
av_cold void ff_rv34dsp_init_x86(RV34DSPContext* c, DSPContext *dsp)
|
||||||
{
|
{
|
||||||
#if HAVE_YASM
|
#if HAVE_YASM
|
||||||
int mm_flags = av_get_cpu_flags();
|
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) {
|
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[0] = ff_rv34_idct_dc_mmx2;
|
||||||
c->rv34_inv_transform_dc_tab[1] = ff_rv34_idct_dequant4x4_dc_noround_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
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user