?? bitstream.c
字號:
} READ_MARKER(); length = bs_get_spritetrajectory(bs); if(length){ y = BitstreamGetBits(bs, length); if ((y >> (length - 1)) == 0) /* if MSB not set it is negative*/ y = - (y ^ ((1 << length) - 1)); } READ_MARKER(); gmc_warp->duv[i].x = x; gmc_warp->duv[i].y = y; DPRINTF(XVID_DEBUG_HEADER,"sprite_warping_point[%i] xy=(%i,%i)\n", i, x, y); } if (dec->sprite_brightness_change) { /* XXX: brightness_change_factor() */ } if (dec->sprite_enable == SPRITE_STATIC) { /* XXX: todo */ } } if ((*quant = BitstreamGetBits(bs, dec->quant_bits)) < 1) /* vop_quant */ *quant = 1; DPRINTF(XVID_DEBUG_HEADER, "quant %i\n", *quant); if (coding_type != I_VOP) { *fcode_forward = BitstreamGetBits(bs, 3); /* fcode_forward */ DPRINTF(XVID_DEBUG_HEADER, "fcode_forward %i\n", *fcode_forward); } if (coding_type == B_VOP) { *fcode_backward = BitstreamGetBits(bs, 3); /* fcode_backward */ DPRINTF(XVID_DEBUG_HEADER, "fcode_backward %i\n", *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) { char tmp[256]; int i, version, build; char packed; BitstreamSkip(bs, 32); /* user_data_start_code */ tmp[0] = BitstreamShowBits(bs, 8); for(i = 1; i < 256; i++){ tmp[i] = (BitstreamShowBits(bs, 16) & 0xFF); if(tmp[i] == 0) break; BitstreamSkip(bs, 8); } DPRINTF(XVID_DEBUG_STARTCODE, "<user_data>: %s\n", tmp); /* read xvid bitstream version */ if(strncmp(tmp, "XviD", 4) == 0) { if (tmp[strlen(tmp)-1] == 'C') { sscanf(tmp, "XviD%dC", &dec->bs_version); dec->cartoon_mode = 1; } else sscanf(tmp, "XviD%d", &dec->bs_version); DPRINTF(XVID_DEBUG_HEADER, "xvid bitstream version=%i\n", dec->bs_version); } /* divx detection */ i = sscanf(tmp, "DivX%dBuild%d%c", &version, &build, &packed); if (i < 2) i = sscanf(tmp, "DivX%db%d%c", &version, &build, &packed); if (i >= 2) { dec->packed_mode = (i == 3 && packed == 'p'); DPRINTF(XVID_DEBUG_HEADER, "divx version=%i, build=%i packed=%i\n", version, build, dec->packed_mode); } } else /* start_code == ? */ { if (BitstreamShowBits(bs, 24) == 0x000001) { DPRINTF(XVID_DEBUG_STARTCODE, "<unknown: %x>\n", BitstreamShowBits(bs, 32)); } BitstreamSkip(bs, 8); } } while ((BitstreamPos(bs) >> 3) < bs->length);#if 0 DPRINTF("*** WARNING: no vop_start_code found");#endif return -1; /* ignore it */}/* write custom quant matrix */static voidbs_put_matrix(Bitstream * bs, const uint16_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 * const frame){ static const unsigned int vo_id = 0; static const unsigned int vol_id = 0; int vol_ver_id = 1; int vol_type_ind = VIDOBJLAY_TYPE_SIMPLE; int vol_profile = pParam->profile; if ( (pParam->vol_flags & XVID_VOL_QUARTERPEL) || (pParam->vol_flags & XVID_VOL_GMC) || (pParam->vol_flags & XVID_VOL_REDUCED_ENABLE)) vol_ver_id = 2; if ((pParam->vol_flags & XVID_VOL_REDUCED_ENABLE)) { vol_type_ind = VIDOBJLAY_TYPE_ART_SIMPLE; } if ((pParam->vol_flags & XVID_VOL_QUARTERPEL) || (pParam->vol_flags & XVID_VOL_GMC)) { vol_type_ind = VIDOBJLAY_TYPE_ASP; } /* visual_object_sequence_start_code */#if 0 BitstreamPad(bs);#endif /* * no padding here, anymore. You have to make sure that you are * byte aligned, and that always 1-8 padding bits have been written */ if (!vol_profile) { /* Profile was not set by client app, use the more permissive profile * compatible with the vol_type_id */ switch(vol_type_ind) { case VIDOBJLAY_TYPE_ASP: vol_profile = 0xf5; /* ASP level 5 */ break; case VIDOBJLAY_TYPE_ART_SIMPLE: vol_profile = 0x94; /* ARTS level 4 */ break; default: vol_profile = 0x03; /* Simple level 3 */ break; } } /* Write the VOS header */ BitstreamPutBits(bs, VISOBJSEQ_START_CODE, 32); BitstreamPutBits(bs, vol_profile, 8); /* profile_and_level_indication */ /* visual_object_start_code */ BitstreamPad(bs); BitstreamPutBits(bs, VISOBJ_START_CODE, 32); BitstreamPutBits(bs, 0, 1); /* is_visual_object_identifier */ /* Video type */ BitstreamPutBits(bs, VISOBJ_TYPE_VIDEO, 4); /* visual_object_type */ BitstreamPutBit(bs, 0); /* video_signal_type */ /* video object_start_code & vo_id */ BitstreamPadAlways(bs); /* next_start_code() */ BitstreamPutBits(bs, VIDOBJ_START_CODE|(vo_id&0x5), 32); /* video_object_layer_start_code & vol_id */ BitstreamPad(bs); BitstreamPutBits(bs, VIDOBJLAY_START_CODE|(vol_id&0x4), 32); BitstreamPutBit(bs, 0); /* random_accessible_vol */ BitstreamPutBits(bs, vol_type_ind, 8); /* video_object_type_indication */ if (vol_ver_id == 1) { BitstreamPutBit(bs, 0); /* is_object_layer_identified (0=not given) */ } else { BitstreamPutBit(bs, 1); /* is_object_layer_identified */ BitstreamPutBits(bs, vol_ver_id, 4); /* vol_ver_id == 2 */ BitstreamPutBits(bs, 4, 3); /* vol_ver_priority (1==highest, 7==lowest) */ } /* Aspect ratio */ BitstreamPutBits(bs, pParam->par, 4); /* aspect_ratio_info (1=1:1) */ if(pParam->par == XVID_PAR_EXT) { BitstreamPutBits(bs, pParam->par_width, 8); BitstreamPutBits(bs, pParam->par_height, 8); } BitstreamPutBit(bs, 1); /* vol_control_parameters */ BitstreamPutBits(bs, 1, 2); /* chroma_format 1="4:2:0" */ if (pParam->max_bframes > 0) { BitstreamPutBit(bs, 0); /* low_delay */ } else { 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_inc_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(); if (pParam->fincr>0) { BitstreamPutBit(bs, 1); /* fixed_vop_rate = 1 */ BitstreamPutBits(bs, pParam->fincr, MAX(log2bin(pParam->fbase-1),1)); /* fixed_vop_time_increment */ }else{ BitstreamPutBit(bs, 0); /* fixed_vop_rate = 0 */ } WRITE_MARKER(); BitstreamPutBits(bs, pParam->width, 13); /* width */ WRITE_MARKER(); BitstreamPutBits(bs, pParam->height, 13); /* height */ WRITE_MARKER(); BitstreamPutBit(bs, pParam->vol_flags & XVID_VOL_INTERLACING); /* interlace */ BitstreamPutBit(bs, 1); /* obmc_disable (overlapped block motion compensation) */ if (vol_ver_id != 1) { if ((pParam->vol_flags & XVID_VOL_GMC)) { BitstreamPutBits(bs, 2, 2); /* sprite_enable=='GMC' */ BitstreamPutBits(bs, 3, 6); /* no_of_sprite_warping_points */ BitstreamPutBits(bs, 3, 2); /* sprite_warping_accuracy 0==1/2, 1=1/4, 2=1/8, 3=1/16 */ BitstreamPutBit(bs, 0); /* sprite_brightness_change (not supported) */ /* * currently we use no_of_sprite_warping_points==2, sprite_warping_accuracy==3 * for DivX5 compatability */ } else BitstreamPutBits(bs, 0, 2); /* sprite_enable==off */ } else BitstreamPutBit(bs, 0); /* sprite_enable==off */ BitstreamPutBit(bs, 0); /* not_8_bit */ /* quant_type 0=h.263 1=mpeg4(quantizer tables) */ BitstreamPutBit(bs, pParam->vol_flags & XVID_VOL_MPEGQUANT); if ((pParam->vol_flags & XVID_VOL_MPEGQUANT)) { BitstreamPutBit(bs, is_custom_intra_matrix(pParam->mpeg_quant_matrices)); /* load_intra_quant_mat */ if(is_custom_intra_matrix(pParam->mpeg_quant_matrices)) bs_put_matrix(bs, get_intra_matrix(pParam->mpeg_quant_matrices)); BitstreamPutBit(bs, is_custom_inter_matrix(pParam->mpeg_quant_matrices)); /* load_inter_quant_mat */ if(is_custom_inter_matrix(pParam->mpeg_quant_matrices)) bs_put_matrix(bs, get_inter_matrix(pParam->mpeg_quant_matrices)); } if (vol_ver_id != 1) { if ((pParam->vol_flags & XVID_VOL_QUARTERPEL)) BitstreamPutBit(bs, 1); /* quarterpel */ else BitstreamPutBit(bs, 0); /* no quarterpel */ } BitstreamPutBit(bs, 1); /* complexity_estimation_disable */ BitstreamPutBit(bs, 1); /* resync_marker_disable */ BitstreamPutBit(bs, 0); /* data_partitioned */ if (vol_ver_id != 1) { BitstreamPutBit(bs, 0); /* newpred_enable */ BitstreamPutBit(bs, (pParam->vol_flags & XVID_VOL_REDUCED_ENABLE)?1:0); /* reduced_resolution_vop_enabled */ } BitstreamPutBit(bs, 0); /* scalability */ BitstreamPadAlways(bs); /* next_start_code(); */ /* fake divx5 id, to ensure compatibility with divx5 decoder */#define DIVX5_ID "DivX999b000p" if (pParam->max_bframes > 0 && (pParam->global_flags & XVID_GLOBAL_PACKED)) { BitstreamWriteUserData(bs, DIVX5_ID, strlen(DIVX5_ID)); } /* xvid id */ { const char xvid_user_format[] = "XviD%04d%c"; char xvid_user_data[100]; sprintf(xvid_user_data, xvid_user_format, XVID_BS_VERSION, (frame->vop_flags & XVID_VOP_CARTOON)?'C':'\0'); BitstreamWriteUserData(bs, xvid_user_data, strlen(xvid_user_data)); }}/* write vop header*/voidBitstreamWriteVopHeader( Bitstream * const bs, const MBParam * pParam, const FRAMEINFO * const frame, int vop_coded, unsigned int quant){ uint32_t i;#if 0 BitstreamPad(bs);#endif /* * no padding here, anymore. You have to make sure that you are * byte aligned, and that always 1-8 padding bits have been written */ BitstreamPutBits(bs, VOP_START_CODE, 32); BitstreamPutBits(bs, frame->coding_type, 2);#if 0 DPRINTF(XVID_DEBUG_HEADER, "coding_type = %i\n", frame->coding_type);#endif 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, MAX(log2bin(pParam->fbase-1), 1));#if 0 DPRINTF("[%i:%i] %c", frame->seconds, frame->ticks, frame->coding_type == I_VOP ? 'I' : frame->coding_type == P_VOP ? 'P' : frame->coding_type == S_VOP ? 'S' : 'B');#endif WRITE_MARKER(); if (!vop_coded) { BitstreamPutBits(bs, 0, 1);#if 0 BitstreamPadAlways(bs); /* next_start_code() */#endif /* NB: It's up to the function caller to write the next_start_code(). * At the moment encoder.c respects that requisite because a VOP * always ends with a next_start_code either if it's coded or not * and encoder.c terminates a frame with a next_start_code in whatever * case */ return; } BitstreamPutBits(bs, 1, 1); /* vop_coded */ if ( (frame->coding_type == P_VOP) || (frame->coding_type == S_VOP) ) BitstreamPutBits(bs, frame->rounding_type, 1); if ((frame->vol_flags & XVID_VOL_REDUCED_ENABLE)) BitstreamPutBit(bs, (frame->vop_flags & XVID_VOP_REDUCED)?1:0); BitstreamPutBits(bs, 0, 3); /* intra_dc_vlc_threshold */ if ((frame->vol_flags & XVID_VOL_INTERLACING)) { BitstreamPutBit(bs, (frame->vop_flags & XVID_VOP_TOPFIELDFIRST)); BitstreamPutBit(bs, (frame->vop_flags & XVID_VOP_ALTERNATESCAN)); } if (frame->coding_type == S_VOP) { if (1) { /* no_of_sprite_warping_points>=1 (we use 2!) */ int k; for (k=0;k<3;k++) { bs_put_spritetrajectory(bs, frame->warp.duv[k].x ); /* du[k] */ WRITE_MARKER(); bs_put_spritetrajectory(bs, frame->warp.duv[k].y ); /* dv[k] */ WRITE_MARKER(); if ((frame->vol_flags & XVID_VOL_QUARTERPEL)) { DPRINTF(XVID_DEBUG_HEADER,"sprite_warping_point[%i] xy=(%i,%i) *QPEL*\n", k, frame->warp.duv[k].x/2, frame->warp.duv[k].y/2); } else { DPRINTF(XVID_DEBUG_HEADER,"sprite_warping_point[%i] xy=(%i,%i)\n", k, frame->warp.duv[k].x, frame->warp.duv[k].y); } } } }#if 0 DPRINTF(XVID_DEBUG_HEADER, "quant = %i\n", quant);#endif BitstreamPutBits(bs, 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 */}voidBitstreamWriteUserData(Bitstream * const bs, uint8_t * data, const int length){ int i; BitstreamPad(bs); BitstreamPutBits(bs, USERDATA_START_CODE, 32); for (i = 0; i < length; i++) { BitstreamPutBits(bs, data[i], 8); }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -