summaryrefslogtreecommitdiff
path: root/sys/vdpau
diff options
context:
space:
mode:
authorCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2010-06-17 15:20:51 +0200
committerCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2010-06-23 21:51:53 +0200
commit322d1ff9460b7eeedc78d2c07d2195b785be2f3f (patch)
treec464fe8acb500918edad2ac55a0110369354a33f /sys/vdpau
parent80749da1668bf93b73fdb4c54b7b2834ff4fa19b (diff)
vdpauh264dec: now works for simple streams
Diffstat (limited to 'sys/vdpau')
-rw-r--r--sys/vdpau/h264/gsth264dpb.c45
-rw-r--r--sys/vdpau/h264/gsth264parser.c83
-rw-r--r--sys/vdpau/h264/gstvdph264dec.c32
3 files changed, 104 insertions, 56 deletions
diff --git a/sys/vdpau/h264/gsth264dpb.c b/sys/vdpau/h264/gsth264dpb.c
index 85f3c3056..a2d695686 100644
--- a/sys/vdpau/h264/gsth264dpb.c
+++ b/sys/vdpau/h264/gsth264dpb.c
@@ -48,8 +48,8 @@ gst_h264_dpb_fill_reference_frames (GstH264DPB * dpb,
GstVdpH264Frame *frame = frames[i];
reference_frames[i].surface =
- GST_VDP_VIDEO_BUFFER (GST_VIDEO_FRAME_CAST (frame)->src_buffer)->
- surface;
+ GST_VDP_VIDEO_BUFFER (GST_VIDEO_FRAME_CAST (frame)->
+ src_buffer)->surface;
reference_frames[i].is_long_term = frame->is_long_term;
reference_frames[i].top_is_reference = frame->is_reference;
@@ -58,6 +58,26 @@ gst_h264_dpb_fill_reference_frames (GstH264DPB * dpb,
reference_frames[i].field_order_cnt[1] = frame->poc;
reference_frames[i].frame_idx = frame->frame_num;
}
+
+ for (i = dpb->n_frames; i < 16; i++) {
+ reference_frames[i].surface = VDP_INVALID_HANDLE;
+ reference_frames[i].top_is_reference = VDP_FALSE;
+ reference_frames[i].bottom_is_reference = VDP_FALSE;
+ }
+}
+
+static void
+gst_h264_dpb_remove (GstH264DPB * dpb, guint idx)
+{
+ GstVdpH264Frame **frames;
+ guint i;
+
+ frames = dpb->frames;
+ gst_video_frame_unref (GST_VIDEO_FRAME_CAST (frames[idx]));
+ dpb->n_frames--;
+
+ for (i = idx; i < dpb->n_frames; i++)
+ frames[i] = frames[i + 1];
}
static void
@@ -67,18 +87,10 @@ gst_h264_dpb_output (GstH264DPB * dpb, guint idx)
gst_video_frame_ref (GST_VIDEO_FRAME_CAST (frame));
dpb->output (dpb, frame);
+ frame->output_needed = FALSE;
- if (!frame->is_reference) {
- GstVdpH264Frame **frames;
- guint i;
-
- gst_video_frame_unref (GST_VIDEO_FRAME_CAST (frame));
- dpb->n_frames--;
-
- frames = dpb->frames;
- for (i = idx; i < dpb->n_frames; i++)
- frames[i] = frames[i + 1];
- }
+ if (!frame->is_reference)
+ gst_h264_dpb_remove (dpb, idx);
}
static gboolean
@@ -153,6 +165,8 @@ gst_h264_dpb_flush (GstH264DPB * dpb, gboolean output)
GstVideoFrame **frames;
guint i;
+ GST_DEBUG ("flush");
+
if (output)
while (gst_h264_dpb_bump (dpb, G_MAXUINT));
@@ -171,6 +185,9 @@ gst_h264_dpb_mark_sliding (GstH264DPB * dpb)
guint i;
gint mark_idx;
+ if (dpb->n_frames != dpb->max_frames)
+ return;
+
frames = dpb->frames;
for (i = 0; i < dpb->n_frames; i++) {
if (frames[i]->is_reference && !frames[i]->is_long_term) {
@@ -187,6 +204,8 @@ gst_h264_dpb_mark_sliding (GstH264DPB * dpb)
}
frames[mark_idx]->is_reference = FALSE;
+ if (!frames[mark_idx]->output_needed)
+ gst_h264_dpb_remove (dpb, mark_idx);
}
}
diff --git a/sys/vdpau/h264/gsth264parser.c b/sys/vdpau/h264/gsth264parser.c
index 1614c2d59..6d442d8d3 100644
--- a/sys/vdpau/h264/gsth264parser.c
+++ b/sys/vdpau/h264/gsth264parser.c
@@ -255,45 +255,46 @@ gst_h264_parser_parse_scaling_list (GstNalReader * reader,
const guint8 fallback_8x8_inter[64], const guint8 fallback_8x8_intra[64],
guint32 chroma_format_idc)
{
- gint i;
- guint8 seq_scaling_list_present_flag[12] = { 0, };
+ guint i;
GST_WARNING ("parsing scaling lists");
- for (i = 0; i < ((chroma_format_idc) != 3) ? 8 : 12; i++) {
- READ_UINT8 (reader, seq_scaling_list_present_flag[i], 1);
- }
-
for (i = 0; i < 12; i++) {
gboolean use_default = FALSE;
- if (seq_scaling_list_present_flag[i]) {
- guint8 *scaling_list;
- guint size;
- guint j;
- guint8 last_scale, next_scale;
-
- if (i <= 5) {
- scaling_list = scaling_lists_4x4[i];
- size = 16;
- } else {
- scaling_list = scaling_lists_8x8[i];
- size = 64;
- }
-
- last_scale = 8;
- next_scale = 8;
- for (j = 0; j < size; j++) {
- if (next_scale != 0) {
- gint32 delta_scale;
+ if (i < ((chroma_format_idc != 3) ? 8 : 12)) {
+ guint8 scaling_list_present_flag;
+
+ READ_UINT8 (reader, scaling_list_present_flag, 1);
+ if (scaling_list_present_flag) {
+ guint8 *scaling_list;
+ guint size;
+ guint j;
+ guint8 last_scale, next_scale;
+
+ if (i <= 5) {
+ scaling_list = scaling_lists_4x4[i];
+ size = 16;
+ } else {
+ scaling_list = scaling_lists_8x8[i - 6];
+ size = 64;
+ }
- READ_SE (reader, delta_scale);
- next_scale = (last_scale + delta_scale + 256) % 256;
- use_default = (j == 0 && next_scale == 0);
+ last_scale = 8;
+ next_scale = 8;
+ for (j = 0; j < size; j++) {
+ if (next_scale != 0) {
+ gint32 delta_scale;
+
+ READ_SE (reader, delta_scale);
+ next_scale = (last_scale + delta_scale + 256) % 256;
+ use_default = (j == 0 && next_scale == 0);
+ }
+ scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
+ last_scale = scaling_list[j];
}
- scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
- last_scale = scaling_list[j];
- }
+ } else
+ use_default = TRUE;
} else
use_default = TRUE;
@@ -396,8 +397,8 @@ gst_h264_parser_parse_sequence (GstH264Parser * parser, guint8 * data,
if (seq->profile_idc == 100 || seq->profile_idc == 110 ||
seq->profile_idc == 122 || seq->profile_idc == 244 ||
- seq->profile_idc == 244 || seq->profile_idc == 44 ||
- seq->profile_idc == 83 || seq->profile_idc == 86) {
+ seq->profile_idc == 44 || seq->profile_idc == 83 ||
+ seq->profile_idc == 86) {
READ_UE_ALLOWED (&reader, seq->chroma_format_idc, 0, 3);
if (seq->chroma_format_idc == 3)
READ_UINT8 (&reader, seq->separate_colour_plane_flag, 1);
@@ -497,8 +498,18 @@ gst_h264_parser_more_data (GstNalReader * reader)
if (!gst_nal_reader_peek_bits_uint8 (reader, &rbsp_stop_one_bit, 1))
return FALSE;
- if (rbsp_stop_one_bit == 1)
- return FALSE;
+ if (rbsp_stop_one_bit == 1) {
+ guint8 zero_bits;
+
+ if (remaining == 1)
+ return FALSE;
+
+ if (!gst_nal_reader_peek_bits_uint8 (reader, &zero_bits, remaining))
+ return FALSE;
+
+ if ((zero_bits - (1 << (remaining - 1))) == 0)
+ return FALSE;
+ }
}
return TRUE;
@@ -754,7 +765,7 @@ gst_h264_slice_parse_dec_ref_pic_marking (GstH264Slice * slice,
m = &slice->dec_ref_pic_marking;
- if (slice->nal_unit.IdrPicFlag == 0) {
+ if (slice->nal_unit.IdrPicFlag) {
READ_UINT8 (reader, m->no_output_of_prior_pics_flag, 1);
READ_UINT8 (reader, m->long_term_reference_flag, 1);
} else {
diff --git a/sys/vdpau/h264/gstvdph264dec.c b/sys/vdpau/h264/gstvdph264dec.c
index 222971444..93071fb21 100644
--- a/sys/vdpau/h264/gstvdph264dec.c
+++ b/sys/vdpau/h264/gstvdph264dec.c
@@ -183,9 +183,13 @@ gst_vdp_h264_dec_shape_output (GstBaseVideoDecoder * base_video_decoder,
static void
gst_vdp_h264_dec_output (GstH264DPB * dpb, GstVdpH264Frame * h264_frame)
{
+ GstBaseVideoDecoder *base_video_decoder;
+
GST_DEBUG ("poc: %d", h264_frame->poc);
- gst_video_frame_unref (GST_VIDEO_FRAME_CAST (h264_frame));
+ base_video_decoder = g_object_get_data (G_OBJECT (dpb), "decoder");
+ gst_base_video_decoder_finish_frame (base_video_decoder,
+ GST_VIDEO_FRAME_CAST (h264_frame));
}
static guint
@@ -230,7 +234,9 @@ gst_vdp_h264_dec_init_frame_info (GstVdpH264Dec * h264_dec,
h264_frame->poc = gst_vdp_h264_dec_calculate_poc (h264_dec, slice);
+ h264_frame->output_needed = TRUE;
h264_frame->is_long_term = FALSE;
+ h264_frame->frame_num = slice->frame_num;
/* is reference */
if (slice->nal_unit.ref_idc == 0)
@@ -266,14 +272,16 @@ gst_vdp_h264_dec_idr (GstVdpH264Dec * h264_dec, GstVdpH264Frame * h264_frame)
seq = slice->picture->sequence;
if (seq != h264_dec->sequence) {
+ GstFlowReturn ret;
GstVdpDevice *device;
gst_base_video_decoder_update_src_caps (GST_BASE_VIDEO_DECODER (h264_dec));
- device = gst_vdp_video_src_pad_get_device
- (GST_VDP_VIDEO_SRC_PAD (GST_BASE_VIDEO_DECODER_SRC_PAD (h264_dec)));
+ ret = gst_vdp_video_src_pad_get_device
+ (GST_VDP_VIDEO_SRC_PAD (GST_BASE_VIDEO_DECODER_SRC_PAD (h264_dec)),
+ &device, NULL);
- if (device) {
+ if (ret == GST_FLOW_OK) {
GstVideoState *state;
VdpDecoderProfile profile;
VdpStatus status;
@@ -344,6 +352,7 @@ gst_vdp_h264_dec_fill_info (GstVdpH264Dec * h264_dec,
info.field_order_cnt[1] = h264_frame->poc;
info.is_reference = h264_frame->is_reference;
+ info.frame_num = slice->frame_num;
info.field_pic_flag = slice->field_pic_flag;
info.bottom_field_flag = slice->bottom_field_flag;
@@ -374,8 +383,13 @@ gst_vdp_h264_dec_fill_info (GstVdpH264Dec * h264_dec,
pic->deblocking_filter_control_present_flag;
info.redundant_pic_cnt_present_flag = pic->redundant_pic_cnt_present_flag;
- memcpy (&info.scaling_lists_4x4, &pic->scaling_lists_4x4, 96);
- memcpy (&info.scaling_lists_8x8, &pic->scaling_lists_8x8, 128);
+ if (pic->scaling_matrix_present_flag) {
+ memcpy (&info.scaling_lists_4x4, &pic->scaling_lists_4x4, 96);
+ memcpy (&info.scaling_lists_8x8, &pic->scaling_lists_8x8, 128);
+ } else {
+ memcpy (&info.scaling_lists_4x4, &seq->scaling_lists_4x4, 96);
+ memcpy (&info.scaling_lists_8x8, &seq->scaling_lists_8x8, 128);
+ }
gst_h264_dpb_fill_reference_frames (h264_dec->dpb, info.referenceFrames);
@@ -652,6 +666,7 @@ gst_vdp_h264_dec_parse_data (GstBaseVideoDecoder * base_video_decoder,
if (!gst_bit_reader_skip (&reader, 24))
goto invalid_packet;
}
+ nal_unit.IdrPicFlag = (nal_unit.type == 5 ? 1 : 0);
data = GST_BUFFER_DATA (buf) + gst_bit_reader_get_pos (&reader) / 8;
size = gst_bit_reader_get_remaining (&reader) / 8;
@@ -811,6 +826,7 @@ gst_vdp_h264_dec_start (GstBaseVideoDecoder * base_video_decoder)
h264_dec->parser = g_object_new (GST_TYPE_H264_PARSER, NULL);
h264_dec->dpb = g_object_new (GST_TYPE_H264_DPB, NULL);
+ g_object_set_data (G_OBJECT (h264_dec->dpb), "decoder", h264_dec);
h264_dec->dpb->output = gst_vdp_h264_dec_output;
return TRUE;
@@ -822,6 +838,7 @@ gst_vdp_h264_dec_stop (GstBaseVideoDecoder * base_video_decoder)
GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (base_video_decoder);
GstVdpVideoSrcPad *vdp_pad;
+ GstFlowReturn ret;
GstVdpDevice *device;
g_object_unref (h264_dec->parser);
@@ -831,7 +848,8 @@ gst_vdp_h264_dec_stop (GstBaseVideoDecoder * base_video_decoder)
GST_VDP_VIDEO_SRC_PAD (GST_BASE_VIDEO_DECODER_SRC_PAD
(base_video_decoder));
- if ((device = gst_vdp_video_src_pad_get_device (vdp_pad))) {
+ ret = gst_vdp_video_src_pad_get_device (vdp_pad, &device, NULL);
+ if (ret == GST_FLOW_OK) {
if (h264_dec->decoder != VDP_INVALID_HANDLE)
device->vdp_decoder_destroy (h264_dec->decoder);