1 |
|
// 14.04.2002 added FrameCodeB() |
2 |
|
|
3 |
#include <stdlib.h> |
#include <stdlib.h> |
4 |
#include <stdio.h> |
#include <stdio.h> |
5 |
#include <math.h> |
#include <math.h> |
80 |
pParam->fincr = (int)(pParam->fincr / div); |
pParam->fincr = (int)(pParam->fincr / div); |
81 |
} |
} |
82 |
|
|
83 |
if (pParam->bitrate <= 0) |
if (pParam->rc_bitrate <= 0) |
84 |
pParam->bitrate = 900000; |
pParam->rc_bitrate = 900000; |
85 |
|
|
86 |
|
if (pParam->rc_reaction_delay_factor <= 0) |
87 |
|
pParam->rc_reaction_delay_factor = 16; |
88 |
|
|
89 |
|
if (pParam->rc_averaging_period <= 0) |
90 |
|
pParam->rc_averaging_period = 100; |
91 |
|
|
92 |
if (pParam->rc_buffersize <= 0) |
if (pParam->rc_buffer <= 0) |
93 |
pParam->rc_buffersize = 16; |
pParam->rc_buffer = 100; |
94 |
|
|
95 |
if ((pParam->min_quantizer <= 0) || (pParam->min_quantizer > 31)) |
if ((pParam->min_quantizer <= 0) || (pParam->min_quantizer > 31)) |
96 |
pParam->min_quantizer = 1; |
pParam->min_quantizer = 1; |
124 |
|
|
125 |
pEnc->mbParam.quant = 4; |
pEnc->mbParam.quant = 4; |
126 |
|
|
127 |
pEnc->bitrate = pParam->bitrate; |
pEnc->bitrate = pParam->rc_bitrate; |
128 |
|
|
129 |
pEnc->iFrameNum = 0; |
pEnc->iFrameNum = 0; |
130 |
pEnc->iMaxKeyInterval = pParam->max_key_interval; |
pEnc->iMaxKeyInterval = pParam->max_key_interval; |
148 |
image_create(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || |
image_create(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || |
149 |
image_create(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || |
image_create(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || |
150 |
image_create(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || |
image_create(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || |
151 |
|
#ifdef _DEBUG |
152 |
|
image_create(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || |
153 |
|
#endif |
154 |
(pEnc->pMBs = xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height, CACHE_LINE)) == NULL) |
(pEnc->pMBs = xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height, CACHE_LINE)) == NULL) |
155 |
{ |
{ |
156 |
image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
160 |
image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
161 |
image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
162 |
image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
163 |
|
#ifdef _DEBUG |
164 |
|
image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
165 |
|
#endif |
166 |
if (pEnc) |
if (pEnc) |
167 |
{ |
{ |
168 |
xvid_free(pEnc); |
xvid_free(pEnc); |
178 |
|
|
179 |
pParam->handle = (void *)pEnc; |
pParam->handle = (void *)pEnc; |
180 |
|
|
181 |
if (pParam->bitrate) |
if (pParam->rc_bitrate) |
182 |
{ |
{ |
183 |
RateControlInit(pParam->bitrate, pParam->rc_buffersize, pParam->fbase * 1000 / pParam->fincr, |
RateControlInit(pParam->rc_bitrate, pParam->rc_reaction_delay_factor, |
184 |
|
pParam->rc_averaging_period, pParam->rc_buffer, pParam->fbase * 1000 / pParam->fincr, |
185 |
pParam->max_quantizer, pParam->min_quantizer); |
pParam->max_quantizer, pParam->min_quantizer); |
186 |
} |
} |
187 |
|
|
205 |
image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
206 |
image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
207 |
image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
208 |
|
#ifdef _DEBUG |
209 |
|
image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
210 |
|
#endif |
211 |
xvid_free(pEnc); |
xvid_free(pEnc); |
212 |
|
|
213 |
return XVID_ERR_OK; |
return XVID_ERR_OK; |
219 |
Bitstream bs; |
Bitstream bs; |
220 |
uint32_t bits; |
uint32_t bits; |
221 |
uint16_t write_vol_header = 0; |
uint16_t write_vol_header = 0; |
222 |
|
#ifdef _DEBUG |
223 |
|
float psnr; |
224 |
|
uint8_t temp[100]; |
225 |
|
#endif |
226 |
|
|
227 |
start_global_timer(); |
start_global_timer(); |
228 |
|
|
245 |
|
|
246 |
EMMS(); |
EMMS(); |
247 |
|
|
248 |
|
#ifdef _DEBUG |
249 |
|
image_copy(&pEnc->sOriginal, &pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.height); |
250 |
|
#endif |
251 |
|
|
252 |
BitstreamInit(&bs, pFrame->bitstream, 0); |
BitstreamInit(&bs, pFrame->bitstream, 0); |
253 |
|
|
254 |
if (pFrame->quant == 0) |
if (pFrame->quant == 0) |
349 |
RateControlUpdate(pEnc->mbParam.quant, pFrame->length, pFrame->intra); |
RateControlUpdate(pEnc->mbParam.quant, pFrame->length, pFrame->intra); |
350 |
} |
} |
351 |
|
|
352 |
|
#ifdef _DEBUG |
353 |
|
psnr = image_psnr(&pEnc->sOriginal, &pEnc->sCurrent, pEnc->mbParam.edged_width, |
354 |
|
pEnc->mbParam.width, pEnc->mbParam.height); |
355 |
|
|
356 |
|
sprintf(temp, "PSNR: %f\n", psnr); |
357 |
|
DEBUG(temp); |
358 |
|
#endif |
359 |
|
|
360 |
pEnc->iFrameNum++; |
pEnc->iFrameNum++; |
361 |
image_swap(&pEnc->sCurrent, &pEnc->sReference); |
image_swap(&pEnc->sCurrent, &pEnc->sReference); |
362 |
|
|
431 |
|
|
432 |
pMB->mode = (hint->rawhints) ? bhint->mode : BitstreamGetBits(&bs, MODEBITS); |
pMB->mode = (hint->rawhints) ? bhint->mode : BitstreamGetBits(&bs, MODEBITS); |
433 |
|
|
434 |
if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) |
pMB->mode = (pMB->mode == MODE_INTER_Q) ? MODE_INTER : pMB->mode; |
435 |
|
pMB->mode = (pMB->mode == MODE_INTRA_Q) ? MODE_INTRA : pMB->mode; |
436 |
|
|
437 |
|
if (pMB->mode == MODE_INTER) |
438 |
{ |
{ |
439 |
tmp.x = (hint->rawhints) ? bhint->mvs[0].x : BitstreamGetBits(&bs, length); |
tmp.x = (hint->rawhints) ? bhint->mvs[0].x : BitstreamGetBits(&bs, length); |
440 |
tmp.y = (hint->rawhints) ? bhint->mvs[0].y : BitstreamGetBits(&bs, length); |
tmp.y = (hint->rawhints) ? bhint->mvs[0].y : BitstreamGetBits(&bs, length); |
468 |
pMB->pmvs[vec].y = pMB->mvs[vec].y - pred[0].y; |
pMB->pmvs[vec].y = pMB->mvs[vec].y - pred[0].y; |
469 |
} |
} |
470 |
} |
} |
471 |
else // intra / intra_q / stuffing / not_coded |
else // intra / stuffing / not_coded |
472 |
{ |
{ |
473 |
for (vec=0 ; vec<4 ; ++vec) |
for (vec=0 ; vec<4 ; ++vec) |
474 |
{ |
{ |
475 |
pMB->mvs[vec].x = pMB->mvs[vec].y = 0; |
pMB->mvs[vec].x = pMB->mvs[vec].y = 0; |
476 |
} |
} |
477 |
} |
} |
478 |
|
|
479 |
|
if (pMB->dquant != NO_CHANGE && pMB->mode == MODE_INTER4V) |
480 |
|
{ |
481 |
|
pMB->mode = MODE_INTRA; |
482 |
|
|
483 |
|
for (vec=0 ; vec<4 ; ++vec) |
484 |
|
{ |
485 |
|
pMB->mvs[vec].x = pMB->mvs[vec].y = 0; |
486 |
|
} |
487 |
|
} |
488 |
} |
} |
489 |
} |
} |
490 |
} |
} |
836 |
|
|
837 |
return 0; // inter |
return 0; // inter |
838 |
} |
} |
839 |
|
|
840 |
|
|
841 |
|
|
842 |
|
/* |
843 |
|
static void FrameCodeB(Encoder * pEnc, FRAMEINFO * frame, Bitstream * bs, uint32_t *pBits) |
844 |
|
{ |
845 |
|
int16_t dct_codes[6][64]; |
846 |
|
int16_t qcoeff[6][64]; |
847 |
|
uint32_t x, y; |
848 |
|
VECTOR forward; |
849 |
|
VECTOR backward; |
850 |
|
|
851 |
|
IMAGE *f_ref = &pEnc->reference->image; |
852 |
|
IMAGE *b_ref = &pEnc->current->image; |
853 |
|
|
854 |
|
// forward |
855 |
|
image_setedges(f_ref, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height); |
856 |
|
start_timer(); |
857 |
|
image_interpolate(f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv, |
858 |
|
pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, 0); |
859 |
|
stop_inter_timer(); |
860 |
|
|
861 |
|
// backward |
862 |
|
image_setedges(b_ref, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height); |
863 |
|
start_timer(); |
864 |
|
image_interpolate(b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV, |
865 |
|
pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, 0); |
866 |
|
stop_inter_timer(); |
867 |
|
|
868 |
|
start_timer(); |
869 |
|
MotionEstimationBVOP(&pEnc->mbParam, frame, |
870 |
|
pEnc->reference->mbs, f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv, |
871 |
|
pEnc->current->mbs, b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV); |
872 |
|
|
873 |
|
stop_motion_timer(); |
874 |
|
|
875 |
|
if (test_quant_type(&pEnc->mbParam, pEnc->current)) |
876 |
|
{ |
877 |
|
BitstreamWriteVolHeader(bs, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.quant_type); |
878 |
|
} |
879 |
|
|
880 |
|
frame->coding_type = B_VOP; |
881 |
|
BitstreamWriteVopHeader(bs, B_VOP, frame->tick, 0, |
882 |
|
frame->quant, frame->fcode, frame->bcode); |
883 |
|
|
884 |
|
*pBits = BitstreamPos(bs); |
885 |
|
|
886 |
|
pEnc->sStat.iTextBits = 0; |
887 |
|
pEnc->sStat.iMvSum = 0; |
888 |
|
pEnc->sStat.iMvCount = 0; |
889 |
|
pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0; |
890 |
|
|
891 |
|
|
892 |
|
for (y = 0; y < pEnc->mbParam.mb_height; y++) |
893 |
|
{ |
894 |
|
// reset prediction |
895 |
|
|
896 |
|
forward.x = 0; |
897 |
|
forward.y = 0; |
898 |
|
backward.x = 0; |
899 |
|
backward.y = 0; |
900 |
|
|
901 |
|
for (x = 0; x < pEnc->mbParam.mb_width; x++) |
902 |
|
{ |
903 |
|
MACROBLOCK * f_mb = &pEnc->reference->mbs[x + y * pEnc->mbParam.mb_width]; |
904 |
|
MACROBLOCK * b_mb = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width]; |
905 |
|
MACROBLOCK * mb = &frame->mbs[x + y * pEnc->mbParam.mb_width]; |
906 |
|
|
907 |
|
// decoder ignores mb when refence block is INTER(0,0), CBP=0 |
908 |
|
if (mb->mode == MODE_NOT_CODED) |
909 |
|
{ |
910 |
|
mb->mvs[0].x = 0; |
911 |
|
mb->mvs[0].y = 0; |
912 |
|
continue; |
913 |
|
} |
914 |
|
|
915 |
|
MBMotionCompensationBVOP(&pEnc->mbParam, mb, x, y, &frame->image, |
916 |
|
f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv, |
917 |
|
b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV, |
918 |
|
dct_codes); |
919 |
|
|
920 |
|
mb->quant = frame->quant; |
921 |
|
mb->cbp = MBTransQuantInter(&pEnc->mbParam, frame, x, y, dct_codes, qcoeff); |
922 |
|
//mb->cbp = MBTransQuantBVOP(&pEnc->mbParam, x, y, dct_codes, qcoeff, &frame->image, frame->quant); |
923 |
|
|
924 |
|
|
925 |
|
if ((mb->mode == MODE_INTERPOLATE || mb->mode == MODE_DIRECT) && |
926 |
|
mb->cbp == 0 && |
927 |
|
mb->mvs[0].x == 0 && |
928 |
|
mb->mvs[0].y == 0) |
929 |
|
{ |
930 |
|
mb->mode = 5; // skipped |
931 |
|
} |
932 |
|
|
933 |
|
if (mb->mode == MODE_INTERPOLATE || mb->mode == MODE_FORWARD) |
934 |
|
{ |
935 |
|
mb->pmvs[0].x = mb->mvs[0].x - forward.x; |
936 |
|
mb->pmvs[0].y = mb->mvs[0].y - forward.y; |
937 |
|
forward.x = mb->mvs[0].x; |
938 |
|
forward.y = mb->mvs[0].y; |
939 |
|
} |
940 |
|
|
941 |
|
if (mb->mode == MODE_INTERPOLATE || mb->mode == MODE_BACKWARD) |
942 |
|
{ |
943 |
|
mb->b_pmvs[0].x = mb->b_mvs[0].x - backward.x; |
944 |
|
mb->b_pmvs[0].y = mb->b_mvs[0].y - backward.y; |
945 |
|
backward.x = mb->b_mvs[0].x; |
946 |
|
backward.y = mb->b_mvs[0].y; |
947 |
|
} |
948 |
|
|
949 |
|
// 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); |
950 |
|
|
951 |
|
start_timer(); |
952 |
|
MBCodingBVOP(frame, mb, qcoeff, bs, &pEnc->sStat); |
953 |
|
stop_coding_timer(); |
954 |
|
} |
955 |
|
} |
956 |
|
|
957 |
|
emms(); |
958 |
|
|
959 |
|
// TODO: dynamic fcode/bcode ??? |
960 |
|
|
961 |
|
*pBits = BitstreamPos(bs) - *pBits; |
962 |
|
|
963 |
|
} |
964 |
|
|
965 |
|
*/ |