summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2009-11-22 22:30:19 +0100
committerCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2009-11-22 22:38:09 +0100
commit2d03815e1969427d29a8925777ce5ffe34f79151 (patch)
tree4d73c0b96781875c1afde2061630df76d323b93a
parent4dd36435a768d0355a364d59f38a7f5e46917a96 (diff)
vdpauvideopostprocess: use GstVdpVideoSrcPad
-rw-r--r--sys/vdpau/gstvdpvideopostprocess.c172
-rw-r--r--sys/vdpau/gstvdpvideopostprocess.h2
2 files changed, 76 insertions, 98 deletions
diff --git a/sys/vdpau/gstvdpvideopostprocess.c b/sys/vdpau/gstvdpvideopostprocess.c
index a77939d261..b2cace4847 100644
--- a/sys/vdpau/gstvdpvideopostprocess.c
+++ b/sys/vdpau/gstvdpvideopostprocess.c
@@ -47,6 +47,7 @@
#include "gstvdputils.h"
#include "gstvdpoutputbuffer.h"
+#include "gstvdpoutputsrcpad.h"
#include "gstvdpvideopostprocess.h"
@@ -72,15 +73,6 @@ enum
PROP_INVERSE_TELECINE
};
-/* the capabilities of the inputs and outputs.
- *
- * describe the real formats here.
- */
-static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VDP_OUTPUT_CAPS));
-
#define DEBUG_INIT(bla) \
GST_DEBUG_CATEGORY_INIT (gst_vdp_vpp_debug, "vdpauvideopostprocess", 0, "VDPAU video surface to output surface");
@@ -361,12 +353,27 @@ gst_vdp_vpp_add_buffer (GstVdpVideoPostProcess * vpp, GstVdpVideoBuffer * buf)
}
static GstFlowReturn
-gst_vdp_vpp_create_mixer (GstVdpVideoPostProcess * vpp, GstVdpDevice * device)
+gst_vdp_vpp_open_device (GstVdpVideoPostProcess * vpp)
+{
+ GstFlowReturn ret;
+
+ GST_DEBUG ("open_device");
+
+ ret =
+ gst_vdp_output_src_pad_get_device (GST_VDP_OUTPUT_SRC_PAD (vpp->srcpad),
+ &vpp->device);
+
+ return ret;
+}
+
+static GstFlowReturn
+gst_vdp_vpp_create_mixer (GstVdpVideoPostProcess * vpp)
{
#define VDP_NUM_MIXER_PARAMETER 3
#define MAX_NUM_FEATURES 5
VdpStatus status;
+ GstVdpDevice *device;
VdpVideoMixerFeature features[5];
guint n_features = 0;
@@ -393,6 +400,10 @@ gst_vdp_vpp_create_mixer (GstVdpVideoPostProcess * vpp, GstVdpDevice * device)
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 =
device->vdp_video_mixer_create (device->device, n_features, features,
VDP_NUM_MIXER_PARAMETER, parameters, parameter_values, &vpp->mixer);
@@ -404,8 +415,6 @@ gst_vdp_vpp_create_mixer (GstVdpVideoPostProcess * vpp, GstVdpDevice * device)
return GST_FLOW_ERROR;
}
- vpp->device = g_object_ref (device);
-
if (vpp->noise_reduction > 0.0) {
gst_vdp_vpp_set_attribute_float (vpp,
VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL, vpp->noise_reduction);
@@ -418,56 +427,6 @@ gst_vdp_vpp_create_mixer (GstVdpVideoPostProcess * vpp, GstVdpDevice * device)
return GST_FLOW_OK;
}
-static GstFlowReturn
-gst_vdp_vpp_open_device (GstVdpVideoPostProcess * vpp)
-{
- GstCaps *src_caps;
- GstStructure *src_structure;
- GstFlowReturn ret;
-
- src_caps = gst_pad_get_allowed_caps (vpp->srcpad);
- if (G_UNLIKELY (!src_caps))
- return GST_FLOW_NOT_NEGOTIATED;
-
- if (G_UNLIKELY (gst_caps_is_empty (src_caps))) {
- gst_caps_unref (src_caps);
- return GST_FLOW_NOT_NEGOTIATED;
- }
-
- gst_caps_truncate (src_caps);
- gst_pad_fixate_caps (vpp->srcpad, src_caps);
-
- src_structure = gst_caps_get_structure (src_caps, 0);
- if (gst_structure_has_name (src_structure, "video/x-vdpau-output")) {
- GstVdpOutputBuffer *outbuf;
-
- /* we allocate a buffer from downstream to get a GstVdpDevice */
- ret = gst_pad_alloc_buffer (vpp->srcpad, GST_BUFFER_OFFSET_NONE, 0,
- src_caps, (GstBuffer **) & outbuf);
- if (ret != GST_FLOW_OK)
- goto error;
- vpp->device = g_object_ref (outbuf->device);
- gst_buffer_unref (GST_BUFFER (outbuf));
- } else {
- vpp->device = gst_vdp_get_device (vpp->display);
- if (!vpp->device)
- goto device_error;
- }
-
- ret = GST_FLOW_OK;
-
-error:
- gst_caps_unref (src_caps);
- return ret;
-
-device_error:
- GST_ELEMENT_ERROR (vpp, RESOURCE, OPEN_READ,
- ("Couldn't create GstVdpDevice"), (NULL));
- ret = GST_FLOW_ERROR;
- goto error;
-
-}
-
static gint
gst_greatest_common_divisor (gint a, gint b)
{
@@ -554,6 +513,7 @@ gst_vdp_vpp_sink_setcaps (GstPad * pad, GstCaps * caps)
output_caps = gst_vdp_yuv_to_output_caps (caps);
}
+ GST_DEBUG ("output_caps: %" GST_PTR_FORMAT, output_caps);
allowed_caps = gst_pad_get_allowed_caps (vpp->srcpad);
GST_DEBUG ("allowed_caps: %" GST_PTR_FORMAT, allowed_caps);
@@ -568,13 +528,13 @@ gst_vdp_vpp_sink_setcaps (GstPad * pad, GstCaps * caps)
gst_caps_unref (output_caps);
gst_caps_unref (allowed_caps);
- if (gst_caps_is_empty (src_caps))
- goto done;
- gst_caps_truncate (src_caps);
+ if (gst_caps_is_empty (src_caps)) {
+ gst_caps_unref (src_caps);
+ goto not_negotiated;
+ }
gst_pad_fixate_caps (vpp->srcpad, src_caps);
- GST_DEBUG ("output_caps: %" GST_PTR_FORMAT " allowed_caps: %" GST_PTR_FORMAT
- " src_caps: %" GST_PTR_FORMAT, output_caps, allowed_caps, src_caps);
+ GST_DEBUG ("src_caps: %" GST_PTR_FORMAT, src_caps);
if (gst_vdp_vpp_is_interlaced (vpp)) {
gint fps_n, fps_d;
@@ -591,7 +551,8 @@ gst_vdp_vpp_sink_setcaps (GstPad * pad, GstCaps * caps)
gst_structure_remove_field (structure, "interlaced");
}
- res = gst_pad_set_caps (vpp->srcpad, src_caps);
+ res = gst_vdp_output_src_pad_set_caps (GST_VDP_OUTPUT_SRC_PAD (vpp->srcpad),
+ src_caps);
done:
gst_object_unref (vpp);
@@ -600,6 +561,11 @@ done:
allowed_caps_error:
gst_caps_unref (output_caps);
goto done;
+
+not_negotiated:
+ GST_DEBUG_OBJECT (vpp, "Couldn't find suitable output format");
+ res = FALSE;
+ goto done;
}
static void
@@ -645,8 +611,6 @@ gst_vdp_vpp_stop (GstVdpVideoPostProcess * vpp)
{
if (vpp->mixer != VDP_INVALID_HANDLE)
vpp->device->vdp_video_mixer_destroy (vpp->mixer);
- if (vpp->device)
- g_object_unref (vpp->device);
gst_vdp_vpp_flush (vpp);
}
@@ -680,11 +644,14 @@ gst_vdp_vpp_drain (GstVdpVideoPostProcess * vpp)
VdpStatus status;
ret =
- gst_pad_alloc_buffer_and_set_caps (vpp->srcpad, GST_BUFFER_OFFSET_NONE,
- 0, GST_PAD_CAPS (vpp->srcpad), (GstBuffer **) & outbuf);
+ gst_vdp_output_src_pad_alloc_buffer ((GstVdpOutputSrcPad *) vpp->srcpad,
+ &outbuf);
if (ret != GST_FLOW_OK)
break;
+ gst_vdp_output_src_pad_set_caps ((GstVdpOutputSrcPad *) vpp->srcpad,
+ GST_BUFFER_CAPS (outbuf));
+
src_r.w = vpp->width;
src_r.h = vpp->height;
if (vpp->got_par) {
@@ -747,7 +714,9 @@ gst_vdp_vpp_drain (GstVdpVideoPostProcess * vpp)
if (GST_BUFFER_FLAG_IS_SET (current_pic.buf, GST_BUFFER_FLAG_GAP))
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
- ret = gst_pad_push (vpp->srcpad, GST_BUFFER (outbuf));
+ ret =
+ gst_vdp_output_src_pad_push ((GstVdpOutputSrcPad *) vpp->srcpad,
+ outbuf);
if (ret != GST_FLOW_OK)
break;
@@ -771,6 +740,8 @@ gst_vdp_vpp_chain (GstPad * pad, GstBuffer * buffer)
GstClockTime qostime;
GstFlowReturn ret = GST_FLOW_OK;
+ GST_DEBUG ("chain");
+
/* can only do QoS if the segment is in TIME */
if (vpp->segment.format != GST_FORMAT_TIME)
goto no_qos;
@@ -820,11 +791,8 @@ no_qos:
if (!vpp->native_input) {
GstVdpVideoBuffer *video_buf;
- if (G_UNLIKELY (!vpp->device)) {
- ret = gst_vdp_vpp_open_device (vpp);
- if (ret != GST_FLOW_OK)
- goto error;
- }
+ 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);
@@ -847,8 +815,8 @@ no_qos:
buffer = GST_BUFFER (video_buf);
}
- if (vpp->mixer == VDP_INVALID_HANDLE) {
- ret = gst_vdp_vpp_create_mixer (vpp, vpp->device);
+ if (G_UNLIKELY (vpp->mixer == VDP_INVALID_HANDLE)) {
+ ret = gst_vdp_vpp_create_mixer (vpp);
if (ret != GST_FLOW_OK)
goto error;
}
@@ -910,6 +878,7 @@ gst_vdp_vpp_sink_bufferalloc (GstPad * pad, guint64 offset, guint size,
GstFlowReturn ret = GST_FLOW_ERROR;
GstStructure *structure;
+ GST_DEBUG ("buffer_alloc");
structure = gst_caps_get_structure (caps, 0);
if (gst_structure_has_name (structure, "video/x-vdpau-video")) {
gint width, height;
@@ -918,7 +887,7 @@ gst_vdp_vpp_sink_bufferalloc (GstPad * pad, guint64 offset, guint size,
if (G_UNLIKELY (!vpp->device)) {
ret = gst_vdp_vpp_open_device (vpp);
if (ret != GST_FLOW_OK)
- goto done;
+ return ret;
}
if (!gst_structure_get_int (structure, "width", &width) ||
@@ -1073,7 +1042,7 @@ gst_vdp_vpp_get_property (GObject * object, guint property_id, GValue * value,
switch (property_id) {
case PROP_DISPLAY:
- g_value_set_string (value, vpp->display);
+ g_object_get_property (G_OBJECT (vpp->srcpad), "display", value);
break;
case PROP_FORCE_ASPECT_RATIO:
g_value_set_boolean (value, vpp->force_aspect_ratio);
@@ -1108,7 +1077,7 @@ gst_vdp_vpp_set_property (GObject * object, guint property_id,
switch (property_id) {
case PROP_DISPLAY:
- vpp->display = g_value_dup_string (value);
+ g_object_set_property (G_OBJECT (vpp->srcpad), "display", value);
break;
case PROP_FORCE_ASPECT_RATIO:
vpp->force_aspect_ratio = g_value_get_boolean (value);
@@ -1125,11 +1094,11 @@ gst_vdp_vpp_set_property (GObject * object, guint property_id,
if (oldvalue == vpp->method)
break;
- if (vpp->device) {
+ if (vpp->mixer != VDP_INVALID_HANDLE) {
if (oldvalue != GST_VDP_DEINTERLACE_METHOD_BOB)
gst_vdp_vpp_activate_deinterlace_method (vpp, oldvalue, FALSE);
- if (vpp->method != GST_VDP_DEINTERLACE_METHOD_BOB && vpp->device)
+ if (vpp->method != GST_VDP_DEINTERLACE_METHOD_BOB)
gst_vdp_vpp_activate_deinterlace_method (vpp, oldvalue, TRUE);
}
break;
@@ -1143,7 +1112,7 @@ gst_vdp_vpp_set_property (GObject * object, guint property_id,
if (vpp->noise_reduction == old_value)
break;
- if (vpp->device) {
+ if (vpp->mixer != VDP_INVALID_HANDLE) {
if (vpp->noise_reduction == 0.0)
gst_vdp_vpp_activate_feature (vpp,
VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION, FALSE);
@@ -1167,7 +1136,7 @@ gst_vdp_vpp_set_property (GObject * object, guint property_id,
if (vpp->sharpening == old_value)
break;
- if (vpp->device) {
+ if (vpp->mixer != VDP_INVALID_HANDLE) {
if (vpp->sharpening == 0.0)
gst_vdp_vpp_activate_feature (vpp,
VDP_VIDEO_MIXER_FEATURE_SHARPNESS, FALSE);
@@ -1185,7 +1154,7 @@ gst_vdp_vpp_set_property (GObject * object, guint property_id,
{
vpp->inverse_telecine = g_value_get_boolean (value);
- if (vpp->device) {
+ if (vpp->mixer != VDP_INVALID_HANDLE) {
gst_vdp_vpp_activate_feature (vpp,
VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE, vpp->inverse_telecine);
}
@@ -1203,8 +1172,8 @@ static void
gst_vdp_vpp_base_init (gpointer gclass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
- GstCaps *caps;
- GstPadTemplate *sink_template;
+ GstCaps *src_caps, *sink_caps;
+ GstPadTemplate *src_template, *sink_template;
gst_element_class_set_details_simple (element_class,
"VdpauVideoPostProcess",
@@ -1212,13 +1181,17 @@ gst_vdp_vpp_base_init (gpointer gclass)
"Post process GstVdpVideoBuffers and output GstVdpOutputBuffers",
"Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>");
- caps = gst_vdp_video_buffer_get_caps (FALSE, 0);
+ /* SRC PAD */
+ src_caps = gst_vdp_output_buffer_get_template_caps ();
+ src_template = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
+ src_caps);
+ gst_element_class_add_pad_template (element_class, src_template);
+
+ /* SINK PAD */
+ sink_caps = gst_vdp_video_buffer_get_caps (FALSE, 0);
sink_template = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
- caps);
+ sink_caps);
gst_element_class_add_pad_template (element_class, sink_template);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&src_template));
}
/* initialize the vdpaumpegdecoder's class */
@@ -1279,7 +1252,7 @@ static void
gst_vdp_vpp_init (GstVdpVideoPostProcess * vpp,
GstVdpVideoPostProcessClass * gclass)
{
- GstPadTemplate *sink_template;
+ GstPadTemplate *src_template, *sink_template;
vpp->device = NULL;
@@ -1293,7 +1266,12 @@ gst_vdp_vpp_init (GstVdpVideoPostProcess * vpp,
vpp->sharpening = 0.0;
/* SRC PAD */
- vpp->srcpad = gst_pad_new_from_static_template (&src_template, "src");
+ src_template =
+ gst_element_class_get_pad_template (GST_ELEMENT_CLASS (gclass), "src");
+
+ vpp->srcpad =
+ GST_PAD (gst_vdp_output_src_pad_new (gst_pad_template_get_caps
+ (src_template)));
gst_element_add_pad (GST_ELEMENT (vpp), vpp->srcpad);
gst_pad_set_event_function (vpp->srcpad,
diff --git a/sys/vdpau/gstvdpvideopostprocess.h b/sys/vdpau/gstvdpvideopostprocess.h
index 9aa57a9206..a1a03b6de1 100644
--- a/sys/vdpau/gstvdpvideopostprocess.h
+++ b/sys/vdpau/gstvdpvideopostprocess.h
@@ -81,7 +81,7 @@ struct _GstVdpVideoPostProcess
GstSegment segment;
GstClockTime earliest_time;
gboolean discont;
-
+
GstVdpDevice *device;
VdpVideoMixer mixer;