[svn] / branches / dev-api-3 / xvidcore / src / decoder.c Repository:
ViewVC logotype

Diff of /branches/dev-api-3/xvidcore/src/decoder.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 42, Wed Mar 20 14:02:59 2002 UTC revision 69, Tue Mar 26 11:16:08 2002 UTC
# Line 32  Line 32 
32   *   *
33   *      History:   *      History:
34   *   *
35     *  26.03.2002  interlacing support - moved transfers outside decode loop
36   *      26.12.2001      decoder_mbinter: dequant/idct moved within if(coded) block   *      26.12.2001      decoder_mbinter: dequant/idct moved within if(coded) block
37   *      22.12.2001      block based interpolation   *      22.12.2001      block based interpolation
38   *      01.12.2001      inital version; (c)2001 peter ross <pross@cs.rmit.edu.au>   *      01.12.2001      inital version; (c)2001 peter ross <pross@cs.rmit.edu.au>
# Line 54  Line 55 
55  #include "dct/fdct.h"  #include "dct/fdct.h"
56  #include "utils/mem_transfer.h"  #include "utils/mem_transfer.h"
57  #include "image/interpolate8x8.h"  #include "image/interpolate8x8.h"
58    #include "utils/mbfunctions.h"
59    
60  #include "bitstream/mbcoding.h"  #include "bitstream/mbcoding.h"
61  #include "prediction/mbprediction.h"  #include "prediction/mbprediction.h"
# Line 135  Line 137 
137    
138  // decode an intra macroblock  // decode an intra macroblock
139    
140  void decoder_mbintra(DECODER * dec, MACROBLOCK * mb, int x, int y, uint32_t acpred_flag, uint32_t cbp, Bitstream * bs, int quant, int intra_dc_threshold)  void decoder_mbintra(DECODER * dec,
141                                             MACROBLOCK * pMB,
142                                             const uint32_t x_pos,
143                                             const uint32_t y_pos,
144                                             const uint32_t acpred_flag,
145                                             const uint32_t cbp,
146                                             Bitstream * bs,
147                                             const uint32_t quant,
148                                             const uint32_t intra_dc_threshold)
149  {  {
150          uint32_t k;          CACHE_ALIGN int16_t block[6][64];
151            CACHE_ALIGN int16_t data[6][64];
152    
153          for (k = 0; k < 6; k++)          const uint32_t stride = dec->edged_width;
154            uint32_t i;
155            uint32_t iQuant = pMB->quant;
156            uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
157    
158        pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
159        pU_Cur = dec->cur.u + (y_pos << 3) * (stride >> 1) + (x_pos << 3);
160        pV_Cur = dec->cur.v + (y_pos << 3) * (stride >> 1) + (x_pos << 3);
161    
162            memset(block, 0, sizeof(block));                // clear
163    
164            for (i = 0; i < 6; i++)
165          {          {
166                  uint32_t dcscalar;                  uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);
                 CACHE_ALIGN int16_t block[64];  
                 CACHE_ALIGN int16_t data[64];  
167                  int16_t predictors[8];                  int16_t predictors[8];
168                  int start_coeff;                  int start_coeff;
169    
                 dcscalar = get_dc_scaler(mb->quant, k < 4);  
   
170                  start_timer();                  start_timer();
171                  predict_acdc(dec->mbs, x, y, dec->mb_width, k, block, mb->quant, dcscalar, predictors);                  predict_acdc(dec->mbs, x_pos, y_pos, dec->mb_width, i, block[i], iQuant, iDcScaler, predictors);
172                  if (!acpred_flag)                  if (!acpred_flag)
173                  {                  {
174                          mb->acpred_directions[k] = 0;                          pMB->acpred_directions[i] = 0;
175                  }                  }
176                  stop_prediction_timer();                  stop_prediction_timer();
177    
                 memset(block, 0, 64*sizeof(int16_t));           // clear  
   
178                  if (quant < intra_dc_threshold)                  if (quant < intra_dc_threshold)
179                  {                  {
180                          int dc_size;                          int dc_size;
181                          int dc_dif;                          int dc_dif;
182    
183                          dc_size = k < 4 ?  get_dc_size_lum(bs) : get_dc_size_chrom(bs);                          dc_size = i < 4 ?  get_dc_size_lum(bs) : get_dc_size_chrom(bs);
184                          dc_dif = dc_size ? get_dc_dif(bs, dc_size) : 0 ;                          dc_dif = dc_size ? get_dc_dif(bs, dc_size) : 0 ;
185    
186                          if (dc_size > 8)                          if (dc_size > 8)
# Line 172  Line 188 
188                                  BitstreamSkip(bs, 1);           // marker                                  BitstreamSkip(bs, 1);           // marker
189                          }                          }
190    
191                          block[0] = dc_dif;                          block[i][0] = dc_dif;
192                          start_coeff = 1;                          start_coeff = 1;
193                  }                  }
194                  else                  else
# Line 181  Line 197 
197                  }                  }
198    
199                  start_timer();                  start_timer();
200                  if (cbp & (1 << (5-k)))                 // coded                  if (cbp & (1 << (5-i)))                 // coded
201                  {                  {
202                          get_intra_block(bs, block, mb->acpred_directions[k], start_coeff);                          get_intra_block(bs, block[i], pMB->acpred_directions[i], start_coeff);
203                  }                  }
204                  stop_coding_timer();                  stop_coding_timer();
205    
206                  start_timer();                  start_timer();
207                  add_acdc(mb, k, block, dcscalar, predictors);                  add_acdc(pMB, i, block[i], iDcScaler, predictors);
208                  stop_prediction_timer();                  stop_prediction_timer();
209    
210                  start_timer();                  start_timer();
211                  if (dec->quant_type == 0)                  if (dec->quant_type == 0)
212                  {                  {
213                          dequant_intra(data, block, mb->quant, dcscalar);                          dequant_intra(data[i], block[i], iQuant, iDcScaler);
214                  }                  }
215                  else                  else
216                  {                  {
217                          dequant4_intra(data, block, mb->quant, dcscalar);                          dequant4_intra(data[i], block[i], iQuant, iDcScaler);
218                  }                  }
219                  stop_iquant_timer();                  stop_iquant_timer();
220    
221                  start_timer();                  start_timer();
222                  idct(data);                  idct(data[i]);
223                  stop_idct_timer();                  stop_idct_timer();
224            }
225    
226                  start_timer();                  start_timer();
227                  if (k < 4)          if (dec->interlacing && pMB->field_dct)
                 {  
                         transfer_16to8copy(dec->cur.y + (16*y*dec->edged_width) + 16*x + (4*(k&2)*dec->edged_width) + 8*(k&1), data, dec->edged_width);  
                 }  
                 else if (k == 4)  
