summaryrefslogtreecommitdiff
path: root/sys/vdpau/h264/gsth264dpb.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vdpau/h264/gsth264dpb.c')
-rw-r--r--sys/vdpau/h264/gsth264dpb.c45
1 files changed, 32 insertions, 13 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);
}
}