summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2009-10-27 21:18:04 +0100
committerCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2009-11-22 22:38:08 +0100
commitea364d7a5a19b3387745e8f28694f1bed0d43c2a (patch)
tree50e78e9b7183a74d16a8a9a283455dec35b8acac
parent51caa55d4e0166f9816698c37cd4ba7c202b85df (diff)
vdpauvideopostprocess: split up chain function
-rw-r--r--sys/vdpau/gstvdpvideopostprocess.c216
1 files changed, 116 insertions, 100 deletions
diff --git a/sys/vdpau/gstvdpvideopostprocess.c b/sys/vdpau/gstvdpvideopostprocess.c
index da7661a65..a77939d26 100644
--- a/sys/vdpau/gstvdpvideopostprocess.c
+++ b/sys/vdpau/gstvdpvideopostprocess.c
@@ -652,14 +652,8 @@ gst_vdp_vpp_stop (GstVdpVideoPostProcess * vpp)
}
static GstFlowReturn
-gst_vdp_vpp_chain (GstPad * pad, GstBuffer * buffer)
+gst_vdp_vpp_drain (GstVdpVideoPostProcess * vpp)
{
- GstVdpVideoPostProcess *vpp =
- GST_VDP_VIDEO_POST_PROCESS (gst_pad_get_parent (pad));
-
- GstClockTime qostime;
-
- GstFlowReturn ret = GST_FLOW_OK;
GstVdpPicture current_pic;
guint32 video_surfaces_past_count;
@@ -668,89 +662,7 @@ gst_vdp_vpp_chain (GstPad * pad, GstBuffer * buffer)
guint32 video_surfaces_future_count;
VdpVideoSurface video_surfaces_future[MAX_PICTURES];
- /* can only do QoS if the segment is in TIME */
- if (vpp->segment.format != GST_FORMAT_TIME)
- goto no_qos;
-
- /* QOS is done on the running time of the buffer, get it now */
- qostime = gst_segment_to_running_time (&vpp->segment, GST_FORMAT_TIME,
- GST_BUFFER_TIMESTAMP (buffer));
-
- if (qostime != -1) {
- gboolean need_skip;
- GstClockTime earliest_time;
-
- /* lock for getting the QoS parameters that are set (in a different thread)
- * with the QOS events */
- GST_OBJECT_LOCK (vpp);
- earliest_time = vpp->earliest_time;
- /* check for QoS, don't perform conversion for buffers
- * that are known to be late. */
- need_skip = GST_CLOCK_TIME_IS_VALID (earliest_time) && qostime != -1 &&
- qostime <= earliest_time;
-
- GST_OBJECT_UNLOCK (vpp);
-
- if (need_skip) {
- GST_DEBUG_OBJECT (vpp, "skipping transform: qostime %"
- GST_TIME_FORMAT " <= %" GST_TIME_FORMAT,
- GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
- /* mark discont for next buffer */
- vpp->discont = TRUE;
- gst_buffer_unref (buffer);
- return GST_FLOW_OK;
- }
- }
-
-no_qos:
-
- if (vpp->discont) {
- GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
- vpp->discont = FALSE;
- }
-
- if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) {
- GST_DEBUG_OBJECT (vpp, "Received discont buffer");
- gst_vdp_vpp_flush (vpp);
- }
-
- 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;
- }
-
- video_buf = gst_vdp_video_buffer_new (vpp->device, vpp->chroma_type,
- vpp->width, vpp->height);
- if (G_UNLIKELY (!video_buf))
- goto video_buf_error;
-
- if (!gst_vdp_video_buffer_upload (video_buf, buffer, vpp->fourcc,
- vpp->width, vpp->height)) {
- gst_buffer_unref (GST_BUFFER (video_buf));
- GST_ELEMENT_ERROR (vpp, RESOURCE, READ,
- ("Couldn't upload YUV data to vdpau"), (NULL));
- ret = GST_FLOW_ERROR;
- goto error;
- }
-
- gst_buffer_copy_metadata (GST_BUFFER (video_buf), buffer,
- GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS);
-
- gst_buffer_unref (buffer);
- buffer = GST_BUFFER (video_buf);
- }
-
- if (vpp->mixer == VDP_INVALID_HANDLE) {
- ret = gst_vdp_vpp_create_mixer (vpp, vpp->device);
- if (ret != GST_FLOW_OK)
- goto error;
- }
-
- gst_vdp_vpp_add_buffer (vpp, GST_VDP_VIDEO_BUFFER (buffer));
+ GstFlowReturn ret;
while (gst_vdp_vpp_get_next_picture (vpp,
&current_pic,
@@ -785,8 +697,10 @@ no_qos:
structure = gst_caps_get_structure (GST_BUFFER_CAPS (outbuf), 0);
if (!gst_structure_get_int (structure, "width", &dest_r.w) ||
- !gst_structure_get_int (structure, "height", &dest_r.h))
+ !gst_structure_get_int (structure, "height", &dest_r.h)) {
+ gst_buffer_unref (GST_BUFFER (outbuf));
goto invalid_caps;
+ }
if (vpp->force_aspect_ratio) {
GstVideoRectangle res_r;
@@ -810,12 +724,12 @@ no_qos:
current_pic.buf->surface, video_surfaces_future_count,
video_surfaces_future, NULL, outbuf->surface, NULL, &rect, 0, NULL);
if (status != VDP_STATUS_OK) {
+ gst_buffer_unref (GST_BUFFER (outbuf));
GST_ELEMENT_ERROR (vpp, RESOURCE, READ,
- ("Could not post process frame"),
+ ("Could not postprocess frame"),
("Error returned from vdpau was: %s",
device->vdp_get_error_string (status)));
- ret = GST_FLOW_ERROR;
- goto done;
+ return GST_FLOW_ERROR;
}
GST_BUFFER_TIMESTAMP (outbuf) = current_pic.timestamp;
@@ -838,13 +752,111 @@ no_qos:
break;
continue;
+ }
- invalid_caps:
- gst_buffer_unref (GST_BUFFER (outbuf));
- ret = GST_FLOW_ERROR;
- break;
+ return ret;
+
+invalid_caps:
+ GST_ELEMENT_ERROR (vpp, STREAM, FAILED, ("Invalid output caps"), (NULL));
+ return GST_FLOW_ERROR;
+
+}
+
+static GstFlowReturn
+gst_vdp_vpp_chain (GstPad * pad, GstBuffer * buffer)
+{
+ GstVdpVideoPostProcess *vpp =
+ GST_VDP_VIDEO_POST_PROCESS (gst_pad_get_parent (pad));
+
+ GstClockTime qostime;
+ GstFlowReturn ret = GST_FLOW_OK;
+
+ /* can only do QoS if the segment is in TIME */
+ if (vpp->segment.format != GST_FORMAT_TIME)
+ goto no_qos;
+
+ /* QOS is done on the running time of the buffer, get it now */
+ qostime = gst_segment_to_running_time (&vpp->segment, GST_FORMAT_TIME,
+ GST_BUFFER_TIMESTAMP (buffer));
+
+ if (qostime != -1) {
+ gboolean need_skip;
+ GstClockTime earliest_time;
+
+ /* lock for getting the QoS parameters that are set (in a different thread)
+ * with the QOS events */
+ GST_OBJECT_LOCK (vpp);
+ earliest_time = vpp->earliest_time;
+ /* check for QoS, don't perform conversion for buffers
+ * that are known to be late. */
+ need_skip = GST_CLOCK_TIME_IS_VALID (earliest_time) && qostime != -1 &&
+ qostime <= earliest_time;
+
+ GST_OBJECT_UNLOCK (vpp);
+
+ if (need_skip) {
+ GST_DEBUG_OBJECT (vpp, "skipping transform: qostime %"
+ GST_TIME_FORMAT " <= %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
+ /* mark discont for next buffer */
+ vpp->discont = TRUE;
+ gst_buffer_unref (buffer);
+ return GST_FLOW_OK;
+ }
+ }
+
+no_qos:
+
+ if (vpp->discont) {
+ GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
+ vpp->discont = FALSE;
}
+ if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) {
+ GST_DEBUG_OBJECT (vpp, "Received discont buffer");
+ gst_vdp_vpp_flush (vpp);
+ }
+
+ 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;
+ }
+
+ video_buf = gst_vdp_video_buffer_new (vpp->device, vpp->chroma_type,
+ vpp->width, vpp->height);
+ if (G_UNLIKELY (!video_buf))
+ goto video_buf_error;
+
+ if (!gst_vdp_video_buffer_upload (video_buf, buffer, vpp->fourcc,
+ vpp->width, vpp->height)) {
+ gst_buffer_unref (GST_BUFFER (video_buf));
+ GST_ELEMENT_ERROR (vpp, RESOURCE, READ,
+ ("Couldn't upload YUV data to vdpau"), (NULL));
+ ret = GST_FLOW_ERROR;
+ goto error;
+ }
+
+ gst_buffer_copy_metadata (GST_BUFFER (video_buf), buffer,
+ GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS);
+
+ gst_buffer_unref (buffer);
+ buffer = GST_BUFFER (video_buf);
+ }
+
+ if (vpp->mixer == VDP_INVALID_HANDLE) {
+ ret = gst_vdp_vpp_create_mixer (vpp, vpp->device);
+ if (ret != GST_FLOW_OK)
+ goto error;
+ }
+
+ gst_vdp_vpp_add_buffer (vpp, GST_VDP_VIDEO_BUFFER (buffer));
+
+ ret = gst_vdp_vpp_drain (vpp);
+
done:
gst_object_unref (vpp);
@@ -966,6 +978,9 @@ gst_vdp_vpp_src_event (GstPad * pad, GstEvent * event)
GST_OBJECT_LOCK (vpp);
vpp->earliest_time = timestamp + diff;
GST_OBJECT_UNLOCK (vpp);
+
+ res = gst_pad_event_default (pad, event);
+ break;
}
default:
res = gst_pad_event_default (pad, event);
@@ -989,8 +1004,8 @@ gst_vdp_vpp_sink_event (GstPad * pad, GstEvent * event)
GST_DEBUG_OBJECT (vpp, "flush stop");
gst_vdp_vpp_flush (vpp);
- res = gst_pad_push_event (vpp->srcpad, event);
+ res = gst_pad_event_default (pad, event);
break;
}
case GST_EVENT_NEWSEGMENT:
@@ -1008,7 +1023,8 @@ gst_vdp_vpp_sink_event (GstPad * pad, GstEvent * event)
applied_rate, format, start, stop, time);
GST_OBJECT_UNLOCK (vpp);
- res = gst_pad_push_event (vpp->srcpad, event);
+ res = gst_pad_event_default (pad, event);
+ break;
}
default:
res = gst_pad_event_default (pad, event);