228                  {                  {
229                          transfer_16to8copy(dec->cur.u+ 8*y*(dec->edged_width/2) + 8*x, data, (dec->edged_width/2));                  MBFieldToFrame(data);
                 }  
                 else    // if (k == 5)  
                 {  
                         transfer_16to8copy(dec->cur.v + 8*y*(dec->edged_width/2) + 8*x, data, (dec->edged_width/2));  
230                  }                  }
231            stop_interlacing_timer();
232    
233            start_timer();
234            transfer_16to8copy(pY_Cur, data[0], stride);
235            transfer_16to8copy(pY_Cur + 8, data[1], stride);
236            transfer_16to8copy(pY_Cur + 8 * stride, data[2], stride);
237            transfer_16to8copy(pY_Cur + 8 + 8 * stride, data[3], stride);
238            transfer_16to8copy(pU_Cur, data[4], stride / 2);
239            transfer_16to8copy(pV_Cur, data[5], stride / 2);
240                  stop_transfer_timer();                  stop_transfer_timer();
241          }          }
 }  
242    
243    
244    
# Line 235  Line 252 
252    
253  // decode an inter macroblock  // decode an inter macroblock
254    
255  void decoder_mbinter(DECODER * dec, MACROBLOCK * mb, int x, int y, uint32_t acpred_flag, uint32_t cbp, Bitstream * bs, int quant, int rounding)  void decoder_mbinter(DECODER * dec,
256                                             const MACROBLOCK * pMB,
257                                             const uint32_t x_pos,
258                                             const uint32_t y_pos,
259                                             const uint32_t acpred_flag,
260                                             const uint32_t cbp,
261                                             Bitstream * bs,
262                                             const uint32_t quant,
263                                             const uint32_t rounding)
264  {  {
265            CACHE_ALIGN int16_t block[6][64];
266            CACHE_ALIGN int16_t data[6][64];
267    
268          const uint32_t stride = dec->edged_width;          const uint32_t stride = dec->edged_width;
269          const uint32_t stride2 = dec->edged_width / 2;          const uint32_t stride2 = dec->edged_width / 2;
270        uint32_t i;
271        uint32_t iQuant = pMB->quant;
272            uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
273          int uv_dx, uv_dy;          int uv_dx, uv_dy;
         uint32_t k;  
274    
275          if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q)      pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
276        pU_Cur = dec->cur.u + (y_pos << 3) * (stride >> 1) + (x_pos << 3);
277        pV_Cur = dec->cur.v + (y_pos << 3) * (stride >> 1) + (x_pos << 3);
278    
279            if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q)
280          {          {
281                  uv_dx = mb->mvs[0].x;                  uv_dx = pMB->mvs[0].x;
282                  uv_dy = mb->mvs[0].y;                  uv_dy = pMB->mvs[0].y;
283    
284                  uv_dx = (uv_dx & 3) ? (uv_dx >> 1) | 1 : uv_dx / 2;                  uv_dx = (uv_dx & 3) ? (uv_dx >> 1) | 1 : uv_dx / 2;
285                  uv_dy = (uv_dy & 3) ? (uv_dy >> 1) | 1 : uv_dy / 2;                  uv_dy = (uv_dy & 3) ? (uv_dy >> 1) | 1 : uv_dy / 2;
# Line 253  Line 287 
287          else          else
288          {          {
289                  int sum;                  int sum;
290                  sum = mb->mvs[0].x + mb->mvs[1].x + mb->mvs[2].x + mb->mvs[3].x;                  sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;
291                  uv_dx = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2) );                  uv_dx = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2) );
292    
293                  sum = mb->mvs[0].y + mb->mvs[1].y + mb->mvs[2].y + mb->mvs[3].y;                  sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;
294                  uv_dy = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2) );                  uv_dy = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2) );
295          }          }
296    
297          start_timer();          start_timer();
298          interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x,     16*y    , mb->mvs[0].x, mb->mvs[0].y, stride,  rounding);          interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x_pos,     16*y_pos    , pMB->mvs[0].x, pMB->mvs[0].y, stride,  rounding);
299          interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x + 8, 16*y    , mb->mvs[1].x, mb->mvs[1].y, stride,  rounding);          interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x_pos + 8, 16*y_pos    , pMB->mvs[1].x, pMB->mvs[1].y, stride,  rounding);
300          interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x,     16*y + 8, mb->mvs[2].x, mb->mvs[2].y, stride,  rounding);          interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x_pos,     16*y_pos + 8, pMB->mvs[2].x, pMB->mvs[2].y, stride,  rounding);
301          interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x + 8, 16*y + 8, mb->mvs[3].x, mb->mvs[3].y, stride,  rounding);          interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x_pos + 8, 16*y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride,  rounding);
302          interpolate8x8_switch(dec->cur.u, dec->refn.u, 8*x, 8*y, uv_dx, uv_dy, stride2, rounding);          interpolate8x8_switch(dec->cur.u, dec->refn.u, 8*x_pos,      8*y_pos,      uv_dx,         uv_dy,         stride2, rounding);
303          interpolate8x8_switch(dec->cur.v, dec->refn.v, 8*x, 8*y, uv_dx, uv_dy, stride2, rounding);          interpolate8x8_switch(dec->cur.v, dec->refn.v, 8*x_pos,      8*y_pos,      uv_dx,         uv_dy,         stride2, rounding);
304          stop_comp_timer();          stop_comp_timer();
305    
306            for (i = 0; i < 6; i++)
         for (k = 0; k < 6; k++)  
