diff options
-rw-r--r-- | sys/vdpau/gstvdp/gstvdpoutputsrcpad.c | 166 | ||||
-rw-r--r-- | sys/vdpau/gstvdpvideopostprocess.c | 89 |
2 files changed, 101 insertions, 154 deletions
diff --git a/sys/vdpau/gstvdp/gstvdpoutputsrcpad.c b/sys/vdpau/gstvdp/gstvdpoutputsrcpad.c index bd67ba8c3..e54f799f7 100644 --- a/sys/vdpau/gstvdp/gstvdpoutputsrcpad.c +++ b/sys/vdpau/gstvdp/gstvdpoutputsrcpad.c @@ -29,7 +29,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vdp_output_src_pad_debug); enum { PROP_0, - PROP_DISPLAY, + PROP_DEVICE, PROP_TEMPL_CAPS }; @@ -46,7 +46,6 @@ struct _GstVdpOutputSrcPad GstPad pad; GstCaps *caps; - GstVdpDevice *device; GstCaps *input_caps; GstVdpOutputSrcPadFormat output_format; @@ -54,7 +53,7 @@ struct _GstVdpOutputSrcPad gint width, height; /* properties */ - gchar *display; + GstVdpDevice *device; GstCaps *templ_caps; }; @@ -123,25 +122,6 @@ gst_vdp_output_src_pad_push (GstVdpOutputSrcPad * vdp_pad, return gst_pad_push (pad, outbuf); } -static void -gst_vdp_output_src_pad_update_caps (GstVdpOutputSrcPad * vdp_pad) -{ - GstCaps *allowed_caps; - - allowed_caps = gst_vdp_output_buffer_get_allowed_caps (vdp_pad->device); - - if (vdp_pad->caps) - gst_caps_unref (vdp_pad->caps); - - if (vdp_pad->templ_caps) { - vdp_pad->caps = gst_caps_intersect (allowed_caps, vdp_pad->templ_caps); - gst_caps_unref (allowed_caps); - } else - vdp_pad->caps = allowed_caps; - - GST_DEBUG_OBJECT (vdp_pad, "allowed caps: %" GST_PTR_FORMAT, vdp_pad->caps); -} - static GstFlowReturn gst_vdp_output_src_pad_create_buffer (GstVdpOutputSrcPad * vdp_pad, GstVdpOutputBuffer ** output_buf, GError ** error) @@ -201,26 +181,6 @@ output_buf_error: } -static gboolean -gst_vdp_output_src_pad_open_device (GstVdpOutputSrcPad * vdp_pad, - GError ** error) -{ - GstVdpDevice *device; - - vdp_pad->device = device = gst_vdp_get_device (vdp_pad->display); - if (G_UNLIKELY (!vdp_pad->device)) - goto device_error; - - gst_vdp_output_src_pad_update_caps (vdp_pad); - - return TRUE; - -device_error: - g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_OPEN_READ, - "Couldn't create GstVdpDevice"); - return FALSE; -} - static GstFlowReturn gst_vdp_output_src_pad_alloc_with_caps (GstVdpOutputSrcPad * vdp_pad, GstCaps * caps, GstVdpOutputBuffer ** output_buf, GError ** error) @@ -260,11 +220,6 @@ gst_vdp_output_src_pad_alloc_buffer (GstVdpOutputSrcPad * vdp_pad, switch (vdp_pad->output_format) { case GST_VDP_OUTPUT_SRC_PAD_FORMAT_RGB: { - if (G_UNLIKELY (!vdp_pad->device)) { - if (!gst_vdp_output_src_pad_open_device (vdp_pad, error)) - return GST_FLOW_ERROR; - } - ret = gst_vdp_output_src_pad_create_buffer (vdp_pad, output_buf, error); if (ret != GST_FLOW_OK) return ret; @@ -279,13 +234,6 @@ gst_vdp_output_src_pad_alloc_buffer (GstVdpOutputSrcPad * vdp_pad, if (ret != GST_FLOW_OK) return ret; - if (G_UNLIKELY (!vdp_pad->device)) { - vdp_pad->device = - g_object_ref (GST_VDP_VIDEO_BUFFER (*output_buf)->device); - - gst_vdp_output_src_pad_update_caps (vdp_pad); - } - break; } @@ -365,54 +313,6 @@ not_negotiated: return FALSE; } -GstFlowReturn -gst_vdp_output_src_pad_get_device (GstVdpOutputSrcPad * vdp_pad, - GstVdpDevice ** device, GError ** error) -{ - g_return_val_if_fail (GST_IS_VDP_OUTPUT_SRC_PAD (vdp_pad), FALSE); - - if (G_UNLIKELY (!vdp_pad->device)) { - GstCaps *src_caps; - GstStructure *structure; - - src_caps = gst_pad_get_allowed_caps (GST_PAD (vdp_pad)); - - if (gst_caps_is_empty (src_caps)) { - gst_caps_unref (src_caps); - return GST_FLOW_NOT_NEGOTIATED; - } - gst_pad_fixate_caps (GST_PAD (vdp_pad), src_caps); - - structure = gst_caps_get_structure (src_caps, 0); - if (gst_structure_has_name (structure, "video/x-raw-rgb")) { - if (!gst_vdp_output_src_pad_open_device (vdp_pad, error)) { - gst_caps_unref (src_caps); - return GST_FLOW_ERROR; - } - } - - else { - GstFlowReturn ret; - GstVdpOutputBuffer *buf; - - ret = gst_vdp_output_src_pad_alloc_with_caps (vdp_pad, src_caps, - &buf, error); - if (ret != GST_FLOW_OK) { - gst_caps_unref (src_caps); - return ret; - } - - vdp_pad->device = g_object_ref (buf->device); - gst_buffer_unref (GST_BUFFER (buf)); - } - - gst_caps_unref (src_caps); - } - - *device = vdp_pad->device; - return GST_FLOW_OK; -} - static GstCaps * gst_vdp_output_src_pad_getcaps (GstPad * pad) { @@ -430,13 +330,13 @@ gst_vdp_output_src_pad_activate_push (GstPad * pad, gboolean active) GstVdpOutputSrcPad *vdp_pad = GST_VDP_OUTPUT_SRC_PAD (pad); if (!active) { - if (vdp_pad->device) - g_object_unref (vdp_pad->device); - vdp_pad->device = NULL; - if (vdp_pad->caps) gst_caps_unref (vdp_pad->caps); vdp_pad->caps = NULL; + + if (vdp_pad->device) + gst_object_unref (vdp_pad->device); + vdp_pad->device = NULL; } return TRUE; @@ -450,18 +350,39 @@ gst_vdp_output_src_pad_new (GstCaps * templ_caps) } static void +gst_vdp_output_src_pad_update_caps (GstVdpOutputSrcPad * vdp_pad) +{ + GstCaps *allowed_caps; + + allowed_caps = gst_vdp_output_buffer_get_allowed_caps (vdp_pad->device); + + if (vdp_pad->caps) + gst_caps_unref (vdp_pad->caps); + + if (vdp_pad->templ_caps) { + vdp_pad->caps = gst_caps_intersect (allowed_caps, vdp_pad->templ_caps); + gst_caps_unref (allowed_caps); + } else + vdp_pad->caps = allowed_caps; + + GST_DEBUG_OBJECT (vdp_pad, "allowed caps: %" GST_PTR_FORMAT, vdp_pad->caps); +} + +static void gst_vdp_output_src_pad_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstVdpOutputSrcPad *vdp_pad = (GstVdpOutputSrcPad *) object; switch (prop_id) { - case PROP_DISPLAY: - g_value_set_string (value, vdp_pad->display); + case PROP_DEVICE: + g_value_set_object (value, vdp_pad->device); break; + case PROP_TEMPL_CAPS: gst_value_set_caps (value, vdp_pad->templ_caps); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -475,14 +396,19 @@ gst_vdp_output_src_pad_set_property (GObject * object, guint prop_id, GstVdpOutputSrcPad *vdp_pad = (GstVdpOutputSrcPad *) object; switch (prop_id) { - case PROP_DISPLAY: - vdp_pad->display = g_value_dup_string (value); + case PROP_DEVICE: + if (vdp_pad->device) + g_object_unref (vdp_pad->device); + vdp_pad->device = g_value_dup_object (value); + gst_vdp_output_src_pad_update_caps (vdp_pad); break; + case PROP_TEMPL_CAPS: if (vdp_pad->templ_caps) gst_caps_unref (vdp_pad->templ_caps); vdp_pad->templ_caps = gst_caps_copy (gst_value_get_caps (value)); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -497,8 +423,6 @@ gst_vdp_output_src_pad_finalize (GObject * object) if (vdp_pad->templ_caps) gst_caps_unref (vdp_pad->templ_caps); - g_free (vdp_pad->display); - G_OBJECT_CLASS (gst_vdp_output_src_pad_parent_class)->finalize (object); } @@ -507,10 +431,9 @@ gst_vdp_output_src_pad_init (GstVdpOutputSrcPad * vdp_pad) { GstPad *pad = GST_PAD (vdp_pad); - vdp_pad->device = NULL; vdp_pad->caps = NULL; - vdp_pad->display = NULL; + vdp_pad->device = NULL; vdp_pad->templ_caps = NULL; gst_pad_set_getcaps_function (pad, @@ -528,9 +451,18 @@ gst_vdp_output_src_pad_class_init (GstVdpOutputSrcPadClass * klass) object_class->set_property = gst_vdp_output_src_pad_set_property; object_class->finalize = gst_vdp_output_src_pad_finalize; - g_object_class_install_property (object_class, PROP_DISPLAY, - g_param_spec_string ("display", "Display", "X Display name", - NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + /** + * GstVdpVideoSrcPad:device: + * + * The #GstVdpDevice this pool is bound to. + */ + g_object_class_install_property + (object_class, + PROP_DEVICE, + g_param_spec_object ("device", + "Device", + "The GstVdpDevice the pad should use", + GST_TYPE_VDP_DEVICE, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_TEMPL_CAPS, g_param_spec_boxed ("template-caps", "Template caps", diff --git a/sys/vdpau/gstvdpvideopostprocess.c b/sys/vdpau/gstvdpvideopostprocess.c index cd45b4dbf..9f2c22106 100644 --- a/sys/vdpau/gstvdpvideopostprocess.c +++ b/sys/vdpau/gstvdpvideopostprocess.c @@ -363,23 +363,6 @@ gst_vdp_vpp_post_error (GstVdpVideoPostProcess * vpp, GError * error) } static GstFlowReturn -gst_vdp_vpp_open_device (GstVdpVideoPostProcess * vpp) -{ - GstFlowReturn ret; - GError *err = NULL; - - GST_DEBUG ("open_device"); - - ret = - gst_vdp_output_src_pad_get_device (GST_VDP_OUTPUT_SRC_PAD (vpp->srcpad), - &vpp->device, &err); - if (ret == GST_FLOW_ERROR) - gst_vdp_vpp_post_error (vpp, err); - - return ret; -} - -static GstFlowReturn gst_vdp_vpp_create_mixer (GstVdpVideoPostProcess * vpp) { #define VDP_NUM_MIXER_PARAMETER 3 @@ -413,8 +396,6 @@ gst_vdp_vpp_create_mixer (GstVdpVideoPostProcess * vpp) if (vpp->inverse_telecine) features[n_features++] = VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE; - if (G_UNLIKELY (!vpp->device)) - gst_vdp_vpp_open_device (vpp); device = vpp->device; status = @@ -569,7 +550,7 @@ gst_vdp_vpp_flush (GstVdpVideoPostProcess * vpp) vpp->n_past_pictures = 0; } -static void +static gboolean gst_vdp_vpp_start (GstVdpVideoPostProcess * vpp) { gint i; @@ -589,15 +570,41 @@ gst_vdp_vpp_start (GstVdpVideoPostProcess * vpp) } vpp->n_future_pictures = 0; vpp->n_past_pictures = 0; + + vpp->device = gst_vdp_get_device (vpp->display); + if (G_UNLIKELY (!vpp->device)) + goto device_error; + + g_object_set (G_OBJECT (vpp->srcpad), "device", vpp->device, NULL); + + return TRUE; + +device_error: + GST_ELEMENT_ERROR (vpp, RESOURCE, OPEN_READ, + ("Couldn't create GstVdpDevice"), (NULL)); + return FALSE; } -static void +static gboolean gst_vdp_vpp_stop (GstVdpVideoPostProcess * vpp) { - if (vpp->mixer != VDP_INVALID_HANDLE) - vpp->device->vdp_video_mixer_destroy (vpp->mixer); - gst_vdp_vpp_flush (vpp); + + if (vpp->mixer != VDP_INVALID_HANDLE) { + GstVdpDevice *device = vpp->device; + VdpStatus status; + + status = device->vdp_video_mixer_destroy (vpp->mixer); + if (status != VDP_STATUS_OK) { + GST_ELEMENT_ERROR (vpp, RESOURCE, READ, + ("Could not destroy vdpau decoder"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + return FALSE; + } + } + + return TRUE; } static GstFlowReturn @@ -783,9 +790,6 @@ no_qos: if (!vpp->native_input) { GstVdpVideoBuffer *video_buf; - if (G_UNLIKELY (!vpp->device)) - gst_vdp_vpp_open_device (vpp); - video_buf = gst_vdp_video_buffer_new (vpp->device, vpp->chroma_type, vpp->width, vpp->height); if (G_UNLIKELY (!video_buf)) @@ -872,12 +876,6 @@ gst_vdp_vpp_sink_bufferalloc (GstPad * pad, guint64 offset, guint size, gint width, height; VdpChromaType chroma_type; - if (G_UNLIKELY (!vpp->device)) { - ret = gst_vdp_vpp_open_device (vpp); - if (ret != GST_FLOW_OK) - return ret; - } - if (!gst_structure_get_int (structure, "width", &width) || !gst_structure_get_int (structure, "height", &height) || !gst_structure_get_int (structure, "chroma-type", @@ -1002,7 +1000,8 @@ gst_vdp_vpp_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: - gst_vdp_vpp_start (vpp); + if (!gst_vdp_vpp_start (vpp)) + return GST_STATE_CHANGE_FAILURE; break; default: break; @@ -1012,7 +1011,8 @@ gst_vdp_vpp_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_vdp_vpp_stop (vpp); + if (!gst_vdp_vpp_stop (vpp)) + ret = GST_STATE_CHANGE_FAILURE; break; default: break; @@ -1030,26 +1030,33 @@ gst_vdp_vpp_get_property (GObject * object, guint property_id, GValue * value, switch (property_id) { case PROP_DISPLAY: - g_object_get_property (G_OBJECT (vpp->srcpad), "display", value); + g_value_set_string (value, vpp->display); break; + case PROP_FORCE_ASPECT_RATIO: g_value_set_boolean (value, vpp->force_aspect_ratio); break; + case PROP_DEINTERLACE_MODE: g_value_set_enum (value, vpp->mode); break; + case PROP_DEINTERLACE_METHOD: g_value_set_enum (value, vpp->method); break; + case PROP_NOISE_REDUCTION: g_value_set_float (value, vpp->noise_reduction); break; + case PROP_SHARPENING: g_value_set_float (value, vpp->sharpening); break; + case PROP_INVERSE_TELECINE: g_value_set_boolean (value, vpp->inverse_telecine); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -1065,14 +1072,18 @@ gst_vdp_vpp_set_property (GObject * object, guint property_id, switch (property_id) { case PROP_DISPLAY: - g_object_set_property (G_OBJECT (vpp->srcpad), "display", value); + g_free (vpp->display); + vpp->display = g_value_dup_string (value); break; + case PROP_FORCE_ASPECT_RATIO: vpp->force_aspect_ratio = g_value_get_boolean (value); break; + case PROP_DEINTERLACE_MODE: vpp->mode = g_value_get_enum (value); break; + case PROP_DEINTERLACE_METHOD: { GstVdpDeinterlaceMethods oldvalue; @@ -1091,6 +1102,7 @@ gst_vdp_vpp_set_property (GObject * object, guint property_id, } break; } + case PROP_NOISE_REDUCTION: { gfloat old_value; @@ -1115,6 +1127,7 @@ gst_vdp_vpp_set_property (GObject * object, guint property_id, } break; } + case PROP_SHARPENING: { gfloat old_value; @@ -1138,6 +1151,7 @@ gst_vdp_vpp_set_property (GObject * object, guint property_id, } break; } + case PROP_INVERSE_TELECINE: { vpp->inverse_telecine = g_value_get_boolean (value); @@ -1148,6 +1162,7 @@ gst_vdp_vpp_set_property (GObject * object, guint property_id, } break; } + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; |