37 |
* MinChen <chenm001@163.com> |
* MinChen <chenm001@163.com> |
38 |
* 14.04.2002 added FrameCodeB() |
* 14.04.2002 added FrameCodeB() |
39 |
* |
* |
40 |
* $Id: encoder.c,v 1.46 2002-06-23 03:58:32 suxen_drol Exp $ |
* $Id: encoder.c,v 1.50 2002-06-28 15:14:40 suxen_drol Exp $ |
41 |
* |
* |
42 |
****************************************************************************/ |
****************************************************************************/ |
43 |
|
|
51 |
#include "global.h" |
#include "global.h" |
52 |
#include "utils/timer.h" |
#include "utils/timer.h" |
53 |
#include "image/image.h" |
#include "image/image.h" |
54 |
|
#ifdef BFRAMES |
55 |
#include "image/font.h" |
#include "image/font.h" |
56 |
|
#endif |
57 |
#include "motion/motion.h" |
#include "motion/motion.h" |
58 |
#include "bitstream/cbp.h" |
#include "bitstream/cbp.h" |
59 |
#include "utils/mbfunctions.h" |
#include "utils/mbfunctions.h" |
378 |
pEnc->bframenum_head = 0; |
pEnc->bframenum_head = 0; |
379 |
pEnc->bframenum_tail = 0; |
pEnc->bframenum_tail = 0; |
380 |
pEnc->flush_bframes = 0; |
pEnc->flush_bframes = 0; |
381 |
|
pEnc->bframenum_dx50bvop = -1; |
382 |
|
|
383 |
pEnc->queue = NULL; |
pEnc->queue = NULL; |
384 |
|
|
742 |
pEnc->bframenum_head, pEnc->bframenum_tail, |
pEnc->bframenum_head, pEnc->bframenum_tail, |
743 |
pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); |
pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); |
744 |
|
|
|
|
|
745 |
BitstreamWriteVopHeader(&bs, &pEnc->mbParam, pEnc->current, 0); |
BitstreamWriteVopHeader(&bs, &pEnc->mbParam, pEnc->current, 0); |
746 |
BitstreamPad(&bs); |
BitstreamPad(&bs); |
747 |
BitstreamPutBits(&bs, 0x7f, 8); |
BitstreamPutBits(&bs, 0x7f, 8); |
759 |
|
|
760 |
bvop_loop: |
bvop_loop: |
761 |
|
|
762 |
if (input_valid) { |
if (pEnc->bframenum_dx50bvop != -1) |
763 |
|
{ |
764 |
|
|
765 |
|
SWAP(pEnc->current, pEnc->reference); |
766 |
|
SWAP(pEnc->current, pEnc->bframes[pEnc->bframenum_dx50bvop]); |
767 |
|
|
768 |
|
if ((pEnc->global & XVID_GLOBAL_DEBUG)) { |
769 |
|
image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 100, "DX50 IVOP"); |
770 |
|
} |
771 |
|
|
772 |
|
if (input_valid) |
773 |
|
{ |
774 |
|
queue_image(pEnc, pFrame); |
775 |
|
input_valid = 0; |
776 |
|
} |
777 |
|
|
778 |
|
} else if (input_valid) { |
779 |
|
|
780 |
SWAP(pEnc->current, pEnc->reference); |
SWAP(pEnc->current, pEnc->reference); |
781 |
|
|
812 |
pEnc->bframenum_head, pEnc->bframenum_tail, |
pEnc->bframenum_head, pEnc->bframenum_tail, |
813 |
pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); |
pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); |
814 |
|
|
|
|
|
815 |
pFrame->intra = 0; |
pFrame->intra = 0; |
816 |
|
|
817 |
BitstreamPutBits(&bs, 0x7f, 8); |
BitstreamPutBits(&bs, 0x7f, 8); |
833 |
* comment style :-) |
* comment style :-) |
834 |
* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ |
* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ |
835 |
|
|
|
//$$ SWAP(pEnc->current, pEnc->reference); |
|
|
|
|
836 |
emms(); |
emms(); |
837 |
|
|
838 |
|
// only inc frame num, adapt quant, etc. if we havent seen it before |
839 |
|
if (pEnc->bframenum_dx50bvop < 0 ) |
840 |
|
{ |
841 |
if (pFrame->quant == 0) |
if (pFrame->quant == 0) |
842 |
pEnc->current->quant = RateControlGetQ(&pEnc->rate_control, 0); |
pEnc->current->quant = RateControlGetQ(&pEnc->rate_control, 0); |
843 |
else |
else |
851 |
|
|
852 |
pEnc->current->global_flags = pFrame->general; |
pEnc->current->global_flags = pFrame->general; |
853 |
pEnc->current->motion_flags = pFrame->motion; |
pEnc->current->motion_flags = pFrame->motion; |
854 |
pEnc->current->seconds = pEnc->mbParam.m_seconds; |
|
|
pEnc->current->ticks = pEnc->mbParam.m_ticks; |
|
855 |
/* ToDo : dynamic fcode (in both directions) */ |
/* ToDo : dynamic fcode (in both directions) */ |
856 |
pEnc->current->fcode = pEnc->mbParam.m_fcode; |
pEnc->current->fcode = pEnc->mbParam.m_fcode; |
857 |
pEnc->current->bcode = pEnc->mbParam.m_fcode; |
pEnc->current->bcode = pEnc->mbParam.m_fcode; |
858 |
|
|
859 |
//$$$ start_timer(); |
pEnc->current->seconds = pEnc->mbParam.m_seconds; |
860 |
//$$$ if (image_input |
pEnc->current->ticks = pEnc->mbParam.m_ticks; |
861 |
//$$$ (&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height, |
|
862 |
//$$$ pEnc->mbParam.edged_width, pFrame->image, pFrame->colorspace)) |
inc_frame_num(pEnc); |
|
//$$$ return XVID_ERR_FORMAT; |
|
|
//$$$ stop_conv_timer(); |
|
863 |
|
|
864 |
#ifdef _DEBUG_PSNR |
#ifdef _DEBUG_PSNR |
865 |
image_copy(&pEnc->sOriginal, &pEnc->current->image, |
image_copy(&pEnc->sOriginal, &pEnc->current->image, |
873 |
"%i if:%i st:%i:%i", pEnc->m_framenum++, pEnc->iFrameNum, pEnc->current->seconds, pEnc->current->ticks); |
"%i if:%i st:%i:%i", pEnc->m_framenum++, pEnc->iFrameNum, pEnc->current->seconds, pEnc->current->ticks); |
874 |
} |
} |
875 |
|
|
|
|
|
876 |
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
877 |
* Luminance masking |
* Luminance masking |
878 |
* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ |
* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ |
902 |
} |
} |
903 |
|
|
904 |
#undef OFFSET |
#undef OFFSET |
|
|
|
905 |
} |
} |
906 |
|
|
907 |
xvid_free(temp_dquants); |
xvid_free(temp_dquants); |
908 |
} |
} |
909 |
|
|
910 |
|
} |
911 |
|
|
912 |
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
913 |
* ivop/pvop/bvop selection |
* ivop/pvop/bvop selection |
914 |
* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ |
* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ |
915 |
|
|
916 |
|
|
917 |
if (pEnc->iFrameNum == 0 || pFrame->intra == 1 || |
if (pEnc->iFrameNum == 0 || pFrame->intra == 1 || pEnc->bframenum_dx50bvop >= 0 || |
918 |
(pFrame->intra < 0 && pEnc->iMaxKeyInterval > 0 && |
(pFrame->intra < 0 && pEnc->iMaxKeyInterval > 0 && |
919 |
pEnc->iFrameNum >= pEnc->iMaxKeyInterval) |
pEnc->iFrameNum >= pEnc->iMaxKeyInterval) |
920 |
|| image_mad(&pEnc->reference->image, &pEnc->current->image, |
|| image_mad(&pEnc->reference->image, &pEnc->current->image, |
932 |
image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 200, "IVOP"); |
image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 200, "IVOP"); |
933 |
} |
} |
934 |
|
|
935 |
FrameCodeI(pEnc, &bs, &bits); |
// when we reach an iframe in DX50BVOP mode, encode the last bframe as a pframe |
936 |
|
|
937 |
|
if ((pEnc->global & XVID_GLOBAL_DX50BVOP) && pEnc->bframenum_tail > 0) { |
938 |
|
|
939 |
|
pEnc->bframenum_tail--; |
940 |
|
pEnc->bframenum_dx50bvop = pEnc->bframenum_tail; |
941 |
|
|
942 |
|
SWAP(pEnc->current, pEnc->bframes[pEnc->bframenum_dx50bvop]); |
943 |
|
if ((pEnc->global & XVID_GLOBAL_DEBUG)) { |
944 |
|
image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 100, "DX50 BVOP->PVOP"); |
945 |
|
} |
946 |
|
FrameCodeP(pEnc, &bs, &bits, 1, 0); |
947 |
|
|
948 |
|
pFrame->intra = 0; |
949 |
|
|
950 |
|
} else { |
951 |
|
|
952 |
|
FrameCodeI(pEnc, &bs, &bits); |
953 |
pFrame->intra = 1; |
pFrame->intra = 1; |
|
pEnc->flush_bframes = 1; |
|
954 |
|
|
955 |
inc_frame_num(pEnc); |
pEnc->bframenum_dx50bvop = -1; |
956 |
|
} |
957 |
|
|
958 |
if ((pEnc->global & XVID_GLOBAL_PACKED)) { |
pEnc->flush_bframes = 1; |
959 |
|
|
960 |
|
if ((pEnc->global & XVID_GLOBAL_PACKED) && pEnc->bframenum_tail > 0) { |
961 |
BitstreamPad(&bs); |
BitstreamPad(&bs); |
962 |
input_valid = 0; |
input_valid = 0; |
963 |
goto ipvop_loop; |
goto ipvop_loop; |
984 |
pFrame->intra = 0; |
pFrame->intra = 0; |
985 |
pEnc->flush_bframes = 1; |
pEnc->flush_bframes = 1; |
986 |
|
|
|
inc_frame_num(pEnc); |
|
|
|
|
987 |
if ((pEnc->global & XVID_GLOBAL_PACKED)) { |
if ((pEnc->global & XVID_GLOBAL_PACKED)) { |
988 |
BitstreamPad(&bs); |
BitstreamPad(&bs); |
989 |
input_valid = 0; |
input_valid = 0; |
1020 |
pFrame->intra = 0; |
pFrame->intra = 0; |
1021 |
pFrame->length = 0; |
pFrame->length = 0; |
1022 |
|
|
|
inc_frame_num(pEnc); |
|
|
|
|
1023 |
input_valid = 0; |
input_valid = 0; |
1024 |
goto bvop_loop; |
goto bvop_loop; |
1025 |
} |
} |
1335 |
tmp.y -= (tmp.y >= high) ? high * 2 : 0; |
tmp.y -= (tmp.y >= high) ? high * 2 : 0; |
1336 |
|
|
1337 |
get_pmvdata(pEnc->current->mbs, x, y, pEnc->mbParam.mb_width, |
get_pmvdata(pEnc->current->mbs, x, y, pEnc->mbParam.mb_width, |
1338 |
0, pred, dummy); |
0, pred, dummy, 0, 0); |
1339 |
|
|
1340 |
for (vec = 0; vec < 4; ++vec) { |
for (vec = 0; vec < 4; ++vec) { |
1341 |
pMB->mvs[vec].x = tmp.x; |
pMB->mvs[vec].x = tmp.x; |
1355 |
tmp.y -= (tmp.y >= high) ? high * 2 : 0; |
tmp.y -= (tmp.y >= high) ? high * 2 : 0; |
1356 |
|
|
1357 |
get_pmvdata(pEnc->current->mbs, x, y, |
get_pmvdata(pEnc->current->mbs, x, y, |
1358 |
pEnc->mbParam.mb_width, vec, pred, dummy); |
pEnc->mbParam.mb_width, vec, pred, dummy, 0, 0); |
1359 |
|
|
1360 |
pMB->mvs[vec].x = tmp.x; |
pMB->mvs[vec].x = tmp.x; |
1361 |
pMB->mvs[vec].y = tmp.y; |
pMB->mvs[vec].y = tmp.y; |