[cvs] / xvidcore / src / decoder.c Repository:
ViewVC logotype

Diff of /xvidcore/src/decoder.c

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

revision 1.7, Thu Mar 28 20:57:24 2002 UTC revision 1.12, Sun Apr 28 22:12:45 2002 UTC
# Line 1  Line 1 
1  /**************************************************************************  /**************************************************************************
2   *   *
3   *      XVID MPEG-4 VIDEO CODEC   *      XVID MPEG-4 VIDEO CODEC
4   *      decoder main   *  -  Decoder main module  -
5   *   *
6   *      This program is an implementation of a part of one or more MPEG-4   *      This program is an implementation of a part of one or more MPEG-4
7   *      Video tools as specified in ISO/IEC 14496-2 standard.  Those intending   *      Video tools as specified in ISO/IEC 14496-2 standard.  Those intending
# Line 12  Line 12 
12   *      editors and their companies, will have no liability for use of this   *      editors and their companies, will have no liability for use of this
13   *      software or modifications or derivatives thereof.   *      software or modifications or derivatives thereof.
14   *   *
15   *      This program is xvid_free software; you can redistribute it and/or modify   *  This program is free software; you can redistribute it and/or modify
16   *      it under the terms of the GNU General Public License as published by   *      it under the terms of the GNU General Public License as published by
17   *      the xvid_free Software Foundation; either version 2 of the License, or   *  the Free Software Foundation; either version 2 of the License, or
18   *      (at your option) any later version.   *      (at your option) any later version.
19   *   *
20   *      This program is distributed in the hope that it will be useful,   *      This program is distributed in the hope that it will be useful,
# Line 23  Line 23 
23   *      GNU General Public License for more details.   *      GNU General Public License for more details.
24   *   *
25   *      You should have received a copy of the GNU General Public License   *      You should have received a copy of the GNU General Public License
26   *      along with this program; if not, write to the xvid_free Software   *  along with this program; if not, write to the Free Software
27   *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
28   *   *
29   *************************************************************************/   *************************************************************************/
30    
# Line 32  Line 32 
32   *   *
33   *      History:   *      History:
34   *   *
35     *  22.04.2002  add some B-frame decode support;  chenm001 <chenm001@163.com>
36     *  29.03.2002  interlacing fix - compensated block wasn't being used when
37     *              reconstructing blocks, thus artifacts
38     *              interlacing speedup - used transfers to re-interlace
39     *              interlaced decoding should be as fast as progressive now
40   *  26.03.2002  interlacing support - moved transfers outside decode loop   *  26.03.2002  interlacing support - moved transfers outside decode loop
41   *      26.12.2001      decoder_mbinter: dequant/idct moved within if(coded) block   *      26.12.2001      decoder_mbinter: dequant/idct moved within if(coded) block
42   *      22.12.2001      block based interpolation   *  22.12.2001  lock based interpolation
43   *      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>
44   *   *
45     *  $Id$
46     *
47   *************************************************************************/   *************************************************************************/
48    
49  #include <stdlib.h>  #include <stdlib.h>
50  #include <string.h>  // memset  #include <string.h>
51    
52  #include "xvid.h"  #include "xvid.h"
53  #include "portab.h"  #include "portab.h"
# Line 55  Line 62 
62  #include "dct/fdct.h"  #include "dct/fdct.h"
63  #include "utils/mem_transfer.h"  #include "utils/mem_transfer.h"
64  #include "image/interpolate8x8.h"  #include "image/interpolate8x8.h"
 #include "utils/mbfunctions.h"  
65    
66  #include "bitstream/mbcoding.h"  #include "bitstream/mbcoding.h"
67  #include "prediction/mbprediction.h"  #include "prediction/mbprediction.h"
# Line 92  Line 98 
98                  return XVID_ERR_MEMORY;                  return XVID_ERR_MEMORY;
99          }          }
100    
101          if (image_create(&dec->refn, dec->edged_width, dec->edged_height))          if (image_create(&dec->refn[0], dec->edged_width, dec->edged_height))
102          {          {
103                  image_destroy(&dec->cur, dec->edged_width, dec->edged_height);                  image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
104                  xvid_free(dec);                  xvid_free(dec);
105                  return XVID_ERR_MEMORY;                  return XVID_ERR_MEMORY;
106          }          }
107            // add by chenm001 <chenm001@163.com>
108            // for support B-frame to reference last 2 frame
109            if (image_create(&dec->refn[1], dec->edged_width, dec->edged_height))
110            {
111                    image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
112                    image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
113                    xvid_free(dec);
114                    return XVID_ERR_MEMORY;
115            }
116    
117          dec->mbs = xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height, CACHE_LINE);          dec->mbs = xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height, CACHE_LINE);
118          if (dec->mbs == NULL)          if (dec->mbs == NULL)
# Line 108  Line 123 
123          }          }
124    
125          init_timer();          init_timer();
         create_vlc_tables();  
