--- encoder.c 2003/01/11 14:59:23 1.76.2.35 +++ encoder.c 2003/01/21 22:05:44 1.76.2.40 @@ -39,7 +39,7 @@ * MinChen * 14.04.2002 added FrameCodeB() * - * $Id: encoder.c,v 1.76.2.35 2003/01/11 14:59:23 chl Exp $ + * $Id: encoder.c,v 1.76.2.40 2003/01/21 22:05:44 edgomez Exp $ * ****************************************************************************/ @@ -229,7 +229,7 @@ pEnc->bitrate = pParam->rc_bitrate; - pEnc->iFrameNum = 0; + pEnc->iFrameNum = -1; pEnc->mbParam.iMaxKeyInterval = pParam->max_key_interval; /* try to allocate frame memory */ @@ -658,10 +658,10 @@ /* convert pFrame->intra to coding_type */ static int intra2coding_type(int intra) { - if (intra < 0) return -1; - if (intra == 1) return I_VOP; - if (intra == 2) return B_VOP; - + if (intra < 0) return -1; + if (intra == 1) return I_VOP; + if (intra == 2) return B_VOP; + return P_VOP; } @@ -730,12 +730,21 @@ FrameCodeP(pEnc, &bs, &bits, 1, 0); bframes_count = 0; - BitstreamPad(&bs); + BitstreamPadAlways(&bs); pFrame->length = BitstreamLength(&bs); pFrame->intra = 0; + emms(); + if (pResult) { + pResult->quant = pEnc->current->quant; + pResult->hlength = pFrame->length - (pEnc->current->sStat.iTextBits / 8); + pResult->kblks = pEnc->current->sStat.kblks; + pResult->mblks = pEnc->current->sStat.mblks; + pResult->ublks = pEnc->current->sStat.ublks; + } + return XVID_ERR_OK; } @@ -747,10 +756,18 @@ FrameCodeB(pEnc, pEnc->bframes[pEnc->bframenum_head], &bs, &bits); pEnc->bframenum_head++; - BitstreamPad(&bs); + BitstreamPadAlways(&bs); pFrame->length = BitstreamLength(&bs); pFrame->intra = 2; + if (pResult) { + pResult->quant = pEnc->current->quant; + pResult->hlength = pFrame->length - (pEnc->current->sStat.iTextBits / 8); + pResult->kblks = pEnc->current->sStat.kblks; + pResult->mblks = pEnc->current->sStat.mblks; + pResult->ublks = pEnc->current->sStat.ublks; + } + if (input_valid) queue_image(pEnc, pFrame); @@ -776,16 +793,25 @@ pEnc->bframenum_head, pEnc->bframenum_tail, pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); - BitstreamPad(&bs); tmp = pEnc->current->seconds; pEnc->current->seconds = 0; /* force time_base = 0 */ + BitstreamWriteVopHeader(&bs, &pEnc->mbParam, pEnc->current, 0); pEnc->current->seconds = tmp; + BitstreamPadAlways(&bs); pFrame->length = BitstreamLength(&bs); pFrame->intra = 4; + if (pResult) { + pResult->quant = pEnc->current->quant; + pResult->hlength = pFrame->length - (pEnc->current->sStat.iTextBits / 8); + pResult->kblks = pEnc->current->sStat.kblks; + pResult->mblks = pEnc->current->sStat.mblks; + pResult->ublks = pEnc->current->sStat.ublks; + } + if (input_valid) queue_image(pEnc, pFrame); @@ -859,12 +885,45 @@ pEnc->bframenum_head, pEnc->bframenum_tail, pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); - BitstreamPutBits(&bs, 0x7f, 8); + // BitstreamPutBits(&bs, 0x7f, 8); pFrame->intra = 5; + + if (pResult) { + /* + * We must decide what to put there because i know some apps + * are storing statistics about quantizers and just do + * stats[quant]++ or stats[quant-1]++ + * transcode is one of these app with its 2pass module + */ + + /* + * For now i prefer 31 than 0 that could lead to a segfault + * in transcode + */ + pResult->quant = 31; + + pResult->hlength = 0; + pResult->kblks = 0; + pResult->mblks = 0; + pResult->ublks = 0; + } + + } else { + + if (pResult) { + pResult->quant = pEnc->current->quant; + pResult->hlength = pFrame->length - (pEnc->current->sStat.iTextBits / 8); + pResult->kblks = pEnc->current->sStat.kblks; + pResult->mblks = pEnc->current->sStat.mblks; + pResult->ublks = pEnc->current->sStat.ublks; + } + } pFrame->length = BitstreamLength(&bs); + emms(); + return XVID_ERR_OK; } @@ -1001,9 +1060,8 @@ } FrameCodeP(pEnc, &bs, &bits, 1, 0); bframes_count = 0; - pFrame->intra = 0; - + } else { FrameCodeI(pEnc, &bs, &bits); @@ -1025,7 +1083,7 @@ * NB : sequences like "IIBB" decode fine with msfdam but, * go screwy with divx 5.00 */ - } else if (mode == P_VOP || pEnc->bframenum_tail >= pEnc->mbParam.max_bframes) { + } else if (mode == P_VOP || mode == S_VOP || pEnc->bframenum_tail >= pEnc->mbParam.max_bframes) { /* * This will be coded as a Predicted Frame */ @@ -1089,7 +1147,7 @@ goto bvop_loop; } - BitstreamPad(&bs); + BitstreamPadAlways(&bs); pFrame->length = BitstreamLength(&bs); if (pResult) { @@ -1275,9 +1333,9 @@ } - BitstreamPutBits(&bs, 0xFFFF, 16); - BitstreamPutBits(&bs, 0xFFFF, 16); - BitstreamPad(&bs); +// BitstreamPutBits(&bs, 0xFFFF, 16); +// BitstreamPutBits(&bs, 0xFFFF, 16); + BitstreamPadAlways(&bs); pFrame->length = BitstreamLength(&bs); if (pResult) { @@ -1468,7 +1526,7 @@ if (intra) { if (!hint->rawhints) { - BitstreamPad(&bs); + BitstreamPadAlways(&bs); hint->hintlength = BitstreamLength(&bs); } return; @@ -1574,6 +1632,8 @@ BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current); set_timecodes(pEnc->current,pEnc->reference,pEnc->mbParam.fbase); + + BitstreamPadAlways(bs); BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1); *pBits = BitstreamPos(bs); @@ -1713,15 +1773,17 @@ generate_GMCimage(&pEnc->current->gmc_data, &pEnc->reference->image, pEnc->mbParam.mb_width, pEnc->mbParam.mb_height, pEnc->mbParam.edged_width, pEnc->mbParam.edged_width/2, - pEnc->mbParam.m_fcode, 0, 0, + pEnc->mbParam.m_fcode, pEnc->mbParam.m_quarterpel, 0, pEnc->current->rounding_type, pEnc->current->mbs, &pEnc->vGMC); } + set_timecodes(pEnc->current,pEnc->reference,pEnc->mbParam.fbase); if (vol_header) - BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current); + { BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current); + BitstreamPadAlways(bs); + } - set_timecodes(pEnc->current,pEnc->reference,pEnc->mbParam.fbase); BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1); *pBits = BitstreamPos(bs); @@ -1738,7 +1800,6 @@ /* Mode decision: Check, if the block should be INTRA / INTER or GMC-coded */ /* For a start, leave INTRA decision as is, only choose only between INTER/GMC - gruel, 9.1.2002 */ - bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q); if (bIntra) { @@ -1753,6 +1814,7 @@ pEnc->current->sStat.kblks++; MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->current->sStat); + stop_coding_timer(); continue; } @@ -1760,13 +1822,22 @@ int32_t iSAD = sad16(pEnc->current->image.y + 16*y*pEnc->mbParam.edged_width + 16*x, pEnc->vGMC.y + 16*y*pEnc->mbParam.edged_width + 16*x, - pEnc->mbParam.edged_width,65536); + pEnc->mbParam.edged_width, 65536); + if (pEnc->current->motion_flags & PMV_CHROMA16) { + iSAD += sad8(pEnc->current->image.u + 8*y*(pEnc->mbParam.edged_width/2) + 8*x, + pEnc->vGMC.u + 8*y*(pEnc->mbParam.edged_width/2) + 8*x, pEnc->mbParam.edged_width/2); + + iSAD += sad8(pEnc->current->image.v + 8*y*(pEnc->mbParam.edged_width/2) + 8*x, + pEnc->vGMC.v + 8*y*(pEnc->mbParam.edged_width/2) + 8*x, pEnc->mbParam.edged_width/2); + } + if (iSAD <= pMB->sad16) { /* mode decision GMC */ + if (pEnc->mbParam.m_quarterpel) - pMB->qmvs[0] = pMB->qmvs[1] =pMB->qmvs[2] =pMB->qmvs[3] = pMB->amv; + pMB->qmvs[0] = pMB->qmvs[1] = pMB->qmvs[2] = pMB->qmvs[3] = pMB->amv; else - pMB->mvs[0] = pMB->mvs[1] =pMB->mvs[2] =pMB->mvs[3] = pMB->amv; + pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv; pMB->mode = MODE_INTER; pMB->mcsel = 1; @@ -1774,8 +1845,7 @@ } else { pMB->mcsel = 0; } - } else - { + } else { pMB->mcsel = 0; /* just a precaution */ } @@ -1813,7 +1883,6 @@ dct_codes, qcoeff); } - 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) { @@ -1826,16 +1895,16 @@ /* Finished processing the MB, now check if to CODE or SKIP */ - skip_possible = (pMB->cbp == 0) & (pMB->mode == MODE_INTER) & + skip_possible = (pMB->cbp == 0) && (pMB->mode == MODE_INTER) && (pMB->dquant == NO_CHANGE); if (pEnc->current->coding_type == S_VOP) skip_possible &= (pMB->mcsel == 1); else if (pEnc->current->coding_type == P_VOP) { if (pEnc->mbParam.m_quarterpel) - skip_possible &= (pMB->qmvs[0].x == 0) & (pMB->qmvs[0].y == 0); + skip_possible &= ( (pMB->qmvs[0].x == 0) && (pMB->qmvs[0].y == 0) ); else - skip_possible &= (pMB->mvs[0].x == 0) & (pMB->mvs[0].y == 0); + skip_possible &= ( (pMB->mvs[0].x == 0) && (pMB->mvs[0].y == 0) ); } if ( (pMB->mode == MODE_NOT_CODED) || (skip_possible)) { @@ -1873,6 +1942,7 @@ pMB->cbp = 0; MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->current->sStat); stop_coding_timer(); + continue; /* next MB */ } } @@ -1922,8 +1992,10 @@ } } + MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->current->sStat); stop_coding_timer(); + } }