static void PutPPS( decoder_t *p_dec, block_t *p_frag ) { decoder_sys_t *p_sys = p_dec->p_sys; bs_t s; int i_pps_id; int i_sps_id; bs_init( &s, &p_frag->p_buffer[5], p_frag->i_buffer - 5 ); i_pps_id = bs_read_ue( &s ); // pps id i_sps_id = bs_read_ue( &s ); // sps id if( i_pps_id >= PPS_MAX || i_sps_id >= SPS_MAX ) { msg_Warn( p_dec, "invalid PPS (pps_id=%d sps_id=%d)", i_pps_id, i_sps_id ); block_Release( p_frag ); return; } bs_skip( &s, 1 ); // entropy coding mode flag p_sys->i_pic_order_present_flag = bs_read( &s, 1 ); /* TODO */ /* We have a new PPS */ if( !p_sys->b_pps ) msg_Dbg( p_dec, "found NAL_PPS (pps_id=%d sps_id=%d)", i_pps_id, i_sps_id ); p_sys->b_pps = true; if( p_sys->pp_pps[i_pps_id] ) block_Release( p_sys->pp_pps[i_pps_id] ); p_sys->pp_pps[i_pps_id] = p_frag; }
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 bool h264_parse_picture_parameter_set_rbsp( bs_t *p_bs, h264_picture_parameter_set_t *p_pps ) { p_pps->i_id = bs_read_ue( p_bs ); // pps id p_pps->i_sps_id = bs_read_ue( p_bs ); // sps id if( p_pps->i_id >= H264_PPS_MAX || p_pps->i_sps_id >= H264_SPS_MAX ) return false; bs_skip( p_bs, 1 ); // entropy coding mode flag p_pps->i_pic_order_present_flag = bs_read( p_bs, 1 ); /* TODO */ return true; }
// D.1.1 SEI buffering period syntax static void read_sei_type_0(h264_stream_t* h, sei_t* s) { int sched_sel_idx; bs_t bs; sps_t *sps = h->sps; sei_type_0 *bp = malloc(sizeof(sei_type_0)); bs_init(&bs, s->payload, s->payloadSize); bp->seq_parameter_set_id = bs_read_ue(&bs); if(sps->vui.nal_hrd_parameters_present_flag) { for (sched_sel_idx = 0; sched_sel_idx < sps->hrd.cpb_cnt_minus1 + 1; sched_sel_idx++) { bp->initial_cbp_removal_delay[sched_sel_idx] = bs_read_u(&bs, sps->hrd.initial_cpb_removal_delay_length_minus1 + 1); bp->initial_cbp_removal_delay_offset[sched_sel_idx] = bs_read_u(&bs, sps->hrd.initial_cpb_removal_delay_length_minus1 + 1); } } if (sps->vui.vcl_hrd_parameters_present_flag) { for (sched_sel_idx = 0; sched_sel_idx < sps->hrd.cpb_cnt_minus1 + 1; sched_sel_idx++) { bp->initial_cbp_removal_delay[sched_sel_idx] = bs_read_u(&bs, sps->hrd.initial_cpb_removal_delay_length_minus1 + 1); bp->initial_cbp_removal_delay_offset[sched_sel_idx] = bs_read_u(&bs, sps->hrd.initial_cpb_removal_delay_length_minus1 + 1); } } s->sei_type_struct = bp; }
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; }
bool h264MediaStream::h264_decode_hrd_parameters(bs_t& s, h264_sps_t* p_sps) { int cpb_count, i; cpb_count = bs_read_ue(&s) + 1; bs_read(&s, 4); /* bit_rate_scale */ bs_read(&s, 4); /* cpb_size_scale */ for(i=0; i<cpb_count; i++){ bs_read_ue(&s); /* bit_rate_value_minus1 */ bs_read_ue(&s); /* cpb_size_value_minus1 */ bs_read(&s, 1); /* cbr_flag */ } bs_read(&s, 5); /* initial_cpb_removal_delay_length_minus1 */ bs_read(&s, 5); /* cpb_removal_delay_length_minus1 */ bs_read(&s, 5); /* dpb_output_delay_length_minus1 */ bs_read(&s, 5); /* time_offset_length */ return true; }
//Appendix E.1.2 HRD parameters syntax void read_hrd_parameters(sps_t *sps, bs_t* b) { int SchedSelIdx; sps->hrd.cpb_cnt_minus1 = bs_read_ue(b); sps->hrd.bit_rate_scale = bs_read(b, 4); sps->hrd.cpb_size_scale = bs_read(b, 4); for (SchedSelIdx = 0; SchedSelIdx <= sps->hrd.cpb_cnt_minus1; SchedSelIdx++) { sps->hrd.bit_rate_value_minus1[SchedSelIdx] = bs_read_ue(b); sps->hrd.cpb_size_value_minus1[SchedSelIdx] = bs_read_ue(b); sps->hrd.cbr_flag[SchedSelIdx] = bs_read(b, 1); } sps->hrd.initial_cpb_removal_delay_length_minus1 = bs_read(b, 5); sps->hrd.cpb_removal_delay_length_minus1 = bs_read(b, 5); sps->hrd.dpb_output_delay_length_minus1 = bs_read(b, 5); sps->hrd.time_offset_length = bs_read(b, 5); }
int32_t bs_read_se(bs_t* b) { int32_t r = bs_read_ue(b); if (r & 0x01) { r = (r+1)/2; } else { r = -(r/2); } return r; }
int h264_parse_pps( const uint8_t *p_pps_buf, int i_pps_size, struct nal_pps *p_pps ) { bs_t s; if (i_pps_size < 5 || (p_pps_buf[4] & 0x1f) != NAL_PPS) return -1; memset( p_pps, 0, sizeof(struct nal_pps) ); bs_init( &s, &p_pps_buf[5], i_pps_size - 5 ); p_pps->i_id = bs_read_ue( &s ); // pps id p_pps->i_sps_id = bs_read_ue( &s ); // sps id if( p_pps->i_id >= PPS_MAX || p_pps->i_sps_id >= SPS_MAX ) { return -1; } bs_skip( &s, 1 ); // entropy coding mode flag p_pps->i_pic_order_present_flag = bs_read( &s, 1 ); /* TODO */ return 0; }
/* Shortcut for retrieving vps/sps/pps id */ bool hevc_get_xps_id(const uint8_t *p_buf, size_t i_buf, uint8_t *pi_id) { if(unlikely(!hxxx_strip_AnnexB_startcode(&p_buf, &i_buf) || i_buf < 3)) return false; /* No need to lookup convert from emulation for that data */ uint8_t i_nal_type = hevc_getNALType(p_buf); bs_t bs; bs_init(&bs, &p_buf[2], i_buf - 2); if(i_nal_type == HEVC_NAL_PPS) *pi_id = bs_read_ue( &bs ); else *pi_id = bs_read( &bs, 4 ); return true; }
//7.3.2.1 Sequence parameter set RBSP syntax void read_seq_parameter_set_rbsp(sps_t *sps, bs_t* b) { int i; // NOTE can't read directly into sps because seq_parameter_set_id not yet known and so sps is not selected int profile_idc = bs_read(b, 8); int constraint_set0_flag = bs_read(b, 1); int constraint_set1_flag = bs_read(b, 1); int constraint_set2_flag = bs_read(b, 1); int constraint_set3_flag = bs_read(b, 1); int constraint_set4_flag = bs_read(b, 1); int constraint_set5_flag = bs_read(b, 1); int reserved_zero_2bits = bs_read(b, 2); /* all 0's */ int level_idc = bs_read(b, 8); int seq_parameter_set_id = bs_read_ue(b); memset(sps, 0, sizeof(sps_t)); sps->chroma_format_idc = 1; sps->profile_idc = profile_idc; // bs_read(b, 8); sps->constraint_set0_flag = constraint_set0_flag;//bs_read(b, 1); sps->constraint_set1_flag = constraint_set1_flag;//bs_read(b, 1); sps->constraint_set2_flag = constraint_set2_flag;//bs_read(b, 1); sps->constraint_set3_flag = constraint_set3_flag;//bs_read(b, 1); sps->constraint_set4_flag = constraint_set4_flag;//bs_read(b, 1); sps->constraint_set5_flag = constraint_set5_flag;//bs_read(b, 1); sps->reserved_zero_2bits = reserved_zero_2bits;//bs_read(b,2); sps->level_idc = level_idc; //bs_read(b, 8); sps->seq_parameter_set_id = seq_parameter_set_id; // bs_read_ue(b); if (sps->profile_idc == 100 || sps->profile_idc == 110 || sps->profile_idc == 122 || sps->profile_idc == 144) { sps->chroma_format_idc = bs_read_ue(b); if (sps->chroma_format_idc == 3) { sps->residual_colour_transform_flag = bs_read(b, 1); } sps->bit_depth_luma_minus8 = bs_read_ue(b); sps->bit_depth_chroma_minus8 = bs_read_ue(b); sps->qpprime_y_zero_transform_bypass_flag = bs_read(b, 1); sps->seq_scaling_matrix_present_flag = bs_read(b, 1); if (sps->seq_scaling_matrix_present_flag) { for (i = 0; i < 8; i++) { sps->seq_scaling_list_present_flag[i] = bs_read(b, 1); if (sps->seq_scaling_list_present_flag[i]) { if (i < 6) { read_scaling_list(b, sps->ScalingList4x4[i], 16, sps->UseDefaultScalingMatrix4x4Flag[i]); } else { read_scaling_list(b, sps->ScalingList8x8[i - 6], 64, sps->UseDefaultScalingMatrix8x8Flag[i - 6]); } } } } } sps->log2_max_frame_num_minus4 = bs_read_ue(b); sps->pic_order_cnt_type = bs_read_ue(b); if (sps->pic_order_cnt_type == 0) { sps->log2_max_pic_order_cnt_lsb_minus4 = bs_read_ue(b); } else if (sps->pic_order_cnt_type == 1) { sps->delta_pic_order_always_zero_flag = bs_read(b, 1); sps->offset_for_non_ref_pic = bs_read_se(b); sps->offset_for_top_to_bottom_field = bs_read_se(b); sps->num_ref_frames_in_pic_order_cnt_cycle = bs_read_ue(b); for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++) { sps->offset_for_ref_frame[i] = bs_read_se(b); } } sps->num_ref_frames = bs_read_ue(b); sps->gaps_in_frame_num_value_allowed_flag = bs_read(b, 1); sps->pic_width_in_mbs_minus1 = bs_read_ue(b); sps->pic_height_in_map_units_minus1 = bs_read_ue(b); sps->frame_mbs_only_flag = bs_read(b, 1); if (!sps->frame_mbs_only_flag) { sps->mb_adaptive_frame_field_flag = bs_read(b, 1); } sps->direct_8x8_inference_flag = bs_read(b, 1); sps->frame_cropping_flag = bs_read(b, 1); if (sps->frame_cropping_flag) { sps->frame_crop_left_offset = bs_read_ue(b); sps->frame_crop_right_offset = bs_read_ue(b); sps->frame_crop_top_offset = bs_read_ue(b); sps->frame_crop_bottom_offset = bs_read_ue(b); } sps->vui_parameters_present_flag = bs_read(b, 1); if (sps->vui_parameters_present_flag) { read_vui_parameters(sps, b); } //read_rbsp_trailing_bits(h, b); }
//Appendix E.1.1 VUI parameters syntax void read_vui_parameters(sps_t *sps, bs_t* b) { sps->vui.aspect_ratio_info_present_flag = bs_read(b, 1); if (sps->vui.aspect_ratio_info_present_flag) { sps->vui.aspect_ratio_idc = bs_read(b, 8); if (sps->vui.aspect_ratio_idc == SAR_Extended) { sps->vui.sar_width = bs_read(b, 16); sps->vui.sar_height = bs_read(b, 16); } } sps->vui.overscan_info_present_flag = bs_read(b, 1); if (sps->vui.overscan_info_present_flag) { sps->vui.overscan_appropriate_flag = bs_read(b, 1); } sps->vui.video_signal_type_present_flag = bs_read(b, 1); if (sps->vui.video_signal_type_present_flag) { sps->vui.video_format = bs_read(b, 3); sps->vui.video_full_range_flag = bs_read(b, 1); sps->vui.colour_description_present_flag = bs_read(b, 1); if (sps->vui.colour_description_present_flag) { sps->vui.colour_primaries = bs_read(b, 8); sps->vui.transfer_characteristics = bs_read(b, 8); sps->vui.matrix_coefficients = bs_read(b, 8); } } sps->vui.chroma_loc_info_present_flag = bs_read(b, 1); if (sps->vui.chroma_loc_info_present_flag) { sps->vui.chroma_sample_loc_type_top_field = bs_read_ue(b); sps->vui.chroma_sample_loc_type_bottom_field = bs_read_ue(b); } sps->vui.timing_info_present_flag = bs_read(b, 1); if (sps->vui.timing_info_present_flag) { sps->vui.num_units_in_tick = bs_read(b, 32); sps->vui.time_scale = bs_read(b, 32); sps->vui.fixed_frame_rate_flag = bs_read(b, 1); } sps->vui.nal_hrd_parameters_present_flag = bs_read(b, 1); if (sps->vui.nal_hrd_parameters_present_flag) { read_hrd_parameters(sps, b); } sps->vui.vcl_hrd_parameters_present_flag = bs_read(b, 1); if (sps->vui.vcl_hrd_parameters_present_flag) { read_hrd_parameters(sps, b); } if (sps->vui.nal_hrd_parameters_present_flag || sps->vui.vcl_hrd_parameters_present_flag) { sps->vui.low_delay_hrd_flag = bs_read(b, 1); } sps->vui.pic_struct_present_flag = bs_read(b, 1); sps->vui.bitstream_restriction_flag = bs_read(b, 1); if (sps->vui.bitstream_restriction_flag) { sps->vui.motion_vectors_over_pic_boundaries_flag = bs_read(b, 1); sps->vui.max_bytes_per_pic_denom = bs_read_ue(b); sps->vui.max_bits_per_mb_denom = bs_read_ue(b); sps->vui.log2_max_mv_length_horizontal = bs_read_ue(b); sps->vui.log2_max_mv_length_vertical = bs_read_ue(b); sps->vui.num_reorder_frames = bs_read_ue(b); sps->vui.max_dec_frame_buffering = bs_read_ue(b); } }
void Parser::parse(int *pb_nal_start) { h264_t *h = &h264; bs_t s; *pb_nal_start = 0; if( nal.i_type == NAL_SPS || nal.i_type == NAL_PPS ) *pb_nal_start = 1; bs_init( &s, nal.p_payload, nal.i_payload ); if( nal.i_type == NAL_SPS ) { int i_tmp; i_tmp = bs_read( &s, 8 ); bs_skip( &s, 1+1+1 + 5 + 8 ); /* sps id */ bs_read_ue( &s ); if( i_tmp >= 100 ) { b_hiprofile = 1; bs_read_ue( &s ); // chroma_format_idc bs_read_ue( &s ); // bit_depth_luma_minus8 bs_read_ue( &s ); // bit_depth_chroma_minus8 bs_skip( &s, 1 ); // qpprime_y_zero_transform_bypass_flag if( bs_read( &s, 1 ) ) // seq_scaling_matrix_present_flag { int i, j; for( i = 0; i < 8; i++ ) { if( bs_read( &s, 1 ) ) // seq_scaling_list_present_flag[i] { uint8 i_tmp = 8; for( j = 0; j < (i<6?16:64); j++ ) { i_tmp += bs_read_se( &s ); if( i_tmp == 0 ) break; } } } } } /* Skip i_log2_max_frame_num */ h->i_log2_max_frame_num = bs_read_ue( &s ) + 4; /* Read poc_type */ h->i_poc_type = bs_read_ue( &s ); if( h->i_poc_type == 0 ) { h->i_log2_max_poc_lsb = bs_read_ue( &s ) + 4; } else if( h->i_poc_type == 1 ) { int i_cycle; /* skip b_delta_pic_order_always_zero */ bs_skip( &s, 1 ); /* skip i_offset_for_non_ref_pic */ bs_read_se( &s ); /* skip i_offset_for_top_to_bottom_field */ bs_read_se( &s ); /* read i_num_ref_frames_in_poc_cycle */ i_cycle = bs_read_ue( &s ); if( i_cycle > 256 ) i_cycle = 256; while( i_cycle > 0 ) { /* skip i_offset_for_ref_frame */ bs_read_se(&s ); } } /* i_num_ref_frames */ bs_read_ue( &s ); /* b_gaps_in_frame_num_value_allowed */ bs_skip( &s, 1 ); /* Read size */ h->i_width = 16 * ( bs_read_ue( &s ) + 1 ); h->i_height = 32 * ( bs_read_ue( &s ) + 1 ); /* b_frame_mbs_only */ i_tmp = bs_read( &s, 1 ); if( i_tmp == 1 ) { // fix: progressive, half height h->i_height /= 2; } else { // mb_adaptive_frame_field_flag bs_skip( &s, 1 ); } /* b_direct8x8_inference */ bs_skip( &s, 1 ); /* crop ? */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { // fix: no cropping /* left */ //h->i_width -= 2 * bs_read_ue( &s ); /* right */ //h->i_width -= 2 * bs_read_ue( &s ); /* top */ //h->i_height -= 2 * bs_read_ue( &s ); /* bottom */ //h->i_height -= 2 * bs_read_ue( &s ); } /* vui: ignored */ } else if( nal.i_type >= NAL_SLICE && nal.i_type <= NAL_SLICE_IDR ) { int i_tmp; /* i_first_mb */ bs_read_ue( &s ); /* picture type */ switch( bs_read_ue( &s ) ) { case 0: case 5: /* P */ case 1: case 6: /* B */ case 3: case 8: /* SP */ h->b_key = 0; break; case 2: case 7: /* I */ case 4: case 9: /* SI */ // fix: key flags in high profile h->b_key = (nal.i_type == NAL_SLICE_IDR || (b_hiprofile && nal.i_type == NAL_SLICE)); break; } /* pps id */ bs_read_ue( &s ); /* frame num */ i_tmp = bs_read( &s, h->i_log2_max_frame_num ); if( i_tmp != h->i_frame_num ) *pb_nal_start = 1; h->i_frame_num = i_tmp; if( nal.i_type == NAL_SLICE_IDR ) { i_tmp = bs_read_ue( &s ); if( h->i_nal_type == NAL_SLICE_IDR && h->i_idr_pic_id != i_tmp ) *pb_nal_start = 1; h->i_idr_pic_id = i_tmp; } if( h->i_poc_type == 0 ) { i_tmp = bs_read( &s, h->i_log2_max_poc_lsb ); if( i_tmp != h->i_poc ) *pb_nal_start = 1; h->i_poc = i_tmp; } } h->i_nal_type = nal.i_type; h->i_ref_idc = nal.i_ref_idc; }
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 void ParseSlice( decoder_t *p_dec, bool *pb_new_picture, slice_t *p_slice, int i_nal_ref_idc, int i_nal_type, const block_t *p_frag ) { decoder_sys_t *p_sys = p_dec->p_sys; uint8_t *pb_dec; int i_dec; int i_slice_type; slice_t slice; bs_t s; /* do not convert the whole frame */ CreateDecodedNAL( &pb_dec, &i_dec, &p_frag->p_buffer[5], __MIN( p_frag->i_buffer - 5, 60 ) ); bs_init( &s, pb_dec, i_dec ); /* first_mb_in_slice */ /* int i_first_mb = */ bs_read_ue( &s ); /* slice_type */ switch( (i_slice_type = bs_read_ue( &s )) ) { case 0: case 5: slice.i_frame_type = BLOCK_FLAG_TYPE_P; break; case 1: case 6: slice.i_frame_type = BLOCK_FLAG_TYPE_B; break; case 2: case 7: slice.i_frame_type = BLOCK_FLAG_TYPE_I; break; case 3: case 8: /* SP */ slice.i_frame_type = BLOCK_FLAG_TYPE_P; break; case 4: case 9: slice.i_frame_type = BLOCK_FLAG_TYPE_I; break; default: slice.i_frame_type = 0; break; } /* */ slice.i_nal_type = i_nal_type; slice.i_nal_ref_idc = i_nal_ref_idc; slice.i_pic_parameter_set_id = bs_read_ue( &s ); slice.i_frame_num = bs_read( &s, p_sys->i_log2_max_frame_num + 4 ); slice.i_field_pic_flag = 0; slice.i_bottom_field_flag = -1; if( !p_sys->b_frame_mbs_only ) { /* field_pic_flag */ slice.i_field_pic_flag = bs_read( &s, 1 ); if( slice.i_field_pic_flag ) slice.i_bottom_field_flag = bs_read( &s, 1 ); } slice.i_idr_pic_id = p_sys->slice.i_idr_pic_id; if( slice.i_nal_type == NAL_SLICE_IDR ) slice.i_idr_pic_id = bs_read_ue( &s ); slice.i_pic_order_cnt_lsb = -1; slice.i_delta_pic_order_cnt_bottom = -1; slice.i_delta_pic_order_cnt0 = 0; slice.i_delta_pic_order_cnt1 = 0; if( p_sys->i_pic_order_cnt_type == 0 ) { slice.i_pic_order_cnt_lsb = bs_read( &s, p_sys->i_log2_max_pic_order_cnt_lsb + 4 ); if( p_sys->i_pic_order_present_flag && !slice.i_field_pic_flag ) slice.i_delta_pic_order_cnt_bottom = bs_read_se( &s ); } else if( (p_sys->i_pic_order_cnt_type == 1) && (!p_sys->i_delta_pic_order_always_zero_flag) ) { slice.i_delta_pic_order_cnt0 = bs_read_se( &s ); if( p_sys->i_pic_order_present_flag && !slice.i_field_pic_flag ) slice.i_delta_pic_order_cnt1 = bs_read_se( &s ); } free( pb_dec ); /* Detection of the first VCL NAL unit of a primary coded picture * (cf. 7.4.1.2.4) */ bool b_pic = false; if( slice.i_frame_num != p_sys->slice.i_frame_num || slice.i_pic_parameter_set_id != p_sys->slice.i_pic_parameter_set_id || slice.i_field_pic_flag != p_sys->slice.i_field_pic_flag || slice.i_nal_ref_idc != p_sys->slice.i_nal_ref_idc ) b_pic = true; if( (slice.i_bottom_field_flag != -1) && (p_sys->slice.i_bottom_field_flag != -1) && (slice.i_bottom_field_flag != p_sys->slice.i_bottom_field_flag) ) b_pic = true; if( p_sys->i_pic_order_cnt_type == 0 && ( slice.i_pic_order_cnt_lsb != p_sys->slice.i_pic_order_cnt_lsb || slice.i_delta_pic_order_cnt_bottom != p_sys->slice.i_delta_pic_order_cnt_bottom ) ) b_pic = true; else if( p_sys->i_pic_order_cnt_type == 1 && ( slice.i_delta_pic_order_cnt0 != p_sys->slice.i_delta_pic_order_cnt0 || slice.i_delta_pic_order_cnt1 != p_sys->slice.i_delta_pic_order_cnt1 ) ) b_pic = true; if( ( slice.i_nal_type == NAL_SLICE_IDR || p_sys->slice.i_nal_type == NAL_SLICE_IDR ) && ( slice.i_nal_type != p_sys->slice.i_nal_type || slice.i_idr_pic_id != p_sys->slice.i_idr_pic_id ) ) b_pic = true; /* */ *pb_new_picture = b_pic; *p_slice = slice; }
void h264MediaStream::ParseSlice(uint8_t* p_nal, int n_nal_size, int i_nal_type) { if(CurSlice == NULL) CurSlice = new h264_slice_t; //转化00 00 03为00 00 int icount = 0; uint8_t p_slice[64] = {0}; int parcount = (n_nal_size>64?64:n_nal_size); for (int t = 0; t < parcount; t++) { if (t < parcount-2 && p_nal[t] == 0x00 && p_nal[t + 1] == 0x00 && p_nal[t + 2] == 0x03) { p_slice[icount++] = 0x00; p_slice[icount++] = 0x00; t += 2; continue; } p_slice[icount++] = p_nal[t]; } bs_t s; bs_init(&s, p_slice, icount); bs_read_ue( &s ); // first_mb_in_slice CurSlice->i_slice_type = bs_read_ue( &s ); // slice type int i_pic_parameter_set_id = bs_read_ue( &s ); CurSlice->i_frame_num = bs_read( &s, StreamSps->log2_max_frame_num + 4 ); int i_field_pic_flag = 0; int i_bottom_field_flag = -1; if( !StreamSps->frame_mbs_only_flag) { /* field_pic_flag */ i_field_pic_flag = bs_read( &s, 1 ); if( i_field_pic_flag ) i_bottom_field_flag = bs_read( &s, 1 ); } int i_idr_pic_id; if( i_nal_type == 5/*NAL_SLICE_IDR*/ ) i_idr_pic_id = bs_read_ue( &s ); int i_delta_pic_order_cnt_bottom = -1; int i_delta_pic_order_cnt0 = 0; int i_delta_pic_order_cnt1 = 0; CurSlice->i_pic_order_cnt_lsb = 0; if( StreamSps->poc_type == 0 ) { CurSlice->i_pic_order_cnt_lsb = bs_read( &s, StreamSps->log2_max_poc_lsb + 4 ); //if( g_pic_order_present_flag && !i_field_pic_flag ) // i_delta_pic_order_cnt_bottom = bs_read_se( &s ); } else if( (StreamSps->poc_type == 1) && (!StreamSps->delta_pic_order_always_zero_flag) ) { i_delta_pic_order_cnt0 = bs_read_se( &s ); //if( g_pic_order_present_flag && !i_field_pic_flag ) // i_delta_pic_order_cnt1 = bs_read_se( &s ); } }
bool h264MediaStream::ParseSqs(const buf_share_ptr SqsNode) { assert(SqsNode); if (StreamSps == NULL) StreamSps = new h264_sps_t; uint8_t *pb_dec = NULL; int i_dec = 0; bs_t s; int i_sps_id; i_dec = SqsNode->GetSizeValue(); int nal_hrd_parameters_present_flag, vcl_hrd_parameters_present_flag; pb_dec = const_cast<uint8_t *>(SqsNode->GetBuffer()); //转化00 00 03为00 00 uint8_t *p_nal = new uint8_t[i_dec]; int pcount = 0; for (int tmp = 1; tmp < i_dec ; tmp++) { if (tmp < i_dec - 3 && *(pb_dec + tmp) == 0x00 && *(pb_dec + tmp + 1) == 0x00 && *(pb_dec + tmp + 2) == 0x03) { p_nal[pcount++] = 0x00; p_nal[pcount++] = 0x00; //printf("count = %d %2X\n",tmp, *(p_nal + tmp)); tmp += 2; continue; } p_nal[pcount++] = *(pb_dec + tmp); } pb_dec = p_nal; //以下内容根据H264协议解读,属于直接复制粘贴代码 同parseslice bs_init( &s, pb_dec, i_dec ); // profile(8) StreamSps->profile_idc = bs_read( &s, 8); /* constraint_set012, reserver(5), level(8) */ bs_skip( &s, 1+1+1 + 5 + 8 ); /* sps id */ i_sps_id = bs_read_ue( &s ); if( i_sps_id >= 32/*SPS_MAX*/ ) { printf("invalid SPS (sps_id=%d)", i_sps_id ); delete pb_dec; return false; } StreamSps->scaling_matrix_present = 0; if(StreamSps->profile_idc >= 100) //high profile { if(bs_read_ue(&s) == 3) //chroma_format_idc bs_read(&s, 1); //residual_color_transform_flag bs_read_ue(&s); //bit_depth_luma_minus8 bs_read_ue(&s); //bit_depth_chroma_minus8 StreamSps->transform_bypass = bs_read(&s, 1); bs_skip(&s, 1); //decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8); } /* Skip i_log2_max_frame_num */ StreamSps->log2_max_frame_num = bs_read_ue( &s ); if( StreamSps->log2_max_frame_num > 12) StreamSps->log2_max_frame_num = 12; /* Read poc_type */ StreamSps->poc_type/*->i_pic_order_cnt_type*/ = bs_read_ue( &s ); if( StreamSps->poc_type == 0 ) { /* skip i_log2_max_poc_lsb */ StreamSps->log2_max_poc_lsb/*->i_log2_max_pic_order_cnt_lsb*/ = bs_read_ue( &s ); if( StreamSps->log2_max_poc_lsb > 12 ) StreamSps->log2_max_poc_lsb = 12; } else if( StreamSps->poc_type/*p_sys->i_pic_order_cnt_type*/ == 1 ) { int i_cycle; /* skip b_delta_pic_order_always_zero */ StreamSps->delta_pic_order_always_zero_flag/*->i_delta_pic_order_always_zero_flag*/ = bs_read( &s, 1 ); /* skip i_offset_for_non_ref_pic */ bs_read_se( &s ); /* skip i_offset_for_top_to_bottom_field */ bs_read_se( &s ); /* read i_num_ref_frames_in_poc_cycle */ i_cycle = bs_read_ue( &s ); if( i_cycle > 256 ) i_cycle = 256; while( i_cycle > 0 ) { /* skip i_offset_for_ref_frame */ bs_read_se(&s ); i_cycle--; } } /* i_num_ref_frames */ bs_read_ue( &s ); /* b_gaps_in_frame_num_value_allowed */ bs_skip( &s, 1 ); /* Read size */ StreamSps->mb_width/*->fmt_out.video.i_width*/ = 16 * ( bs_read_ue( &s ) + 1 ); StreamSps->mb_height/*fmt_out.video.i_height*/ = 16 * ( bs_read_ue( &s ) + 1 ); /* b_frame_mbs_only */ StreamSps->frame_mbs_only_flag/*->b_frame_mbs_only*/ = bs_read( &s, 1 ); if( StreamSps->frame_mbs_only_flag == 0 ) { bs_skip( &s, 1 ); } /* b_direct8x8_inference */ bs_skip( &s, 1 ); /* crop */ StreamSps->crop = bs_read( &s, 1 ); if( StreamSps->crop ) { /* left */ bs_read_ue( &s ); /* right */ bs_read_ue( &s ); /* top */ bs_read_ue( &s ); /* bottom */ bs_read_ue( &s ); } /* vui */ StreamSps->vui_parameters_present_flag = bs_read( &s, 1 ); if( StreamSps->vui_parameters_present_flag ) { int aspect_ratio_info_present_flag = bs_read( &s, 1 ); if( aspect_ratio_info_present_flag ) { static const struct { int num, den; } 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( &s, 8 ); if( i_sar < 17 ) { StreamSps->sar.num = sar[i_sar].num; StreamSps->sar.den = sar[i_sar].den; } else if( i_sar == 255 ) { StreamSps->sar.num = bs_read( &s, 16 ); StreamSps->sar.den = bs_read( &s, 16 ); } else { StreamSps->sar.num = 0; StreamSps->sar.den = 0; } //if( den != 0 ) // p_dec->fmt_out.video.i_aspect = (int64_t)VOUT_ASPECT_FACTOR * // ( num * p_dec->fmt_out.video.i_width ) / // ( den * p_dec->fmt_out.video.i_height); //else // p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR; } else { StreamSps->sar.num = 0; StreamSps->sar.den = 0; } if(bs_read(&s, 1)) /* overscan_info_present_flag */ { bs_read(&s, 1); /* overscan_appropriate_flag */ } if(bs_read(&s, 1)) /* video_signal_type_present_flag */ { bs_read(&s, 3); /* video_format */ bs_read(&s, 1); /* video_full_range_flag */ if(bs_read(&s, 1)) /* colour_description_present_flag */ { bs_read(&s, 8); /* colour_primaries */ bs_read(&s, 8); /* transfer_characteristics */ bs_read(&s, 8); /* matrix_coefficients */ } } if(bs_read(&s, 1)) /* chroma_location_info_present_flag */ { bs_read_ue(&s); /* chroma_sample_location_type_top_field */ bs_read_ue(&s); /* chroma_sample_location_type_bottom_field */ } StreamSps->timing_info_present_flag = bs_read(&s, 1); if(StreamSps->timing_info_present_flag) { StreamSps->num_units_in_tick = bs_read(&s, 32); StreamSps->time_scale = bs_read(&s, 32); StreamSps->fixed_frame_rate_flag = bs_read(&s, 1); } nal_hrd_parameters_present_flag = bs_read(&s, 1); if(nal_hrd_parameters_present_flag) h264_decode_hrd_parameters(s, StreamSps); vcl_hrd_parameters_present_flag = bs_read(&s, 1); if(vcl_hrd_parameters_present_flag) h264_decode_hrd_parameters(s, StreamSps); if(nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) bs_read(&s, 1); /* low_delay_hrd_flag */ bs_read(&s, 1); /* pic_struct_present_flag */ StreamSps->bitstream_restriction_flag = bs_read(&s, 1); if(StreamSps->bitstream_restriction_flag) { unsigned int num_reorder_frames; bs_read(&s, 1); /* motion_vectors_over_pic_boundaries_flag */ bs_read_ue(&s); /* max_bytes_per_pic_denom */ bs_read_ue(&s); /* max_bits_per_mb_denom */ bs_read_ue(&s); /* log2_max_mv_length_horizontal */ bs_read_ue(&s); /* log2_max_mv_length_vertical */ num_reorder_frames= bs_read_ue(&s); bs_read_ue(&s); /*max_dec_frame_buffering*/ if(num_reorder_frames > 16 /*max_dec_frame_buffering || max_dec_frame_buffering > 16*/){ printf("illegal num_reorder_frames %d\n", num_reorder_frames); delete pb_dec; return true; } StreamSps->num_reorder_frames= num_reorder_frames; } } delete pb_dec; return true; }
static block_t *ParseNALBlock( decoder_t *p_dec, block_t *p_frag ) { decoder_sys_t *p_sys = p_dec->p_sys; block_t *p_pic = NULL; const int i_nal_ref_idc = (p_frag->p_buffer[3] >> 5)&0x03; const int i_nal_type = p_frag->p_buffer[3]&0x1f; if( p_sys->b_slice && !p_sys->b_sps ) { block_ChainRelease( p_sys->p_frame ); msg_Warn( p_dec, "waiting for SPS" ); /* Reset context */ p_sys->p_frame = NULL; p_sys->b_slice = VLC_FALSE; } if( !p_sys->b_sps && i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR ) { p_sys->b_slice = VLC_TRUE; /* Fragment will be discarded later on */ } else if( i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR ) { uint8_t *dec; int i_dec, i_first_mb, i_slice_type, i_frame_num, i_pic_flags = 0; vlc_bool_t b_pic = VLC_FALSE; bs_t s; /* do not convert the whole frame */ nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[4], __MIN( p_frag->i_buffer - 4, 60 ) ); bs_init( &s, dec, i_dec ); /* first_mb_in_slice */ i_first_mb = bs_read_ue( &s ); /* slice_type */ switch( (i_slice_type = bs_read_ue( &s )) ) { case 0: case 5: i_pic_flags = BLOCK_FLAG_TYPE_P; break; case 1: case 6: i_pic_flags = BLOCK_FLAG_TYPE_B; break; case 2: case 7: i_pic_flags = BLOCK_FLAG_TYPE_I; break; case 3: case 8: /* SP */ i_pic_flags = BLOCK_FLAG_TYPE_P; break; case 4: case 9: i_pic_flags = BLOCK_FLAG_TYPE_I; break; } /* pic_parameter_set_id */ bs_read_ue( &s ); /* frame_num */ i_frame_num = bs_read( &s, p_sys->i_log2_max_frame_num + 4 ); /* Detection of the first VCL NAL unit of a primary coded picture * (cf. 7.4.1.2.4) */ if( i_frame_num != p_sys->i_frame_num || ( (i_nal_ref_idc != p_sys->i_nal_ref_idc) && (!i_nal_ref_idc || !p_sys->i_nal_ref_idc) ) ) { b_pic = VLC_TRUE; } p_sys->i_frame_num = i_frame_num; p_sys->i_nal_ref_idc = i_nal_ref_idc; if( !p_sys->b_frame_mbs_only ) { /* field_pic_flag */ if( bs_read( &s, 1 ) ) { /* bottom_field_flag */ bs_read( &s, 1 ); } } if( i_nal_type == NAL_SLICE_IDR ) { /* id_pic_id */ int i_idr_pic_id = bs_read_ue( &s ); if( p_sys->i_nal_type != i_nal_type ) b_pic = VLC_TRUE; if( p_sys->i_idr_pic_id != i_idr_pic_id ) b_pic = VLC_TRUE; p_sys->i_idr_pic_id = i_idr_pic_id; } p_sys->i_nal_type = i_nal_type; if( b_pic && p_sys->b_slice ) { p_pic = block_ChainGather( p_sys->p_frame ); p_pic->i_dts = p_sys->i_dts; p_pic->i_pts = p_sys->i_pts; p_pic->i_length = 0; /* FIXME */ p_pic->i_flags = p_sys->i_flags; /* Reset context */ p_sys->p_frame = NULL; p_sys->b_slice = VLC_FALSE; } p_sys->b_slice = VLC_TRUE; p_sys->i_flags = i_pic_flags; p_sys->i_dts = p_frag->i_dts; p_sys->i_pts = p_frag->i_pts; free( dec ); } else if( i_nal_type == NAL_SPS ) { uint8_t *dec; int i_dec; bs_t s; int i_tmp; msg_Dbg( p_dec, "found NAL_SPS" ); p_sys->b_sps = VLC_TRUE; nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[4], p_frag->i_buffer - 4 ); bs_init( &s, dec, i_dec ); /* Skip profile(8), constraint_set012, reserver(5), level(8) */ bs_skip( &s, 8 + 1+1+1 + 5 + 8 ); /* sps id */ bs_read_ue( &s ); /* Skip i_log2_max_frame_num */ p_sys->i_log2_max_frame_num = bs_read_ue( &s ); /* Read poc_type */ i_tmp = bs_read_ue( &s ); if( i_tmp == 0 ) { /* skip i_log2_max_poc_lsb */ bs_read_ue( &s ); } else if( i_tmp == 1 ) { int i_cycle; /* skip b_delta_pic_order_always_zero */ bs_skip( &s, 1 ); /* skip i_offset_for_non_ref_pic */ bs_read_se( &s ); /* skip i_offset_for_top_to_bottom_field */ bs_read_se( &s ); /* read i_num_ref_frames_in_poc_cycle */ i_cycle = bs_read_ue( &s ); if( i_cycle > 256 ) i_cycle = 256; while( i_cycle > 0 ) { /* skip i_offset_for_ref_frame */ bs_read_se(&s ); } } /* i_num_ref_frames */ bs_read_ue( &s ); /* b_gaps_in_frame_num_value_allowed */ bs_skip( &s, 1 ); /* Read size */ p_dec->fmt_out.video.i_width = 16 * ( bs_read_ue( &s ) + 1 ); p_dec->fmt_out.video.i_height = 16 * ( bs_read_ue( &s ) + 1 ); /* b_frame_mbs_only */ p_sys->b_frame_mbs_only = bs_read( &s, 1 ); if( p_sys->b_frame_mbs_only == 0 ) { bs_skip( &s, 1 ); } /* b_direct8x8_inference */ bs_skip( &s, 1 ); /* crop */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { /* left */ bs_read_ue( &s ); /* right */ bs_read_ue( &s ); /* top */ bs_read_ue( &s ); /* bottom */ bs_read_ue( &s ); } /* vui */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { /* read the aspect ratio part if any FIXME check it */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { static const struct { int w, h; } sar[14] = { { 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 }, }; int i_sar = bs_read( &s, 8 ); int w, h; if( i_sar < 14 ) { w = sar[i_sar].w; h = sar[i_sar].h; } else { w = bs_read( &s, 16 ); h = bs_read( &s, 16 ); } p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * w / h * p_dec->fmt_out.video.i_width / p_dec->fmt_out.video.i_height; } } free( dec ); } else if( i_nal_type == NAL_PPS ) { bs_t s; bs_init( &s, &p_frag->p_buffer[4], p_frag->i_buffer - 4 ); /* TODO */ msg_Dbg( p_dec, "found NAL_PPS" ); } /* Append the block */ block_ChainAppend( &p_sys->p_frame, p_frag ); return p_pic; }
static void PutSPS( decoder_t *p_dec, block_t *p_frag ) { decoder_sys_t *p_sys = p_dec->p_sys; uint8_t *pb_dec = NULL; int i_dec = 0; bs_t s; int i_tmp; int i_sps_id; CreateDecodedNAL( &pb_dec, &i_dec, &p_frag->p_buffer[5], p_frag->i_buffer - 5 ); bs_init( &s, pb_dec, i_dec ); int i_profile_idc = bs_read( &s, 8 ); p_dec->fmt_out.i_profile = i_profile_idc; /* Skip constraint_set0123, reserved(4) */ bs_skip( &s, 1+1+1+1 + 4 ); p_dec->fmt_out.i_level = bs_read( &s, 8 ); /* sps id */ i_sps_id = bs_read_ue( &s ); if( i_sps_id >= SPS_MAX || i_sps_id < 0 ) { msg_Warn( p_dec, "invalid SPS (sps_id=%d)", i_sps_id ); free( pb_dec ); block_Release( p_frag ); return; } if( i_profile_idc == 100 || i_profile_idc == 110 || i_profile_idc == 122 || i_profile_idc == 244 || i_profile_idc == 44 || i_profile_idc == 83 || i_profile_idc == 86 ) { /* chroma_format_idc */ const int i_chroma_format_idc = bs_read_ue( &s ); if( i_chroma_format_idc == 3 ) bs_skip( &s, 1 ); /* separate_colour_plane_flag */ /* bit_depth_luma_minus8 */ bs_read_ue( &s ); /* bit_depth_chroma_minus8 */ bs_read_ue( &s ); /* qpprime_y_zero_transform_bypass_flag */ bs_skip( &s, 1 ); /* seq_scaling_matrix_present_flag */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { for( int i = 0; i < ((3 != i_chroma_format_idc) ? 8 : 12); i++ ) { /* seq_scaling_list_present_flag[i] */ i_tmp = bs_read( &s, 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( &s ); 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_sys->i_log2_max_frame_num = bs_read_ue( &s ); if( p_sys->i_log2_max_frame_num > 12) p_sys->i_log2_max_frame_num = 12; /* Read poc_type */ p_sys->i_pic_order_cnt_type = bs_read_ue( &s ); if( p_sys->i_pic_order_cnt_type == 0 ) { /* skip i_log2_max_poc_lsb */ p_sys->i_log2_max_pic_order_cnt_lsb = bs_read_ue( &s ); if( p_sys->i_log2_max_pic_order_cnt_lsb > 12 ) p_sys->i_log2_max_pic_order_cnt_lsb = 12; } else if( p_sys->i_pic_order_cnt_type == 1 ) { int i_cycle; /* skip b_delta_pic_order_always_zero */ p_sys->i_delta_pic_order_always_zero_flag = bs_read( &s, 1 ); /* skip i_offset_for_non_ref_pic */ bs_read_se( &s ); /* skip i_offset_for_top_to_bottom_field */ bs_read_se( &s ); /* read i_num_ref_frames_in_poc_cycle */ i_cycle = bs_read_ue( &s ); if( i_cycle > 256 ) i_cycle = 256; while( i_cycle > 0 ) { /* skip i_offset_for_ref_frame */ bs_read_se(&s ); i_cycle--; } } /* i_num_ref_frames */ bs_read_ue( &s ); /* b_gaps_in_frame_num_value_allowed */ bs_skip( &s, 1 ); /* Read size */ p_dec->fmt_out.video.i_width = 16 * ( bs_read_ue( &s ) + 1 ); p_dec->fmt_out.video.i_height = 16 * ( bs_read_ue( &s ) + 1 ); /* b_frame_mbs_only */ p_sys->b_frame_mbs_only = bs_read( &s, 1 ); p_dec->fmt_out.video.i_height *= ( 2 - p_sys->b_frame_mbs_only ); if( p_sys->b_frame_mbs_only == 0 ) { bs_skip( &s, 1 ); } /* b_direct8x8_inference */ bs_skip( &s, 1 ); /* crop */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { /* left */ bs_read_ue( &s ); /* right */ bs_read_ue( &s ); /* top */ bs_read_ue( &s ); /* bottom */ bs_read_ue( &s ); } /* vui */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { /* read the aspect ratio part if any */ i_tmp = bs_read( &s, 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( &s, 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( &s, 16 ); h = bs_read( &s, 16 ); } else { w = 0; h = 0; } if( w != 0 && h != 0 ) { p_dec->fmt_out.video.i_sar_num = w; p_dec->fmt_out.video.i_sar_den = h; } else { p_dec->fmt_out.video.i_sar_num = 1; p_dec->fmt_out.video.i_sar_den = 1; } } } free( pb_dec ); /* We have a new SPS */ if( !p_sys->b_sps ) msg_Dbg( p_dec, "found NAL_SPS (sps_id=%d)", i_sps_id ); p_sys->b_sps = true; if( p_sys->pp_sps[i_sps_id] ) block_Release( p_sys->pp_sps[i_sps_id] ); p_sys->pp_sps[i_sps_id] = p_frag; }
static void ParseSei( decoder_t *p_dec, block_t *p_frag ) { decoder_sys_t *p_sys = p_dec->p_sys; uint8_t *pb_dec; int i_dec; /* */ CreateDecodedNAL( &pb_dec, &i_dec, &p_frag->p_buffer[5], p_frag->i_buffer - 5 ); if( !pb_dec ) return; /* The +1 is for rbsp trailing bits */ for( int i_used = 0; i_used+1 < i_dec; ) { /* Read type */ int i_type = 0; while( i_used+1 < i_dec ) { const int i_byte = pb_dec[i_used++]; i_type += i_byte; if( i_byte != 0xff ) break; } /* Read size */ int i_size = 0; while( i_used+1 < i_dec ) { const int i_byte = pb_dec[i_used++]; i_size += i_byte; if( i_byte != 0xff ) break; } /* Check room */ if( i_used + i_size + 1 > i_dec ) break; /* Look for user_data_registered_itu_t_t35 */ if( i_type == 4 ) { static const uint8_t p_dvb1_data_start_code[] = { 0xb5, 0x00, 0x31, 0x47, 0x41, 0x39, 0x34 }; const int i_t35 = i_size; const uint8_t *p_t35 = &pb_dec[i_used]; /* Check for we have DVB1_data() */ if( i_t35 >= 5 && !memcmp( p_t35, p_dvb1_data_start_code, sizeof(p_dvb1_data_start_code) ) ) { cc_Extract( &p_sys->cc_next, true, &p_t35[3], i_t35 - 3 ); } } /* Look for SEI recovery point */ if( i_type == 6 ) { bs_t s; const int i_rec = i_size; const uint8_t *p_rec = &pb_dec[i_used]; bs_init( &s, p_rec, i_rec ); int i_recovery_frames = bs_read_ue( &s ); //bool b_exact_match = bs_read( &s, 1 ); //bool b_broken_link = bs_read( &s, 1 ); //int i_changing_slice_group = bs_read( &s, 2 ); if( !p_sys->b_header ) { msg_Dbg( p_dec, "Seen SEI recovery point, %d recovery frames", i_recovery_frames ); if ( p_sys->i_recovery_frames == -1 || i_recovery_frames < p_sys->i_recovery_frames ) p_sys->i_recovery_frames = i_recovery_frames; } } i_used += i_size; } free( pb_dec ); }
static inline int bs_read_se( bs_t *s ) { int val = bs_read_ue( s ); return val&0x01 ? (val+1)/2 : -(val/2); }
int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size, struct nal_sps *p_sps ) { uint8_t *pb_dec = NULL; int i_dec = 0; bs_t s; int i_tmp; if (i_sps_size < 5 || (p_sps_buf[4] & 0x1f) != NAL_SPS) return -1; memset( p_sps, 0, sizeof(struct nal_sps) ); CreateRbspFromNAL( &pb_dec, &i_dec, &p_sps_buf[5], i_sps_size - 5 ); bs_init( &s, pb_dec, i_dec ); int i_profile_idc = bs_read( &s, 8 ); p_sps->i_profile = i_profile_idc; p_sps->i_profile_compatibility = bs_read( &s, 8 ); p_sps->i_level = bs_read( &s, 8 ); /* sps id */ p_sps->i_id = bs_read_ue( &s ); if( p_sps->i_id >= SPS_MAX || p_sps->i_id < 0 ) { free( pb_dec ); return -1; } 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_PREDICTIVE || i_profile_idc == PROFILE_H264_CAVLC_INTRA || i_profile_idc == PROFILE_H264_SVC_BASELINE || i_profile_idc == PROFILE_H264_SVC_HIGH ) { /* chroma_format_idc */ const int i_chroma_format_idc = bs_read_ue( &s ); if( i_chroma_format_idc == 3 ) bs_skip( &s, 1 ); /* separate_colour_plane_flag */ /* bit_depth_luma_minus8 */ bs_read_ue( &s ); /* bit_depth_chroma_minus8 */ bs_read_ue( &s ); /* qpprime_y_zero_transform_bypass_flag */ bs_skip( &s, 1 ); /* seq_scaling_matrix_present_flag */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { for( int i = 0; i < ((3 != i_chroma_format_idc) ? 8 : 12); i++ ) { /* seq_scaling_list_present_flag[i] */ i_tmp = bs_read( &s, 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( &s ); 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( &s ); 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( &s ); 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( &s ); 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( &s, 1 ); /* skip i_offset_for_non_ref_pic */ bs_read_se( &s ); /* skip i_offset_for_top_to_bottom_field */ bs_read_se( &s ); /* read i_num_ref_frames_in_poc_cycle */ i_cycle = bs_read_ue( &s ); if( i_cycle > 256 ) i_cycle = 256; while( i_cycle > 0 ) { /* skip i_offset_for_ref_frame */ bs_read_se(&s ); i_cycle--; } } /* i_num_ref_frames */ bs_read_ue( &s ); /* b_gaps_in_frame_num_value_allowed */ bs_skip( &s, 1 ); /* Read size */ p_sps->i_width = 16 * ( bs_read_ue( &s ) + 1 ); p_sps->i_height = 16 * ( bs_read_ue( &s ) + 1 ); /* b_frame_mbs_only */ p_sps->b_frame_mbs_only = bs_read( &s, 1 ); p_sps->i_height *= ( 2 - p_sps->b_frame_mbs_only ); if( p_sps->b_frame_mbs_only == 0 ) { bs_skip( &s, 1 ); } /* b_direct8x8_inference */ bs_skip( &s, 1 ); /* crop */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { /* left */ bs_read_ue( &s ); /* right */ bs_read_ue( &s ); /* top */ bs_read_ue( &s ); /* bottom */ bs_read_ue( &s ); } /* vui */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { p_sps->vui.b_valid = true; /* read the aspect ratio part if any */ i_tmp = bs_read( &s, 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( &s, 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( &s, 16 ); h = bs_read( &s, 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( &s, 1 ); if ( i_tmp ) bs_read( &s, 1 ); /* video signal type */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { bs_read( &s, 4 ); /* colour desc */ bs_read( &s, 1 ); if ( i_tmp ) bs_read( &s, 24 ); } /* chroma loc info */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { bs_read_ue( &s ); bs_read_ue( &s ); } /* timing info */ p_sps->vui.b_timing_info_present_flag = bs_read( &s, 1 ); if( p_sps->vui.b_timing_info_present_flag ) { p_sps->vui.i_num_units_in_tick = bs_read( &s, 32 ); p_sps->vui.i_time_scale = bs_read( &s, 32 ); p_sps->vui.b_fixed_frame_rate = bs_read( &s, 1 ); } /* Nal hrd & VC1 hrd parameters */ p_sps->vui.b_cpb_dpb_delays_present_flag = false; for ( int i=0; i<2; i++ ) { i_tmp = bs_read( &s, 1 ); if( i_tmp ) { p_sps->vui.b_cpb_dpb_delays_present_flag = true; uint32_t count = bs_read_ue( &s ) + 1; bs_read( &s, 4 ); bs_read( &s, 4 ); for( uint32_t i=0; i<count; i++ ) { bs_read_ue( &s ); bs_read_ue( &s ); bs_read( &s, 1 ); } bs_read( &s, 5 ); p_sps->vui.i_cpb_removal_delay_length_minus1 = bs_read( &s, 5 ); p_sps->vui.i_dpb_output_delay_length_minus1 = bs_read( &s, 5 ); bs_read( &s, 5 ); } } if( p_sps->vui.b_cpb_dpb_delays_present_flag ) bs_read( &s, 1 ); /* pic struct info */ p_sps->vui.b_pic_struct_present_flag = bs_read( &s, 1 ); /* + unparsed remains */ } free( pb_dec ); return 0; }
/***************************************************************************** * ParseNALBlock: parses annexB type NALs * All p_frag blocks are required to start with 0 0 0 1 4-byte startcode *****************************************************************************/ static block_t *ParseNALBlock( decoder_t *p_dec, block_t *p_frag ) { decoder_sys_t *p_sys = p_dec->p_sys; block_t *p_pic = NULL; const int i_nal_ref_idc = (p_frag->p_buffer[4] >> 5)&0x03; const int i_nal_type = p_frag->p_buffer[4]&0x1f; #define OUTPUT \ do { \ if( !p_sys->b_header && p_sys->slice.i_frame_type != BLOCK_FLAG_TYPE_I) \ break; \ \ if( p_sys->slice.i_frame_type == BLOCK_FLAG_TYPE_I && p_sys->p_sps && p_sys->p_pps && !p_sys->b_header ) \ { \ block_t *p_sps = block_Duplicate( p_sys->p_sps ); \ block_t *p_pps = block_Duplicate( p_sys->p_pps ); \ p_sps->i_dts = p_sys->p_frame->i_dts; \ p_sps->i_pts = p_sys->p_frame->i_pts; \ block_ChainAppend( &p_sps, p_pps ); \ block_ChainAppend( &p_sps, p_sys->p_frame ); \ p_sys->b_header = VLC_TRUE; \ p_pic = block_ChainGather( p_sps ); \ } else { \ p_pic = block_ChainGather( p_sys->p_frame ); \ } \ p_pic->i_length = 0; /* FIXME */ \ p_pic->i_flags |= p_sys->slice.i_frame_type; \ \ p_sys->slice.i_frame_type = 0; \ p_sys->p_frame = NULL; \ p_sys->b_slice = VLC_FALSE; \ } while(0) if( p_sys->b_slice && ( !p_sys->b_sps || !p_sys->b_pps ) ) { block_ChainRelease( p_sys->p_frame ); msg_Warn( p_dec, "waiting for SPS/PPS" ); /* Reset context */ p_sys->slice.i_frame_type = 0; p_sys->p_frame = NULL; p_sys->b_slice = VLC_FALSE; } if( ( !p_sys->b_sps || !p_sys->b_pps ) && i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR ) { p_sys->b_slice = VLC_TRUE; /* Fragment will be discarded later on */ } else if( i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR ) { uint8_t *dec; int i_dec, i_first_mb, i_slice_type; slice_t slice; vlc_bool_t b_pic; bs_t s; /* do not convert the whole frame */ nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[5], __MIN( p_frag->i_buffer - 5, 60 ) ); bs_init( &s, dec, i_dec ); /* first_mb_in_slice */ i_first_mb = bs_read_ue( &s ); /* slice_type */ switch( (i_slice_type = bs_read_ue( &s )) ) { case 0: case 5: slice.i_frame_type = BLOCK_FLAG_TYPE_P; break; case 1: case 6: slice.i_frame_type = BLOCK_FLAG_TYPE_B; break; case 2: case 7: slice.i_frame_type = BLOCK_FLAG_TYPE_I; break; case 3: case 8: /* SP */ slice.i_frame_type = BLOCK_FLAG_TYPE_P; break; case 4: case 9: slice.i_frame_type = BLOCK_FLAG_TYPE_I; break; default: slice.i_frame_type = 0; break; } /* */ slice.i_nal_type = i_nal_type; slice.i_nal_ref_idc = i_nal_ref_idc; slice.i_pic_parameter_set_id = bs_read_ue( &s ); slice.i_frame_num = bs_read( &s, p_sys->i_log2_max_frame_num + 4 ); slice.i_field_pic_flag = 0; slice.i_bottom_field_flag = -1; if( !p_sys->b_frame_mbs_only ) { /* field_pic_flag */ slice.i_field_pic_flag = bs_read( &s, 1 ); if( slice.i_field_pic_flag ) slice.i_bottom_field_flag = bs_read( &s, 1 ); } slice.i_idr_pic_id = p_sys->slice.i_idr_pic_id; if( slice.i_nal_type == NAL_SLICE_IDR ) slice.i_idr_pic_id = bs_read_ue( &s ); slice.i_pic_order_cnt_lsb = -1; slice.i_delta_pic_order_cnt_bottom = -1; slice.i_delta_pic_order_cnt0 = 0; slice.i_delta_pic_order_cnt1 = 0; if( p_sys->i_pic_order_cnt_type == 0 ) { slice.i_pic_order_cnt_lsb = bs_read( &s, p_sys->i_log2_max_pic_order_cnt_lsb + 4 ); if( p_sys->i_pic_order_present_flag && !slice.i_field_pic_flag ) slice.i_delta_pic_order_cnt_bottom = bs_read_se( &s ); } else if( p_sys->i_pic_order_cnt_type == 1 && !p_sys->i_delta_pic_order_always_zero_flag ) { slice.i_delta_pic_order_cnt0 = bs_read_se( &s ); if( p_sys->i_pic_order_present_flag && !slice.i_field_pic_flag ) slice.i_delta_pic_order_cnt1 = bs_read_se( &s ); } /* Detection of the first VCL NAL unit of a primary coded picture * (cf. 7.4.1.2.4) */ b_pic = VLC_FALSE; if( slice.i_frame_num != p_sys->slice.i_frame_num || slice.i_pic_parameter_set_id != p_sys->slice.i_pic_parameter_set_id || slice.i_field_pic_flag != p_sys->slice.i_field_pic_flag || slice.i_nal_ref_idc != p_sys->slice.i_nal_ref_idc ) b_pic = VLC_TRUE; if( slice.i_bottom_field_flag != -1 && p_sys->slice.i_bottom_field_flag != -1 && slice.i_bottom_field_flag != p_sys->slice.i_bottom_field_flag ) b_pic = VLC_TRUE; if( p_sys->i_pic_order_cnt_type == 0 && ( slice.i_pic_order_cnt_lsb != p_sys->slice.i_pic_order_cnt_lsb || slice.i_delta_pic_order_cnt_bottom != p_sys->slice.i_delta_pic_order_cnt_bottom ) ) b_pic = VLC_TRUE; else if( p_sys->i_pic_order_cnt_type == 1 && ( slice.i_delta_pic_order_cnt0 != p_sys->slice.i_delta_pic_order_cnt0 || slice.i_delta_pic_order_cnt1 != p_sys->slice.i_delta_pic_order_cnt1 ) ) b_pic = VLC_TRUE; if( ( slice.i_nal_type == NAL_SLICE_IDR || p_sys->slice.i_nal_type == NAL_SLICE_IDR ) && ( slice.i_nal_type != p_sys->slice.i_nal_type || slice.i_idr_pic_id != p_sys->slice.i_idr_pic_id ) ) b_pic = VLC_TRUE; /* */ p_sys->slice = slice; if( b_pic && p_sys->b_slice ) OUTPUT; p_sys->b_slice = VLC_TRUE; free( dec ); } else if( i_nal_type == NAL_SPS ) { uint8_t *dec; int i_dec; bs_t s; int i_tmp; if( !p_sys->b_sps ) msg_Dbg( p_dec, "found NAL_SPS" ); p_sys->b_sps = VLC_TRUE; nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[5], p_frag->i_buffer - 5 ); bs_init( &s, dec, i_dec ); /* Skip profile(8), constraint_set012, reserver(5), level(8) */ bs_skip( &s, 8 + 1+1+1 + 5 + 8 ); /* sps id */ bs_read_ue( &s ); /* Skip i_log2_max_frame_num */ p_sys->i_log2_max_frame_num = bs_read_ue( &s ); if( p_sys->i_log2_max_frame_num > 12) p_sys->i_log2_max_frame_num = 12; /* Read poc_type */ p_sys->i_pic_order_cnt_type = bs_read_ue( &s ); if( p_sys->i_pic_order_cnt_type == 0 ) { /* skip i_log2_max_poc_lsb */ p_sys->i_log2_max_pic_order_cnt_lsb = bs_read_ue( &s ); if( p_sys->i_log2_max_pic_order_cnt_lsb > 12 ) p_sys->i_log2_max_pic_order_cnt_lsb = 12; } else if( p_sys->i_pic_order_cnt_type == 1 ) { int i_cycle; /* skip b_delta_pic_order_always_zero */ p_sys->i_delta_pic_order_always_zero_flag = bs_read( &s, 1 ); /* skip i_offset_for_non_ref_pic */ bs_read_se( &s ); /* skip i_offset_for_top_to_bottom_field */ bs_read_se( &s ); /* read i_num_ref_frames_in_poc_cycle */ i_cycle = bs_read_ue( &s ); if( i_cycle > 256 ) i_cycle = 256; while( i_cycle > 0 ) { /* skip i_offset_for_ref_frame */ bs_read_se(&s ); } } /* i_num_ref_frames */ bs_read_ue( &s ); /* b_gaps_in_frame_num_value_allowed */ bs_skip( &s, 1 ); /* Read size */ p_dec->fmt_out.video.i_width = 16 * ( bs_read_ue( &s ) + 1 ); p_dec->fmt_out.video.i_height = 16 * ( bs_read_ue( &s ) + 1 ); /* b_frame_mbs_only */ p_sys->b_frame_mbs_only = bs_read( &s, 1 ); if( p_sys->b_frame_mbs_only == 0 ) { bs_skip( &s, 1 ); } /* b_direct8x8_inference */ bs_skip( &s, 1 ); /* crop */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { /* left */ bs_read_ue( &s ); /* right */ bs_read_ue( &s ); /* top */ bs_read_ue( &s ); /* bottom */ bs_read_ue( &s ); } /* vui */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { /* read the aspect ratio part if any FIXME check it */ i_tmp = bs_read( &s, 1 ); if( i_tmp ) { static const struct { int w, h; } sar[14] = { { 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 }, }; int i_sar = bs_read( &s, 8 ); int w, h; if( i_sar < 14 ) { w = sar[i_sar].w; h = sar[i_sar].h; } else { w = bs_read( &s, 16 ); h = bs_read( &s, 16 ); } if( h != 0 ) p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * w / h * p_dec->fmt_out.video.i_width / p_dec->fmt_out.video.i_height; else p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR; } } free( dec ); if( p_sys->b_slice ) OUTPUT; /* We have a new SPS */ if( p_sys->p_sps ) block_Release( p_sys->p_sps ); p_sys->p_sps = p_frag; /* Do not append the SPS because we will insert it on keyframes */ return p_pic; } else if( i_nal_type == NAL_PPS ) { bs_t s; bs_init( &s, &p_frag->p_buffer[5], p_frag->i_buffer - 5 ); bs_read_ue( &s ); // pps id bs_read_ue( &s ); // sps id bs_skip( &s, 1 ); // entropy coding mode flag p_sys->i_pic_order_present_flag = bs_read( &s, 1 ); if( !p_sys->b_pps ) msg_Dbg( p_dec, "found NAL_PPS" ); p_sys->b_pps = VLC_TRUE; /* TODO */ if( p_sys->b_slice ) OUTPUT; /* We have a new PPS */ if( p_sys->p_pps ) block_Release( p_sys->p_pps ); p_sys->p_pps = p_frag; /* Do not append the PPS because we will insert it on keyframes */ return p_pic; } else if( i_nal_type == NAL_AU_DELIMITER || i_nal_type == NAL_SEI || ( i_nal_type >= 13 && i_nal_type <= 18 ) ) { if( p_sys->b_slice ) OUTPUT; } #undef OUTPUT /* Append the block */ block_ChainAppend( &p_sys->p_frame, p_frag ); return p_pic; }
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; }
// Appendix G.13.1.1 Scalability information SEI message syntax void read_sei_scalability_info( h264_stream_t* h, bs_t* b ) { sei_scalability_info_t* sei_svc = h->sei->sei_svc; sei_svc->temporal_id_nesting_flag = bs_read_u1(b); sei_svc->priority_layer_info_present_flag = bs_read_u1(b); sei_svc->priority_id_setting_flag = bs_read_u1(b); sei_svc->num_layers_minus1 = bs_read_ue(b); for( int i = 0; i <= sei_svc->num_layers_minus1; i++ ) { sei_svc->layers[i].layer_id = bs_read_ue(b); sei_svc->layers[i].priority_id = bs_read_u(b, 6); sei_svc->layers[i].discardable_flag = bs_read_u1(b); sei_svc->layers[i].dependency_id = bs_read_u(b, 3); sei_svc->layers[i].quality_id = bs_read_u(b, 4); sei_svc->layers[i].temporal_id = bs_read_u(b, 3); sei_svc->layers[i].sub_pic_layer_flag = bs_read_u1(b); sei_svc->layers[i].sub_region_layer_flag = bs_read_u1(b); sei_svc->layers[i].iroi_division_info_present_flag = bs_read_u1(b); sei_svc->layers[i].profile_level_info_present_flag = bs_read_u1(b); sei_svc->layers[i].bitrate_info_present_flag = bs_read_u1(b); sei_svc->layers[i].frm_rate_info_present_flag = bs_read_u1(b); sei_svc->layers[i].frm_size_info_present_flag = bs_read_u1(b); sei_svc->layers[i].layer_dependency_info_present_flag = bs_read_u1(b); sei_svc->layers[i].parameter_sets_info_present_flag = bs_read_u1(b); sei_svc->layers[i].bitstream_restriction_info_present_flag = bs_read_u1(b); sei_svc->layers[i].exact_inter_layer_pred_flag = bs_read_u1(b); if( sei_svc->layers[i].sub_pic_layer_flag || sei_svc->layers[i].iroi_division_info_present_flag ) { sei_svc->layers[i].exact_sample_value_match_flag = bs_read_u1(b); } sei_svc->layers[i].layer_conversion_flag = bs_read_u1(b); sei_svc->layers[i].layer_output_flag = bs_read_u1(b); if( sei_svc->layers[i].profile_level_info_present_flag ) { sei_svc->layers[i].layer_profile_level_idc = bs_read_u(b, 24); } if( sei_svc->layers[i].bitrate_info_present_flag ) { sei_svc->layers[i].avg_bitrate = bs_read_u(b, 16); sei_svc->layers[i].max_bitrate_layer = bs_read_u(b, 16); sei_svc->layers[i].max_bitrate_layer_representation = bs_read_u(b, 16); sei_svc->layers[i].max_bitrate_calc_window = bs_read_u(b, 16); } if( sei_svc->layers[i].frm_rate_info_present_flag ) { sei_svc->layers[i].constant_frm_rate_idc = bs_read_u(b, 2); sei_svc->layers[i].avg_frm_rate = bs_read_u(b, 16); } if( sei_svc->layers[i].frm_size_info_present_flag || sei_svc->layers[i].iroi_division_info_present_flag ) { sei_svc->layers[i].frm_width_in_mbs_minus1 = bs_read_ue(b); sei_svc->layers[i].frm_height_in_mbs_minus1 = bs_read_ue(b); } if( sei_svc->layers[i].sub_region_layer_flag ) { sei_svc->layers[i].base_region_layer_id = bs_read_ue(b); sei_svc->layers[i].dynamic_rect_flag = bs_read_u1(b); if( sei_svc->layers[i].dynamic_rect_flag ) { sei_svc->layers[i].horizontal_offset = bs_read_u(b, 16); sei_svc->layers[i].vertical_offset = bs_read_u(b, 16); sei_svc->layers[i].region_width = bs_read_u(b, 16); sei_svc->layers[i].region_height = bs_read_u(b, 16); } } if( sei_svc->layers[i].sub_pic_layer_flag ) { sei_svc->layers[i].roi_id = bs_read_ue(b); } if( sei_svc->layers[i].iroi_division_info_present_flag ) { sei_svc->layers[i].iroi_grid_flag = bs_read_u1(b); if( sei_svc->layers[i].iroi_grid_flag ) { sei_svc->layers[i].grid_width_in_mbs_minus1 = bs_read_ue(b); sei_svc->layers[i].grid_height_in_mbs_minus1 = bs_read_ue(b); } else { sei_svc->layers[i].num_rois_minus1 = bs_read_ue(b); for( int j = 0; j <= sei_svc->layers[i].num_rois_minus1; j++ ) { sei_svc->layers[i].roi[j].first_mb_in_roi = bs_read_ue(b); sei_svc->layers[i].roi[j].roi_width_in_mbs_minus1 = bs_read_ue(b); sei_svc->layers[i].roi[j].roi_height_in_mbs_minus1 = bs_read_ue(b); } } } if( sei_svc->layers[i].layer_dependency_info_present_flag ) { sei_svc->layers[i].num_directly_dependent_layers = bs_read_ue(b); for( int j = 0; j < sei_svc->layers[i].num_directly_dependent_layers; j++ ) { sei_svc->layers[i].directly_dependent_layer_id_delta_minus1[j] = bs_read_ue(b); } } else { sei_svc->layers[i].layer_dependency_info_src_layer_id_delta = bs_read_ue(b); } if( sei_svc->layers[i].parameter_sets_info_present_flag ) { sei_svc->layers[i].num_seq_parameter_sets = bs_read_ue(b); for( int j = 0; j < sei_svc->layers[i].num_seq_parameter_sets; j++ ) { sei_svc->layers[i].seq_parameter_set_id_delta[j] = bs_read_ue(b); } sei_svc->layers[i].num_subset_seq_parameter_sets = bs_read_ue(b); for( int j = 0; j < sei_svc->layers[i].num_subset_seq_parameter_sets; j++ ) { sei_svc->layers[i].subset_seq_parameter_set_id_delta[j] = bs_read_ue(b); } sei_svc->layers[i].num_pic_parameter_sets_minus1 = bs_read_ue(b); for( int j = 0; j < sei_svc->layers[i].num_pic_parameter_sets_minus1; j++ ) { sei_svc->layers[i].pic_parameter_set_id_delta[j] = bs_read_ue(b); } } else { sei_svc->layers[i].parameter_sets_info_src_layer_id_delta = bs_read_ue(b); } if( sei_svc->layers[i].bitstream_restriction_info_present_flag ) { sei_svc->layers[i].motion_vectors_over_pic_boundaries_flag = bs_read_u1(b); sei_svc->layers[i].max_bytes_per_pic_denom = bs_read_ue(b); sei_svc->layers[i].max_bits_per_mb_denom = bs_read_ue(b); sei_svc->layers[i].log2_max_mv_length_horizontal = bs_read_ue(b); sei_svc->layers[i].log2_max_mv_length_vertical = bs_read_ue(b); sei_svc->layers[i].max_num_reorder_frames = bs_read_ue(b); sei_svc->layers[i].max_dec_frame_buffering = bs_read_ue(b); } if( sei_svc->layers[i].layer_conversion_flag ) { sei_svc->layers[i].conversion_type_idc = bs_read_ue(b); for( int j = 0; j < 2; j++ ) { sei_svc->layers[i].rewriting_info_flag[j] = bs_read_u(b, 1); if( sei_svc->layers[i].rewriting_info_flag[j] ) { sei_svc->layers[i].rewriting_profile_level_idc[j] = bs_read_u(b, 24); sei_svc->layers[i].rewriting_avg_bitrate[j] = bs_read_u(b, 16); sei_svc->layers[i].rewriting_max_bitrate[j] = bs_read_u(b, 16); } } } } if( sei_svc->priority_layer_info_present_flag ) { sei_svc->pr_num_dIds_minus1 = bs_read_ue(b); for( int i = 0; i <= sei_svc->pr_num_dIds_minus1; i++ ) { sei_svc->pr[i].pr_dependency_id = bs_read_u(b, 3); sei_svc->pr[i].pr_num_minus1 = bs_read_ue(b); for( int j = 0; j <= sei_svc->pr[i].pr_num_minus1; j++ ) { sei_svc->pr[i].pr_info[j].pr_id = bs_read_ue(b); sei_svc->pr[i].pr_info[j].pr_profile_level_idc = bs_read_u(b, 24); sei_svc->pr[i].pr_info[j].pr_avg_bitrate = bs_read_u(b, 16); sei_svc->pr[i].pr_info[j].pr_max_bitrate = bs_read_u(b, 16); } } } }