diff options
author | Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> | 2010-07-30 11:20:35 +0200 |
---|---|---|
committer | Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> | 2010-07-30 11:33:13 +0200 |
commit | 57175ece9e629520c89112571bcea8c99b3cd581 (patch) | |
tree | cea0373c893f5138182c6e9fd53000b0d02ca09d | |
parent | c0e1fba08943e6b4873d0c3e0e2ae23c768de84f (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.c | 91 | ||||
-rw-r--r-- | sys/vdpau/gstvdpsink.h | 1 |
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 | ||
571 | static GstVdpDevice * | 572 | static gboolean |
572 | gst_vdp_sink_setup_device (VdpSink * vdp_sink) | 573 | gst_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 | ||
596 | static gboolean | 599 | static 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 | ||
897 | static GstFlowReturn | 901 | static void |
898 | gst_vdp_sink_get_output_buffer (VdpSink * vdp_sink, GstCaps * caps, | 902 | gst_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 | ||
1024 | alloc: | 1005 | alloc: |
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 | ||
1031 | beach: | 1017 | beach: |
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; |