--- decoder.c 2003/10/22 09:47:52 1.49.2.18 +++ decoder.c 2003/12/21 19:41:53 1.49.2.28 @@ -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.18 2003/10/22 09:47:52 edgomez Exp $ + * $Id: decoder.c,v 1.49.2.28 2003/12/21 19:41:53 Isibaar 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(); @@ -392,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(); @@ -1164,15 +1176,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); @@ -1180,18 +1183,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] = @@ -1304,20 +1312,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); @@ -1361,7 +1375,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 { @@ -1431,7 +1445,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 */ @@ -1452,6 +1466,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; } @@ -1464,11 +1479,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; } } @@ -1493,16 +1508,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"); + 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); + 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++; } @@ -1522,7 +1539,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, @@ -1530,7 +1547,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; } }