307          {          {
308                  CACHE_ALIGN int16_t block[64];                  if (cbp & (1 << (5-i)))                 // coded
                 CACHE_ALIGN int16_t data[64];  
   
                 if (cbp & (1 << (5-k)))                 // coded  
309                  {                  {
310                          memset(block, 0, 64 * sizeof(int16_t));         // clear                          memset(block[i], 0, 64 * sizeof(int16_t));              // clear
311    
312                          start_timer();                          start_timer();
313                          get_inter_block(bs, block);                          get_inter_block(bs, block[i]);
314                          stop_coding_timer();                          stop_coding_timer();
315    
316                          start_timer();                          start_timer();
317                          if (dec->quant_type == 0)                          if (dec->quant_type == 0)
318                          {                          {
319                                  dequant_inter(data, block, mb->quant);                                  dequant_inter(data[i], block[i], iQuant);
320                          }                          }
321                          else                          else
322                          {                          {
323                                  dequant4_inter(data, block, mb->quant);                                  dequant4_inter(data[i], block[i], iQuant);
324                          }                          }
325                          stop_iquant_timer();                          stop_iquant_timer();
326    
327                          start_timer();                          start_timer();
328                          idct(data);                          idct(data[i]);
329                          stop_idct_timer();                          stop_idct_timer();
   
                         start_timer();  
                         if (k < 4)  
                         {  
                                 transfer_16to8add(dec->cur.y + (16*y + 4*(k&2))*stride + 16*x + 8*(k&1), data, stride);  
330                          }                          }
                         else if (k == 4)  
                         {  
                                 transfer_16to8add(dec->cur.u + 8*y*stride2 + 8*x, data, stride2);  
331                          }                          }
332                          else // k == 5  
333            start_timer();
334            if (pMB->field_dct)
335                          {                          {
336                                  transfer_16to8add(dec->cur.v + 8*y*stride2 + 8*x, data, stride2);                  MBFieldToFrame(data);
337                          }                          }
338            stop_interlacing_timer();
339    
340            start_timer();
341            if (cbp & 32)
342                    transfer_16to8add(pY_Cur, data[0], stride);
343            if (cbp & 16)
344                    transfer_16to8add(pY_Cur + 8, data[1], stride);
345            if (cbp & 8)
346                    transfer_16to8add(pY_Cur + 8 * stride, data[2], stride);
347            if (cbp & 4)
348                    transfer_16to8add(pY_Cur + 8 + 8 * stride, data[3], stride);
349            if (cbp & 2)
350                    transfer_16to8add(pU_Cur, data[4], stride / 2);
351            if (cbp & 1)
352                    transfer_16to8add(pV_Cur, data[5], stride / 2);
353                          stop_transfer_timer();                          stop_transfer_timer();
354                  }                  }
         }  
 }  
   