126    
127          return XVID_ERR_OK;          return XVID_ERR_OK;
128  }  }
# Line 117  Line 131 
131  int decoder_destroy(DECODER * dec)  int decoder_destroy(DECODER * dec)
132  {  {
133          xvid_free(dec->mbs);          xvid_free(dec->mbs);
134          image_destroy(&dec->refn, dec->edged_width, dec->edged_height);          image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
135          image_destroy(&dec->cur, dec->edged_width, dec->edged_height);          image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
136          xvid_free(dec);          xvid_free(dec);
137    
         destroy_vlc_tables();  
   
138          write_timer();          write_timer();
139          return XVID_ERR_OK;          return XVID_ERR_OK;
140  }  }
# Line 151  Line 163 
163          DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);          DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);
164          DECLARE_ALIGNED_MATRIX(data,  6, 64, int16_t, CACHE_LINE);          DECLARE_ALIGNED_MATRIX(data,  6, 64, int16_t, CACHE_LINE);
165    
166          const uint32_t stride = dec->edged_width;          uint32_t stride = dec->edged_width;
167            uint32_t stride2 = stride / 2;
168            uint32_t next_block = stride * 8;
169          uint32_t i;          uint32_t i;
170          uint32_t iQuant = pMB->quant;          uint32_t iQuant = pMB->quant;
171          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
172    
173          pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);          pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
174          pU_Cur = dec->cur.u + (y_pos << 3) * (stride >> 1) + (x_pos << 3);          pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
175          pV_Cur = dec->cur.v + (y_pos << 3) * (stride >> 1) + (x_pos << 3);          pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
176    
177          memset(block, 0, 6*64*sizeof(int16_t));         // clear          memset(block, 0, 6*64*sizeof(int16_t));         // clear
178    
# Line 224  Line 238 
238                  stop_idct_timer();                  stop_idct_timer();
239          }          }
240    
         start_timer();  
241          if (dec->interlacing && pMB->field_dct)          if (dec->interlacing && pMB->field_dct)
242          {          {
243                  MBFieldToFrame(data);                  next_block = stride;
244                    stride *= 2;
245          }          }
         stop_interlacing_timer();  
