summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libvdpau/nal_parser.c124
-rw-r--r--src/libvdpau/nal_parser.h122
-rw-r--r--src/libvdpau/vdpau_h264.c12
3 files changed, 240 insertions, 18 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)
diff --git a/src/libvdpau/nal_parser.h b/src/libvdpau/nal_parser.h
index 609f700a1..792f2e0f2 100644
--- a/src/libvdpau/nal_parser.h
+++ b/src/libvdpau/nal_parser.h
@@ -33,6 +33,27 @@ enum slice_types {
SLICE_SI
};
+enum aspect_ratio {
+ ASPECT_UNSPECIFIED = 0,
+ ASPECT_1_1,
+ ASPECT_12_11,
+ ASPECT_10_11,
+ ASPECT_16_11,
+ ASPECT_40_33,
+ ASPECT_24_11,
+ ASPECT_20_11,
+ ASPECT_32_11,
+ ASPECT_80_33,
+ ASPECT_18_11,
+ ASPECT_15_11,
+ ASPECT_64_33,
+ ASPECT_160_99,
+ ASPECT_4_3,
+ ASPECT_3_2,
+ ASPECT_2_1,
+ ASPECT_RESERVED
+};
+
static inline uint32_t slice_type(uint32_t slice_type) { return (slice_type < 10 ? slice_type % 5 : slice_type); }
struct nal_unit {
@@ -44,6 +65,21 @@ struct nal_unit {
struct slice_header *slc;
};
+struct hrd_parameters {
+ uint32_t cpb_cnt_minus1;
+ uint8_t bit_rate_scale;
+ uint8_t cpb_size_scale;
+
+ uint32_t bit_rate_value_minus1[32];
+ uint32_t cpb_size_value_minus1[32];
+ uint8_t cbr_flag[32];
+
+ uint8_t initial_cpb_removal_delay_length_minus1;
+ uint8_t cpb_removal_delay_length_minus1;
+ uint8_t dpb_output_delay_length_minus1;
+ uint8_t time_offset_length;
+};
+
struct seq_parameter_set_rbsp {
uint8_t profile_idc; // 0xff
uint8_t constraint_setN_flag; // 0x0f
@@ -89,7 +125,61 @@ struct seq_parameter_set_rbsp {
uint32_t frame_crop_top_offset;
uint32_t frame_crop_bottom_offset;
uint8_t vui_parameters_present_flag;
- // TODO: add vui_parameters, rtbsp_trailing_bits
+
+ /* vui_parameters */
+ union {
+ uint8_t aspect_ration_info_present_flag;
+
+ /* aspect_ration_info_present_flag == 1 */
+ uint8_t aspect_ratio_idc;
+ uint16_t sar_width;
+ uint16_t sar_height;
+
+ uint8_t overscan_info_present_flag;
+ /* overscan_info_present_flag == 1 */
+ uint8_t overscan_appropriate_flag;
+
+ uint8_t video_signal_type_present_flag;
+ /* video_signal_type_present_flag == 1 */
+ uint8_t video_format;
+ uint8_t video_full_range_flag;
+ uint8_t colour_description_present;
+ /* colour_description_present == 1 */
+ uint8_t colour_primaries;
+ uint8_t transfer_characteristics;
+ uint8_t matrix_coefficients;
+
+ uint8_t chroma_loc_info_present_flag;
+ /* chroma_loc_info_present_flag == 1 */
+ uint8_t chroma_sample_loc_type_top_field;
+ uint8_t chroma_sample_loc_type_bottom_field;
+
+ uint8_t timing_info_present_flag;
+ /* timing_info_present_flag == 1 */
+ uint32_t num_units_in_tick;
+ uint32_t time_scale;
+ uint8_t fixed_frame_rate_flag;
+
+ uint8_t nal_hrd_parameters_present_flag;
+ struct hrd_parameters nal_hrd_parameters;
+
+ uint8_t vc1_hrd_parameters_present_flag;
+ struct hrd_parameters vc1_hrd_parameters;
+
+ uint8_t low_delay_hrd_flag;
+
+ uint8_t pic_struct_present_flag;
+ uint8_t bitstream_restriction_flag;
+
+ /* bitstream_restriction_flag == 1 */
+ uint8_t motion_vectors_over_pic_boundaries;
+ uint32_t max_bytes_per_pic_denom;
+ uint32_t max_bits_per_mb_denom;
+ uint32_t log2_max_mv_length_horizontal;
+ uint32_t log2_max_mv_length_vertical;
+ uint32_t num_reorder_frames;
+ uint32_t max_dec_frame_buffering;
+ } vui_parameters;
};
@@ -196,17 +286,17 @@ struct slice_header {
/* chroma_format_idc != 0 */
uint32_t chroma_log2_weight_denom;
- int32_t luma_weight_l0[31];
- int32_t luma_offset_l0[31];
+ int32_t luma_weight_l0[32];
+ int32_t luma_offset_l0[32];
- int32_t chroma_weight_l0[31][2];
- int32_t chroma_offset_l0[31][2];
+ int32_t chroma_weight_l0[32][2];
+ int32_t chroma_offset_l0[32][2];
- int32_t luma_weight_l1[31];
- int32_t luma_offset_l1[31];
+ int32_t luma_weight_l1[32];
+ int32_t luma_offset_l1[32];
- int32_t chroma_weight_l1[31][2];
- int32_t chroma_offset_l1[31][2];
+ int32_t chroma_weight_l1[32][2];
+ int32_t chroma_offset_l1[32][2];
} pred_weight_table;
/* def_rec_pic_marking */
@@ -236,15 +326,29 @@ struct nal_parser {
int found_sps;
int found_pps;
int last_nal_res;
+
int field; /* 0=top, 1=bottom, -1=both */
int slice;
int slice_cnt;
int have_top;
int have_frame;
+
struct nal_unit *nal0;
struct nal_unit *nal1;
struct nal_unit *current_nal;
struct nal_unit *last_nal;
+
+ /* pic_order_cnt */
+ int32_t top_field_order_cnt;
+ int32_t bottom_field_oder_cnt;
+ int32_t prev_pic_order_cnt_msb;
+ int32_t prev_pic_order_cnt_lsb;
+};
+
+/* Decoded Picture Buffer */
+struct dpb {
+ uint32_t max_frame_number;
+
};
int parse_nal(uint8_t *buf, int buf_len, struct nal_parser *parser);
diff --git a/src/libvdpau/vdpau_h264.c b/src/libvdpau/vdpau_h264.c
index 841a94eb1..10577bc59 100644
--- a/src/libvdpau/vdpau_h264.c
+++ b/src/libvdpau/vdpau_h264.c
@@ -178,7 +178,8 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen,
}
if(this->decoder_initialized) {
- if(this->nal_parser->current_nal->slc != NULL &&
+ if(vdp_buffer.bitstream_bytes > 0 &&
+ this->nal_parser->current_nal->slc != NULL &&
this->nal_parser->current_nal->sps != NULL &&
this->nal_parser->current_nal->pps != NULL) {
@@ -197,7 +198,8 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen,
pic.slice_count = slice_count;
pic.field_order_cnt[0] = 0; // FIXME
- pic.is_reference = 1; // FIXME
+ pic.is_reference =
+ (this->nal_parser->current_nal->nal_ref_idc != 0) ? VDP_TRUE : VDP_FALSE;
pic.frame_num = slc->frame_num;
pic.field_pic_flag = slc->field_pic_flag;
pic.bottom_field_flag = slc->bottom_field_flag;
@@ -229,6 +231,7 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen,
img->pts = buf->pts;
img->bad_frame = 0;
+ printf("Decode pts: %lld, %d\n", img->pts, vdp_buffer.bitstream_bytes);
/* create surface if needed */
if(this->vdpau_accel->surface == VDP_INVALID_HANDLE) {
VdpStatus status = this->vdpau_accel->vdp_video_surface_create(this->vdpau_accel->vdp_device,
@@ -240,17 +243,18 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen,
}
VdpStatus status = this->vdpau_accel->vdp_decoder_render(this->decoder,
- this->vdpau_accel->surface, &pic, 1, (VdpPictureInfo*)&vdp_buffer);
+ this->vdpau_accel->surface, (VdpPictureInfo*)&pic, 1, &vdp_buffer);
if(status != VDP_STATUS_OK)
xprintf(this->xine, XINE_VERBOSITY_LOG, "vdpau_h264: Decoder failure: %d\n", status);
+ else
+ printf("DECODING SUCCESS\n");
img->draw(img, this->stream);
img->free(img);
}
}
}
-
}
}