355    
356    
357  void decoder_iframe(DECODER * dec, Bitstream * bs, int quant, int intra_dc_threshold)  void decoder_iframe(DECODER * dec, Bitstream * bs, int quant, int intra_dc_threshold)
# Line 363  Line 399 
399                          }                          }
400                          mb->quant = quant;                          mb->quant = quant;
401    
402                            if (dec->interlacing)
403                            {
404                                    mb->field_dct = BitstreamGetBit(bs);
405                                    DEBUG1("deci: field_dct: ", mb->field_dct);
406                            }
407    
408                          decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant, intra_dc_threshold);                          decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant, intra_dc_threshold);
409                  }                  }
# Line 426  Line 467 
467          image_swap(&dec->cur, &dec->refn);          image_swap(&dec->cur, &dec->refn);
468    
469          start_timer();          start_timer();
470          image_setedges(&dec->refn, dec->edged_width, dec->edged_height, dec->width, dec->height);          image_setedges(&dec->refn, dec->edged_width, dec->edged_height, dec->width, dec->height, dec->interlacing);
471          stop_edges_timer();          stop_edges_timer();
472    
473          for (y = 0; y < dec->mb_height; y++)          for (y = 0; y < dec->mb_height; y++)
# Line 479  Line 520 
520                                  }                                  }
521                                  mb->quant = quant;                                  mb->quant = quant;
522    
523                                    if (dec->interlacing)
524                                    {
525                                            mb->field_dct = BitstreamGetBit(bs);
526                                            DEBUG1("decp: field_dct: ", mb->field_dct);
527    
528                                  if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q)                                  if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q)
529                                  {                                  {
530                                                    mb->field_pred = BitstreamGetBit(bs);
531                                                    DEBUG1("decp: field_pred: ", mb->field_pred);
532    
533                                                    if (mb->field_pred)
534                                                    {
535                                                            mb->field_for_top = BitstreamGetBit(bs);
536                                                            DEBUG1("decp: field_for_top: ", mb->field_for_top);
537                                                            mb->field_for_bot = BitstreamGetBit(bs);
538                                                            DEBUG1("decp: field_for_bot: ", mb->field_for_bot);
539                                                    }
540                                            }
541                                    }
542    
543                                    if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q)
544                                    {
545                                            if (dec->interlacing && mb->field_pred)
546                                            {
547                                                    get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode);
548                                                    get_motion_vector(dec, bs, x, y, 0, &mb->mvs[1], fcode);
549                                            }
550                                            else
551                                            {
552                                          get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode);                                          get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode);
553                                          mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = mb->mvs[0].x;                                          mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = mb->mvs[0].x;
554                                          mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = mb->mvs[0].y;                                          mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = mb->mvs[0].y;
555                                  }                                  }
556                                    }
557                                  else if (mb->mode == MODE_INTER4V /* || mb->mode == MODE_INTER4V_Q */)                                  else if (mb->mode == MODE_INTER4V /* || mb->mode == MODE_INTER4V_Q */)
558                                  {                                  {
559                                          get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode);                                          get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode);

Legend:
Removed from v.42  
changed lines
  Added in v.69

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4