246    
247          start_timer();          start_timer();
248          transfer_16to8copy(pY_Cur,                  &data[0*64], stride);          transfer_16to8copy(pY_Cur,                  &data[0*64], stride);
249          transfer_16to8copy(pY_Cur + 8,              &data[1*64], stride);          transfer_16to8copy(pY_Cur + 8,              &data[1*64], stride);
250          transfer_16to8copy(pY_Cur + 8 * stride,     &data[2*64], stride);          transfer_16to8copy(pY_Cur + next_block,     &data[2*64], stride);
251          transfer_16to8copy(pY_Cur + 8 + 8 * stride, &data[3*64], stride);          transfer_16to8copy(pY_Cur + 8 + next_block, &data[3*64], stride);
252          transfer_16to8copy(pU_Cur,                  &data[4*64], stride / 2);          transfer_16to8copy(pU_Cur,                  &data[4*64], stride2);
253          transfer_16to8copy(pV_Cur,                  &data[5*64], stride / 2);          transfer_16to8copy(pV_Cur,                  &data[5*64], stride2);
254          stop_transfer_timer();          stop_transfer_timer();
255  }  }
256    
# Line 267  Line 280 
280          DECLARE_ALIGNED_MATRIX(block,6, 64, int16_t, CACHE_LINE);          DECLARE_ALIGNED_MATRIX(block,6, 64, int16_t, CACHE_LINE);
281          DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);          DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);
282    
283          const uint32_t stride = dec->edged_width;          uint32_t stride = dec->edged_width;
284          const uint32_t stride2 = dec->edged_width / 2;          uint32_t stride2 = stride / 2;
285            uint32_t next_block = stride * 8;
286          uint32_t i;          uint32_t i;
287          uint32_t iQuant = pMB->quant;          uint32_t iQuant = pMB->quant;
288          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
289          int uv_dx, uv_dy;          int uv_dx, uv_dy;
290    
291          pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);          pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
292          pU_Cur = dec->cur.u + (y_pos << 3) * (stride >> 1) + (x_pos << 3);          pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
293          pV_Cur = dec->cur.v + (y_pos << 3) * (stride >> 1) + (x_pos << 3);          pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
294    
295          if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q)          if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q)
296          {          {
# Line 297  Line 311 
311          }          }
312    
313          start_timer();          start_timer();
314          interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x_pos,     16*y_pos    , pMB->mvs[0].x, pMB->mvs[0].y, stride,  rounding);          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos,     16*y_pos    , pMB->mvs[0].x, pMB->mvs[0].y, stride,  rounding);
315          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);          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos + 8, 16*y_pos    , pMB->mvs[1].x, pMB->mvs[1].y, stride,  rounding);
316          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);          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos,     16*y_pos + 8, pMB->mvs[2].x, pMB->mvs[2].y, stride,  rounding);
317          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);          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos + 8, 16*y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride,  rounding);
318          interpolate8x8_switch(dec->cur.u, dec->refn.u, 8*x_pos,      8*y_pos,      uv_dx,         uv_dy,         stride2, rounding);          interpolate8x8_switch(dec->cur.u, dec->refn[0].u, 8*x_pos,      8*y_pos,      uv_dx,         uv_dy,         stride2, rounding);
319          interpolate8x8_switch(dec->cur.v, dec->refn.v, 8*x_pos,      8*y_pos,      uv_dx,         uv_dy,         stride2, rounding);          interpolate8x8_switch(dec->cur.v, dec->refn[0].v, 8*x_pos,      8*y_pos,      uv_dx,         uv_dy,         stride2, rounding);
320          stop_comp_timer();          stop_comp_timer();
321    
322          for (i = 0; i < 6; i++)          for (i = 0; i < 6; i++)
# Line 332  Line 346 
346                  }                  }
347          }          }
348    
349          start_timer();          if (dec->interlacing && pMB->field_dct)
         if (pMB->field_dct)  
350          {          {
351                  MBFieldToFrame(data);                  next_block = stride;
352                    stride *= 2;
353          }          }
         stop_interlacing_timer();  
354    
355          start_timer();          start_timer();
356          if (cbp & 32)          if (cbp & 32)
# Line 345  Line 358 
358          if (cbp & 16)          if (cbp & 16)
359                  transfer_16to8add(pY_Cur + 8,              &data[1*64], stride);                  transfer_16to8add(pY_Cur + 8,              &data[1*64], stride);
360          if (cbp & 8)          if (cbp & 8)
361                  transfer_16to8add(pY_Cur + 8 * stride,     &data[2*64], stride);                  transfer_16to8add(pY_Cur + next_block,     &data[2*64], stride);
362          if (cbp & 4)          if (cbp & 4)
363                  transfer_16to8add(pY_Cur + 8 + 8 * stride, &data[3*64], stride);                  transfer_16to8add(pY_Cur + 8 + next_block, &data[3*64], stride);
364          if (cbp & 2)          if (cbp & 2)
365                  transfer_16to8add(pU_Cur,                  &data[4*64], stride / 2);                  transfer_16to8add(pU_Cur,                  &data[4*64], stride2);
366          if (cbp & 1)          if (cbp & 1)
367                  transfer_16to8add(pV_Cur,                  &data[5*64], stride / 2);                  transfer_16to8add(pV_Cur,                  &data[5*64], stride2);
368          stop_transfer_timer();          stop_transfer_timer();
369  }  }
370    
# Line 470  Line 483 
483    
484          uint32_t x, y;          uint32_t x, y;
485    
         image_swap(&dec->cur, &dec->refn);  
   
