41 |
* * |
* * |
42 |
* Revision history: * |
* Revision history: * |
43 |
* * |
* * |
44 |
|
* 06.05.2002 low_delay * |
45 |
|
* 06.05.2002 fixed fincr/fbase error * |
46 |
|
* 01.05.2002 added BVOP support to BitstreamWriteVopHeader * |
47 |
* 15.04.2002 rewrite log2bin use asm386 By MinChen <chenm001@163.com> * |
* 15.04.2002 rewrite log2bin use asm386 By MinChen <chenm001@163.com> * |
48 |
* 26.03.2002 interlacing support * |
* 26.03.2002 interlacing support * |
49 |
* 03.03.2002 qmatrix writing * |
* 03.03.2002 qmatrix writing * |
60 |
#include "../quant/quant_matrix.h" |
#include "../quant/quant_matrix.h" |
61 |
|
|
62 |
|
|
63 |
static int __inline log2bin(int value) |
static uint32_t __inline log2bin(uint32_t value) |
64 |
{ |
{ |
65 |
/* Changed by Chenm001 */ |
/* Changed by Chenm001 */ |
66 |
#ifndef WIN32 |
#ifndef WIN32 |
117 |
returns coding_type, or -1 if error |
returns coding_type, or -1 if error |
118 |
*/ |
*/ |
119 |
|
|
120 |
int BitstreamReadHeaders(Bitstream * bs, DECODER * dec, uint32_t * rounding, uint32_t * quant, uint32_t * fcode, uint32_t * intra_dc_threshold) |
int BitstreamReadHeaders(Bitstream * bs, DECODER * dec, uint32_t * rounding, uint32_t * quant, uint32_t * fcode_forward, uint32_t * fcode_backward, uint32_t * intra_dc_threshold) |
121 |
{ |
{ |
122 |
uint32_t vol_ver_id; |
uint32_t vol_ver_id; |
123 |
uint32_t time_inc_resolution; |
static uint32_t time_increment_resolution; |
124 |
uint32_t coding_type; |
uint32_t coding_type; |
125 |
uint32_t start_code; |
uint32_t start_code; |
126 |
|
uint32_t time_incr=0; |
127 |
|
int32_t time_increment; |
128 |
|
|
129 |
do |
do |
130 |
{ |
{ |
253 |
|
|
254 |
READ_MARKER(); |
READ_MARKER(); |
255 |
|
|
256 |
time_inc_resolution = BitstreamGetBits(bs, 16); // vop_time_increment_resolution |
// *************************** for decode B-frame time *********************** |
257 |
time_inc_resolution--; |
time_increment_resolution = BitstreamGetBits(bs, 16); // vop_time_increment_resolution |
258 |
if (time_inc_resolution > 0) |
time_increment_resolution--; |
259 |
|
//DEBUG1("time_increment_resolution=",time_increment_resolution); |
260 |
|
if (time_increment_resolution > 0) |
261 |
{ |
{ |
262 |
dec->time_inc_bits = log2bin(time_inc_resolution); |
dec->time_inc_bits = log2bin(time_increment_resolution); |
263 |
} |
} |
264 |
else |
else |
265 |
{ |
{ |
423 |
} |
} |
424 |
} |
} |
425 |
|
|
426 |
if (BitstreamGetBit(bs)) // scalability |
if ((dec->scalability=BitstreamGetBit(bs))) // scalability |
427 |
{ |
{ |
428 |
// TODO |
// TODO |
429 |
DEBUG("TODO: scalability"); |
DEBUG("TODO: scalability"); |
469 |
coding_type = BitstreamGetBits(bs, 2); // vop_coding_type |
coding_type = BitstreamGetBits(bs, 2); // vop_coding_type |
470 |
//DEBUG1("coding_type", coding_type); |
//DEBUG1("coding_type", coding_type); |
471 |
|
|
472 |
while (BitstreamGetBit(bs) != 0) ; // time_base |
// *************************** for decode B-frame time *********************** |
473 |
|
while (BitstreamGetBit(bs) != 0) // time_base |
474 |
|
time_incr++; |
475 |
|
|
476 |
READ_MARKER(); |
READ_MARKER(); |
477 |
|
|
479 |
//DEBUG1("vop_time_incr", BitstreamShowBits(bs, dec->time_inc_bits)); |
//DEBUG1("vop_time_incr", BitstreamShowBits(bs, dec->time_inc_bits)); |
480 |
if (dec->time_inc_bits) |
if (dec->time_inc_bits) |
481 |
{ |
{ |
482 |
BitstreamSkip(bs, dec->time_inc_bits); // vop_time_increment |
//BitstreamSkip(bs, dec->time_inc_bits); // vop_time_increment |
483 |
|
time_increment = (BitstreamGetBits(bs, dec->time_inc_bits)); // vop_time_increment |
484 |
|
} |
485 |
|
if(coding_type != B_VOP){ |
486 |
|
dec->last_time_base = dec->time_base; |
487 |
|
dec->time_base += time_incr; |
488 |
|
dec->time = dec->time_base*time_increment_resolution + time_increment; |
489 |
|
dec->time_pp= (uint32_t)(dec->time - dec->last_non_b_time); |
490 |
|
dec->last_non_b_time= dec->time; |
491 |
|
}else{ |
492 |
|
dec->time = (dec->last_time_base + time_incr)*time_increment_resolution + time_increment; |
493 |
|
dec->time_bp= (uint32_t)(dec->last_non_b_time - dec->time); |
494 |
} |
} |
495 |
|
//DEBUG1("time_increment=",time_increment); |
496 |
|
|
497 |
READ_MARKER(); |
READ_MARKER(); |
498 |
|
|
506 |
} |
} |
507 |
*/ |
*/ |
508 |
|
|
509 |
if (coding_type != I_VOP) |
// fix a little bug by MinChen <chenm002@163.com> |
510 |
|
if ((dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) && (coding_type == P_VOP)) |
511 |
{ |
{ |
512 |
*rounding = BitstreamGetBit(bs); // rounding_type |
*rounding = BitstreamGetBit(bs); // rounding_type |
513 |
//DEBUG1("rounding", *rounding); |
//DEBUG1("rounding", *rounding); |
561 |
} |
} |
562 |
} |
} |
563 |
|
|
564 |
*quant = BitstreamGetBits(bs, dec->quant_bits); // vop_quant |
if((*quant = BitstreamGetBits(bs, dec->quant_bits)) < 1) // vop_quant |
565 |
|
*quant = 1; |
566 |
|
|
567 |
//DEBUG1("quant", *quant); |
//DEBUG1("quant", *quant); |
568 |
|
|
569 |
if (coding_type != I_VOP) |
if (coding_type != I_VOP) |
570 |
{ |
{ |
571 |
*fcode = BitstreamGetBits(bs, 3); // fcode_forward |
*fcode_forward = BitstreamGetBits(bs, 3); // fcode_forward |
572 |
} |
} |
573 |
|
|
574 |
if (coding_type == B_VOP) |
if (coding_type == B_VOP) |
575 |
{ |
{ |
576 |
// *fcode_backward = BitstreamGetBits(bs, 3); // fcode_backward |
*fcode_backward = BitstreamGetBits(bs, 3); // fcode_backward |
577 |
|
} |
578 |
|
if (!dec->scalability){ |
579 |
|
if ((dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) && (coding_type != I_VOP)){ |
580 |
|
BitstreamSkip(bs, 1); // vop_shape_coding_type |
581 |
|
} |
582 |
} |
} |
583 |
return coding_type; |
return coding_type; |
584 |
} |
} |
628 |
write vol header |
write vol header |
629 |
*/ |
*/ |
630 |
void BitstreamWriteVolHeader(Bitstream * const bs, |
void BitstreamWriteVolHeader(Bitstream * const bs, |
631 |
const MBParam * pParam) |
const MBParam * pParam, const FRAMEINFO * frame) |
632 |
{ |
{ |
633 |
// video object_start_code & vo_id |
// video object_start_code & vo_id |
634 |
BitstreamPad(bs); |
BitstreamPad(bs); |
643 |
BitstreamPutBits(bs, 0, 8); // video_object_type_indication |
BitstreamPutBits(bs, 0, 8); // video_object_type_indication |
644 |
BitstreamPutBit(bs, 0); // is_object_layer_identified (0=not given) |
BitstreamPutBit(bs, 0); // is_object_layer_identified (0=not given) |
645 |
BitstreamPutBits(bs, 1, 4); // aspect_ratio_info (1=1:1) |
BitstreamPutBits(bs, 1, 4); // aspect_ratio_info (1=1:1) |
646 |
BitstreamPutBit(bs, 0); // vol_control_parameters (0=not given) |
|
647 |
|
#ifdef BFRAMES |
648 |
|
if (pParam->max_bframes > 0) |
649 |
|
{ |
650 |
|
dprintf("low_delay=1"); |
651 |
|
BitstreamPutBit(bs, 1); // vol_control_parameters |
652 |
|
BitstreamPutBits(bs, 1, 2); // chroma_format 1="4:2:0" |
653 |
|
BitstreamPutBit(bs, 0); // low_delay |
654 |
|
BitstreamPutBit(bs, 0); // vbv_parameters (0=not given) |
655 |
|
} |
656 |
|
else |
657 |
|
#endif |
658 |
|
{ |
659 |
|
BitstreamPutBits(bs, 0, 1); // vol_control_parameters (0=not given) |
660 |
|
} |
661 |
|
|
662 |
|
|
663 |
BitstreamPutBits(bs, 0, 2); // video_object_layer_shape (0=rectangular) |
BitstreamPutBits(bs, 0, 2); // video_object_layer_shape (0=rectangular) |
664 |
|
|
665 |
WRITE_MARKER(); |
WRITE_MARKER(); |
669 |
25fps res=25 inc=1 |
25fps res=25 inc=1 |
670 |
29.97fps res=30000 inc=1001 |
29.97fps res=30000 inc=1001 |
671 |
*/ |
*/ |
672 |
|
#ifdef BFRAMES |
673 |
|
BitstreamPutBits(bs, pParam->fbase, 16); |
674 |
|
#else |
675 |
BitstreamPutBits(bs, 2, 16); |
BitstreamPutBits(bs, 2, 16); |
676 |
|
#endif |
677 |
|
|
678 |
WRITE_MARKER(); |
WRITE_MARKER(); |
679 |
|
|
689 |
BitstreamPutBits(bs, pParam->height, 13); // height |
BitstreamPutBits(bs, pParam->height, 13); // height |
690 |
WRITE_MARKER(); |
WRITE_MARKER(); |
691 |
|
|
692 |
BitstreamPutBit(bs, pParam->global_flags & XVID_INTERLACING); // interlace |
BitstreamPutBit(bs, frame->global_flags & XVID_INTERLACING); // interlace |
693 |
BitstreamPutBit(bs, 1); // obmc_disable (overlapped block motion compensation) |
BitstreamPutBit(bs, 1); // obmc_disable (overlapped block motion compensation) |
694 |
BitstreamPutBit(bs, 0); // sprite_enable |
BitstreamPutBit(bs, 0); // sprite_enable |
695 |
BitstreamPutBit(bs, 0); // not_in_bit |
BitstreamPutBit(bs, 0); // not_in_bit |
696 |
|
|
697 |
// quant_type 0=h.263 1=mpeg4(quantizer tables) |
// quant_type 0=h.263 1=mpeg4(quantizer tables) |
698 |
BitstreamPutBit(bs, pParam->quant_type); |
BitstreamPutBit(bs, pParam->m_quant_type); |
699 |
|
|
700 |
if (pParam->quant_type) |
if (pParam->m_quant_type) |
701 |
{ |
{ |
702 |
BitstreamPutBit(bs, get_intra_matrix_status()); // load_intra_quant_mat |
BitstreamPutBit(bs, get_intra_matrix_status()); // load_intra_quant_mat |
703 |
if (get_intra_matrix_status()) |
if (get_intra_matrix_status()) |
729 |
(decoder uses these values to determine precise time since last resync) |
(decoder uses these values to determine precise time since last resync) |
730 |
*/ |
*/ |
731 |
void BitstreamWriteVopHeader(Bitstream * const bs, |
void BitstreamWriteVopHeader(Bitstream * const bs, |
732 |
const MBParam * pParam) |
const MBParam * pParam, |
733 |
|
const FRAMEINFO * frame) |
734 |
{ |
{ |
735 |
|
#ifdef BFRAMES |
736 |
|
uint32_t i; |
737 |
|
#endif |
738 |
BitstreamPad(bs); |
BitstreamPad(bs); |
739 |
BitstreamPutBits(bs, VOP_START_CODE, 32); |
BitstreamPutBits(bs, VOP_START_CODE, 32); |
740 |
|
|
741 |
BitstreamPutBits(bs, pParam->coding_type, 2); |
BitstreamPutBits(bs, frame->coding_type, 2); |
742 |
|
|
743 |
// time_base = 0 write n x PutBit(1), PutBit(0) |
// time_base = 0 write n x PutBit(1), PutBit(0) |
744 |
|
#ifdef BFRAMES |
745 |
|
for (i = 0; i < frame->seconds; i++) |
746 |
|
{ |
747 |
|
BitstreamPutBit(bs, 1); |
748 |
|
} |
749 |
|
BitstreamPutBit(bs, 0); |
750 |
|
#else |
751 |
BitstreamPutBits(bs, 0, 1); |
BitstreamPutBits(bs, 0, 1); |
752 |
|
#endif |
753 |
|
|
754 |
WRITE_MARKER(); |
WRITE_MARKER(); |
755 |
|
|
756 |
// time_increment: value=nth_of_sec, nbits = log2(resolution) |
// time_increment: value=nth_of_sec, nbits = log2(resolution) |
757 |
|
#ifdef BFRAMES |
758 |
|
BitstreamPutBits(bs, frame->ticks, log2bin(pParam->fbase)); |
759 |
|
dprintf("[%i:%i] %c\n", frame->seconds, frame->ticks, frame->coding_type == I_VOP ? 'I' : frame->coding_type == P_VOP ? 'P' : 'B'); |
760 |
|
#else |
761 |
BitstreamPutBits(bs, 1, 1); |
BitstreamPutBits(bs, 1, 1); |
762 |
|
#endif |
763 |
|
|
764 |
WRITE_MARKER(); |
WRITE_MARKER(); |
765 |
|
|
766 |
BitstreamPutBits(bs, 1, 1); // vop_coded |
BitstreamPutBits(bs, 1, 1); // vop_coded |
767 |
|
|
768 |
if (pParam->coding_type != I_VOP) |
if (frame->coding_type == P_VOP) |
769 |
BitstreamPutBits(bs, pParam->rounding_type, 1); |
BitstreamPutBits(bs, frame->rounding_type, 1); |
770 |
|
|
771 |
BitstreamPutBits(bs, 0, 3); // intra_dc_vlc_threshold |
BitstreamPutBits(bs, 0, 3); // intra_dc_vlc_threshold |
772 |
|
|
773 |
if (pParam->global_flags & XVID_INTERLACING) |
if (frame->global_flags & XVID_INTERLACING) |
774 |
{ |
{ |
775 |
BitstreamPutBit(bs, 1); // top field first |
BitstreamPutBit(bs, 1); // top field first |
776 |
BitstreamPutBit(bs, 0); // alternate vertical scan |
BitstreamPutBit(bs, 0); // alternate vertical scan |
777 |
} |
} |
778 |
|
|
779 |
BitstreamPutBits(bs, pParam->quant, 5); // quantizer |
BitstreamPutBits(bs, frame->quant, 5); // quantizer |
780 |
|
|
781 |
|
if (frame->coding_type != I_VOP) |
782 |
|
BitstreamPutBits(bs, frame->fcode, 3); // forward_fixed_code |
783 |
|
|
784 |
|
if (frame->coding_type == B_VOP) |
785 |
|
BitstreamPutBits(bs, frame->bcode, 3); // backward_fixed_code |
786 |
|
|
|
if (pParam->coding_type != I_VOP) |
|
|
BitstreamPutBits(bs, pParam->fixed_code, 3); // fixed_code = [1,4] |
|
787 |
} |
} |