[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.73, Tue Sep 13 12:12:15 2005 UTC revision 1.87, Tue Dec 28 19:19:43 2010 UTC
# Line 4  Line 4 
4   *  - Decoder Module -   *  - Decoder Module -
5   *   *
6   *  Copyright(C) 2002      MinChen <chenm001@163.com>   *  Copyright(C) 2002      MinChen <chenm001@163.com>
7   *               2002-2004 Peter Ross <pross@xvid.org>   *               2002-2010 Peter Ross <pross@xvid.org>
8   *   *
9   *  This program is free software ; you can redistribute it and/or modify   *  This program is free software ; you can redistribute it and/or modify
10   *  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
# Line 172  Line 172 
172    dec->width = create->width;    dec->width = create->width;
173    dec->height = create->height;    dec->height = create->height;
174    
175      dec->num_threads = MAX(0, create->num_threads);
176    
177    image_null(&dec->cur);    image_null(&dec->cur);
178    image_null(&dec->refn[0]);    image_null(&dec->refn[0]);
179    image_null(&dec->refn[1]);    image_null(&dec->refn[1]);
# Line 195  Line 197 
197    dec->low_delay = 0;    dec->low_delay = 0;
198    dec->packed_mode = 0;    dec->packed_mode = 0;
199    dec->time_inc_resolution = 1; /* until VOL header says otherwise */    dec->time_inc_resolution = 1; /* until VOL header says otherwise */
200      dec->ver_id = 1;
201    
202      if (create->fourcc == ((int)('X')|((int)('V')<<8)|
203                             ((int)('I')<<16)|((int)('D')<<24))) { /* XVID */
204        dec->bs_version = 0; /* Initially assume oldest xvid version */
205      }
206      else {
207            dec->bs_version = 0xffff; /* Initialize to very high value -> assume bugfree stream */
208      }
209    
210    dec->fixed_dimensions = (dec->width > 0 && dec->height > 0);    dec->fixed_dimensions = (dec->width > 0 && dec->height > 0);
211    
212    if (dec->fixed_dimensions)    if (dec->fixed_dimensions) {
213      return decoder_resize(dec);      int ret = decoder_resize(dec);
214        if (ret == XVID_ERR_MEMORY) create->handle = NULL;
215        return ret;
216      }
217    else    else
218      return 0;      return 0;
219  }  }
# Line 316  Line 330 
330      stop_iquant_timer();      stop_iquant_timer();
331    
332      start_timer();      start_timer();
333      idct(&data[i * 64]);      idct((short * const)&data[i * 64]);
334      stop_idct_timer();      stop_idct_timer();
335    
336    }    }
# Line 406  Line 420 
420    
421        /* iDCT */        /* iDCT */
422        start_timer();        start_timer();
423        idct(&data[0]);        idct((short * const)&data[0]);
424        stop_idct_timer();        stop_idct_timer();
425    
426        /* Add this residual to the predicted block */        /* Add this residual to the predicted block */
# Line 466  Line 480 
480          const uint32_t cbp,          const uint32_t cbp,
481          Bitstream * bs,          Bitstream * bs,
482          const uint32_t rounding,          const uint32_t rounding,
483          const int ref)          const int ref,
484                    const int bvop)
485  {  {
486    uint32_t stride = dec->edged_width;    uint32_t stride = dec->edged_width;
487    uint32_t stride2 = stride / 2;    uint32_t stride2 = stride / 2;
# Line 487  Line 502 
502    
503    start_timer();    start_timer();
504    
505    if (pMB->mode != MODE_INTER4V) { /* INTER, INTER_Q, NOT_CODED, FORWARD, BACKWARD */    if ((pMB->mode != MODE_INTER4V) || (bvop)) { /* INTER, INTER_Q, NOT_CODED, FORWARD, BACKWARD */
506    
507      uv_dx = mv[0].x;      uv_dx = mv[0].x;
508      uv_dy = mv[0].y;      uv_dy = mv[0].y;
# Line 581  Line 596 
596          const uint32_t cbp,          const uint32_t cbp,
597          Bitstream * bs,          Bitstream * bs,
598          const uint32_t rounding,          const uint32_t rounding,
599          const int ref)          const int ref,
600                    const int bvop)
601  {  {
602    uint32_t stride = dec->edged_width;    uint32_t stride = dec->edged_width;
603    uint32_t stride2 = stride / 2;    uint32_t stride2 = stride / 2;
# Line 605  Line 621 
621    
622    start_timer();    start_timer();
623    
624    if(pMB->mode!=MODE_INTER4V)   /* INTER, INTER_Q, NOT_CODED, FORWARD, BACKWARD */    if((pMB->mode!=MODE_INTER4V) || (bvop))   /* INTER, INTER_Q, NOT_CODED, FORWARD, BACKWARD */
625    {    {
626      /* Prepare top field vector */      /* Prepare top field vector */
627      uvtop_dx = DIV2ROUND(mv[0].x);      uvtop_dx = DIV2ROUND(mv[0].x);
# Line 743  Line 759 
759          bound = read_video_packet_header(bs, dec, 0,          bound = read_video_packet_header(bs, dec, 0,
760                &quant, NULL, NULL, &intra_dc_threshold);                &quant, NULL, NULL, &intra_dc_threshold);
761          x = bound % mb_width;          x = bound % mb_width;
762          y = bound / mb_width;          y = MIN((bound / mb_width), (mb_height-1));
763        }        }
764        mb = &dec->mbs[y * dec->mb_width + x];        mb = &dec->mbs[y * dec->mb_width + x];
765    
# Line 970  Line 986 
986          bound = read_video_packet_header(bs, dec, fcode - 1,          bound = read_video_packet_header(bs, dec, fcode - 1,
987            &quant, &fcode, NULL, &intra_dc_threshold);            &quant, &fcode, NULL, &intra_dc_threshold);
988          x = bound % mb_width;          x = bound % mb_width;
989          y = bound / mb_width;          y = MIN((bound / mb_width), (mb_height-1));
990        }        }
991        mb = &dec->mbs[y * dec->mb_width + x];        mb = &dec->mbs[y * dec->mb_width + x];
992    
# Line 1063  Line 1079 
1079    
1080          /* See how to decode */          /* See how to decode */
1081          if(!mb->field_pred)          if(!mb->field_pred)
1082           decoder_mbinter(dec, mb, x, y, cbp, bs, rounding, 0);           decoder_mbinter(dec, mb, x, y, cbp, bs, rounding, 0, 0);
1083          else          else
1084           decoder_mbinter_field(dec, mb, x, y, cbp, bs, rounding, 0);           decoder_mbinter_field(dec, mb, x, y, cbp, bs, rounding, 0, 0);
1085    
1086        } else if (gmc_warp) {  /* a not coded S(GMC)-VOP macroblock */        } else if (gmc_warp) {  /* a not coded S(GMC)-VOP macroblock */
1087          mb->mode = MODE_NOT_CODED_GMC;          mb->mode = MODE_NOT_CODED_GMC;
# Line 1086  Line 1102 
1102          mb->field_pred=0; /* (!) */          mb->field_pred=0; /* (!) */
1103    
1104          decoder_mbinter(dec, mb, x, y, 0, bs,          decoder_mbinter(dec, mb, x, y, 0, bs,
1105                                  rounding, 0);                                  rounding, 0, 0);
1106    
1107          if(dec->out_frm && cp_mb > 0) {          if(dec->out_frm && cp_mb > 0) {
1108            output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,st_mb,y,cp_mb);            output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,st_mb,y,cp_mb);
# Line 1188  Line 1204 
1204      b_uv_dy = (b_uv_dy >> 1) + roundtab_79[b_uv_dy & 0x3];      b_uv_dy = (b_uv_dy >> 1) + roundtab_79[b_uv_dy & 0x3];
1205    
1206    } else {    } else {
1207      uv_dx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;            if (dec->quarterpel) { /* for qpel the /2 shall be done before summation. We've done it right in the encoder in the past. */
1208      uv_dy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;                                                           /* TODO: figure out if we ever did it wrong on the encoder side. If yes, add some workaround */
     b_uv_dx = pMB->b_mvs[0].x + pMB->b_mvs[1].x + pMB->b_mvs[2].x + pMB->b_mvs[3].x;  
     b_uv_dy = pMB->b_mvs[0].y + pMB->b_mvs[1].y + pMB->b_mvs[2].y + pMB->b_mvs[3].y;  
   
     if (dec->quarterpel) {  
1209        if (dec->bs_version <= BS_VERSION_BUGGY_CHROMA_ROUNDING) {        if (dec->bs_version <= BS_VERSION_BUGGY_CHROMA_ROUNDING) {
1210                                  uv_dx = (uv_dx>>1) | (uv_dx&1);                          int z;
1211                                  uv_dy = (uv_dy>>1) | (uv_dy&1);                          uv_dx = 0; uv_dy = 0;
1212                                  b_uv_dx = (b_uv_dx>>1) | (b_uv_dx&1);                          b_uv_dx = 0; b_uv_dy = 0;
1213                                  b_uv_dy = (b_uv_dy>>1) | (b_uv_dy&1);                          for (z = 0; z < 4; z++) {
1214                              uv_dx += ((pMB->mvs[z].x>>1) | (pMB->mvs[z].x&1));
1215                              uv_dy += ((pMB->mvs[z].y>>1) | (pMB->mvs[z].y&1));
1216                              b_uv_dx += ((pMB->b_mvs[z].x>>1) | (pMB->b_mvs[z].x&1));
1217                              b_uv_dy += ((pMB->b_mvs[z].y>>1) | (pMB->b_mvs[z].y&1));
1218                            }
1219                          }                          }
1220                          else {                          else {
1221          uv_dx /= 2;                          uv_dx = (pMB->mvs[0].x / 2) + (pMB->mvs[1].x / 2) + (pMB->mvs[2].x / 2) + (pMB->mvs[3].x / 2);
1222          uv_dy /= 2;                          uv_dy = (pMB->mvs[0].y / 2) + (pMB->mvs[1].y / 2) + (pMB->mvs[2].y / 2) + (pMB->mvs[3].y / 2);
1223          b_uv_dx /= 2;                          b_uv_dx = (pMB->b_mvs[0].x / 2) + (pMB->b_mvs[1].x / 2) + (pMB->b_mvs[2].x / 2) + (pMB->b_mvs[3].x / 2);
1224          b_uv_dy /= 2;                          b_uv_dy = (pMB->b_mvs[0].y / 2) + (pMB->b_mvs[1].y / 2) + (pMB->b_mvs[2].y / 2) + (pMB->b_mvs[3].y / 2);
1225        }        }
1226            } else {
1227          uv_dx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;
1228          uv_dy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;
1229          b_uv_dx = pMB->b_mvs[0].x + pMB->b_mvs[1].x + pMB->b_mvs[2].x + pMB->b_mvs[3].x;
1230          b_uv_dy = pMB->b_mvs[0].y + pMB->b_mvs[1].y + pMB->b_mvs[2].y + pMB->b_mvs[3].y;
1231      }      }
1232    
1233      uv_dx = (uv_dx >> 3) + roundtab_76[uv_dx & 0xf];      uv_dx = (uv_dx >> 3) + roundtab_76[uv_dx & 0xf];
# Line 1324  Line 1346 
1346    return -1;    return -1;
1347  }  }
1348    
1349    static int __inline get_resync_len_b(const int fcode_backward,
1350                                         const int fcode_forward) {
1351      int resync_len = ((fcode_forward>fcode_backward) ? fcode_forward : fcode_backward) - 1;
1352      if (resync_len < 1) resync_len = 1;
1353      return resync_len;
1354    }
1355    
1356  static void  static void
1357  decoder_bframe(DECODER * dec,  decoder_bframe(DECODER * dec,
1358          Bitstream * bs,          Bitstream * bs,
# Line 1335  Line 1364 
1364    VECTOR mv;    VECTOR mv;
1365    const VECTOR zeromv = {0,0};    const VECTOR zeromv = {0,0};
1366    int i;    int i;
1367      int resync_len;
1368    
1369    if (!dec->is_edged[0]) {    if (!dec->is_edged[0]) {
1370      start_timer();      start_timer();
# Line 1352  Line 1382 
1382      stop_edges_timer();      stop_edges_timer();
1383    }    }
1384    
1385      resync_len = get_resync_len_b(fcode_backward, fcode_forward);
1386    for (y = 0; y < dec->mb_height; y++) {    for (y = 0; y < dec->mb_height; y++) {
1387      /* Initialize Pred Motion Vector */      /* Initialize Pred Motion Vector */
1388      dec->p_fmv = dec->p_bmv = zeromv;      dec->p_fmv = dec->p_bmv = zeromv;
1389      for (x = 0; x < dec->mb_width; x++) {      for (x = 0; x < dec->mb_width; x++) {
1390        MACROBLOCK *mb = &dec->mbs[y * dec->mb_width + x];        MACROBLOCK *mb = &dec->mbs[y * dec->mb_width + x];
1391        MACROBLOCK *last_mb = &dec->last_mbs[y * dec->mb_width + x];        MACROBLOCK *last_mb = &dec->last_mbs[y * dec->mb_width + x];
1392        const int fcode_max = (fcode_forward>fcode_backward) ? fcode_forward : fcode_backward;        int intra_dc_threshold; /* fake variable */
       uint32_t intra_dc_threshold; /* fake variable */  
   
       if (check_resync_marker(bs, fcode_max  - 1)) {  
         int bound = read_video_packet_header(bs, dec, fcode_max - 1, &quant,  
                            &fcode_forward, &fcode_backward, &intra_dc_threshold);  
         x = bound % dec->mb_width;  
         y = bound / dec->mb_width;  
         /* reset predicted macroblocks */  
         dec->p_fmv = dec->p_bmv = zeromv;  
       }  
1393    
1394        mv =        mv =
1395        mb->b_mvs[0] = mb->b_mvs[1] = mb->b_mvs[2] = mb->b_mvs[3] =        mb->b_mvs[0] = mb->b_mvs[1] = mb->b_mvs[2] = mb->b_mvs[3] =
# Line 1384  Line 1405 
1405        if (last_mb->mode == MODE_NOT_CODED) {        if (last_mb->mode == MODE_NOT_CODED) {
1406          mb->cbp = 0;          mb->cbp = 0;
1407          mb->mode = MODE_FORWARD;          mb->mode = MODE_FORWARD;
1408          decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 1);          decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 1, 1);
1409          continue;          continue;
1410        }        }
1411    
1412          if (check_resync_marker(bs, resync_len)) {
1413            int bound = read_video_packet_header(bs, dec, resync_len, &quant,
1414                               &fcode_forward, &fcode_backward, &intra_dc_threshold);
1415    
1416                    bound = MAX(0, bound-1); /* valid bound must always be >0 */
1417            x = bound % dec->mb_width;
1418            y = MIN((bound / dec->mb_width), (dec->mb_height-1));
1419            /* reset predicted macroblocks */
1420            dec->p_fmv = dec->p_bmv = zeromv;
1421            /* update resync len with new fcodes */
1422            resync_len = get_resync_len_b(fcode_backward, fcode_forward);
1423                    continue; /* re-init loop */
1424              }
1425    
1426        if (!BitstreamGetBit(bs)) { /* modb=='0' */        if (!BitstreamGetBit(bs)) { /* modb=='0' */
1427          const uint8_t modb2 = BitstreamGetBit(bs);          const uint8_t modb2 = BitstreamGetBit(bs);
1428    
# Line 1467  Line 1502 
1502          get_b_motion_vector(bs, &mb->mvs[0], fcode_backward, dec->p_bmv, dec, x, y);          get_b_motion_vector(bs, &mb->mvs[0], fcode_backward, dec->p_bmv, dec, x, y);
1503          dec->p_bmv = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = mb->mvs[0];          dec->p_bmv = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = mb->mvs[0];
1504    
1505          decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 0);          decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 0, 1);
1506          break;          break;
1507    
1508        case MODE_FORWARD:        case MODE_FORWARD:
1509          get_b_motion_vector(bs, &mb->mvs[0], fcode_forward, dec->p_fmv, dec, x, y);          get_b_motion_vector(bs, &mb->mvs[0], fcode_forward, dec->p_fmv, dec, x, y);
1510          dec->p_fmv = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = mb->mvs[0];          dec->p_fmv = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = mb->mvs[0];
1511    
1512          decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 1);          decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 1, 1);
1513          break;          break;
1514    
1515        default:        default:
# Line 1485  Line 1520 
1520  }  }
1521    
1522  /* perform post processing if necessary, and output the image */  /* perform post processing if necessary, and output the image */
1523  void decoder_output(DECODER * dec, IMAGE * img, MACROBLOCK * mbs,  static void decoder_output(DECODER * dec, IMAGE * img, MACROBLOCK * mbs,
1524            xvid_dec_frame_t * frame, xvid_dec_stats_t * stats,            xvid_dec_frame_t * frame, xvid_dec_stats_t * stats,
1525            int coding_type, int quant)            int coding_type, int quant)
1526  {  {
# Line 1501  Line 1536 
1536      image_copy(&dec->tmp, img, dec->edged_width, dec->height);      image_copy(&dec->tmp, img, dec->edged_width, dec->height);
1537      image_postproc(&dec->postproc, &dec->tmp, dec->edged_width,      image_postproc(&dec->postproc, &dec->tmp, dec->edged_width,
1538               mbs, dec->mb_width, dec->mb_height, dec->mb_width,               mbs, dec->mb_width, dec->mb_height, dec->mb_width,
1539               frame->general, brightness, dec->frames, (coding_type == B_VOP));               frame->general, brightness, dec->frames, (coding_type == B_VOP), dec->num_threads);
1540      img = &dec->tmp;      img = &dec->tmp;
1541    }    }
1542    
# Line 1607  Line 1642 
1642    if (coding_type == -2 || coding_type == -3) { /* vol and/or resize */    if (coding_type == -2 || coding_type == -3) { /* vol and/or resize */
1643    
1644      if (coding_type == -3)      if (coding_type == -3)
1645        decoder_resize(dec);        if (decoder_resize(dec)) return XVID_ERR_MEMORY;
1646    
1647      if(stats) {      if(stats) {
1648        stats->type = XVID_TYPE_VOL;        stats->type = XVID_TYPE_VOL;
# Line 1630  Line 1665 
1665      goto repeat;      goto repeat;
1666    }    }
1667    
1668    dec->p_bmv.x = dec->p_bmv.y = dec->p_fmv.y = dec->p_fmv.y = 0;  /* init pred vector to 0 */    dec->p_bmv.x = dec->p_bmv.y = dec->p_fmv.x = dec->p_fmv.y = 0;  /* init pred vector to 0 */
1669    
1670    /* packed_mode: special-N_VOP treament */    /* packed_mode: special-N_VOP treament */
1671    if (dec->packed_mode && coding_type == N_VOP) {    if (dec->packed_mode && coding_type == N_VOP) {

Legend:
Removed from v.1.73  
changed lines
  Added in v.1.87

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