📄 bitstream.c
字号:
bs_get_matrix(bs, matrix); set_intra_matrix(matrix); } else set_intra_matrix(get_default_intra_matrix()); if (BitstreamGetBit(bs)) /* load_inter_quant_mat */ { uint8_t matrix[64]; DPRINTF(DPRINTF_HEADER, "load_inter_quant_mat"); bs_get_matrix(bs, matrix); set_inter_matrix(matrix); } else set_inter_matrix(get_default_inter_matrix()); if (dec->shape == VIDOBJLAY_SHAPE_GRAYSCALE) { DPRINTF(DPRINTF_ERROR, "greyscale matrix not supported"); return -1; } } if (vol_ver_id != 1) { DPRINTF(DPRINTF_DEBUG, "QUARTERPEL BITSTREAM"); dec->quarterpel = BitstreamGetBit(bs); /* quarter_sample */ } else dec->quarterpel = 0; if (!BitstreamGetBit(bs)) /* complexity_estimation_disable */ { DPRINTF(DPRINTF_ERROR, "complexity_estimation not supported"); return -1; } BitstreamSkip(bs, 1); /* resync_marker_disable */ if (BitstreamGetBit(bs)) /* data_partitioned */ { DPRINTF(DPRINTF_ERROR, "data_partitioned not supported"); BitstreamSkip(bs, 1); /* reversible_vlc */ } if (vol_ver_id != 1) { if (BitstreamGetBit(bs)) /* newpred_enable */ { DPRINTF(DPRINTF_HEADER, "+ newpred_enable"); BitstreamSkip(bs, 2); /* requested_upstream_message_type */ BitstreamSkip(bs, 1); /* newpred_segment_type */ } if (BitstreamGetBit(bs)) /* reduced_resolution_vop_enable */ { DPRINTF(DPRINTF_ERROR, "reduced_resolution_vop not supported"); return -1; } } if ((dec->scalability = (int8_t)BitstreamGetBit(bs))) /* scalability */ { DPRINTF(DPRINTF_ERROR, "scalability not supported"); return -1; } } else /* dec->shape == BINARY_ONLY */ { if (vol_ver_id != 1) { if (BitstreamGetBit(bs)) /* scalability */ { DPRINTF(DPRINTF_ERROR, "scalability not supported"); return -1; } } BitstreamSkip(bs, 1); /* resync_marker_disable */ } } else if (start_code == GRPOFVOP_START_CODE) { DPRINTF(DPRINTF_STARTCODE, "<group_of_vop>"); BitstreamSkip(bs, 32); { int hours, minutes, seconds; hours = BitstreamGetBits(bs, 5); minutes = BitstreamGetBits(bs, 6); READ_MARKER(); seconds = BitstreamGetBits(bs, 6); DPRINTF(DPRINTF_HEADER, "time %ih%im%is", hours); } BitstreamSkip(bs, 1); /* closed_gov */ BitstreamSkip(bs, 1); /* broken_link */ } else if (start_code == VOP_START_CODE) { DPRINTF(DPRINTF_STARTCODE, "<vop>"); BitstreamSkip(bs, 32); /* vop_start_code */ coding_type = BitstreamGetBits(bs, 2); /* vop_coding_type */ DPRINTF(DPRINTF_HEADER, "coding_type %i", coding_type);/* *************************** for decode B-frame time *********************** */ while (BitstreamGetBit(bs) != 0) /* time_base */ time_incr++; READ_MARKER(); if (dec->time_inc_bits) { time_increment = (BitstreamGetBits(bs, dec->time_inc_bits)); /* vop_time_increment */ } DPRINTF(DPRINTF_HEADER, "time_base %i", time_incr); DPRINTF(DPRINTF_HEADER, "time_increment %i", time_increment); DPRINTF(DPRINTF_TIMECODE, "%c %i:%i", coding_type == I_VOP ? 'I' : coding_type == P_VOP ? 'P' : 'B', time_incr, time_increment); if (coding_type != B_VOP) { dec->last_time_base = dec->time_base; dec->time_base += time_incr; dec->time = time_increment;/* dec->time_base * time_increment_resolution + time_increment;*/ dec->time_pp = (uint32_t) (time_increment_resolution + dec->time - dec->last_non_b_time)%time_increment_resolution; dec->last_non_b_time = dec->time; } else { dec->time = time_increment; /* (dec->last_time_base + time_incr) * time_increment_resolution + time_increment; */ dec->time_bp = (uint32_t) (time_increment_resolution + dec->last_non_b_time - dec->time)%time_increment_resolution; } READ_MARKER(); if (!BitstreamGetBit(bs)) /* vop_coded */ { DPRINTF(DPRINTF_HEADER, "vop_coded==false"); return N_VOP; } /* if (newpred_enable) { } */ /* fix a little bug by MinChen <chenm002@163.com> */ if ((dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) && (coding_type == P_VOP)) { *rounding = BitstreamGetBit(bs); /* rounding_type */ DPRINTF(DPRINTF_HEADER, "rounding %i", *rounding); } /* if (reduced_resolution_enable) { } */ if (dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) { uint32_t width, height; uint32_t horiz_mc_ref, vert_mc_ref; width = BitstreamGetBits(bs, 13); READ_MARKER(); height = BitstreamGetBits(bs, 13); READ_MARKER(); horiz_mc_ref = BitstreamGetBits(bs, 13); READ_MARKER(); vert_mc_ref = BitstreamGetBits(bs, 13); READ_MARKER(); DPRINTF(DPRINTF_HEADER, "width %i", width); DPRINTF(DPRINTF_HEADER, "height %i", height); DPRINTF(DPRINTF_HEADER, "horiz_mc_ref %i", horiz_mc_ref); DPRINTF(DPRINTF_HEADER, "vert_mc_ref %i", vert_mc_ref); BitstreamSkip(bs, 1); /* change_conv_ratio_disable */ if (BitstreamGetBit(bs)) /* vop_constant_alpha */ { BitstreamSkip(bs, 8); /* vop_constant_alpha_value */ } } if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) { /* intra_dc_vlc_threshold */ *intra_dc_threshold = intra_dc_threshold_table[BitstreamGetBits(bs, 3)]; if (dec->interlacing) { dec->top_field_first = BitstreamGetBit(bs); DPRINTF(DPRINTF_HEADER, "interlace top_field_first %i", dec->top_field_first); dec->alternate_vertical_scan = BitstreamGetBit(bs); DPRINTF(DPRINTF_HEADER, "interlace alternate_vertical_scan %i", dec->alternate_vertical_scan); } } if ((*quant = BitstreamGetBits(bs, dec->quant_bits)) < 1) /* vop_quant */ *quant = 1; DPRINTF(DPRINTF_HEADER, "quant %i", *quant); if (coding_type != I_VOP) { *fcode_forward = BitstreamGetBits(bs, 3); /* fcode_forward */ DPRINTF(DPRINTF_HEADER, "fcode_forward %i", *fcode_forward); } if (coding_type == B_VOP) { *fcode_backward = BitstreamGetBits(bs, 3); /* fcode_backward */ DPRINTF(DPRINTF_HEADER, "fcode_backward %i", *fcode_backward); } if (!dec->scalability) { if ((dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) && (coding_type != I_VOP)) { BitstreamSkip(bs, 1); /* vop_shape_coding_type */ } } return coding_type; } else if (start_code == USERDATA_START_CODE) { DPRINTF(DPRINTF_STARTCODE, "<user_data>"); BitstreamSkip(bs, 32); /* user_data_start_code */ } else /* start_code == ? */ { if (BitstreamShowBits(bs, 24) == 0x000001) { DPRINTF(DPRINTF_STARTCODE, "<unknown: %x>", BitstreamShowBits(bs, 32)); } BitstreamSkip(bs, 8); } } while ((BitstreamPos(bs) >> 3) < bs->length); /*DPRINTF("*** WARNING: no vop_start_code found"); */ return -1; /* ignore it */}/* write custom quant matrix */static voidbs_put_matrix(Bitstream * bs, const int16_t * matrix){ int i, j; const int last = matrix[scan_tables[0][63]]; for (j = 63; j > 0 && matrix[scan_tables[0][j - 1]] == last; j--); for (i = 0; i <= j; i++) { BitstreamPutBits(bs, matrix[scan_tables[0][i]], 8); } if (j < 63) { BitstreamPutBits(bs, 0, 8); }}/* write vol header*/voidBitstreamWriteVolHeader(Bitstream * const bs, const MBParam * pParam, const FRAMEINFO * frame){ /* video object_start_code & vo_id */ BitstreamPad(bs); BitstreamPutBits(bs, VO_START_CODE, 27); BitstreamPutBits(bs, 0, 5); /* video_object_layer_start_code & vol_id */ BitstreamPutBits(bs, VOL_START_CODE, 28); BitstreamPutBits(bs, 0, 4); BitstreamPutBit(bs, 0); /* random_accessible_vol */ BitstreamPutBits(bs, 1, 8); /* video_object_type_indication "Video ID" == 00000001 */ BitstreamPutBit(bs, 0); /* is_object_layer_identified (0=not given) */ BitstreamPutBits(bs, 1, 4); /* aspect_ratio_info (1=1:1) */ BitstreamPutBit(bs, 1); /* vol_control_parameters */ BitstreamPutBits(bs, 1, 2); /* chroma_format 1="4:2:0" */ BitstreamPutBit(bs, 1); /* low_delay */ BitstreamPutBit(bs, 0); /* vbv_parameters (0=not given) */ BitstreamPutBits(bs, 0, 2); /* video_object_layer_shape (0=rectangular) */ WRITE_MARKER(); /* * time_increment_resolution; ignored by current decore versions * eg. 2fps res=2 inc=1 * 25fps res=25 inc=1 * 29.97fps res=30000 inc=1001 */ BitstreamPutBits(bs, pParam->fbase, 16); WRITE_MARKER(); BitstreamPutBit(bs, 1); /* fixed_vop_rate = 1 */ BitstreamPutBits(bs, pParam->fincr, log2bin(pParam->fbase)); /* fixed_vop_time_increment */ WRITE_MARKER(); BitstreamPutBits(bs, pParam->width, 13); /* width */ WRITE_MARKER(); BitstreamPutBits(bs, pParam->height, 13); /* height */ WRITE_MARKER(); BitstreamPutBit(bs, frame->global_flags & XVID_INTERLACING); /* interlace */ BitstreamPutBit(bs, 1); /* obmc_disable (overlapped block motion compensation) */ BitstreamPutBit(bs, 0); /* sprite_enable */ BitstreamPutBit(bs, 0); /* not_8_bit */ /* quant_type 0=h.263 1=mpeg4(quantizer tables) */ BitstreamPutBit(bs, pParam->m_quant_type); if (pParam->m_quant_type) { BitstreamPutBit(bs, get_intra_matrix_status()); /* load_intra_quant_mat */ if (get_intra_matrix_status()) { bs_put_matrix(bs, get_intra_matrix()); } BitstreamPutBit(bs, get_inter_matrix_status()); /* load_inter_quant_mat */ if (get_inter_matrix_status()) { bs_put_matrix(bs, get_inter_matrix()); } } BitstreamPutBit(bs, 1); /* complexity_estimation_disable */ BitstreamPutBit(bs, 1); /* resync_marker_disable */ BitstreamPutBit(bs, 0); /* data_partitioned */ BitstreamPutBit(bs, 0); /* scalability */ BitstreamPadAlways(bs); /* next_start_code() */}/* 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)*/voidBitstreamWriteVopHeader(Bitstream * const bs, const MBParam * pParam, const FRAMEINFO * frame, int vop_coded){ uint32_t i; BitstreamPad(bs); BitstreamPutBits(bs, VOP_START_CODE, 32); BitstreamPutBits(bs, frame->coding_type, 2); /* time_base = 0 write n x PutBit(1), PutBit(0) */ for (i = 0; i < frame->seconds; i++) { BitstreamPutBit(bs, 1); } BitstreamPutBit(bs, 0); WRITE_MARKER(); /* time_increment: value=nth_of_sec, nbits = log2(resolution) */ BitstreamPutBits(bs, frame->ticks, log2bin(pParam->fbase)); WRITE_MARKER(); if (!vop_coded) { BitstreamPutBits(bs, 0, 1); return; } BitstreamPutBits(bs, 1, 1); /* vop_coded */ if (frame->coding_type == P_VOP) BitstreamPutBits(bs, frame->rounding_type, 1); BitstreamPutBits(bs, 0, 3); /* intra_dc_vlc_threshold */ if (frame->global_flags & XVID_INTERLACING) { BitstreamPutBit(bs, 1); /* top field first */ BitstreamPutBit(bs, 0); /* alternate vertical scan */ } BitstreamPutBits(bs, frame->quant, 5); /* quantizer */ if (frame->coding_type != I_VOP) BitstreamPutBits(bs, frame->fcode, 3); /* forward_fixed_code */ if (frame->coding_type == B_VOP) BitstreamPutBits(bs, frame->bcode, 3); /* backward_fixed_code */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -