--- decoder.c 2003/10/16 12:16:00 1.49.2.17 +++ decoder.c 2004/02/03 02:56:57 1.49.2.31 @@ -20,7 +20,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: decoder.c,v 1.49.2.17 2003/10/16 12:16:00 syskin Exp $ + * $Id: decoder.c,v 1.49.2.31 2004/02/03 02:56:57 syskin Exp $ * ****************************************************************************/ @@ -41,6 +41,7 @@ #include "bitstream/mbcoding.h" #include "quant/quant.h" +#include "quant/quant_matrix.h" #include "dct/idct.h" #include "dct/fdct.h" #include "utils/mem_transfer.h" @@ -57,6 +58,7 @@ #include "image/image.h" #include "image/colorspace.h" +#include "image/postprocessing.h" #include "utils/mem_align.h" static int @@ -175,8 +177,15 @@ if (dec == NULL) { return XVID_ERR_MEMORY; } + memset(dec, 0, sizeof(DECODER)); + dec->mpeg_quant_matrices = xvid_malloc(sizeof(uint16_t) * 64 * 8, CACHE_LINE); + if (dec->mpeg_quant_matrices == NULL) { + xvid_free(dec); + return XVID_ERR_MEMORY; + } + create->handle = dec; dec->width = create->width; @@ -196,6 +205,8 @@ dec->last_mbs = NULL; init_timer(); + init_postproc(&dec->postproc); + init_mpeg_matrix(dec->mpeg_quant_matrices); /* For B-frame support (used to save reference frame's time */ dec->frames = 0; @@ -226,6 +237,7 @@ image_destroy(&dec->tmp, dec->edged_width, dec->edged_height); image_destroy(&dec->qtmp, dec->edged_width, dec->edged_height); image_destroy(&dec->cur, dec->edged_width, dec->edged_height); + xvid_free(dec->mpeg_quant_matrices); xvid_free(dec); write_timer(); @@ -321,9 +333,9 @@ start_timer(); if (dec->quant_type == 0) { - dequant_h263_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler); + dequant_h263_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler, dec->mpeg_quant_matrices); } else { - dequant_mpeg_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler); + dequant_mpeg_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler, dec->mpeg_quant_matrices); } stop_iquant_timer(); @@ -373,7 +385,8 @@ DECLARE_ALIGNED_MATRIX(block, 1, 64, int16_t, CACHE_LINE); DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE); - int stride = dec->edged_width, next_block = stride * (reduced_resolution ? 16 : 8); + int stride = dec->edged_width; + int next_block = stride * (reduced_resolution ? 16 : 8); const int stride2 = stride/2; int i; const uint32_t iQuant = pMB->quant; @@ -391,7 +404,7 @@ stop_coding_timer(); start_timer(); - dequant(&data[i * 64], block, iQuant); + dequant(&data[i * 64], block, iQuant, dec->mpeg_quant_matrices); stop_iquant_timer(); start_timer(); @@ -450,7 +463,6 @@ { uint32_t stride = dec->edged_width; uint32_t stride2 = stride / 2; - uint32_t next_block = stride * (reduced_resolution ? 16 : 8); uint32_t i; uint8_t *pY_Cur, *pU_Cur, *pV_Cur; @@ -839,12 +851,12 @@ mb->quant = quant; if (dec->interlacing) { - if ((cbp || intra) && !mcsel) { + if (cbp || intra) { mb->field_dct = BitstreamGetBit(bs); DPRINTF(XVID_DEBUG_MB,"decp: field_dct: %i\n", mb->field_dct); } - if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) { + if ((mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) && !mcsel) { mb->field_pred = BitstreamGetBit(bs); DPRINTF(XVID_DEBUG_MB, "decp: field_pred: %i\n", mb->field_pred); @@ -888,6 +900,7 @@ } else if (gmc_warp) { /* a not coded S(GMC)-VOP macroblock */ mb->mode = MODE_NOT_CODED_GMC; + mb->quant = quant; decoder_mbgmc(dec, mb, x, y, fcode, 0x00, bs, rounding); if(dec->out_frm && cp_mb > 0) { @@ -897,6 +910,7 @@ st_mb = x+1; } else { /* not coded P_VOP macroblock */ mb->mode = MODE_NOT_CODED; + mb->quant = quant; mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0; mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0; @@ -963,7 +977,6 @@ { uint32_t stride = dec->edged_width; uint32_t stride2 = stride / 2; - uint32_t next_block = stride * 8; int uv_dx, uv_dy; int b_uv_dx, b_uv_dy; uint8_t *pY_Cur, *pU_Cur, *pV_Cur; @@ -1165,15 +1178,6 @@ const int64_t TRB = dec->time_pp - dec->time_bp, TRD = dec->time_pp; int i; -#ifdef BFRAMES_DEC_DEBUG - FILE *fp; - static char first=0; -#define BFRAME_DEBUG - if (!first && fp) { \ - fprintf(fp,"Y=%3d X=%3d MB=%2d CBP=%02X\n",y,x,mb->mode,mb->cbp); \ - } -#endif - start_timer(); image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height, dec->width, dec->height); @@ -1181,18 +1185,23 @@ dec->width, dec->height); stop_edges_timer(); -#ifdef BFRAMES_DEC_DEBUG - if (!first){ - fp=fopen("C:\\XVIDDBG.TXT","w"); - } -#endif - for (y = 0; y < dec->mb_height; y++) { /* Initialize Pred Motion Vector */ dec->p_fmv = dec->p_bmv = zeromv; for (x = 0; x < dec->mb_width; x++) { MACROBLOCK *mb = &dec->mbs[y * dec->mb_width + x]; MACROBLOCK *last_mb = &dec->last_mbs[y * dec->mb_width + x]; + const int fcode_max = (fcode_forward>fcode_backward) ? fcode_forward : fcode_backward; + 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; + } mv = mb->b_mvs[0] = mb->b_mvs[1] = mb->b_mvs[2] = mb->b_mvs[3] = @@ -1305,20 +1314,26 @@ } } /* End of for */ } - -#ifdef BFRAMES_DEC_DEBUG - if (!first){ - first=1; - if (fp) - fclose(fp); - } -#endif } /* perform post processing if necessary, and output the image */ void decoder_output(DECODER * dec, IMAGE * img, MACROBLOCK * mbs, - xvid_dec_frame_t * frame, xvid_dec_stats_t * stats, int coding_type) + xvid_dec_frame_t * frame, xvid_dec_stats_t * stats, + int coding_type, int quant) { + if (dec->cartoon_mode) + frame->general &= ~XVID_FILMEFFECT; + + if (frame->general & (XVID_DEBLOCKY|XVID_DEBLOCKUV|XVID_FILMEFFECT) && mbs != NULL) /* post process */ + { + /* note: image is stored to tmp */ + image_copy(&dec->tmp, img, dec->edged_width, dec->height); + image_postproc(&dec->postproc, &dec->tmp, dec->edged_width, + mbs, dec->mb_width, dec->mb_height, dec->mb_width, + frame->general, dec->frames, (coding_type == B_VOP)); + img = &dec->tmp; + } + image_output(img, dec->width, dec->height, dec->edged_width, (uint8_t**)frame->output.plane, frame->output.stride, frame->output.csp, dec->interlacing); @@ -1362,7 +1377,7 @@ /* if not decoding "low_delay/packed", and this isn't low_delay and we have a reference frame, then outout the reference frame */ if (!(dec->low_delay_default && dec->packed_mode) && !dec->low_delay && dec->frames>0) { - decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type); + decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type, quant); dec->frames = 0; ret = 0; } else { @@ -1432,7 +1447,7 @@ /* packed_mode: special-N_VOP treament */ if (dec->packed_mode && coding_type == N_VOP) { if (dec->low_delay_default && dec->frames > 0) { - decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type); + decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type, quant); output = 1; } /* ignore otherwise */ @@ -1453,6 +1468,7 @@ /* XXX: not_coded vops are not used for forward prediction */ /* we should not swap(last_mbs,mbs) */ image_copy(&dec->cur, &dec->refn[0], dec->edged_width, dec->height); + SWAP(MACROBLOCK *, dec->mbs, dec->last_mbs); /* it will be swapped back */ break; } @@ -1465,11 +1481,11 @@ /* note: for packed_mode, output is performed when the special-N_VOP is decoded */ if (!(dec->low_delay_default && dec->packed_mode)) { if (dec->low_delay) { - decoder_output(dec, &dec->cur, dec->mbs, frame, stats, coding_type); + decoder_output(dec, &dec->cur, dec->mbs, frame, stats, coding_type, quant); output = 1; } else if (dec->frames > 0) { /* is the reference frame valid? */ /* output the reference frame */ - decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type); + decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type, quant); output = 1; } } @@ -1494,16 +1510,18 @@ /* attemping to decode a bvop without atleast 2 reference frames */ image_printf(&dec->cur, dec->edged_width, dec->height, 16, 16, "broken b-frame, mising ref frames"); + if (stats) stats->type = XVID_TYPE_NOTHING; } else if (dec->time_pp <= dec->time_bp) { /* this occurs when dx50_bvop_compatibility==0 sequences are decoded in vfw. */ image_printf(&dec->cur, dec->edged_width, dec->height, 16, 16, "broken b-frame, tpp=%i tbp=%i", dec->time_pp, dec->time_bp); + if (stats) stats->type = XVID_TYPE_NOTHING; } else { decoder_bframe(dec, &bs, quant, fcode_forward, fcode_backward); + decoder_output(dec, &dec->cur, dec->mbs, frame, stats, coding_type, quant); } - decoder_output(dec, &dec->cur, dec->mbs, frame, stats, coding_type); output = 1; dec->frames++; } @@ -1523,7 +1541,7 @@ if (dec->low_delay_default && output == 0) { if (dec->packed_mode && seen_something) { /* output the recently decoded frame */ - decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type); + decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type, quant); } else { image_clear(&dec->cur, dec->width, dec->height, dec->edged_width, 0, 128, 128); image_printf(&dec->cur, dec->edged_width, dec->height, 16, 16, @@ -1531,7 +1549,7 @@ image_printf(&dec->cur, dec->edged_width, dec->height, 16, 64, "bframe decoder lag"); - decoder_output(dec, &dec->cur, NULL, frame, stats, P_VOP); + decoder_output(dec, &dec->cur, NULL, frame, stats, P_VOP, quant); if (stats) stats->type = XVID_TYPE_NOTHING; } }