diff options
author | Julian Scheel <julian@jusst.de> | 2008-12-02 15:51:18 +0000 |
---|---|---|
committer | Julian Scheel <julian@jusst.de> | 2008-12-02 15:51:18 +0000 |
commit | 564fd8cec68835856a2cfe9f313eb64989e6c6f9 (patch) | |
tree | ceb3cbf95c02408a4edeaf96828521d5ea430e37 /src/libvdpau/nal_parser.c | |
parent | bea579e29627546d3c09219a5b01d157d3774ba8 (diff) | |
download | xine-lib-564fd8cec68835856a2cfe9f313eb64989e6c6f9.tar.gz xine-lib-564fd8cec68835856a2cfe9f313eb64989e6c6f9.tar.bz2 |
More extensions to the parser, fixes in the decoder.
Diffstat (limited to 'src/libvdpau/nal_parser.c')
-rw-r--r-- | src/libvdpau/nal_parser.c | 124 |
1 files changed, 119 insertions, 5 deletions
diff --git a/src/libvdpau/nal_parser.c b/src/libvdpau/nal_parser.c index ebe9d562f..9835cb1a4 100644 --- a/src/libvdpau/nal_parser.c +++ b/src/libvdpau/nal_parser.c @@ -34,10 +34,14 @@ struct buf_reader { static inline uint32_t read_bits(struct buf_reader *buf, int len); uint32_t read_exp_golomb(struct buf_reader *buf); int32_t read_exp_golomb_s(struct buf_reader *buf); + +void calculate_pic_order(struct nal_parser *parser); void skip_scaling_list(struct buf_reader *buf, int size); void parse_scaling_list(struct buf_reader *buf, uint8_t *scaling_list, int length, int index); int parse_nal_header(struct buf_reader *buf, struct nal_unit *nal); uint8_t parse_sps(struct buf_reader *buf, struct seq_parameter_set_rbsp *sps); +void parse_vui_parameters(struct buf_reader *buf, struct seq_parameter_set_rbsp *sps); +void parse_hrd_parameters(struct buf_reader *buf, struct hrd_parameters *hrd); uint8_t parse_pps(struct buf_reader *buf, struct pic_parameter_set_rbsp *pps); uint8_t parse_slice_header(struct buf_reader *buf, struct nal_unit *nal); void parse_ref_pic_list_reordering(struct buf_reader *buf, struct nal_unit *nal); @@ -223,6 +227,27 @@ int parse_nal_header(struct buf_reader *buf, struct nal_unit *nal) return ret; } +void calculate_pic_order(struct nal_parser *parser) +{ + struct nal_unit *nal = parser->current_nal; + + struct seq_parameter_set_rbsp *sps = nal->sps; + struct pic_parameter_set_rbsp *pps = nal->pps; + struct slice_header *slc = nal->slc; + if(!sps || !pps) + return; + + if(sps->pic_order_cnt_type == 0) { + if(nal->nal_unit_type == NAL_SLICE_IDR) { + parser->prev_pic_order_cnt_lsb = 0; + parser->prev_pic_order_cnt_msb = 0; + } else { + + } + } + +} + void skip_scaling_list(struct buf_reader *buf, int size) { int i; @@ -351,12 +376,99 @@ uint8_t parse_sps(struct buf_reader *buf, struct seq_parameter_set_rbsp *sps) sps->frame_crop_bottom_offset = read_exp_golomb(buf); } sps->vui_parameters_present_flag = read_bits(buf, 1); - /*if(sps->vui_parameters_present_flag) - printf("ERROR: vui_parameters is not implemented\n");*/ + if(sps->vui_parameters_present_flag) { + parse_vui_parameters(buf, sps); + } return 0; } +void parse_vui_parameters(struct buf_reader *buf, struct seq_parameter_set_rbsp *sps) +{ + sps->vui_parameters.aspect_ration_info_present_flag = read_bits(buf, 1); + if(sps->vui_parameters.aspect_ration_info_present_flag == 1) { + sps->vui_parameters.aspect_ratio_idc = read_bits(buf, 8); + if(sps->vui_parameters.aspect_ratio_idc == ASPECT_RESERVED) { + sps->vui_parameters.sar_width = read_bits(buf, 16); + sps->vui_parameters.sar_height = read_bits(buf, 16); + } + } + + sps->vui_parameters.overscan_info_present_flag = read_bits(buf, 1); + if(sps->vui_parameters.overscan_info_present_flag) { + sps->vui_parameters.overscan_appropriate_flag = read_bits(buf, 1); + } + + sps->vui_parameters.video_signal_type_present_flag = read_bits(buf, 1); + if(sps->vui_parameters.video_signal_type_present_flag) { + sps->vui_parameters.video_format = read_bits(buf, 3); + sps->vui_parameters.video_full_range_flag = read_bits(buf, 1); + sps->vui_parameters.colour_description_present = read_bits(buf, 1); + if(sps->vui_parameters.colour_description_present) { + sps->vui_parameters.colour_primaries = read_bits(buf, 8); + sps->vui_parameters.transfer_characteristics = read_bits(buf, 8); + sps->vui_parameters.matrix_coefficients = read_bits(buf, 8); + } + } + + sps->vui_parameters.chroma_loc_info_present_flag = read_bits(buf, 1); + if(sps->vui_parameters.chroma_loc_info_present_flag) { + sps->vui_parameters.chroma_sample_loc_type_top_field = read_exp_golomb(buf); + sps->vui_parameters.chroma_sample_loc_type_bottom_field = read_exp_golomb(buf); + } + + sps->vui_parameters.timing_info_present_flag = read_bits(buf, 1); + if(sps->vui_parameters.timing_info_present_flag) { + sps->vui_parameters.num_units_in_tick = read_bits(buf, 32); + sps->vui_parameters.time_scale = read_bits(buf, 32); + sps->vui_parameters.fixed_frame_rate_flag = read_bits(buf, 1); + } + + sps->vui_parameters.nal_hrd_parameters_present_flag = read_bits(buf, 1); + if(sps->vui_parameters.nal_hrd_parameters_present_flag) + parse_hrd_parameters(buf, &sps->vui_parameters.nal_hrd_parameters); + + sps->vui_parameters.vc1_hrd_parameters_present_flag = read_bits(buf, 1); + if(sps->vui_parameters.vc1_hrd_parameters_present_flag) + parse_hrd_parameters(buf, &sps->vui_parameters.vc1_hrd_parameters); + + if(sps->vui_parameters.nal_hrd_parameters_present_flag || + sps->vui_parameters.vc1_hrd_parameters_present_flag) + sps->vui_parameters.low_delay_hrd_flag = read_bits(buf, 1); + + sps->vui_parameters.pic_struct_present_flag = read_bits(buf, 1); + sps->vui_parameters.bitstream_restriction_flag = read_bits(buf, 1); + + if(sps->vui_parameters.bitstream_restriction_flag) { + sps->vui_parameters.motion_vectors_over_pic_boundaries = read_bits(buf, 1); + sps->vui_parameters.max_bytes_per_pic_denom = read_exp_golomb(buf); + sps->vui_parameters.max_bits_per_mb_denom = read_exp_golomb(buf); + sps->vui_parameters.log2_max_mv_length_horizontal = read_exp_golomb(buf); + sps->vui_parameters.log2_max_mv_length_vertical = read_exp_golomb(buf); + sps->vui_parameters.num_reorder_frames = read_exp_golomb(buf); + sps->vui_parameters.max_dec_frame_buffering = read_exp_golomb(buf); + } +} + +void parse_hrd_parameters(struct buf_reader *buf, struct hrd_parameters *hrd) +{ + hrd->cpb_cnt_minus1 = read_exp_golomb(buf); + hrd->bit_rate_scale = read_bits(buf, 4); + hrd->cpb_size_scale = read_bits(buf, 4); + + int i; + for(i = 0; i <= hrd->cpb_cnt_minus1; i++) { + hrd->bit_rate_value_minus1[i] = read_exp_golomb(buf); + hrd->cpb_size_value_minus1[i] = read_exp_golomb(buf); + hrd->cbr_flag[i] = read_bits(buf, 1); + } + + hrd->initial_cpb_removal_delay_length_minus1 = read_bits(buf, 5); + hrd->cpb_removal_delay_length_minus1 = read_bits(buf, 5); + hrd->dpb_output_delay_length_minus1 = read_bits(buf, 5); + hrd->time_offset_length = read_bits(buf, 5); +} + uint8_t parse_pps(struct buf_reader *buf, struct pic_parameter_set_rbsp *pps) { pps->pic_parameter_set_id = read_exp_golomb(buf); @@ -740,6 +852,8 @@ int parse_nal(uint8_t *buf, int buf_len, struct nal_parser *parser) int res = parse_nal_header(&bufr, nal); + calculate_pic_order(parser); + if(res >= NAL_SLICE && res <= NAL_SLICE_IDR) { // now detect if it's a new frame! int ret = 0; @@ -822,14 +936,14 @@ int parse_nal(uint8_t *buf, int buf_len, struct nal_parser *parser) return ret; } else if(res == NAL_PPS || res == NAL_SPS) { - return 1; + return 0; } else if (res == NAL_AU_DELIMITER || res == NAL_SEI || (res >= 13 && res <= 18)) { //printf("New Frame\n"); - return 1; + return 0; } - return 0; + return 1; } int seek_for_nal(uint8_t *buf, int buf_len) |