summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/vdpau/gstvdpdecoder.c27
-rw-r--r--sys/vdpau/gstvdpmpegdecoder.c38
2 files changed, 38 insertions, 27 deletions
diff --git a/sys/vdpau/gstvdpdecoder.c b/sys/vdpau/gstvdpdecoder.c
index 8b79dff0..7aca6c2f 100644
--- a/sys/vdpau/gstvdpdecoder.c
+++ b/sys/vdpau/gstvdpdecoder.c
@@ -75,28 +75,6 @@ gst_vdp_decoder_push_video_buffer (GstVdpDecoder * dec,
return gst_pad_push (dec->src, GST_BUFFER (buffer));
}
-static GstStateChangeReturn
-gst_vdp_decoder_change_state (GstElement * element, GstStateChange transition)
-{
- GstVdpDecoder *dec;
-
- dec = GST_VDP_DECODER (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- dec->device = gst_vdp_get_device (dec->display_name);
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- g_object_unref (dec->device);
- dec->device = NULL;
- break;
- default:
- break;
- }
-
- return GST_STATE_CHANGE_SUCCESS;
-}
-
static gboolean
gst_vdp_decoder_sink_set_caps (GstPad * pad, GstCaps * caps)
{
@@ -182,8 +160,6 @@ gst_vdp_decoder_class_init (GstVdpDecoderClass * klass)
g_object_class_install_property (gobject_class, PROP_DISPLAY,
g_param_spec_string ("display", "Display", "X Display name",
NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- gstelement_class->change_state = gst_vdp_decoder_change_state;
}
static void
@@ -214,9 +190,6 @@ gst_vdp_decoder_finalize (GObject * object)
{
GstVdpDecoder *dec = (GstVdpDecoder *) object;
- if (dec->device)
- g_object_unref (dec->device);
-
g_free (dec->display_name);
}
diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c
index 5b461268..1f15feaf 100644
--- a/sys/vdpau/gstvdpmpegdecoder.c
+++ b/sys/vdpau/gstvdpmpegdecoder.c
@@ -120,6 +120,12 @@ gst_vdp_mpeg_decoder_set_caps (GstVdpDecoder * dec, GstCaps * caps)
&hdr.non_intra_quantizer_matrix, 64);
device = dec->device;
+
+ if (mpeg_dec->decoder != VDP_INVALID_HANDLE) {
+ device->vdp_decoder_destroy (mpeg_dec->decoder);
+ mpeg_dec->decoder = VDP_INVALID_HANDLE;
+ }
+
status = device->vdp_decoder_create (device->device, profile, dec->width,
dec->height, 2, &mpeg_dec->decoder);
if (status != VDP_STATUS_OK) {
@@ -499,6 +505,36 @@ gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event)
return res;
}
+static GstStateChangeReturn
+gst_vdp_mpeg_decoder_change_state (GstElement * element,
+ GstStateChange transition)
+{
+ GstVdpMpegDecoder *mpeg_dec;
+ GstVdpDecoder *dec;
+
+ mpeg_dec = GST_VDP_MPEG_DECODER (element);
+ dec = GST_VDP_DECODER (mpeg_dec);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_READY_TO_PAUSED:
+ dec->device = gst_vdp_get_device (dec->display_name);
+ break;
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ gst_vdp_mpeg_decoder_reset (mpeg_dec);
+
+ dec->device->vdp_decoder_destroy (mpeg_dec->decoder);
+ mpeg_dec->decoder = VDP_INVALID_HANDLE;
+
+ g_object_unref (dec->device);
+ dec->device = NULL;
+ break;
+ default:
+ break;
+ }
+
+ return GST_STATE_CHANGE_SUCCESS;
+}
+
/* GObject vmethod implementations */
static void
@@ -533,6 +569,8 @@ gst_vdp_mpeg_decoder_class_init (GstVdpMpegDecoderClass * klass)
gobject_class->get_property = gst_vdp_mpeg_decoder_get_property;
vdpaudec_class->set_caps = gst_vdp_mpeg_decoder_set_caps;
+
+ gstelement_class->change_state = gst_vdp_mpeg_decoder_change_state;
}
static void