summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2010-07-30 11:20:35 +0200
committerCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2010-07-30 11:33:13 +0200
commit57175ece9e629520c89112571bcea8c99b3cd581 (patch)
treecea0373c893f5138182c6e9fd53000b0d02ca09d
parentc0e1fba08943e6b4873d0c3e0e2ae23c768de84f (diff)
vdpausink: use GstVdpOutputBufferPool to alloc our buffers
This way we'll reuse our GstVdpOutputBuffers if they're of the same size and rgba-format
-rw-r--r--sys/vdpau/gstvdpsink.c91
-rw-r--r--sys/vdpau/gstvdpsink.h1
2 files changed, 39 insertions, 53 deletions
diff --git a/sys/vdpau/gstvdpsink.c b/sys/vdpau/gstvdpsink.c
index 933990f8c..70bcd6bfe 100644
--- a/sys/vdpau/gstvdpsink.c
+++ b/sys/vdpau/gstvdpsink.c
@@ -30,6 +30,7 @@
30#include <gst/gstinfo.h> 30#include <gst/gstinfo.h>
31 31
32#include "gstvdp/gstvdpoutputbuffer.h" 32#include "gstvdp/gstvdpoutputbuffer.h"
33#include "gstvdp/gstvdpoutputbufferpool.h"
33 34
34/* Object header */ 35/* Object header */
35#include "gstvdpsink.h" 36#include "gstvdpsink.h"
@@ -568,14 +569,16 @@ gst_vdp_sink_get_allowed_caps (GstVdpDevice * device, GValue * par)
568 return caps; 569 return caps;
569} 570}
570 571
571static GstVdpDevice * 572static gboolean
572gst_vdp_sink_setup_device (VdpSink * vdp_sink) 573gst_vdp_sink_open_device (VdpSink * vdp_sink)
573{ 574{
574 GstVdpDevice *device; 575 GstVdpDevice *device;
575 576
576 device = gst_vdp_get_device (vdp_sink->display_name); 577 vdp_sink->device = device = gst_vdp_get_device (vdp_sink->display_name);
577 if (!device) 578 if (!vdp_sink->device)
578 return NULL; 579 return FALSE;
580
581 vdp_sink->bpool = gst_vdp_output_buffer_pool_new (device);
579 582
580 vdp_sink->caps = gst_vdp_sink_get_allowed_caps (device, vdp_sink->par); 583 vdp_sink->caps = gst_vdp_sink_get_allowed_caps (device, vdp_sink->par);
581 GST_DEBUG ("runtime calculated caps: %" GST_PTR_FORMAT, vdp_sink->caps); 584 GST_DEBUG ("runtime calculated caps: %" GST_PTR_FORMAT, vdp_sink->caps);
@@ -590,7 +593,7 @@ gst_vdp_sink_setup_device (VdpSink * vdp_sink)
590 vdp_sink->event_thread = g_thread_create ( 593 vdp_sink->event_thread = g_thread_create (
591 (GThreadFunc) gst_vdp_sink_event_thread, vdp_sink, TRUE, NULL); 594 (GThreadFunc) gst_vdp_sink_event_thread, vdp_sink, TRUE, NULL);
592 595
593 return device; 596 return TRUE;
594} 597}
595 598
596static gboolean 599static gboolean
@@ -608,10 +611,8 @@ gst_vdp_sink_start (GstBaseSink * bsink)
608 vdp_sink->fps_d = 1; 611 vdp_sink->fps_d = 1;
609 612
610 GST_OBJECT_LOCK (vdp_sink); 613 GST_OBJECT_LOCK (vdp_sink);
611 if (!vdp_sink->device) { 614 if (!vdp_sink->device)
612 if (!(vdp_sink->device = gst_vdp_sink_setup_device (vdp_sink))) 615 res = gst_vdp_sink_open_device (vdp_sink);
613 res = FALSE;
614 }
615 GST_OBJECT_UNLOCK (vdp_sink); 616 GST_OBJECT_UNLOCK (vdp_sink);
616 617
617 return res; 618 return res;
@@ -631,6 +632,7 @@ gst_vdp_device_clear (VdpSink * vdp_sink)
631 632
632 g_mutex_lock (vdp_sink->x_lock); 633 g_mutex_lock (vdp_sink->x_lock);
633 634
635 g_object_unref (vdp_sink->bpool);
634 g_object_unref (vdp_sink->device); 636 g_object_unref (vdp_sink->device);
635 vdp_sink->device = NULL; 637 vdp_sink->device = NULL;
636 638
@@ -732,6 +734,8 @@ gst_vdp_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
732 vdp_sink->fps_n = gst_value_get_fraction_numerator (fps); 734 vdp_sink->fps_n = gst_value_get_fraction_numerator (fps);
733 vdp_sink->fps_d = gst_value_get_fraction_denominator (fps); 735 vdp_sink->fps_d = gst_value_get_fraction_denominator (fps);
734 736
737 gst_vdp_buffer_pool_set_caps (vdp_sink->bpool, caps);
738
735 /* Notify application to set xwindow id now */ 739 /* Notify application to set xwindow id now */
736 g_mutex_lock (vdp_sink->flow_lock); 740 g_mutex_lock (vdp_sink->flow_lock);
737 if (!vdp_sink->window) { 741 if (!vdp_sink->window) {
@@ -894,32 +898,14 @@ gst_vdp_sink_event (GstBaseSink * sink, GstEvent * event)
894 return TRUE; 898 return TRUE;
895} 899}
896 900
897static GstFlowReturn 901static void
898gst_vdp_sink_get_output_buffer (VdpSink * vdp_sink, GstCaps * caps, 902gst_vdp_sink_post_error (VdpSink * vdp_sink, GError * error)
899 GstBuffer ** buf)
900{ 903{
901 GstStructure *structure; 904 GstMessage *message;
902 gint width, height;
903 gint rgba_format;
904 905
905 structure = gst_caps_get_structure (caps, 0); 906 message = gst_message_new_error (GST_OBJECT (vdp_sink), error, NULL);
906 if (!gst_structure_get_int (structure, "width", &width) || 907 gst_element_post_message (GST_ELEMENT (vdp_sink), message);
907 !gst_structure_get_int (structure, "height", &height) || 908 g_error_free (error);
908 !gst_structure_get_int (structure, "rgba-format", &rgba_format)) {
909 GST_WARNING_OBJECT (vdp_sink, "invalid caps for buffer allocation %"
910 GST_PTR_FORMAT, caps);
911 return GST_FLOW_ERROR;
912 }
913
914 *buf = GST_BUFFER (gst_vdp_output_buffer_new (vdp_sink->device,
915 rgba_format, width, height, NULL));
916 if (*buf == NULL) {
917 return GST_FLOW_ERROR;
918 }
919
920 gst_buffer_set_caps (*buf, caps);
921
922 return GST_FLOW_OK;
923} 909}
924 910
925/* Buffer management 911/* Buffer management
@@ -939,10 +925,10 @@ gst_vdp_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
939 VdpSink *vdp_sink; 925 VdpSink *vdp_sink;
940 GstStructure *structure = NULL; 926 GstStructure *structure = NULL;
941 GstFlowReturn ret = GST_FLOW_OK; 927 GstFlowReturn ret = GST_FLOW_OK;
942 GstCaps *alloc_caps;
943 gboolean alloc_unref = FALSE;
944 gint width, height; 928 gint width, height;
929 GstCaps *alloc_caps;
945 gint w_width, w_height; 930 gint w_width, w_height;
931 GError *err;
946 932
947 vdp_sink = GST_VDP_SINK (bsink); 933 vdp_sink = GST_VDP_SINK (bsink);
948 934
@@ -950,12 +936,6 @@ gst_vdp_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
950 "a buffer of %d bytes was requested with caps %" GST_PTR_FORMAT 936 "a buffer of %d bytes was requested with caps %" GST_PTR_FORMAT
951 " and offset %" G_GUINT64_FORMAT, size, caps, offset); 937 " and offset %" G_GUINT64_FORMAT, size, caps, offset);
952 938
953 /* assume we're going to alloc what was requested, keep track of
954 * wheter we need to unref or not. When we suggest a new format
955 * upstream we will create a new caps that we need to unref. */
956 alloc_caps = caps;
957 alloc_unref = FALSE;
958
959 /* get struct to see what is requested */ 939 /* get struct to see what is requested */
960 structure = gst_caps_get_structure (caps, 0); 940 structure = gst_caps_get_structure (caps, 0);
961 if (!gst_structure_get_int (structure, "width", &width) || 941 if (!gst_structure_get_int (structure, "width", &width) ||
@@ -966,6 +946,8 @@ gst_vdp_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
966 goto beach; 946 goto beach;
967 } 947 }
968 948
949 alloc_caps = gst_caps_ref (caps);
950
969 /* We take the flow_lock because the window might go away */ 951 /* We take the flow_lock because the window might go away */
970 g_mutex_lock (vdp_sink->flow_lock); 952 g_mutex_lock (vdp_sink->flow_lock);
971 if (!vdp_sink->window) { 953 if (!vdp_sink->window) {
@@ -1007,26 +989,30 @@ gst_vdp_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
1007 if (gst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (vdp_sink), desired_caps)) { 989 if (gst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (vdp_sink), desired_caps)) {
1008 /* we will not alloc a buffer of the new suggested caps. Make sure 990 /* we will not alloc a buffer of the new suggested caps. Make sure
1009 * we also unref this new caps after we set it on the buffer. */ 991 * we also unref this new caps after we set it on the buffer. */
1010 alloc_caps = desired_caps;
1011 alloc_unref = TRUE;
1012 width = w_width;
1013 height = w_height;
1014 GST_DEBUG ("peer pad accepts our desired caps %" GST_PTR_FORMAT, 992 GST_DEBUG ("peer pad accepts our desired caps %" GST_PTR_FORMAT,
1015 desired_caps); 993 desired_caps);
994 gst_caps_unref (alloc_caps);
995 alloc_caps = desired_caps;
1016 } else { 996 } else {
1017 GST_DEBUG ("peer pad does not accept our desired caps %" GST_PTR_FORMAT, 997 GST_DEBUG ("peer pad does not accept our desired caps %" GST_PTR_FORMAT,
1018 desired_caps); 998 desired_caps);
1019 /* we alloc a buffer with the original incomming caps already in the 999 /* we alloc a buffer with the original incomming caps already in the
1020 * width and height variables */ 1000 * width and height variables */
1001 gst_caps_unref (desired_caps);
1021 } 1002 }
1022 } 1003 }
1023 1004
1024alloc: 1005alloc:
1025 ret = gst_vdp_sink_get_output_buffer (vdp_sink, alloc_caps, buf); 1006 gst_vdp_buffer_pool_set_caps (vdp_sink->bpool, alloc_caps);
1026 1007 gst_caps_unref (alloc_caps);
1027 /* could be our new reffed suggestion or the original unreffed caps */ 1008
1028 if (alloc_unref) 1009 err = NULL;
1029 gst_caps_unref (alloc_caps); 1010 *buf =
1011 GST_BUFFER_CAST (gst_vdp_buffer_pool_get_buffer (vdp_sink->bpool, &err));
1012 if (!*buf) {
1013 gst_vdp_sink_post_error (vdp_sink, err);
1014 return GST_FLOW_ERROR;
1015 }
1030 1016
1031beach: 1017beach:
1032 return ret; 1018 return ret;
@@ -1121,8 +1107,7 @@ gst_vdp_sink_set_xwindow_id (GstXOverlay * overlay, XID xwindow_id)
1121 } 1107 }
1122 1108
1123 /* If the element has not initialized the X11 context try to do so */ 1109 /* If the element has not initialized the X11 context try to do so */
1124 if (!vdp_sink->device 1110 if (!vdp_sink->device && !gst_vdp_sink_open_device (vdp_sink)) {
1125 && !(vdp_sink->device = gst_vdp_sink_setup_device (vdp_sink))) {
1126 g_mutex_unlock (vdp_sink->flow_lock); 1111 g_mutex_unlock (vdp_sink->flow_lock);
1127 /* we have thrown a GST_ELEMENT_ERROR now */ 1112 /* we have thrown a GST_ELEMENT_ERROR now */
1128 return; 1113 return;
diff --git a/sys/vdpau/gstvdpsink.h b/sys/vdpau/gstvdpsink.h
index 6d1ff07df..c26b64d37 100644
--- a/sys/vdpau/gstvdpsink.h
+++ b/sys/vdpau/gstvdpsink.h
@@ -99,6 +99,7 @@ struct _VdpSink {
99 char *display_name; 99 char *display_name;
100 100
101 GstVdpDevice *device; 101 GstVdpDevice *device;
102 GstVdpBufferPool *bpool;
102 GstCaps *caps; 103 GstCaps *caps;
103 104
104 GstVdpWindow *window; 105 GstVdpWindow *window;