static int32_t getFPS( demux_t *p_demux, block_t * p_block ) { demux_sys_t *p_sys = p_demux->p_sys; bs_t bs; uint8_t * p_decoded_nal; int i_decoded_nal; if( p_block->i_buffer < 5 ) return -1; p_decoded_nal = CreateDecodedNAL(&i_decoded_nal, p_block->p_buffer+4, p_block->i_buffer-4); if( !p_decoded_nal ) return -1; bs_init( &bs, p_decoded_nal, i_decoded_nal ); bs_skip( &bs, 12 ); int32_t max_sub_layer_minus1 = bs_read( &bs, 3 ); bs_skip( &bs, 17 ); hevc_skip_profile_tiers_level( &bs, max_sub_layer_minus1 ); int32_t vps_sub_layer_ordering_info_present_flag = bs_read1( &bs ); int32_t i = vps_sub_layer_ordering_info_present_flag? 0 : max_sub_layer_minus1; for( ; i <= max_sub_layer_minus1; i++ ) { bs_read_ue( &bs ); bs_read_ue( &bs ); bs_read_ue( &bs ); } uint32_t vps_max_layer_id = bs_read( &bs, 6); uint32_t vps_num_layer_sets_minus1 = bs_read_ue( &bs ); bs_skip( &bs, vps_max_layer_id * vps_num_layer_sets_minus1 ); if( bs_read1( &bs )) { uint32_t num_units_in_tick = bs_read( &bs, 32 ); uint32_t time_scale = bs_read( &bs, 32 ); if( num_units_in_tick ) { p_sys->f_fps = ( (float) time_scale )/( (float) num_units_in_tick ); msg_Dbg(p_demux,"Using framerate %f fps from VPS", (double) p_sys->f_fps); } else { msg_Err( p_demux, "vps_num_units_in_tick null defaulting to 25 fps"); p_sys->f_fps = 25.0f; } } else { msg_Err( p_demux, "No timing info in VPS defaulting to 25 fps"); p_sys->f_fps = 25.0f; } free(p_decoded_nal); return 0; }
static block_t *PacketizeParse(void *p_private, bool *pb_ts_used, block_t *p_block) { decoder_t *p_dec = p_private; decoder_sys_t *p_sys = p_dec->p_sys; block_t * p_nal = NULL; while (p_block->i_buffer > 5 && p_block->p_buffer[p_block->i_buffer-1] == 0x00 ) p_block->i_buffer--; bs_t bs; bs_init(&bs, p_block->p_buffer+3, p_block->i_buffer-3); /* Get NALU type */ uint32_t forbidden_zero_bit = bs_read1(&bs); if (forbidden_zero_bit) { msg_Err(p_dec,"Forbidden zero bit not null, corrupted NAL"); p_sys->p_frame = NULL; p_sys->b_vcl = false; return NULL; } uint32_t nalu_type = bs_read(&bs,6); bs_skip(&bs, 9); if (nalu_type < VPS) { /* NAL is a VCL NAL */ p_sys->b_vcl = true; uint32_t first_slice_in_pic = bs_read1(&bs); if (first_slice_in_pic && p_sys->p_frame) { p_nal = block_ChainGather(p_sys->p_frame); p_sys->p_frame = NULL; } block_ChainAppend(&p_sys->p_frame, p_block); } else { if (p_sys->b_vcl) { p_nal = block_ChainGather(p_sys->p_frame); p_nal->p_next = p_block; p_sys->p_frame = NULL; p_sys->b_vcl =false; } else p_nal = p_block; } *pb_ts_used = false; return p_nal; }
static bool hevc_parse_scaling_list_rbsp( bs_t *p_bs ) { if( bs_remain( p_bs ) < 16 ) return false; for( int i=0; i<4; i++ ) { for( int j=0; j<6; j += (i == 3) ? 3 : 1 ) { if( bs_read1( p_bs ) == 0 ) bs_read_ue( p_bs ); else { unsigned nextCoef = 8; unsigned coefNum = __MIN( 64, (1 << (4 + (i << 1)))); if( i > 1 ) { nextCoef = bs_read_se( p_bs ) + 8; } for( unsigned k=0; k<coefNum; k++ ) { nextCoef = ( nextCoef + bs_read_se( p_bs ) + 256 ) % 256; } } } } return true; }
static inline int bs_read_ue( bs_t *s ) { int i = 0; while( bs_read1( s ) == 0 && s->p < s->p_end && i < 32 ) { i++; } return( ( 1 << i) - 1 + bs_read( s, i ) ); }
static int ParseVOP( decoder_t *p_dec, block_t *p_vop ) { decoder_sys_t *p_sys = p_dec->p_sys; int64_t i_time_increment, i_time_ref; int i_modulo_time_base = 0, i_time_increment_bits; bs_t s; bs_init( &s, &p_vop->p_buffer[4], p_vop->i_buffer - 4 ); switch( bs_read( &s, 2 ) ) { case 0: p_sys->i_flags = BLOCK_FLAG_TYPE_I; break; case 1: p_sys->i_flags = BLOCK_FLAG_TYPE_P; break; case 2: p_sys->i_flags = BLOCK_FLAG_TYPE_B; p_sys->b_frame = true; break; case 3: /* gni ? */ p_sys->i_flags = BLOCK_FLAG_TYPE_PB; break; } while( bs_read( &s, 1 ) ) i_modulo_time_base++; if( !bs_read1( &s ) ) return VLC_EGENERIC; /* Marker */ /* VOP time increment */ i_time_increment_bits = vlc_log2(p_dec->p_sys->i_fps_num - 1) + 1; if( i_time_increment_bits < 1 ) i_time_increment_bits = 1; i_time_increment = bs_read( &s, i_time_increment_bits ); /* Interpolate PTS/DTS */ if( !(p_sys->i_flags & BLOCK_FLAG_TYPE_B) ) { p_sys->i_last_time_ref = p_sys->i_time_ref; p_sys->i_time_ref += (i_modulo_time_base * p_dec->p_sys->i_fps_num); i_time_ref = p_sys->i_time_ref; } else { i_time_ref = p_sys->i_last_time_ref + (i_modulo_time_base * p_dec->p_sys->i_fps_num); } #if 0 msg_Err( p_dec, "interp pts/dts (%lli,%lli), pts/dts (%lli,%lli)", p_sys->i_interpolated_pts, p_sys->i_interpolated_dts, p_vop->i_pts, p_vop->i_dts ); #endif if( p_dec->p_sys->i_fps_num < 5 && /* Work-around buggy streams */ p_dec->fmt_in.video.i_frame_rate > 0 && p_dec->fmt_in.video.i_frame_rate_base > 0 ) { p_sys->i_interpolated_pts += INT64_C(1000000) * p_dec->fmt_in.video.i_frame_rate_base / p_dec->fmt_in.video.i_frame_rate; } else if( p_dec->p_sys->i_fps_num ) p_sys->i_interpolated_pts += ( INT64_C(1000000) * (i_time_ref + i_time_increment - p_sys->i_last_time - p_sys->i_last_timeincr) / p_dec->p_sys->i_fps_num ); p_sys->i_last_time = i_time_ref; p_sys->i_last_timeincr = i_time_increment; /* Correct interpolated dts when we receive a new pts/dts */ if( p_vop->i_pts > VLC_TS_INVALID ) p_sys->i_interpolated_pts = p_vop->i_pts; if( p_vop->i_dts > VLC_TS_INVALID ) p_sys->i_interpolated_dts = p_vop->i_dts; if( (p_sys->i_flags & BLOCK_FLAG_TYPE_B) || !p_sys->b_frame ) { /* Trivial case (DTS == PTS) */ p_sys->i_interpolated_dts = p_sys->i_interpolated_pts; if( p_vop->i_pts > VLC_TS_INVALID ) p_sys->i_interpolated_dts = p_vop->i_pts; if( p_vop->i_dts > VLC_TS_INVALID ) p_sys->i_interpolated_dts = p_vop->i_dts; p_sys->i_interpolated_pts = p_sys->i_interpolated_dts; } else { if( p_sys->i_last_ref_pts > VLC_TS_INVALID ) p_sys->i_interpolated_dts = p_sys->i_last_ref_pts; p_sys->i_last_ref_pts = p_sys->i_interpolated_pts; } return VLC_SUCCESS; }
/* ParseVOL: * TODO: * - support aspect ratio */ static int ParseVOL( decoder_t *p_dec, es_format_t *fmt, uint8_t *p_vol, int i_vol ) { decoder_sys_t *p_sys = p_dec->p_sys; int i_vo_type, i_vo_ver_id, i_ar, i_shape; bs_t s; for( ;; ) { if( p_vol[0] == 0x00 && p_vol[1] == 0x00 && p_vol[2] == 0x01 && p_vol[3] >= 0x20 && p_vol[3] <= 0x2f ) break; p_vol++; i_vol--; if( i_vol <= 4 ) return VLC_EGENERIC; } bs_init( &s, &p_vol[4], i_vol - 4 ); bs_skip( &s, 1 ); /* random access */ i_vo_type = bs_read( &s, 8 ); if( bs_read1( &s ) ) { i_vo_ver_id = bs_read( &s, 4 ); bs_skip( &s, 3 ); } else { i_vo_ver_id = 1; } i_ar = bs_read( &s, 4 ); if( i_ar == 0xf ) { int i_ar_width, i_ar_height; i_ar_width = bs_read( &s, 8 ); i_ar_height= bs_read( &s, 8 ); } if( bs_read1( &s ) ) { int i_chroma_format; int i_low_delay; /* vol control parameter */ i_chroma_format = bs_read( &s, 2 ); i_low_delay = bs_read1( &s ); if( bs_read1( &s ) ) /* vbv parameters */ { unsigned int i_bitrate, i_vbv_buffer_size, i_vbv_occupancy; i_bitrate = bs_read( &s, 15 ) << 15; bs_skip( &s, 1 ); i_bitrate += bs_read( &s, 15 ); bs_skip( &s, 1 ); i_vbv_buffer_size = bs_read( &s, 15 ) << 3; bs_skip( &s, 1 ); i_vbv_buffer_size += bs_read( &s, 3 ); i_vbv_occupancy = bs_read( &s, 11 ) << 15; bs_skip( &s, 1 ); i_vbv_occupancy += bs_read( &s, 15 ); bs_skip( &s, 1 ); p_dec->fmt_out.i_bitrate = i_bitrate * 400; p_dec->fmt_out.video.i_cpb_buffer = i_vbv_buffer_size * 16384; p_dec->p_sys->i_vbv_occupancy = i_vbv_occupancy * 64; } } /* shape 0->RECT, 1->BIN, 2->BIN_ONLY, 3->GRAY */ i_shape = bs_read( &s, 2 ); if( i_shape == 3 && i_vo_ver_id != 1 ) { bs_skip( &s, 4 ); } if( !bs_read1( &s ) ) return VLC_EGENERIC; /* Marker */ p_sys->i_fps_num = bs_read( &s, 16 ); /* Time increment resolution*/ if( !p_sys->i_fps_num ) p_sys->i_fps_num = 1; if( !bs_read1( &s ) ) return VLC_EGENERIC; /* Marker */ if( bs_read1( &s ) ) { int i_time_increment_bits = vlc_log2( p_sys->i_fps_num - 1 ) + 1; if( i_time_increment_bits < 1 ) i_time_increment_bits = 1; p_sys->i_fps_den = bs_read( &s, i_time_increment_bits ); } if( i_shape == 0 ) { bs_skip( &s, 1 ); fmt->video.i_width = bs_read( &s, 13 ); bs_skip( &s, 1 ); fmt->video.i_height= bs_read( &s, 13 ); bs_skip( &s, 1 ); } return VLC_SUCCESS; }
static bool h264_parse_sequence_parameter_set_rbsp( bs_t *p_bs, h264_sequence_parameter_set_t *p_sps ) { int i_tmp; int i_profile_idc = bs_read( p_bs, 8 ); p_sps->i_profile = i_profile_idc; p_sps->i_constraint_set_flags = bs_read( p_bs, 8 ); p_sps->i_level = bs_read( p_bs, 8 ); /* sps id */ uint32_t i_sps_id = bs_read_ue( p_bs ); if( i_sps_id > H264_SPS_ID_MAX ) return false; p_sps->i_id = i_sps_id; if( i_profile_idc == PROFILE_H264_HIGH || i_profile_idc == PROFILE_H264_HIGH_10 || i_profile_idc == PROFILE_H264_HIGH_422 || i_profile_idc == PROFILE_H264_HIGH_444 || /* Old one, no longer on spec */ i_profile_idc == PROFILE_H264_HIGH_444_PREDICTIVE || i_profile_idc == PROFILE_H264_CAVLC_INTRA || i_profile_idc == PROFILE_H264_SVC_BASELINE || i_profile_idc == PROFILE_H264_SVC_HIGH || i_profile_idc == PROFILE_H264_MVC_MULTIVIEW_HIGH || i_profile_idc == PROFILE_H264_MVC_STEREO_HIGH || i_profile_idc == PROFILE_H264_MVC_MULTIVIEW_DEPTH_HIGH || i_profile_idc == PROFILE_H264_MVC_ENHANCED_MULTIVIEW_DEPTH_HIGH || i_profile_idc == PROFILE_H264_MFC_HIGH ) { /* chroma_format_idc */ p_sps->i_chroma_idc = bs_read_ue( p_bs ); if( p_sps->i_chroma_idc == 3 ) bs_skip( p_bs, 1 ); /* separate_colour_plane_flag */ /* bit_depth_luma_minus8 */ p_sps->i_bit_depth_luma = bs_read_ue( p_bs ) + 8; /* bit_depth_chroma_minus8 */ p_sps->i_bit_depth_chroma = bs_read_ue( p_bs ) + 8; /* qpprime_y_zero_transform_bypass_flag */ bs_skip( p_bs, 1 ); /* seq_scaling_matrix_present_flag */ i_tmp = bs_read( p_bs, 1 ); if( i_tmp ) { for( int i = 0; i < ((3 != p_sps->i_chroma_idc) ? 8 : 12); i++ ) { /* seq_scaling_list_present_flag[i] */ i_tmp = bs_read( p_bs, 1 ); if( !i_tmp ) continue; const int i_size_of_scaling_list = (i < 6 ) ? 16 : 64; /* scaling_list (...) */ int i_lastscale = 8; int i_nextscale = 8; for( int j = 0; j < i_size_of_scaling_list; j++ ) { if( i_nextscale != 0 ) { /* delta_scale */ i_tmp = bs_read_se( p_bs ); i_nextscale = ( i_lastscale + i_tmp + 256 ) % 256; /* useDefaultScalingMatrixFlag = ... */ } /* scalinglist[j] */ i_lastscale = ( i_nextscale == 0 ) ? i_lastscale : i_nextscale; } } } } /* Skip i_log2_max_frame_num */ p_sps->i_log2_max_frame_num = bs_read_ue( p_bs ); if( p_sps->i_log2_max_frame_num > 12) p_sps->i_log2_max_frame_num = 12; /* Read poc_type */ p_sps->i_pic_order_cnt_type = bs_read_ue( p_bs ); if( p_sps->i_pic_order_cnt_type == 0 ) { /* skip i_log2_max_poc_lsb */ p_sps->i_log2_max_pic_order_cnt_lsb = bs_read_ue( p_bs ); if( p_sps->i_log2_max_pic_order_cnt_lsb > 12 ) p_sps->i_log2_max_pic_order_cnt_lsb = 12; } else if( p_sps->i_pic_order_cnt_type == 1 ) { int i_cycle; /* skip b_delta_pic_order_always_zero */ p_sps->i_delta_pic_order_always_zero_flag = bs_read( p_bs, 1 ); /* skip i_offset_for_non_ref_pic */ bs_read_se( p_bs ); /* skip i_offset_for_top_to_bottom_field */ bs_read_se( p_bs ); /* read i_num_ref_frames_in_poc_cycle */ i_cycle = bs_read_ue( p_bs ); if( i_cycle > 256 ) i_cycle = 256; while( i_cycle > 0 ) { /* skip i_offset_for_ref_frame */ bs_read_se(p_bs ); i_cycle--; } } /* i_num_ref_frames */ bs_read_ue( p_bs ); /* b_gaps_in_frame_num_value_allowed */ bs_skip( p_bs, 1 ); /* Read size */ p_sps->pic_width_in_mbs_minus1 = bs_read_ue( p_bs ); p_sps->pic_height_in_map_units_minus1 = bs_read_ue( p_bs ); /* b_frame_mbs_only */ p_sps->frame_mbs_only_flag = bs_read( p_bs, 1 ); if( !p_sps->frame_mbs_only_flag ) bs_skip( p_bs, 1 ); /* b_direct8x8_inference */ bs_skip( p_bs, 1 ); /* crop */ if( bs_read1( p_bs ) ) /* frame_cropping_flag */ { p_sps->frame_crop.left_offset = bs_read_ue( p_bs ); p_sps->frame_crop.right_offset = bs_read_ue( p_bs ); p_sps->frame_crop.right_offset = bs_read_ue( p_bs ); p_sps->frame_crop.bottom_offset = bs_read_ue( p_bs ); } /* vui */ i_tmp = bs_read( p_bs, 1 ); if( i_tmp ) { p_sps->vui.b_valid = true; /* read the aspect ratio part if any */ i_tmp = bs_read( p_bs, 1 ); if( i_tmp ) { static const struct { int w, h; } sar[17] = { { 0, 0 }, { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 }, { 160,99 }, { 4, 3 }, { 3, 2 }, { 2, 1 }, }; int i_sar = bs_read( p_bs, 8 ); int w, h; if( i_sar < 17 ) { w = sar[i_sar].w; h = sar[i_sar].h; } else if( i_sar == 255 ) { w = bs_read( p_bs, 16 ); h = bs_read( p_bs, 16 ); } else { w = 0; h = 0; } if( w != 0 && h != 0 ) { p_sps->vui.i_sar_num = w; p_sps->vui.i_sar_den = h; } else { p_sps->vui.i_sar_num = 1; p_sps->vui.i_sar_den = 1; } } /* overscan */ i_tmp = bs_read( p_bs, 1 ); if ( i_tmp ) bs_read( p_bs, 1 ); /* video signal type */ i_tmp = bs_read( p_bs, 1 ); if( i_tmp ) { bs_read( p_bs, 3 ); p_sps->vui.colour.b_full_range = bs_read( p_bs, 1 ); /* colour desc */ i_tmp = bs_read( p_bs, 1 ); if ( i_tmp ) { p_sps->vui.colour.i_colour_primaries = bs_read( p_bs, 8 ); p_sps->vui.colour.i_transfer_characteristics = bs_read( p_bs, 8 ); p_sps->vui.colour.i_matrix_coefficients = bs_read( p_bs, 8 ); } else { p_sps->vui.colour.i_colour_primaries = HXXX_PRIMARIES_UNSPECIFIED; p_sps->vui.colour.i_transfer_characteristics = HXXX_TRANSFER_UNSPECIFIED; p_sps->vui.colour.i_matrix_coefficients = HXXX_MATRIX_UNSPECIFIED; } } /* chroma loc info */ i_tmp = bs_read( p_bs, 1 ); if( i_tmp ) { bs_read_ue( p_bs ); bs_read_ue( p_bs ); } /* timing info */ p_sps->vui.b_timing_info_present_flag = bs_read( p_bs, 1 ); if( p_sps->vui.b_timing_info_present_flag ) { p_sps->vui.i_num_units_in_tick = bs_read( p_bs, 32 ); p_sps->vui.i_time_scale = bs_read( p_bs, 32 ); p_sps->vui.b_fixed_frame_rate = bs_read( p_bs, 1 ); } /* Nal hrd & VC1 hrd parameters */ p_sps->vui.b_hrd_parameters_present_flag = false; for ( int i=0; i<2; i++ ) { i_tmp = bs_read( p_bs, 1 ); if( i_tmp ) { p_sps->vui.b_hrd_parameters_present_flag = true; uint32_t count = bs_read_ue( p_bs ) + 1; if( count > 31 ) return false; bs_read( p_bs, 4 ); bs_read( p_bs, 4 ); for( uint32_t i=0; i<count; i++ ) { if( bs_remain( p_bs ) < 23 ) return false; bs_read_ue( p_bs ); bs_read_ue( p_bs ); bs_read( p_bs, 1 ); } bs_read( p_bs, 5 ); p_sps->vui.i_cpb_removal_delay_length_minus1 = bs_read( p_bs, 5 ); p_sps->vui.i_dpb_output_delay_length_minus1 = bs_read( p_bs, 5 ); bs_read( p_bs, 5 ); } } if( p_sps->vui.b_hrd_parameters_present_flag ) bs_read( p_bs, 1 ); /* pic struct info */ p_sps->vui.b_pic_struct_present_flag = bs_read( p_bs, 1 ); /* + unparsed remains */ } return true; }
static bool hevc_parse_inner_profile_tier_level_rbsp( bs_t *p_bs, hevc_inner_profile_tier_level_t *p_in ) { if( bs_remain( p_bs ) < 88 ) return false; p_in->profile_space = bs_read( p_bs, 2 ); p_in->tier_flag = bs_read1( p_bs ); p_in->profile_idc = bs_read( p_bs, 5 ); p_in->profile_compatibility_flag = bs_read( p_bs, 32 ); p_in->progressive_source_flag = bs_read1( p_bs ); p_in->interlaced_source_flag = bs_read1( p_bs ); p_in->non_packed_constraint_flag = bs_read1( p_bs ); p_in->frame_only_constraint_flag = bs_read1( p_bs ); if( ( p_in->profile_idc >= 4 && p_in->profile_idc <= 7 ) || ( p_in->profile_compatibility_flag & 0x0F000000 ) ) { p_in->idc4to7.max_12bit_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.max_10bit_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.max_8bit_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.max_422chroma_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.max_420chroma_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.max_monochrome_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.intra_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.one_picture_only_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.lower_bit_rate_constraint_flag = bs_read1( p_bs ); (void) bs_read( p_bs, 2 ); } else { (void) bs_read( p_bs, 11 ); } (void) bs_read( p_bs, 32 ); if( ( p_in->profile_idc >= 1 && p_in->profile_idc <= 5 ) || ( p_in->profile_compatibility_flag & 0x7C000000 ) ) p_in->idc1to5.inbld_flag = bs_read1( p_bs ); else (void) bs_read1( p_bs ); return true; }
static bool hevc_parse_vui_parameters_rbsp( bs_t *p_bs, hevc_vui_parameters_t *p_vui ) { if( bs_remain( p_bs ) < 10 ) return false; p_vui->aspect_ratio_info_present_flag = bs_read1( p_bs ); if( p_vui->aspect_ratio_info_present_flag ) { p_vui->ar.aspect_ratio_idc = bs_read( p_bs, 8 ); if( p_vui->ar.aspect_ratio_idc == 0xFF ) //HEVC_SAR__IDC_EXTENDED_SAR ) { p_vui->ar.sar_width = bs_read( p_bs, 16 ); p_vui->ar.sar_height = bs_read( p_bs, 16 ); } } p_vui->overscan_info_present_flag = bs_read1( p_bs ); if( p_vui->overscan_info_present_flag ) p_vui->overscan_appropriate_flag = bs_read1( p_bs ); p_vui->video_signal_type_present_flag = bs_read1( p_bs ); if( p_vui->video_signal_type_present_flag ) { p_vui->vs.video_format = bs_read( p_bs, 3 ); p_vui->vs.video_full_range_flag = bs_read1( p_bs ); p_vui->vs.colour_description_present_flag = bs_read1( p_bs ); if( p_vui->vs.colour_description_present_flag ) { p_vui->vs.colour.colour_primaries = bs_read( p_bs, 8 ); p_vui->vs.colour.transfer_characteristics = bs_read( p_bs, 8 ); p_vui->vs.colour.matrix_coeffs = bs_read( p_bs, 8 ); } } p_vui->chroma_loc_info_present_flag = bs_read1( p_bs ); if( p_vui->chroma_loc_info_present_flag ) { p_vui->chroma.sample_loc_type_top_field = bs_read_ue( p_bs ); p_vui->chroma.sample_loc_type_bottom_field = bs_read_ue( p_bs ); } p_vui->neutral_chroma_indication_flag = bs_read1( p_bs ); p_vui->field_seq_flag = bs_read1( p_bs ); p_vui->frame_field_info_present_flag = bs_read1( p_bs ); p_vui->default_display_window_flag = bs_read1( p_bs ); if( p_vui->default_display_window_flag ) { p_vui->def_disp.win_left_offset = bs_read_ue( p_bs ); p_vui->def_disp.win_right_offset = bs_read_ue( p_bs ); p_vui->def_disp.win_top_offset = bs_read_ue( p_bs ); p_vui->def_disp.win_bottom_offset = bs_read_ue( p_bs ); } p_vui->vui_timing_info_present_flag = bs_read1( p_bs ); if( p_vui->vui_timing_info_present_flag ) { p_vui->timing.vui_num_units_in_tick = bs_read( p_bs, 32 ); p_vui->timing.vui_time_scale = bs_read( p_bs, 32 ); if( bs_remain( p_bs ) < 3 ) return false; } /* incomplete */ if( bs_remain( p_bs ) < 1 ) /* late fail */ return false; return true; }