41 |
* * |
* * |
42 |
* Revision history: * |
* Revision history: * |
43 |
* * |
* * |
44 |
|
* 28.10.2002 GMC support - gruel * |
45 |
|
* 04.10.2002 qpel support - Isibaar * |
46 |
* 11.07.2002 add VOP width & height return to dec when dec->width * |
* 11.07.2002 add VOP width & height return to dec when dec->width * |
47 |
* or dec->height is 0 (for use in examples/ex1.c) * |
* or dec->height is 0 (for use in examples/ex1.c) * |
48 |
* MinChen <chenm001@163.com> * |
* MinChen <chenm001@163.com> * |
62 |
* 30.02.2002 intra_dc_threshold support * |
* 30.02.2002 intra_dc_threshold support * |
63 |
* 04.12.2001 support for additional headers * |
* 04.12.2001 support for additional headers * |
64 |
* 16.12.2001 inital version * |
* 16.12.2001 inital version * |
65 |
* |
* * |
66 |
******************************************************************************/ |
******************************************************************************/ |
67 |
|
|
68 |
|
|
69 |
#include "bitstream.h" |
#include "bitstream.h" |
70 |
#include "zigzag.h" |
#include "zigzag.h" |
71 |
#include "../quant/quant_matrix.h" |
#include "../quant/quant_matrix.h" |
72 |
|
#include "mbcoding.h" |
73 |
|
|
74 |
|
|
75 |
static uint32_t __inline |
static uint32_t __inline |
333 |
|
|
334 |
DPRINTF(DPRINTF_HEADER,"vop_time_increment_resolution %i", time_increment_resolution); |
DPRINTF(DPRINTF_HEADER,"vop_time_increment_resolution %i", time_increment_resolution); |
335 |
|
|
336 |
time_increment_resolution--; |
// time_increment_resolution--; |
337 |
|
|
338 |
if (time_increment_resolution > 0) { |
if (time_increment_resolution > 0) { |
339 |
dec->time_inc_bits = log2bin(time_increment_resolution); |
dec->time_inc_bits = log2bin(time_increment_resolution-1); |
340 |
} else { |
} else { |
341 |
// dec->time_inc_bits = 0; |
// dec->time_inc_bits = 0; |
342 |
// for "old" xvid compatibility, set time_inc_bits = 1 |
// for "old" xvid compatibility, set time_inc_bits = 1 |
449 |
|
|
450 |
|
|
451 |
if (vol_ver_id != 1) { |
if (vol_ver_id != 1) { |
452 |
dec->quarterpel = BitstreamGetBit(bs); // quarter_sampe |
DEBUG("QUARTERPEL BITSTREAM"); |
453 |
if (dec->quarterpel) { |
dec->quarterpel = BitstreamGetBit(bs); // quarter_sample |
|
DPRINTF(DPRINTF_ERROR, "quarter_sample not supported"); |
|
454 |
} |
} |
455 |
} else { |
else |
456 |
dec->quarterpel = 0; |
dec->quarterpel = 0; |
457 |
} |
|
458 |
|
|
459 |
if (!BitstreamGetBit(bs)) // complexity_estimation_disable |
if (!BitstreamGetBit(bs)) // complexity_estimation_disable |
460 |
{ |
{ |
549 |
if (coding_type != B_VOP) { |
if (coding_type != B_VOP) { |
550 |
dec->last_time_base = dec->time_base; |
dec->last_time_base = dec->time_base; |
551 |
dec->time_base += time_incr; |
dec->time_base += time_incr; |
552 |
dec->time = |
dec->time = time_increment; |
553 |
dec->time_base * time_increment_resolution + |
|
554 |
|
/* dec->time_base * time_increment_resolution + |
555 |
time_increment; |
time_increment; |
556 |
dec->time_pp = (uint32_t) (dec->time - dec->last_non_b_time); |
*/ dec->time_pp = (uint32_t) |
557 |
|
(time_increment_resolution + dec->time - dec->last_non_b_time)%time_increment_resolution; |
558 |
dec->last_non_b_time = dec->time; |
dec->last_non_b_time = dec->time; |
559 |
} else { |
} else { |
560 |
dec->time = |
dec->time = time_increment; |
561 |
|
/* |
562 |
(dec->last_time_base + |
(dec->last_time_base + |
563 |
time_incr) * time_increment_resolution + time_increment; |
time_incr) * time_increment_resolution + time_increment; |
564 |
dec->time_bp = (uint32_t) (dec->last_non_b_time - dec->time); |
*/ |
565 |
|
dec->time_bp = (uint32_t) |
566 |
|
(time_increment_resolution + dec->last_non_b_time - dec->time)%time_increment_resolution; |
567 |
} |
} |
568 |
|
|
569 |
READ_MARKER(); |
READ_MARKER(); |
581 |
|
|
582 |
// fix a little bug by MinChen <chenm002@163.com> |
// fix a little bug by MinChen <chenm002@163.com> |
583 |
if ((dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) && |
if ((dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) && |
584 |
(coding_type == P_VOP)) { |
( (coding_type == P_VOP) || (coding_type == S_VOP) ) ) { |
585 |
*rounding = BitstreamGetBit(bs); // rounding_type |
*rounding = BitstreamGetBit(bs); // rounding_type |
586 |
DPRINTF(DPRINTF_HEADER, "rounding %i", *rounding); |
DPRINTF(DPRINTF_HEADER, "rounding %i", *rounding); |
587 |
} |
} |
622 |
*intra_dc_threshold = |
*intra_dc_threshold = |
623 |
intra_dc_threshold_table[BitstreamGetBits(bs, 3)]; |
intra_dc_threshold_table[BitstreamGetBits(bs, 3)]; |
624 |
|
|
625 |
|
dec->top_field_first = 0; |
626 |
|
dec->alternate_vertical_scan = 0; |
627 |
|
|
628 |
if (dec->interlacing) { |
if (dec->interlacing) { |
629 |
dec->top_field_first = BitstreamGetBit(bs); |
dec->top_field_first = BitstreamGetBit(bs); |
630 |
DPRINTF(DPRINTF_HEADER, "interlace top_field_first %i", dec->top_field_first); |
DPRINTF(DPRINTF_HEADER, "interlace top_field_first %i", dec->top_field_first); |
704 |
void |
void |
705 |
BitstreamWriteVolHeader(Bitstream * const bs, |
BitstreamWriteVolHeader(Bitstream * const bs, |
706 |
const MBParam * pParam, |
const MBParam * pParam, |
707 |
const FRAMEINFO * frame) |
const FRAMEINFO * const frame) |
708 |
{ |
{ |
709 |
|
int vol_ver_id=1; |
710 |
|
|
711 |
|
if ( (pParam->m_quarterpel) || (frame->global_flags & XVID_GMC) ) |
712 |
|
vol_ver_id = 2; |
713 |
|
|
714 |
// video object_start_code & vo_id |
// video object_start_code & vo_id |
715 |
BitstreamPad(bs); |
BitstreamPad(bs); |
716 |
BitstreamPutBits(bs, VO_START_CODE, 27); |
BitstreamPutBits(bs, VO_START_CODE, 27); |
722 |
|
|
723 |
BitstreamPutBit(bs, 0); // random_accessible_vol |
BitstreamPutBit(bs, 0); // random_accessible_vol |
724 |
BitstreamPutBits(bs, 0, 8); // video_object_type_indication |
BitstreamPutBits(bs, 0, 8); // video_object_type_indication |
725 |
|
|
726 |
|
if (vol_ver_id == 1) |
727 |
|
{ |
728 |
BitstreamPutBit(bs, 0); // is_object_layer_identified (0=not given) |
BitstreamPutBit(bs, 0); // is_object_layer_identified (0=not given) |
729 |
|
} |
730 |
|
else |
731 |
|
{ |
732 |
|
BitstreamPutBit(bs, 1); // is_object_layer_identified |
733 |
|
BitstreamPutBits(bs, vol_ver_id, 4); // vol_ver_id == 2 |
734 |
|
BitstreamPutBits(bs, 4, 3); // vol_ver_priority (1==lowest, 7==highest) ?? |
735 |
|
} |
736 |
|
|
737 |
BitstreamPutBits(bs, 1, 4); // aspect_ratio_info (1=1:1) |
BitstreamPutBits(bs, 1, 4); // aspect_ratio_info (1=1:1) |
738 |
|
|
|
#ifdef BFRAMES |
|
|
if (pParam->max_bframes > 0) { |
|
|
//DPRINTF("low_delay=1"); |
|
739 |
BitstreamPutBit(bs, 1); // vol_control_parameters |
BitstreamPutBit(bs, 1); // vol_control_parameters |
740 |
BitstreamPutBits(bs, 1, 2); // chroma_format 1="4:2:0" |
BitstreamPutBits(bs, 1, 2); // chroma_format 1="4:2:0" |
741 |
|
|
742 |
|
if (pParam->max_bframes > 0) { |
743 |
BitstreamPutBit(bs, 0); // low_delay |
BitstreamPutBit(bs, 0); // low_delay |
|
BitstreamPutBit(bs, 0); // vbv_parameters (0=not given) |
|
744 |
} else |
} else |
|
#endif |
|
745 |
{ |
{ |
746 |
BitstreamPutBits(bs, 0, 1); // vol_control_parameters (0=not given) |
BitstreamPutBit(bs, 1); // low_delay |
747 |
} |
} |
748 |
|
BitstreamPutBit(bs, 0); // vbv_parameters (0=not given) |
749 |
|
|
750 |
BitstreamPutBits(bs, 0, 2); // video_object_layer_shape (0=rectangular) |
BitstreamPutBits(bs, 0, 2); // video_object_layer_shape (0=rectangular) |
751 |
|
|
756 |
25fps res=25 inc=1 |
25fps res=25 inc=1 |
757 |
29.97fps res=30000 inc=1001 |
29.97fps res=30000 inc=1001 |
758 |
*/ |
*/ |
|
#ifdef BFRAMES |
|
759 |
BitstreamPutBits(bs, pParam->fbase, 16); |
BitstreamPutBits(bs, pParam->fbase, 16); |
|
#else |
|
|
BitstreamPutBits(bs, 2, 16); |
|
|
#endif |
|
760 |
|
|
761 |
WRITE_MARKER(); |
WRITE_MARKER(); |
762 |
|
|
|
#ifdef BFRAMES |
|
763 |
BitstreamPutBit(bs, 1); // fixed_vop_rate = 1 |
BitstreamPutBit(bs, 1); // fixed_vop_rate = 1 |
764 |
BitstreamPutBits(bs, pParam->fincr, log2bin(pParam->fbase)); // fixed_vop_time_increment |
BitstreamPutBits(bs, pParam->fincr, log2bin(pParam->fbase)); // fixed_vop_time_increment |
|
#else |
|
|
BitstreamPutBit(bs, 0); // fixed_vop_rate = 0 |
|
|
#endif |
|
765 |
|
|
766 |
WRITE_MARKER(); |
WRITE_MARKER(); |
767 |
BitstreamPutBits(bs, pParam->width, 13); // width |
BitstreamPutBits(bs, pParam->width, 13); // width |
771 |
|
|
772 |
BitstreamPutBit(bs, frame->global_flags & XVID_INTERLACING); // interlace |
BitstreamPutBit(bs, frame->global_flags & XVID_INTERLACING); // interlace |
773 |
BitstreamPutBit(bs, 1); // obmc_disable (overlapped block motion compensation) |
BitstreamPutBit(bs, 1); // obmc_disable (overlapped block motion compensation) |
774 |
BitstreamPutBit(bs, 0); // sprite_enable |
|
775 |
BitstreamPutBit(bs, 0); // not_in_bit |
if (vol_ver_id != 1) |
776 |
|
{ if (frame->global_flags & XVID_GMC) |
777 |
|
{ BitstreamPutBits(bs, 2, 2); // sprite_enable=='GMC' |
778 |
|
BitstreamPutBits(bs, 2, 6); // no_of_sprite_warping_points |
779 |
|
BitstreamPutBits(bs, 3, 2); // sprite_warping_accuracy 0==1/2, 1=1/4, 2=1/8, 3=1/16 |
780 |
|
BitstreamPutBit(bs, 0); // sprite_brightness_change (not supported) |
781 |
|
|
782 |
|
/* currently we use no_of_sprite_warping_points==2, sprite_warping_accuracy==3 |
783 |
|
for DivX5 compatability */ |
784 |
|
|
785 |
|
} else |
786 |
|
BitstreamPutBits(bs, 0, 2); // sprite_enable==off |
787 |
|
} |
788 |
|
else |
789 |
|
BitstreamPutBit(bs, 0); // sprite_enable==off |
790 |
|
|
791 |
|
BitstreamPutBit(bs, 0); // not_8_bit |
792 |
|
|
793 |
// quant_type 0=h.263 1=mpeg4(quantizer tables) |
// quant_type 0=h.263 1=mpeg4(quantizer tables) |
794 |
BitstreamPutBit(bs, pParam->m_quant_type); |
BitstreamPutBit(bs, pParam->m_quant_type); |
806 |
|
|
807 |
} |
} |
808 |
|
|
809 |
|
if (vol_ver_id != 1) { |
810 |
|
if (pParam->m_quarterpel) |
811 |
|
BitstreamPutBit(bs, 1); // quarterpel |
812 |
|
else |
813 |
|
BitstreamPutBit(bs, 0); // no quarterpel |
814 |
|
} |
815 |
|
|
816 |
BitstreamPutBit(bs, 1); // complexity_estimation_disable |
BitstreamPutBit(bs, 1); // complexity_estimation_disable |
817 |
BitstreamPutBit(bs, 1); // resync_marker_disable |
BitstreamPutBit(bs, 1); // resync_marker_disable |
818 |
BitstreamPutBit(bs, 0); // data_partitioned |
BitstreamPutBit(bs, 0); // data_partitioned |
819 |
|
|
820 |
|
if (vol_ver_id != 1) |
821 |
|
{ |
822 |
|
BitstreamPutBit(bs, 0); // newpred_enable |
823 |
|
BitstreamPutBit(bs, 0); // reduced_resolution_vop_enabled |
824 |
|
} |
825 |
|
|
826 |
BitstreamPutBit(bs, 0); // scalability |
BitstreamPutBit(bs, 0); // scalability |
827 |
|
|
828 |
} |
} |
829 |
|
|
830 |
|
|
831 |
/* |
/* |
832 |
write vop header |
write vop header |
|
|
|
|
NOTE: doesnt handle bother with time_base & time_inc |
|
|
time_base = n seconds since last resync (eg. last iframe) |
|
|
time_inc = nth of a second since last resync |
|
|
(decoder uses these values to determine precise time since last resync) |
|
833 |
*/ |
*/ |
834 |
void |
void |
835 |
BitstreamWriteVopHeader(Bitstream * const bs, |
BitstreamWriteVopHeader(Bitstream * const bs, |
836 |
const MBParam * pParam, |
const MBParam * pParam, |
837 |
const FRAMEINFO * frame, |
const FRAMEINFO * const frame, |
838 |
int vop_coded) |
int vop_coded) |
839 |
{ |
{ |
|
#ifdef BFRAMES |
|
840 |
uint32_t i; |
uint32_t i; |
841 |
#endif |
|
842 |
BitstreamPad(bs); |
BitstreamPad(bs); |
843 |
BitstreamPutBits(bs, VOP_START_CODE, 32); |
BitstreamPutBits(bs, VOP_START_CODE, 32); |
844 |
|
|
845 |
BitstreamPutBits(bs, frame->coding_type, 2); |
BitstreamPutBits(bs, frame->coding_type, 2); |
846 |
|
|
|
// time_base = 0 write n x PutBit(1), PutBit(0) |
|
|
#ifdef BFRAMES |
|
847 |
for (i = 0; i < frame->seconds; i++) { |
for (i = 0; i < frame->seconds; i++) { |
848 |
BitstreamPutBit(bs, 1); |
BitstreamPutBit(bs, 1); |
849 |
} |
} |
850 |
BitstreamPutBit(bs, 0); |
BitstreamPutBit(bs, 0); |
|
#else |
|
|
BitstreamPutBits(bs, 0, 1); |
|
|
#endif |
|
851 |
|
|
852 |
WRITE_MARKER(); |
WRITE_MARKER(); |
853 |
|
|
854 |
// time_increment: value=nth_of_sec, nbits = log2(resolution) |
// time_increment: value=nth_of_sec, nbits = log2(resolution) |
855 |
#ifdef BFRAMES |
|
856 |
BitstreamPutBits(bs, frame->ticks, log2bin(pParam->fbase)); |
BitstreamPutBits(bs, frame->ticks, log2bin(pParam->fbase)); |
857 |
/*DPRINTF("[%i:%i] %c\n", frame->seconds, frame->ticks, |
/*DPRINTF("[%i:%i] %c\n", frame->seconds, frame->ticks, |
858 |
frame->coding_type == I_VOP ? 'I' : frame->coding_type == |
frame->coding_type == I_VOP ? 'I' : frame->coding_type == |
859 |
P_VOP ? 'P' : 'B');*/ |
P_VOP ? 'P' : 'B');*/ |
|
#else |
|
|
BitstreamPutBits(bs, 1, 1); |
|
|
#endif |
|
860 |
|
|
861 |
WRITE_MARKER(); |
WRITE_MARKER(); |
862 |
|
|
867 |
|
|
868 |
BitstreamPutBits(bs, 1, 1); // vop_coded |
BitstreamPutBits(bs, 1, 1); // vop_coded |
869 |
|
|
870 |
if (frame->coding_type == P_VOP) |
if ( (frame->coding_type == P_VOP) || (frame->coding_type == S_VOP) ) |
871 |
BitstreamPutBits(bs, frame->rounding_type, 1); |
BitstreamPutBits(bs, frame->rounding_type, 1); |
872 |
|
|
873 |
BitstreamPutBits(bs, 0, 3); // intra_dc_vlc_threshold |
BitstreamPutBits(bs, 0, 3); // intra_dc_vlc_threshold |
874 |
|
|
875 |
if (frame->global_flags & XVID_INTERLACING) { |
if (frame->global_flags & XVID_INTERLACING) { |
876 |
BitstreamPutBit(bs, 1); // top field first |
BitstreamPutBit(bs, (frame->global_flags & XVID_TOPFIELDFIRST)); |
877 |
BitstreamPutBit(bs, 0); // alternate vertical scan |
BitstreamPutBit(bs, (frame->global_flags & XVID_ALTERNATESCAN)); |
878 |
|
} |
879 |
|
|
880 |
|
if (frame->coding_type == S_VOP) { |
881 |
|
if (1) { // no_of_sprite_warping_points>=1 |
882 |
|
if (pParam->m_quarterpel) |
883 |
|
bs_put_spritetrajectory(bs, frame->GMC_MV.x/2 ); // du[0] |
884 |
|
else |
885 |
|
bs_put_spritetrajectory(bs, frame->GMC_MV.x ); // du[0] |
886 |
|
WRITE_MARKER(); |
887 |
|
|
888 |
|
if (pParam->m_quarterpel) |
889 |
|
bs_put_spritetrajectory(bs, frame->GMC_MV.y/2 ); // dv[0] |
890 |
|
else |
891 |
|
bs_put_spritetrajectory(bs, frame->GMC_MV.y ); // dv[0] |
892 |
|
WRITE_MARKER(); |
893 |
|
} |
894 |
|
/* GMC is halfpel in bitstream, even though GMC_MV was pseudo-qpel (2*halfpel) */ |
895 |
|
|
896 |
|
if (2) { // no_of_sprite_warping_points>=2 (for DivX5 compat) |
897 |
|
bs_put_spritetrajectory(bs, 0 ); |
898 |
|
WRITE_MARKER(); |
899 |
|
bs_put_spritetrajectory(bs, 0 ); |
900 |
|
WRITE_MARKER(); |
901 |
|
} |
902 |
|
// no support for brightness_change! |
903 |
} |
} |
904 |
|
|
905 |
BitstreamPutBits(bs, frame->quant, 5); // quantizer |
BitstreamPutBits(bs, frame->quant, 5); // quantizer |
912 |
|
|
913 |
} |
} |
914 |
|
|
|
|
|
915 |
void |
void |
916 |
BitstreamWriteUserData(Bitstream * const bs, |
BitstreamWriteUserData(Bitstream * const bs, |
917 |
uint8_t * data, |
uint8_t * data, |