486          start_timer();          start_timer();
487          image_setedges(&dec->refn, dec->edged_width, dec->edged_height, dec->width, dec->height, dec->interlacing);          image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height, dec->width, dec->height, dec->interlacing);
488          stop_edges_timer();          stop_edges_timer();
489    
490          for (y = 0; y < dec->mb_height; y++)          for (y = 0; y < dec->mb_height; y++)
# Line 589  Line 600 
600                                  start_timer();                                  start_timer();
601    
602                                  transfer8x8_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x),                                  transfer8x8_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x),
603                                                   dec->refn.y + (16*y)*dec->edged_width + (16*x),                                                   dec->refn[0].y + (16*y)*dec->edged_width + (16*x),
604                                                   dec->edged_width);                                                   dec->edged_width);
605    
606                                  transfer8x8_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x+8),                                  transfer8x8_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x+8),
607                                                   dec->refn.y + (16*y)*dec->edged_width + (16*x+8),                                                   dec->refn[0].y + (16*y)*dec->edged_width + (16*x+8),
608                                                   dec->edged_width);                                                   dec->edged_width);
609    
610                                  transfer8x8_copy(dec->cur.y + (16*y+8)*dec->edged_width + (16*x),                                  transfer8x8_copy(dec->cur.y + (16*y+8)*dec->edged_width + (16*x),
611                                                   dec->refn.y + (16*y+8)*dec->edged_width + (16*x),                                                   dec->refn[0].y + (16*y+8)*dec->edged_width + (16*x),
612                                                   dec->edged_width);                                                   dec->edged_width);
613    
614                                  transfer8x8_copy(dec->cur.y + (16*y+8)*dec->edged_width + (16*x+8),                                  transfer8x8_copy(dec->cur.y + (16*y+8)*dec->edged_width + (16*x+8),
615                                                   dec->refn.y + (16*y+8)*dec->edged_width + (16*x+8),                                                   dec->refn[0].y + (16*y+8)*dec->edged_width + (16*x+8),
616                                                   dec->edged_width);                                                   dec->edged_width);
617    
618                                  transfer8x8_copy(dec->cur.u + (8*y)*dec->edged_width/2 + (8*x),                                  transfer8x8_copy(dec->cur.u + (8*y)*dec->edged_width/2 + (8*x),
619                                                   dec->refn.u + (8*y)*dec->edged_width/2 + (8*x),                                                   dec->refn[0].u + (8*y)*dec->edged_width/2 + (8*x),
620                                                   dec->edged_width/2);                                                   dec->edged_width/2);
621    
622                                  transfer8x8_copy(dec->cur.v + (8*y)*dec->edged_width/2 + (8*x),                                  transfer8x8_copy(dec->cur.v + (8*y)*dec->edged_width/2 + (8*x),
623                                                   dec->refn.v + (8*y)*dec->edged_width/2 + (8*x),                                                   dec->refn[0].v + (8*y)*dec->edged_width/2 + (8*x),
624                                                   dec->edged_width/2);                                                   dec->edged_width/2);
625    
626                                  stop_transfer_timer();                                  stop_transfer_timer();
# Line 626  Line 637 
637          uint32_t quant;          uint32_t quant;
638          uint32_t fcode;          uint32_t fcode;
639          uint32_t intra_dc_threshold;          uint32_t intra_dc_threshold;
640            uint32_t vop_type;
641    
642          start_global_timer();          start_global_timer();
643    
644          BitstreamInit(&bs, frame->bitstream, frame->length);          BitstreamInit(&bs, frame->bitstream, frame->length);
645    
646          switch (BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode, &intra_dc_threshold))          // add by chenm001 <chenm001@163.com>
647            // for support B-frame to reference last 2 frame
648            vop_type=BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode, &intra_dc_threshold);
649    
650            if (vop_type==I_VOP || vop_type==P_VOP){
651                    image_swap(&dec->refn[0], &dec->refn[1]);
652                    image_swap(&dec->cur, &dec->refn[0]);
653            }
654    
655            switch (vop_type)
656          {          {
657          case P_VOP :          case P_VOP :
658                  decoder_pframe(dec, &bs, rounding, quant, fcode, intra_dc_threshold);                  decoder_pframe(dec, &bs, rounding, quant, fcode, intra_dc_threshold);

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.12

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