--- encoder.c 2003/11/19 15:42:38 1.95.2.54 +++ encoder.c 2003/11/30 16:13:15 1.95.2.56 @@ -21,7 +21,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: encoder.c,v 1.95.2.54 2003/11/19 15:42:38 syskin Exp $ + * $Id: encoder.c,v 1.95.2.56 2003/11/30 16:13:15 edgomez Exp $ * ****************************************************************************/ @@ -250,6 +250,14 @@ if (pEnc->current->mbs == NULL || pEnc->reference->mbs == NULL) goto xvid_err_memory2; + /* allocate quant matrix memory */ + + pEnc->mbParam.mpeg_quant_matrices = + xvid_malloc(sizeof(uint16_t) * 64 * 8, CACHE_LINE); + + if (pEnc->mbParam.mpeg_quant_matrices == NULL) + goto xvid_err_memory2a; + /* allocate interpolation image memory */ if ((pEnc->mbParam.plugin_flags & XVID_REQORIGINAL)) { @@ -403,6 +411,7 @@ create->handle = (void *) pEnc; init_timer(); + init_mpeg_matrix(pEnc->mbParam.mpeg_quant_matrices); return 0; /* ok */ @@ -469,6 +478,8 @@ image_destroy(&pEnc->vGMC, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); + xvid_err_memory2a: + xvid_free(pEnc->mbParam.mpeg_quant_matrices); xvid_err_memory2: xvid_free(pEnc->current->mbs); @@ -597,6 +608,8 @@ xvid_free(pEnc->plugins); } + xvid_free(pEnc->mbParam.mpeg_quant_matrices); + if (pEnc->num_plugins>0) xvid_free(pEnc->zones); @@ -776,15 +789,13 @@ frame->mbs[j*pEnc->mbParam.mb_width + i].dquant = 0; } } - frame->mbs[0].quant = data.quant; /* BEFORE2 will not affect the quant in stats */ + frame->mbs[0].quant = data.quant; /* FRAME will not affect the quant in stats */ } } - - static __inline void inc_frame_num(Encoder * pEnc) { pEnc->current->frame_num = pEnc->m_framenum; @@ -800,6 +811,34 @@ pEnc->m_framenum--; /* debug ticker */ } +static __inline void +MBSetDquant(MACROBLOCK * pMB, int x, int y, MBParam * mbParam) +{ + if (pMB->cbp == 0) { + /* we want to code dquant but the quantizer value will not be used yet + let's find out if we can postpone dquant to next MB + */ + if (x == mbParam->mb_width-1 && y == mbParam->mb_height-1) { + pMB->dquant = 0; /* it's the last MB of all, the easiest case */ + return; + } else { + MACROBLOCK * next = pMB + 1; + const MACROBLOCK * prev = pMB - 1; + if (next->mode != MODE_INTER4V && next->mode != MODE_NOT_CODED) + /* mode allows dquant change in the future */ + if (abs(next->quant - prev->quant) <= 2) { + /* quant change is not out of range */ + pMB->quant = prev->quant; + pMB->dquant = 0; + next->dquant = next->quant - prev->quant; + return; + } + } + } + /* couldn't skip this dquant */ + pMB->mode = MODE_INTER_Q; +} + static __inline void @@ -1201,9 +1240,9 @@ if ((pEnc->mbParam.vol_flags & XVID_VOL_MPEGQUANT)) { if (frame->quant_intra_matrix != NULL) - set_intra_matrix(frame->quant_intra_matrix); + set_intra_matrix(pEnc->mbParam.mpeg_quant_matrices, frame->quant_intra_matrix); if (frame->quant_inter_matrix != NULL) - set_inter_matrix(frame->quant_inter_matrix); + set_inter_matrix(pEnc->mbParam.mpeg_quant_matrices, frame->quant_inter_matrix); } /* prevent vol/vop misuse */ @@ -1603,10 +1642,6 @@ stop_comp_timer(); - if (pMB->dquant != 0) { - pMB->mode = MODE_INTER_Q; - } - pMB->field_pred = 0; if (pMB->mode != MODE_NOT_CODED) @@ -1615,6 +1650,10 @@ dct_codes, qcoeff); } + if (pMB->dquant != 0) + MBSetDquant(pMB, x, y, &pEnc->mbParam); + + if (pMB->cbp || pMB->mvs[0].x || pMB->mvs[0].y || pMB->mvs[1].x || pMB->mvs[1].y || pMB->mvs[2].x || pMB->mvs[2].y || pMB->mvs[3].x || pMB->mvs[3].y) {