diff options
author | Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> | 2009-10-27 21:18:04 +0100 |
---|---|---|
committer | Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> | 2009-11-22 22:38:08 +0100 |
commit | ea364d7a5a19b3387745e8f28694f1bed0d43c2a (patch) | |
tree | 50e78e9b7183a74d16a8a9a283455dec35b8acac | |
parent | 51caa55d4e0166f9816698c37cd4ba7c202b85df (diff) |
vdpauvideopostprocess: split up chain function
-rw-r--r-- | sys/vdpau/gstvdpvideopostprocess.c | 216 |
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, ¤t_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); |