[FFmpeg-soc] [soc]: r414 - rv40/rv40.c
kostya
subversion at mplayerhq.hu
Sat Jul 14 19:32:24 CEST 2007
Author: kostya
Date: Sat Jul 14 19:32:24 2007
New Revision: 414
Log:
Use separate macroblock output function with intra prediction.
Now it takes significantly less imagination to recognize picture.
Modified:
rv40/rv40.c
Modified: rv40/rv40.c
==============================================================================
--- rv40/rv40.c (original)
+++ rv40/rv40.c Sat Jul 14 19:32:24 2007
@@ -551,14 +551,83 @@ static int rv40_decode_intra_types(RV40D
return 0;
}
+/** Mapping of RV40 intra prediction types to standard H.264 types */
+static const int ittrans[9] = {
+ HOR_PRED, // almost ok
+ VERT_PRED, // ok
+ LEFT_DC_PRED, // ok?
+ DIAG_DOWN_RIGHT_PRED, // ok
+ DIAG_DOWN_LEFT_PRED,
+ VERT_RIGHT_PRED, // ok
+ VERT_LEFT_PRED, //ok
+ HOR_DOWN_PRED,
+ HOR_UP_PRED,
+};
+
+static void rv40_output_macroblock(RV40DecContext *r, int *intra_types, int cbp, int is16)
+{
+ MpegEncContext *s = &r->s;
+ DSPContext *dsp = &s->dsp;
+ int i, j, x, y;
+ uint8_t *Y, *YY, *PY;
+ int no_up, no_left, itype;
+
+ no_up = s->first_slice_line;
+ Y = s->dest[0];
+ if(!is16){
+ for(j = 0; j < 4; j++){
+ no_left = !s->mb_x || (s->mb_x == s->resync_mb_x && s->first_slice_line);
+ for(YY = Y, i = 0; i < 4; i++, cbp >>= 1, no_left = 0, YY += 4){
+ itype = ittrans[intra_types[i]];
+ if(no_up && no_left)
+ itype = DC_128_PRED;
+ else if(no_up)
+ itype = HOR_PRED;
+ else if(no_left)
+ itype = VERT_PRED;
+ /* silly RV40 predictor assumes that blocks are aligned in one row
+ so first block may reference block from the previous row
+ or last block from the previous macroblock
+ */
+ if(!i && !j)
+ PY = YY - 1 + s->linesize * 12;
+ else
+ PY = YY - 1;
+ r->h.pred4x4[itype](YY, PY, YY - s->linesize + 4, s->linesize);
+ if(!(cbp & 1)) continue;
+ /* add_pixels_clamped for 4x4 block */
+ for(y = 0; y < 4; y++)
+ for(x = 0; x < 4; x++)
+ YY[x + y * s->linesize] = av_clip_uint8(YY[x + y * s->linesize] + s->block[(i>>1)+(j&2)][(i&1)*4+(j&1)*32+x+y*8]);
+ }
+ no_up = 0;
+ Y += s->linesize * 4;
+ intra_types += r->intra_types_stride;
+ }
+ }else{
+ no_left = !s->mb_x || (s->mb_x == s->resync_mb_x && s->first_slice_line);
+ if(no_up && no_left)
+ r->h.pred16x16[DC_128_PRED8x8](Y, s->linesize);
+ else if(no_up)
+ r->h.pred16x16[HOR_PRED8x8](Y, s->linesize);
+ else if(no_left)
+ r->h.pred16x16[VERT_PRED8x8](Y, s->linesize);
+ else
+ r->h.pred16x16[intra_types[0]](Y, s->linesize);
+ dsp->add_pixels_clamped(s->block[0], Y, s->current_picture.linesize[0]);
+ dsp->add_pixels_clamped(s->block[1], Y + 8, s->current_picture.linesize[0]);
+ Y += s->current_picture.linesize[0] * 8;
+ dsp->add_pixels_clamped(s->block[2], Y, s->current_picture.linesize[0]);
+ dsp->add_pixels_clamped(s->block[3], Y + 8, s->current_picture.linesize[0]);
+ }
+}
+
static int rv40_decode_macroblock(RV40DecContext *r, int *intra_types)
{
MpegEncContext *s = &r->s;
GetBitContext *gb = &s->gb;
- DSPContext *dsp = &s->dsp;
- int q, cbp;
+ int q, cbp, cbp2;
int i, blknum, blkoff;
- uint8_t *Y;
int luma_vlc, chroma_vlc;
int is16 = 0;
DCTELEM block16[64];
@@ -586,7 +655,7 @@ static int rv40_decode_macroblock(RV40De
chroma_vlc = 0;
luma_vlc = 2;
}
- cbp = rv40_decode_cbp(gb, &intra_vlcs[2], is16);
+ cbp = cbp2 = rv40_decode_cbp(gb, &intra_vlcs[2], is16);
if(is16){
memset(block16, 0, sizeof(block16));
@@ -616,15 +685,7 @@ static int rv40_decode_macroblock(RV40De
rv40_dequant4x4(s->block[blknum], blkoff, rv40_qscale_tab[r->quant],rv40_qscale_tab[r->quant]);
rv40_intra_inv_transform(s->block[blknum], blkoff);
}
- Y = s->dest[0];
- dsp->put_pixels_clamped(s->block[0], Y, s->current_picture.linesize[0]);
- dsp->put_pixels_clamped(s->block[1], Y + 8, s->current_picture.linesize[0]);
- Y += s->current_picture.linesize[0] * 8;
- dsp->put_pixels_clamped(s->block[2], Y, s->current_picture.linesize[0]);
- dsp->put_pixels_clamped(s->block[3], Y + 8, s->current_picture.linesize[0]);
-
- dsp->put_pixels_clamped(s->block[4], s->dest[1], s->current_picture.linesize[1]);
- dsp->put_pixels_clamped(s->block[5], s->dest[2], s->current_picture.linesize[2]);
+ rv40_output_macroblock(r, intra_types, cbp2, is16);
return 0;
}
More information about the FFmpeg-soc
mailing list