--- trunk/xvidcore/src/encoder.c 2002/06/12 20:38:41 195 +++ trunk/xvidcore/src/encoder.c 2002/06/25 09:41:54 240 @@ -32,23 +32,28 @@ * * History * + * 20.06.2002 bframe patch * 08.05.2002 fix some problem in DEBUG mode; * MinChen * 14.04.2002 added FrameCodeB() * - * $Id: encoder.c,v 1.41 2002-06-12 20:38:40 edgomez Exp $ + * $Id: encoder.c,v 1.49 2002-06-25 09:41:53 suxen_drol Exp $ * ****************************************************************************/ #include #include #include +#include #include "encoder.h" #include "prediction/mbprediction.h" #include "global.h" #include "utils/timer.h" #include "image/image.h" +#ifdef BFRAMES +#include "image/font.h" +#endif #include "motion/motion.h" #include "bitstream/cbp.h" #include "utils/mbfunctions.h" @@ -131,7 +136,7 @@ encoder_create(XVID_ENC_PARAM * pParam) { Encoder *pEnc; - uint32_t i; + int i; pParam->handle = NULL; @@ -207,6 +212,10 @@ if (pEnc == NULL) return XVID_ERR_MEMORY; + /* Zero the Encoder Structure */ + + memset(pEnc, 0, sizeof(Encoder)); + /* Fill members of Encoder structure */ pEnc->mbParam.width = pParam->width; @@ -221,6 +230,8 @@ pEnc->mbParam.fbase = pParam->fbase; pEnc->mbParam.fincr = pParam->fincr; + pEnc->mbParam.m_quant_type = H263_QUANT; + pEnc->sStat.fMvPrevSigma = -1; /* Fill rate control parameters */ @@ -252,7 +263,7 @@ /* try to allocate image memory */ -#ifdef _DEBUG +#ifdef _DEBUG_PSNR image_null(&pEnc->sOriginal); #endif #ifdef BFRAMES @@ -268,7 +279,7 @@ image_null(&pEnc->vInterHV); image_null(&pEnc->vInterHVf); -#ifdef _DEBUG +#ifdef _DEBUG_PSNR if (image_create (&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0) @@ -322,6 +333,7 @@ /* B Frames specific init */ #ifdef BFRAMES + pEnc->global = pParam->global; pEnc->mbParam.max_bframes = pParam->max_bframes; pEnc->bquant_ratio = pParam->bquant_ratio; pEnc->bframes = NULL; @@ -366,9 +378,41 @@ pEnc->bframenum_head = 0; pEnc->bframenum_tail = 0; pEnc->flush_bframes = 0; + pEnc->bframenum_dx50bvop = -1; + + pEnc->queue = NULL; + + + if (pEnc->mbParam.max_bframes > 0) { + int n; + + pEnc->queue = + xvid_malloc(pEnc->mbParam.max_bframes * sizeof(IMAGE), + CACHE_LINE); + + if (pEnc->queue == NULL) + goto xvid_err_memory4; + + for (n = 0; n < pEnc->mbParam.max_bframes; n++) + image_null(&pEnc->queue[n]); + + for (n = 0; n < pEnc->mbParam.max_bframes; n++) { + if (image_create + (&pEnc->queue[n], pEnc->mbParam.edged_width, + pEnc->mbParam.edged_height) < 0) + goto xvid_err_memory5; + + } + } + + pEnc->queue_head = 0; + pEnc->queue_tail = 0; + pEnc->queue_size = 0; + pEnc->mbParam.m_seconds = 0; pEnc->mbParam.m_ticks = 0; + pEnc->m_framenum = 0; #endif pParam->handle = (void *) pEnc; @@ -389,27 +433,43 @@ * We handle all XVID_ERR_MEMORY here, this makes the code lighter */ #ifdef BFRAMES + xvid_err_memory5: + + + if (pEnc->mbParam.max_bframes > 0) { + + for (i = 0; i < pEnc->mbParam.max_bframes; i++) { + image_destroy(&pEnc->queue[i], pEnc->mbParam.edged_width, + pEnc->mbParam.edged_height); + } + xvid_free(pEnc->queue); + } + xvid_err_memory4: - for (i = 0; i < pEnc->mbParam.max_bframes; i++) { - if (pEnc->bframes[i] == NULL) - continue; + if (pEnc->mbParam.max_bframes > 0) { - image_destroy(&pEnc->bframes[i]->image, pEnc->mbParam.edged_width, - pEnc->mbParam.edged_height); + for (i = 0; i < pEnc->mbParam.max_bframes; i++) { - xvid_free(pEnc->bframes[i]->mbs); + if (pEnc->bframes[i] == NULL) + continue; - xvid_free(pEnc->bframes[i]); + image_destroy(&pEnc->bframes[i]->image, pEnc->mbParam.edged_width, + pEnc->mbParam.edged_height); + + xvid_free(pEnc->bframes[i]->mbs); + + xvid_free(pEnc->bframes[i]); - } + } - xvid_free(pEnc->bframes); + xvid_free(pEnc->bframes); + } #endif xvid_err_memory3: -#ifdef _DEBUG +#ifdef _DEBUG_PSNR image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); #endif @@ -466,28 +526,43 @@ int encoder_destroy(Encoder * pEnc) { +#ifdef BFRAMES + int i; +#endif + ENC_CHECK(pEnc); /* B Frames specific */ #ifdef BFRAMES - int i; + if (pEnc->mbParam.max_bframes > 0) { + + for (i = 0; i < pEnc->mbParam.max_bframes; i++) { + + image_destroy(&pEnc->queue[i], pEnc->mbParam.edged_width, + pEnc->mbParam.edged_height); + } + xvid_free(pEnc->queue); + } - for (i = 0; i < pEnc->mbParam.max_bframes; i++) { - if (pEnc->bframes[i] == NULL) - continue; + if (pEnc->mbParam.max_bframes > 0) { - image_destroy(&pEnc->bframes[i]->image, pEnc->mbParam.edged_width, - pEnc->mbParam.edged_height); + for (i = 0; i < pEnc->mbParam.max_bframes; i++) { - xvid_free(pEnc->bframes[i]->mbs); + if (pEnc->bframes[i] == NULL) + continue; - xvid_free(pEnc->bframes[i]); + image_destroy(&pEnc->bframes[i]->image, pEnc->mbParam.edged_width, + pEnc->mbParam.edged_height); - } + xvid_free(pEnc->bframes[i]->mbs); - xvid_free(pEnc->bframes); + xvid_free(pEnc->bframes[i]); + } + xvid_free(pEnc->bframes); + + } #endif /* All images, reference, current etc ... */ @@ -514,7 +589,7 @@ image_destroy(&pEnc->f_refhv, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); #endif -#ifdef _DEBUG +#ifdef _DEBUG_PSNR image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); #endif @@ -532,11 +607,49 @@ return XVID_ERR_OK; } + +#ifdef BFRAMES +void inc_frame_num(Encoder * pEnc) +{ + pEnc->iFrameNum++; + pEnc->mbParam.m_ticks += pEnc->mbParam.fincr; + + pEnc->mbParam.m_seconds = pEnc->mbParam.m_ticks / pEnc->mbParam.fbase; + pEnc->mbParam.m_ticks = pEnc->mbParam.m_ticks % pEnc->mbParam.fbase; +} +#endif + + +#ifdef BFRAMES +void queue_image(Encoder * pEnc, XVID_ENC_FRAME * pFrame) +{ + if (pEnc->queue_size >= pEnc->mbParam.max_bframes) + { + DPRINTF("FATAL: QUEUE FULL"); + return; + } + + DPRINTF("*** QUEUE bf: head=%i tail=%i queue: head=%i tail=%i size=%i", + pEnc->bframenum_head, pEnc->bframenum_tail, + pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); + + + start_timer(); + if (image_input + (&pEnc->queue[pEnc->queue_tail], pEnc->mbParam.width, pEnc->mbParam.height, + pEnc->mbParam.edged_width, pFrame->image, pFrame->colorspace)) + return; + stop_conv_timer(); + + pEnc->queue_size++; + pEnc->queue_tail = (pEnc->queue_tail + 1) % pEnc->mbParam.max_bframes; +} +#endif + + +#ifdef BFRAMES /***************************************************************************** - * Frame encoder entry point - * - * At this moment 2 versions coexist : one for IPB compatible encoder, - * another one for the old IP encoder. + * IPB frame encoder entry point * * Returned values : * - XVID_ERR_OK - no errors @@ -544,13 +657,8 @@ * format ****************************************************************************/ - -#ifdef BFRAMES -/***************************************************************************** - * Frame encoder entry point for IPB capable encoder - ****************************************************************************/ int -encoder_encode(Encoder * pEnc, +encoder_encode_bframes(Encoder * pEnc, XVID_ENC_FRAME * pFrame, XVID_ENC_STATS * pResult) { @@ -558,18 +666,23 @@ Bitstream bs; uint32_t bits; -#ifdef _DEBUG + int input_valid = 1; + +#ifdef _DEBUG_PSNR float psnr; char temp[128]; #endif ENC_CHECK(pEnc); ENC_CHECK(pFrame); + ENC_CHECK(pFrame->image); start_global_timer(); BitstreamInit(&bs, pFrame->bitstream, 0); +ipvop_loop: + /* * bframe "flush" code */ @@ -584,10 +697,10 @@ * frame as a pframe */ - /* ToDo : remove dprintf calls */ - /* - dprintf("--- PFRAME (final frame correction) --- "); - */ + DPRINTF("*** BFRAME (final frame) bf: head=%i tail=%i queue: head=%i tail=%i size=%i", + pEnc->bframenum_head, pEnc->bframenum_tail, + pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); + pEnc->bframenum_tail--; SWAP(pEnc->current, pEnc->reference); @@ -597,38 +710,120 @@ BitstreamPad(&bs); pFrame->length = BitstreamLength(&bs); - pFrame->input_consumed = 0; pFrame->intra = 0; return XVID_ERR_OK; } - /* ToDo : remove dprintf calls */ - /* - dprintf("--- BFRAME (flush) --- "); - */ + + DPRINTF("*** BFRAME (flush) bf: head=%i tail=%i queue: head=%i tail=%i size=%i", + pEnc->bframenum_head, pEnc->bframenum_tail, + pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); + FrameCodeB(pEnc, pEnc->bframes[pEnc->bframenum_head], &bs, &bits); pEnc->bframenum_head++; - BitstreamPad(&bs); pFrame->length = BitstreamLength(&bs); - pFrame->input_consumed = 0; pFrame->intra = 0; + if (input_valid) + queue_image(pEnc, pFrame); + return XVID_ERR_OK; } - if (pFrame->image == NULL) { - pFrame->length = 0; - pFrame->input_consumed = 1; + if (pEnc->bframenum_head > 0) { + pEnc->bframenum_head = pEnc->bframenum_tail = 0; + + if ((pEnc->global & XVID_GLOBAL_PACKED)) { + + DPRINTF("*** EMPTY bf: head=%i tail=%i queue: head=%i tail=%i size=%i", + pEnc->bframenum_head, pEnc->bframenum_tail, + pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); + + BitstreamWriteVopHeader(&bs, &pEnc->mbParam, pEnc->current, 0); + BitstreamPad(&bs); + BitstreamPutBits(&bs, 0x7f, 8); + + pFrame->length = BitstreamLength(&bs); + pFrame->intra = 0; + + if (input_valid) + queue_image(pEnc, pFrame); + + return XVID_ERR_OK; + } + } + + +bvop_loop: + + if (pEnc->bframenum_dx50bvop != -1) + { + + SWAP(pEnc->current, pEnc->reference); + SWAP(pEnc->current, pEnc->bframes[pEnc->bframenum_dx50bvop]); + + if ((pEnc->global & XVID_GLOBAL_DEBUG)) { + image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 100, "DX50 IVOP"); + } + + if (input_valid) + { + queue_image(pEnc, pFrame); + input_valid = 0; + } + + } else if (input_valid) { + + SWAP(pEnc->current, pEnc->reference); + + start_timer(); + if (image_input + (&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height, + pEnc->mbParam.edged_width, pFrame->image, pFrame->colorspace)) + return XVID_ERR_FORMAT; + stop_conv_timer(); + + // queue input frame, and dequue next image + if (pEnc->queue_size > 0) + { + image_swap(&pEnc->current->image, &pEnc->queue[pEnc->queue_tail]); + if (pEnc->queue_head != pEnc->queue_tail) + { + image_swap(&pEnc->current->image, &pEnc->queue[pEnc->queue_head]); + } + pEnc->queue_head = (pEnc->queue_head + 1) % pEnc->mbParam.max_bframes; + pEnc->queue_tail = (pEnc->queue_tail + 1) % pEnc->mbParam.max_bframes; + } + + } else if (pEnc->queue_size > 0) { + + SWAP(pEnc->current, pEnc->reference); + + image_swap(&pEnc->current->image, &pEnc->queue[pEnc->queue_head]); + pEnc->queue_head = (pEnc->queue_head + 1) % pEnc->mbParam.max_bframes; + pEnc->queue_size--; + + } else if (BitstreamPos(&bs) == 0) { + + DPRINTF("*** SKIP bf: head=%i tail=%i queue: head=%i tail=%i size=%i", + pEnc->bframenum_head, pEnc->bframenum_tail, + pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); + pFrame->intra = 0; + BitstreamPutBits(&bs, 0x7f, 8); + BitstreamPad(&bs); + pFrame->length = BitstreamLength(&bs); + return XVID_ERR_OK; - } - if (pEnc->bframenum_head > 0) { - pEnc->bframenum_head = pEnc->bframenum_tail = 0; + } else { + + pFrame->length = BitstreamLength(&bs); + return XVID_ERR_OK; } pEnc->flush_bframes = 0; @@ -638,76 +833,80 @@ * comment style :-) * %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ - SWAP(pEnc->current, pEnc->reference); + emms(); - EMMS(); + // only inc frame num, adapt quant, etc. if we havent seen it before + if (pEnc->bframenum_dx50bvop < 0 ) + { + if (pFrame->quant == 0) + pEnc->current->quant = RateControlGetQ(&pEnc->rate_control, 0); + else + pEnc->current->quant = pFrame->quant; - if (pFrame->quant == 0) - pEnc->current->quant = RateControlGetQ(&pEnc->rate_control, 0); - else - pEnc->current->quant = pFrame->quant; + if (pEnc->current->quant < 1) + pEnc->current->quant = 1; - if (pEnc->current->quant < 1) - pEnc->current->quant = 1; + if (pEnc->current->quant > 31) + pEnc->current->quant = 31; - if (pEnc->current->quant > 31) - pEnc->current->quant = 31; + pEnc->current->global_flags = pFrame->general; + pEnc->current->motion_flags = pFrame->motion; - pEnc->current->global_flags = pFrame->general; - pEnc->current->motion_flags = pFrame->motion; - pEnc->current->seconds = pEnc->mbParam.m_seconds; - pEnc->current->ticks = pEnc->mbParam.m_ticks; - /* ToDo : dynamic fcode (in both directions) */ - pEnc->current->fcode = pEnc->mbParam.m_fcode; - pEnc->current->bcode = pEnc->mbParam.m_fcode; + /* ToDo : dynamic fcode (in both directions) */ + pEnc->current->fcode = pEnc->mbParam.m_fcode; + pEnc->current->bcode = pEnc->mbParam.m_fcode; - start_timer(); - if (image_input - (&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height, - pEnc->mbParam.edged_width, pFrame->image, pFrame->colorspace)) - return XVID_ERR_FORMAT; - stop_conv_timer(); + pEnc->current->seconds = pEnc->mbParam.m_seconds; + pEnc->current->ticks = pEnc->mbParam.m_ticks; -#ifdef _DEBUG - image_copy(&pEnc->sOriginal, &pEnc->current->image, + inc_frame_num(pEnc); + +#ifdef _DEBUG_PSNR + image_copy(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height); #endif - EMMS(); + emms(); + + if ((pEnc->global & XVID_GLOBAL_DEBUG)) { + image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 5, + "%i if:%i st:%i:%i", pEnc->m_framenum++, pEnc->iFrameNum, pEnc->current->seconds, pEnc->current->ticks); + } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% * Luminance masking * %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ - if ((pEnc->current->global_flags & XVID_LUMIMASKING)) { - int *temp_dquants = - (int *) xvid_malloc(pEnc->mbParam.mb_width * + if ((pEnc->current->global_flags & XVID_LUMIMASKING)) { + int *temp_dquants = + (int *) xvid_malloc(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * sizeof(int), CACHE_LINE); - pEnc->current->quant = - adaptive_quantization(pEnc->current->image.y, + pEnc->current->quant = + adaptive_quantization(pEnc->current->image.y, pEnc->mbParam.edged_width, temp_dquants, pEnc->current->quant, pEnc->current->quant, 2 * pEnc->current->quant, pEnc->mbParam.mb_width, pEnc->mbParam.mb_height); - for (y = 0; y < pEnc->mbParam.mb_height; y++) { + for (y = 0; y < pEnc->mbParam.mb_height; y++) { #define OFFSET(x,y) ((x) + (y)*pEnc->mbParam.mb_width) - for (x = 0; x < pEnc->mbParam.mb_width; x++) { - MACROBLOCK *pMB = &pEnc->current->mbs[OFFSET(x, y)]; + for (x = 0; x < pEnc->mbParam.mb_width; x++) { + MACROBLOCK *pMB = &pEnc->current->mbs[OFFSET(x, y)]; - pMB->dquant = iDQtab[temp_dquants[OFFSET(x, y)] + 2]; - } + pMB->dquant = iDQtab[temp_dquants[OFFSET(x, y)] + 2]; + } #undef OFFSET + } + xvid_free(temp_dquants); } - xvid_free(temp_dquants); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -715,7 +914,7 @@ * %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ - if (pEnc->iFrameNum == 0 || pFrame->intra == 1 || + if (pEnc->iFrameNum == 0 || pFrame->intra == 1 || pEnc->bframenum_dx50bvop >= 0 || (pFrame->intra < 0 && pEnc->iMaxKeyInterval > 0 && pEnc->iFrameNum >= pEnc->iMaxKeyInterval) || image_mad(&pEnc->reference->image, &pEnc->current->image, @@ -725,16 +924,45 @@ * This will be coded as an Intra Frame */ - /* ToDo : Remove dprintf calls */ - /* - dprintf("--- IFRAME ---"); - */ + DPRINTF("*** IFRAME bf: head=%i tail=%i queue: head=%i tail=%i size=%i", + pEnc->bframenum_head, pEnc->bframenum_tail, + pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); + + if ((pEnc->global & XVID_GLOBAL_DEBUG)) { + image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 200, "IVOP"); + } + + // when we reach an iframe in DX50BVOP mode, encode the last bframe as a pframe + + if ((pEnc->global & XVID_GLOBAL_DX50BVOP) && pEnc->bframenum_tail > 0) { + + pEnc->bframenum_tail--; + pEnc->bframenum_dx50bvop = pEnc->bframenum_tail; + + SWAP(pEnc->current, pEnc->bframes[pEnc->bframenum_dx50bvop]); + if ((pEnc->global & XVID_GLOBAL_DEBUG)) { + image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 100, "DX50 BVOP->PVOP"); + } + FrameCodeP(pEnc, &bs, &bits, 1, 0); - FrameCodeI(pEnc, &bs, &bits); + pFrame->intra = 0; + + } else { + + FrameCodeI(pEnc, &bs, &bits); + pFrame->intra = 1; + + pEnc->bframenum_dx50bvop = -1; + } - pFrame->intra = 1; pEnc->flush_bframes = 1; + if ((pEnc->global & XVID_GLOBAL_PACKED) && pEnc->bframenum_tail > 0) { + BitstreamPad(&bs); + input_valid = 0; + goto ipvop_loop; + } + /* * NB : sequences like "IIBB" decode fine with msfdam but, * go screwy with divx 5.00 @@ -744,25 +972,36 @@ * This will be coded as a Predicted Frame */ - /* ToDo : Remove dprintf calls */ - /* - dprintf("--- PFRAME ---"); - */ + DPRINTF("*** PFRAME bf: head=%i tail=%i queue: head=%i tail=%i size=%i", + pEnc->bframenum_head, pEnc->bframenum_tail, + pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); + + if ((pEnc->global & XVID_GLOBAL_DEBUG)) { + image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 200, "PVOP"); + } FrameCodeP(pEnc, &bs, &bits, 1, 0); pFrame->intra = 0; pEnc->flush_bframes = 1; + + if ((pEnc->global & XVID_GLOBAL_PACKED)) { + BitstreamPad(&bs); + input_valid = 0; + goto ipvop_loop; + } + } else { /* * This will be coded as a Bidirectional Frame */ - /* ToDo : Remove dprintf calls */ - /* - dprintf("--- BFRAME (store) --- head=%i tail=%i", - pEnc->bframenum_head, - pEnc->bframenum_tail); - */ + DPRINTF("*** BFRAME (store) bf: head=%i tail=%i queue: head=%i tail=%i size=%i", + pEnc->bframenum_head, pEnc->bframenum_tail, + pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); + + if ((pEnc->global & XVID_GLOBAL_DEBUG)) { + image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 200, "BVOP"); + } if (pFrame->bquant < 1) { pEnc->current->quant = @@ -780,15 +1019,9 @@ pFrame->intra = 0; pFrame->length = 0; - pFrame->input_consumed = 1; - pEnc->mbParam.m_ticks += pEnc->mbParam.fincr; - if (pEnc->mbParam.m_ticks > pEnc->mbParam.fbase) { - pEnc->mbParam.m_seconds++; - pEnc->mbParam.m_ticks = 0; - } - - return XVID_ERR_OK; + input_valid = 0; + goto bvop_loop; } BitstreamPad(&bs); @@ -802,9 +1035,9 @@ pResult->ublks = pEnc->sStat.ublks; } - EMMS(); + emms(); -#ifdef _DEBUG +#ifdef _DEBUG_PSNR psnr = image_psnr(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.width, @@ -819,23 +1052,26 @@ pFrame->length, pFrame->intra); } - pEnc->iFrameNum++; - pEnc->mbParam.m_ticks += pEnc->mbParam.fincr; - if (pEnc->mbParam.m_ticks > pEnc->mbParam.fbase) { - pEnc->mbParam.m_seconds++; - pEnc->mbParam.m_ticks = 0; - } - pFrame->input_consumed = 1; stop_global_timer(); write_timer(); return XVID_ERR_OK; } -#else + +#endif + + + /***************************************************************************** - * Frame encoder entry point for IP capable encoder + * "original" IP frame encoder entry point + * + * Returned values : + * - XVID_ERR_OK - no errors + * - XVID_ERR_FORMAT - the image subsystem reported the image had a wrong + * format ****************************************************************************/ + int encoder_encode(Encoder * pEnc, XVID_ENC_FRAME * pFrame, @@ -846,7 +1082,7 @@ uint32_t bits; uint16_t write_vol_header = 0; -#ifdef _DEBUG +#ifdef _DEBUG_PSNR float psnr; uint8_t temp[128]; #endif @@ -862,6 +1098,10 @@ pEnc->current->global_flags = pFrame->general; pEnc->current->motion_flags = pFrame->motion; +#ifdef BFRAMES + pEnc->current->seconds = pEnc->mbParam.m_seconds; + pEnc->current->ticks = pEnc->mbParam.m_ticks; +#endif pEnc->mbParam.hint = &pFrame->hint; start_timer(); @@ -871,12 +1111,12 @@ return XVID_ERR_FORMAT; stop_conv_timer(); -#ifdef _DEBUG +#ifdef _DEBUG_PSNR image_copy(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height); #endif - EMMS(); + emms(); BitstreamInit(&bs, pFrame->bitstream, 0); @@ -975,13 +1215,13 @@ pResult->ublks = pEnc->sStat.ublks; } - EMMS(); + emms(); if (pFrame->quant == 0) { RateControlUpdate(&pEnc->rate_control, pEnc->current->quant, pFrame->length, pFrame->intra); } -#ifdef _DEBUG +#ifdef _DEBUG_PSNR psnr = image_psnr(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.width, @@ -991,14 +1231,18 @@ DEBUG(temp); #endif +#ifdef BFRAMES + inc_frame_num(pEnc); +#else pEnc->iFrameNum++; +#endif + stop_global_timer(); write_timer(); return XVID_ERR_OK; } -#endif static __inline void @@ -1246,7 +1490,13 @@ pEnc->current->coding_type = I_VOP; BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current); - BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current); +#ifdef BFRAMES +#define DIVX501B481P "DivX501b481p" + if ((pEnc->global & XVID_GLOBAL_PACKED)) { + BitstreamWriteUserData(bs, DIVX501B481P, strlen(DIVX501B481P)); + } +#endif + BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1); *pBits = BitstreamPos(bs); @@ -1307,7 +1557,7 @@ uint32_t x, y; int iSearchRange; int bIntra; - + /* IMAGE *pCurrent = &pEnc->current->image; */ IMAGE *pRef = &pEnc->reference->image; @@ -1357,7 +1607,7 @@ if (vol_header) BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current); - BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current); + BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1); *pBits = BitstreamPos(bs); @@ -1515,7 +1765,7 @@ } */ frame->coding_type = B_VOP; - BitstreamWriteVopHeader(bs, &pEnc->mbParam, frame); + BitstreamWriteVopHeader(bs, &pEnc->mbParam, frame, 1); *pBits = BitstreamPos(bs); @@ -1578,7 +1828,7 @@ backward.x = mb->b_mvs[0].x; backward.y = mb->b_mvs[0].y; } -// printf("[%i %i] M=%i CBP=%i MVX=%i MVY=%i %i,%i %i,%i\n", x, y, pMB->mode, pMB->cbp, pMB->mvs[0].x, bmb->pmvs[0].x, bmb->pmvs[0].y, forward.x, forward.y); +// DPRINTF("%05i : [%i %i] M=%i CBP=%i MVS=%i,%i forward=%i,%i", pEnc->m_framenum, x, y, mb->mode, mb->cbp, mb->mvs[0].x, mb->mvs[0].y, forward.x, forward.y); start_timer(); MBCodingBVOP(mb, qcoeff, frame->fcode, frame->bcode, bs,