<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 12 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:SimSun;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:SimSun;
panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri","sans-serif";
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.25in 1.0in 1.25in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">Hi Gwenole:<o:p></o:p></p>
<p class="MsoNormal"> In order to support raw video stream (decoded by sw decoder) on wayland platform, I heard that you have<o:p></o:p></p>
<p class="MsoNormal">ideas to add upload functionality in vaapisink, right?<o:p></o:p></p>
<p class="MsoNormal"> Here is a patch to make that work, could you give some comments.<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"> Do you prefer to separate the functionality to a new GObject? If yes, I could give more try.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">From d599f18a654025328c34d49a09c60edfb3de147f Mon Sep 17 00:00:00 2001<o:p></o:p></p>
<p class="MsoNormal">From: Zhao Halley <halley.zhao@intel.com><o:p></o:p></p>
<p class="MsoNormal">Date: Fri, 7 Sep 2012 13:14:04 +0800<o:p></o:p></p>
<p class="MsoNormal">Subject: [PATCH] add yuv upload functionality in vaapisink to support raw<o:p></o:p></p>
<p class="MsoNormal">video stream<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">---<o:p></o:p></p>
<p class="MsoNormal">gst/vaapi/gstvaapisink.c | 330 ++++++++++++++++++++++++++++++++++++++++++++--<o:p></o:p></p>
<p class="MsoNormal">gst/vaapi/gstvaapisink.h | 9 ++<o:p></o:p></p>
<p class="MsoNormal">2 files changed, 328 insertions(+), 11 deletions(-)<o:p></o:p></p>
<p class="MsoNormal">mode change 100644 => 100755 gst/vaapi/gstvaapisink.c<o:p></o:p></p>
<p class="MsoNormal">mode change 100644 => 100755 gst/vaapi/gstvaapisink.h<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c<o:p></o:p></p>
<p class="MsoNormal">old mode 100644<o:p></o:p></p>
<p class="MsoNormal">new mode 100755<o:p></o:p></p>
<p class="MsoNormal">index 4611974..9aa453e<o:p></o:p></p>
<p class="MsoNormal">--- a/gst/vaapi/gstvaapisink.c<o:p></o:p></p>
<p class="MsoNormal">+++ b/gst/vaapi/gstvaapisink.c<o:p></o:p></p>
<p class="MsoNormal">@@ -35,6 +35,9 @@<o:p></o:p></p>
<p class="MsoNormal">#include <gst/video/videocontext.h><o:p></o:p></p>
<p class="MsoNormal">#include <gst/vaapi/gstvaapivideobuffer.h><o:p></o:p></p>
<p class="MsoNormal">#include <gst/vaapi/gstvaapivideosink.h><o:p></o:p></p>
<p class="MsoNormal">+#include <gst/vaapi/gstvaapiimagepool.h><o:p></o:p></p>
<p class="MsoNormal">+#include <gst/vaapi/gstvaapisurfacepool.h><o:p></o:p></p>
<p class="MsoNormal">+#include <gst/vaapi/gstvaapipluginbuffer.h><o:p></o:p></p>
<p class="MsoNormal">#if USE_DRM<o:p></o:p></p>
<p class="MsoNormal"># include <gst/vaapi/gstvaapidisplay_drm.h><o:p></o:p></p>
<p class="MsoNormal">#endif<o:p></o:p></p>
<p class="MsoNormal">@@ -72,12 +75,25 @@ static const GstElementDetails gst_vaapisink_details =<o:p></o:p></p>
<p class="MsoNormal"> "Gwenole Beauchesne <gwenole.beauchesne@intel.com>");<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> /* Default template */<o:p></o:p></p>
<p class="MsoNormal">+static const char gst_vaapisink_raw_caps_str[] =<o:p></o:p></p>
<p class="MsoNormal">+ "video/x-raw-yuv, "<o:p></o:p></p>
<p class="MsoNormal">+ "width = (int) [ 1, MAX ], "<o:p></o:p></p>
<p class="MsoNormal">+ "height = (int) [ 1, MAX ]; ";<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+static const char gst_vaapisink_sink_caps_str[] =<o:p></o:p></p>
<p class="MsoNormal">+ "video/x-raw-yuv, "<o:p></o:p></p>
<p class="MsoNormal">+ "width = (int) [ 1, MAX ], "<o:p></o:p></p>
<p class="MsoNormal">+ "height = (int) [ 1, MAX ]; "<o:p></o:p></p>
<p class="MsoNormal">+ GST_VAAPI_SURFACE_CAPS;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">static GstStaticPadTemplate gst_vaapisink_sink_factory =<o:p></o:p></p>
<p class="MsoNormal"> GST_STATIC_PAD_TEMPLATE(<o:p></o:p></p>
<p class="MsoNormal"> "sink",<o:p></o:p></p>
<p class="MsoNormal"> GST_PAD_SINK,<o:p></o:p></p>
<p class="MsoNormal"> GST_PAD_ALWAYS,<o:p></o:p></p>
<p class="MsoNormal">- GST_STATIC_CAPS(GST_VAAPI_SURFACE_CAPS));<o:p></o:p></p>
<p class="MsoNormal">+ GST_STATIC_CAPS(gst_vaapisink_sink_caps_str));<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+static GstStaticCaps in_raw_caps = GST_STATIC_CAPS (gst_vaapisink_raw_caps_str);<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> static void<o:p></o:p></p>
<p class="MsoNormal">gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface);<o:p></o:p></p>
<p class="MsoNormal">@@ -223,6 +239,8 @@ gst_vaapisink_xoverlay_iface_init(GstXOverlayClass *iface)<o:p></o:p></p>
<p class="MsoNormal">static void<o:p></o:p></p>
<p class="MsoNormal">gst_vaapisink_destroy(GstVaapiSink *sink)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">+ g_clear_object(&sink->images);<o:p></o:p></p>
<p class="MsoNormal">+ g_clear_object(&sink->surfaces);<o:p></o:p></p>
<p class="MsoNormal"> g_clear_object(&sink->texture);<o:p></o:p></p>
<p class="MsoNormal"> g_clear_object(&sink->display);<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">@@ -475,13 +493,145 @@ gst_vaapisink_stop(GstBaseSink *base_sink)<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> static gboolean<o:p></o:p></p>
<p class="MsoNormal">+gst_vaapisink_ensure_image_pool(GstVaapiSink *sink, GstCaps *caps)<o:p></o:p></p>
<p class="MsoNormal">+{<o:p></o:p></p>
<p class="MsoNormal">+ GstStructure * const structure = gst_caps_get_structure(caps, 0);<o:p></o:p></p>
<p class="MsoNormal">+ gint width, height;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ gst_structure_get_int(structure, "width", &width);<o:p></o:p></p>
<p class="MsoNormal">+ gst_structure_get_int(structure, "height", &height);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (width != sink->video_width || height != sink->video_height) {<o:p></o:p></p>
<p class="MsoNormal">+ sink->video_width = width;<o:p></o:p></p>
<p class="MsoNormal">+ sink->video_height = height;<o:p></o:p></p>
<p class="MsoNormal">+ g_clear_object(&sink->images);<o:p></o:p></p>
<p class="MsoNormal">+ sink->images = gst_vaapi_image_pool_new(sink->display, caps);<o:p></o:p></p>
<p class="MsoNormal">+ if (!sink->images)<o:p></o:p></p>
<p class="MsoNormal">+ return FALSE;<o:p></o:p></p>
<p class="MsoNormal">+ sink->images_reset = TRUE;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ return TRUE;<o:p></o:p></p>
<p class="MsoNormal">+}<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+static gboolean<o:p></o:p></p>
<p class="MsoNormal">+gst_vaapisink_ensure_surface_pool(GstVaapiSink *sink, GstCaps *caps)<o:p></o:p></p>
<p class="MsoNormal">+{<o:p></o:p></p>
<p class="MsoNormal">+ GstStructure * const structure = gst_caps_get_structure(caps, 0);<o:p></o:p></p>
<p class="MsoNormal">+ gint width, height;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ gst_structure_get_int(structure, "width", &width);<o:p></o:p></p>
<p class="MsoNormal">+ gst_structure_get_int(structure, "height", &height);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (width != sink->surface_width || height != sink->surface_height) {<o:p></o:p></p>
<p class="MsoNormal">+ sink->surface_width = width;<o:p></o:p></p>
<p class="MsoNormal">+ sink->surface_height = height;<o:p></o:p></p>
<p class="MsoNormal">+ g_clear_object(&sink->surfaces);<o:p></o:p></p>
<p class="MsoNormal">+ sink->surfaces = gst_vaapi_surface_pool_new(sink->display, caps);<o:p></o:p></p>
<p class="MsoNormal">+ if (!sink->surfaces)<o:p></o:p></p>
<p class="MsoNormal">+ return FALSE;<o:p></o:p></p>
<p class="MsoNormal">+ sink->surfaces_reset = TRUE;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ return TRUE;<o:p></o:p></p>
<p class="MsoNormal">+}<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+static void<o:p></o:p></p>
<p class="MsoNormal">+gst_vaapisink_ensure_direct_rendering_caps(<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiSink *sink,<o:p></o:p></p>
<p class="MsoNormal">+ GstCaps *caps<o:p></o:p></p>
<p class="MsoNormal">+)<o:p></o:p></p>
<p class="MsoNormal">+{<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiSurface *surface;<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiImage *image;<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiImageFormat vaformat;<o:p></o:p></p>
<p class="MsoNormal">+ GstVideoFormat vformat;<o:p></o:p></p>
<p class="MsoNormal">+ GstStructure *structure;<o:p></o:p></p>
<p class="MsoNormal">+ gint width, height;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (!sink->images_reset && !sink->surfaces_reset)<o:p></o:p></p>
<p class="MsoNormal">+ return;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ sink->images_reset = FALSE;<o:p></o:p></p>
<p class="MsoNormal">+ sink->surfaces_reset = FALSE;<o:p></o:p></p>
<p class="MsoNormal">+ sink->direct_rendering_caps = 0;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ structure = gst_caps_get_structure(caps, 0);<o:p></o:p></p>
<p class="MsoNormal">+ if (!structure)<o:p></o:p></p>
<p class="MsoNormal">+ return;<o:p></o:p></p>
<p class="MsoNormal">+ gst_structure_get_int(structure, "width", &width);<o:p></o:p></p>
<p class="MsoNormal">+ gst_structure_get_int(structure, "height", &height);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ /* Translate from Gst video format to VA image format */<o:p></o:p></p>
<p class="MsoNormal">+ if (!gst_video_format_parse_caps(caps, &vformat, NULL, NULL))<o:p></o:p></p>
<p class="MsoNormal">+ return;<o:p></o:p></p>
<p class="MsoNormal">+ if (!gst_video_format_is_yuv(vformat))<o:p></o:p></p>
<p class="MsoNormal">+ return;<o:p></o:p></p>
<p class="MsoNormal">+ vaformat = gst_vaapi_image_format_from_video(vformat);<o:p></o:p></p>
<p class="MsoNormal">+ if (!vaformat)<o:p></o:p></p>
<p class="MsoNormal">+ return;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ /* Check if we can alias sink & output buffers (same data_size) */<o:p></o:p></p>
<p class="MsoNormal">+ image = gst_vaapi_video_pool_get_object(sink->images);<o:p></o:p></p>
<p class="MsoNormal">+ if (image) {<o:p></o:p></p>
<p class="MsoNormal">+ if (sink->direct_rendering_caps == 0 &&<o:p></o:p></p>
<p class="MsoNormal">+ (gst_vaapi_image_get_format(image) == vaformat &&<o:p></o:p></p>
<p class="MsoNormal">+ gst_vaapi_image_is_linear(image) &&<o:p></o:p></p>
<p class="MsoNormal">+ (gst_vaapi_image_get_data_size(image) ==<o:p></o:p></p>
<p class="MsoNormal">+ gst_video_format_get_size(vformat, width, height))))<o:p></o:p></p>
<p class="MsoNormal">+ sink->direct_rendering_caps = 1;<o:p></o:p></p>
<p class="MsoNormal">+ gst_vaapi_video_pool_put_object(sink->images, image);<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ /* Check if we can access to the surface pixels directly */<o:p></o:p></p>
<p class="MsoNormal">+ surface = gst_vaapi_video_pool_get_object(sink->surfaces);<o:p></o:p></p>
<p class="MsoNormal">+ if (surface) {<o:p></o:p></p>
<p class="MsoNormal">+ image = gst_vaapi_surface_derive_image(surface);<o:p></o:p></p>
<p class="MsoNormal">+ if (image) {<o:p></o:p></p>
<p class="MsoNormal">+ if (gst_vaapi_image_map(image)) {<o:p></o:p></p>
<p class="MsoNormal">+ if (sink->direct_rendering_caps == 1 &&<o:p></o:p></p>
<p class="MsoNormal">+ (gst_vaapi_image_get_format(image) == vaformat &&<o:p></o:p></p>
<p class="MsoNormal">+ gst_vaapi_image_is_linear(image) &&<o:p></o:p></p>
<p class="MsoNormal">+ (gst_vaapi_image_get_data_size(image) ==<o:p></o:p></p>
<p class="MsoNormal">+ gst_video_format_get_size(vformat, width, height))))<o:p></o:p></p>
<p class="MsoNormal">+ sink->direct_rendering_caps = 2;<o:p></o:p></p>
<p class="MsoNormal">+ gst_vaapi_image_unmap(image);<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ g_object_unref(image);<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ gst_vaapi_video_pool_put_object(sink->surfaces, surface);<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+}<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+static gboolean<o:p></o:p></p>
<p class="MsoNormal">+gst_vaapisink_negotiate_buffers(<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiSink *sink,<o:p></o:p></p>
<p class="MsoNormal">+ GstCaps *caps<o:p></o:p></p>
<p class="MsoNormal">+)<o:p></o:p></p>
<p class="MsoNormal">+{<o:p></o:p></p>
<p class="MsoNormal">+ guint dr;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (!gst_vaapisink_ensure_image_pool(sink, caps))<o:p></o:p></p>
<p class="MsoNormal">+ return FALSE;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (!gst_vaapisink_ensure_surface_pool(sink, caps))<o:p></o:p></p>
<p class="MsoNormal">+ return FALSE;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ gst_vaapisink_ensure_direct_rendering_caps(sink, caps);<o:p></o:p></p>
<p class="MsoNormal">+ dr = MIN(sink->direct_rendering, sink->direct_rendering_caps);<o:p></o:p></p>
<p class="MsoNormal">+ if (sink->direct_rendering != dr) {<o:p></o:p></p>
<p class="MsoNormal">+ sink->direct_rendering = dr;<o:p></o:p></p>
<p class="MsoNormal">+ GST_DEBUG("direct-rendering level: %d", dr);<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ return TRUE;<o:p></o:p></p>
<p class="MsoNormal">+}<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+static gboolean<o:p></o:p></p>
<p class="MsoNormal">gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal"> GstVaapiSink * const sink = GST_VAAPISINK(base_sink);<o:p></o:p></p>
<p class="MsoNormal"> GstStructure * const structure = gst_caps_get_structure(caps, 0);<o:p></o:p></p>
<p class="MsoNormal"> guint win_width, win_height, display_width, display_height;<o:p></o:p></p>
<p class="MsoNormal"> gint video_width, video_height, video_par_n = 1, video_par_d = 1;<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">+ <o:p></o:p></p>
<p class="MsoNormal"> #if USE_DRM<o:p></o:p></p>
<p class="MsoNormal"> if (sink->display_type == GST_VAAPI_DISPLAY_TYPE_DRM)<o:p></o:p></p>
<p class="MsoNormal"> return TRUE;<o:p></o:p></p>
<p class="MsoNormal">@@ -489,6 +639,11 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps)<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> if (!structure)<o:p></o:p></p>
<p class="MsoNormal"> return FALSE;<o:p></o:p></p>
<p class="MsoNormal">+ if (gst_structure_has_name(structure, "video/x-raw-yuv")) {<o:p></o:p></p>
<p class="MsoNormal">+ sink->raw_yuv_stream = TRUE;<o:p></o:p></p>
<p class="MsoNormal">+ if (!gst_vaapisink_negotiate_buffers(sink, caps))<o:p></o:p></p>
<p class="MsoNormal">+ return FALSE;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal"> if (!gst_structure_get_int(structure, "width", &video_width))<o:p></o:p></p>
<p class="MsoNormal"> return FALSE;<o:p></o:p></p>
<p class="MsoNormal"> if (!gst_structure_get_int(structure, "height", &video_height))<o:p></o:p></p>
<p class="MsoNormal">@@ -714,34 +869,94 @@ gst_vaapisink_put_surface(<o:p></o:p></p>
<p class="MsoNormal"> return TRUE;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+static GstVaapiSurface *<o:p></o:p></p>
<p class="MsoNormal">+gst_vaapisink_upload_raw_yuv(<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiSink *sink,<o:p></o:p></p>
<p class="MsoNormal">+ GstBuffer *inbuf)<o:p></o:p></p>
<p class="MsoNormal">+{<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiVideoBuffer *vbuffer = NULL;<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiImage *image = NULL;<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiSurface *surface = NULL;<o:p></o:p></p>
<p class="MsoNormal">+ gboolean success = FALSE;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (sink->direct_rendering) {<o:p></o:p></p>
<p class="MsoNormal">+ vbuffer = GST_VAAPI_VIDEO_BUFFER(inbuf);<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (sink->direct_rendering == 2) {<o:p></o:p></p>
<p class="MsoNormal">+ surface = gst_vaapi_video_buffer_get_surface(vbuffer);<o:p></o:p></p>
<p class="MsoNormal">+ g_assert(surface);<o:p></o:p></p>
<p class="MsoNormal">+ return surface;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ <o:p></o:p></p>
<p class="MsoNormal">+ surface = gst_vaapi_video_pool_get_object(sink->surfaces);<o:p></o:p></p>
<p class="MsoNormal">+ g_assert(surface);<o:p></o:p></p>
<p class="MsoNormal">+ if (!surface)<o:p></o:p></p>
<p class="MsoNormal">+ return NULL;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (sink->direct_rendering == 1) {<o:p></o:p></p>
<p class="MsoNormal">+ image = gst_vaapi_video_buffer_get_image(vbuffer);<o:p></o:p></p>
<p class="MsoNormal">+ g_assert(image);<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ else if (sink->direct_rendering == 0) {<o:p></o:p></p>
<p class="MsoNormal">+ image = gst_vaapi_video_pool_get_object(sink->images);<o:p></o:p></p>
<p class="MsoNormal">+ gst_vaapi_image_update_from_buffer(image, inbuf, NULL);<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ success = gst_vaapi_surface_put_image(surface, image);<o:p></o:p></p>
<p class="MsoNormal">+ <o:p></o:p></p>
<p class="MsoNormal">+ if (sink->direct_rendering = 0) {<o:p></o:p></p>
<p class="MsoNormal">+ gst_vaapi_video_pool_put_object(sink->images, image);<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ <o:p></o:p></p>
<p class="MsoNormal">+ if (!success)<o:p></o:p></p>
<p class="MsoNormal">+ goto error_put_image;<o:p></o:p></p>
<p class="MsoNormal">+ return surface;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+error_put_image:<o:p></o:p></p>
<p class="MsoNormal">+ {<o:p></o:p></p>
<p class="MsoNormal">+ GST_WARNING("failed to upload %" GST_FOURCC_FORMAT " image "<o:p></o:p></p>
<p class="MsoNormal">+ "to surface 0x%08x",<o:p></o:p></p>
<p class="MsoNormal">+ GST_FOURCC_ARGS(gst_vaapi_image_get_format(image)),<o:p></o:p></p>
<p class="MsoNormal">+ gst_vaapi_surface_get_id(surface));<o:p></o:p></p>
<p class="MsoNormal">+ return GST_FLOW_OK;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+}<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">static GstFlowReturn<o:p></o:p></p>
<p class="MsoNormal">gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal"> GstVaapiSink * const sink = GST_VAAPISINK(base_sink);<o:p></o:p></p>
<p class="MsoNormal">- GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer);<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiVideoBuffer * vbuffer = NULL; <o:p></o:p></p>
<p class="MsoNormal"> GstVaapiSurface *surface;<o:p></o:p></p>
<p class="MsoNormal"> guint flags;<o:p></o:p></p>
<p class="MsoNormal"> gboolean success;<o:p></o:p></p>
<p class="MsoNormal"> GstVideoOverlayComposition * const composition =<o:p></o:p></p>
<p class="MsoNormal"> gst_video_buffer_get_overlay_composition(buffer);<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">- if (sink->display != gst_vaapi_video_buffer_get_display (vbuffer)) {<o:p></o:p></p>
<p class="MsoNormal">- g_clear_object(&sink->display);<o:p></o:p></p>
<p class="MsoNormal">- sink->display = g_object_ref (gst_vaapi_video_buffer_get_display (vbuffer));<o:p></o:p></p>
<p class="MsoNormal">- }<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal"> if (!sink->window)<o:p></o:p></p>
<p class="MsoNormal"> return GST_FLOW_UNEXPECTED;<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">- surface = gst_vaapi_video_buffer_get_surface(vbuffer);<o:p></o:p></p>
<p class="MsoNormal">+ if (sink->raw_yuv_stream) {<o:p></o:p></p>
<p class="MsoNormal">+ surface = gst_vaapisink_upload_raw_yuv(sink, buffer);<o:p></o:p></p>
<p class="MsoNormal">+ flags = 0; // todo<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ else {<o:p></o:p></p>
<p class="MsoNormal">+ vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer);<o:p></o:p></p>
<p class="MsoNormal">+ surface = gst_vaapi_video_buffer_get_surface(vbuffer);<o:p></o:p></p>
<p class="MsoNormal">+ flags = gst_vaapi_video_buffer_get_render_flags(vbuffer);<o:p></o:p></p>
<p class="MsoNormal">+ if (sink->display != gst_vaapi_video_buffer_get_display (vbuffer)) {<o:p></o:p></p>
<p class="MsoNormal">+ g_clear_object(&sink->display);<o:p></o:p></p>
<p class="MsoNormal">+ sink->display = g_object_ref (gst_vaapi_video_buffer_get_display (vbuffer));<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal"> if (!surface)<o:p></o:p></p>
<p class="MsoNormal"> return GST_FLOW_UNEXPECTED;<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> GST_DEBUG("render surface %" GST_VAAPI_ID_FORMAT,<o:p></o:p></p>
<p class="MsoNormal"> GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface)));<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">- flags = gst_vaapi_video_buffer_get_render_flags(vbuffer);<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal"> if (!gst_vaapi_surface_set_subpictures_from_composition(surface,<o:p></o:p></p>
<p class="MsoNormal"> composition, TRUE))<o:p></o:p></p>
<p class="MsoNormal"> GST_WARNING("could not update subtitles");<o:p></o:p></p>
<p class="MsoNormal">@@ -772,9 +987,92 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer)<o:p></o:p></p>
<p class="MsoNormal"> success = FALSE;<o:p></o:p></p>
<p class="MsoNormal"> break;<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (sink->direct_rendering <2) {<o:p></o:p></p>
<p class="MsoNormal">+ gst_vaapi_video_pool_put_object(sink->surfaces, surface);<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal"> return success ? GST_FLOW_OK : GST_FLOW_UNEXPECTED;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">+static GstFlowReturn<o:p></o:p></p>
<p class="MsoNormal">+gst_vaapisink_buffer_alloc(<o:p></o:p></p>
<p class="MsoNormal">+ GstBaseSink *base_sink,<o:p></o:p></p>
<p class="MsoNormal">+ guint64 offset,<o:p></o:p></p>
<p class="MsoNormal">+ guint size,<o:p></o:p></p>
<p class="MsoNormal">+ GstCaps *caps,<o:p></o:p></p>
<p class="MsoNormal">+ GstBuffer **pbuf<o:p></o:p></p>
<p class="MsoNormal">+)<o:p></o:p></p>
<p class="MsoNormal">+{<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiSink *sink = GST_VAAPISINK(base_sink);<o:p></o:p></p>
<p class="MsoNormal">+ GstBuffer *buffer = NULL;<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiImage *image = NULL;<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiSurface *surface = NULL;<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiVideoBuffer *vbuffer;<o:p></o:p></p>
<p class="MsoNormal">+ GstStructure *structure = NULL;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ *pbuf = NULL;<o:p></o:p></p>
<p class="MsoNormal">+ <o:p></o:p></p>
<p class="MsoNormal">+ structure = gst_caps_get_structure(caps, 0);<o:p></o:p></p>
<p class="MsoNormal">+ if (!gst_structure_has_name(structure, "video/x-raw-yuv")) {<o:p></o:p></p>
<p class="MsoNormal">+ return GST_FLOW_OK;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ /* Check if we can use direct-rendering */<o:p></o:p></p>
<p class="MsoNormal">+ if (!gst_vaapisink_negotiate_buffers(sink, caps))<o:p></o:p></p>
<p class="MsoNormal">+ goto error;<o:p></o:p></p>
<p class="MsoNormal">+ if (!sink->direct_rendering)<o:p></o:p></p>
<p class="MsoNormal">+ return GST_FLOW_OK;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ switch (sink->direct_rendering) {<o:p></o:p></p>
<p class="MsoNormal">+ case 2:<o:p></o:p></p>
<p class="MsoNormal">+ buffer = gst_vaapi_video_buffer_new_from_pool(sink->surfaces);<o:p></o:p></p>
<p class="MsoNormal">+ if (!buffer)<o:p></o:p></p>
<p class="MsoNormal">+ goto error;<o:p></o:p></p>
<p class="MsoNormal">+ vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ surface = gst_vaapi_video_buffer_get_surface(vbuffer);<o:p></o:p></p>
<p class="MsoNormal">+ image = gst_vaapi_surface_derive_image(surface);<o:p></o:p></p>
<p class="MsoNormal">+ if (image && gst_vaapi_image_get_data_size(image) == size) {<o:p></o:p></p>
<p class="MsoNormal">+ gst_vaapi_video_buffer_set_image(vbuffer, image);<o:p></o:p></p>
<p class="MsoNormal">+ g_object_unref(image); /* video buffer owns an extra reference */<o:p></o:p></p>
<p class="MsoNormal">+ break;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ /* We can't use the derive-image optimization. Disable it. */<o:p></o:p></p>
<p class="MsoNormal">+ sink->direct_rendering = 1;<o:p></o:p></p>
<p class="MsoNormal">+ gst_buffer_unref(buffer);<o:p></o:p></p>
<p class="MsoNormal">+ buffer = NULL;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ case 1:<o:p></o:p></p>
<p class="MsoNormal">+ buffer = gst_vaapi_video_buffer_new_from_pool(sink->images);<o:p></o:p></p>
<p class="MsoNormal">+ if (!buffer)<o:p></o:p></p>
<p class="MsoNormal">+ goto error;<o:p></o:p></p>
<p class="MsoNormal">+ vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ image = gst_vaapi_video_buffer_get_image(vbuffer);<o:p></o:p></p>
<p class="MsoNormal">+ break;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ g_assert(image);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (!gst_vaapi_image_map(image))<o:p></o:p></p>
<p class="MsoNormal">+ goto error;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ GST_BUFFER_DATA(buffer) = gst_vaapi_image_get_plane(image, 0);<o:p></o:p></p>
<p class="MsoNormal">+ GST_BUFFER_SIZE(buffer) = gst_vaapi_image_get_data_size(image);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ gst_buffer_set_caps(buffer, caps);<o:p></o:p></p>
<p class="MsoNormal">+ *pbuf = buffer;<o:p></o:p></p>
<p class="MsoNormal">+ return GST_FLOW_OK;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+error:<o:p></o:p></p>
<p class="MsoNormal">+ /* We can't use the inout-buffers optimization. Disable it. */<o:p></o:p></p>
<p class="MsoNormal">+ GST_DEBUG("disable in/out buffer optimization");<o:p></o:p></p>
<p class="MsoNormal">+ if (buffer)<o:p></o:p></p>
<p class="MsoNormal">+ gst_buffer_unref(buffer);<o:p></o:p></p>
<p class="MsoNormal">+ sink->direct_rendering = 0;<o:p></o:p></p>
<p class="MsoNormal">+ return GST_FLOW_OK;<o:p></o:p></p>
<p class="MsoNormal">+}<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">static gboolean<o:p></o:p></p>
<p class="MsoNormal">gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">@@ -870,6 +1168,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass)<o:p></o:p></p>
<p class="MsoNormal"> basesink_class->preroll = gst_vaapisink_show_frame;<o:p></o:p></p>
<p class="MsoNormal"> basesink_class->render = gst_vaapisink_show_frame;<o:p></o:p></p>
<p class="MsoNormal"> basesink_class->query = gst_vaapisink_query;<o:p></o:p></p>
<p class="MsoNormal">+ basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc;<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> gst_element_class_set_details_simple(<o:p></o:p></p>
<p class="MsoNormal"> element_class,<o:p></o:p></p>
<p class="MsoNormal">@@ -942,9 +1241,18 @@ gst_vaapisink_init(GstVaapiSink *sink)<o:p></o:p></p>
<p class="MsoNormal"> sink->video_height = 0;<o:p></o:p></p>
<p class="MsoNormal"> sink->video_par_n = 1;<o:p></o:p></p>
<p class="MsoNormal"> sink->video_par_d = 1;<o:p></o:p></p>
<p class="MsoNormal">+ sink->surface_width = 0;<o:p></o:p></p>
<p class="MsoNormal">+ sink->surface_height = 0;<o:p></o:p></p>
<p class="MsoNormal"> sink->foreign_window = FALSE;<o:p></o:p></p>
<p class="MsoNormal"> sink->fullscreen = FALSE;<o:p></o:p></p>
<p class="MsoNormal"> sink->synchronous = FALSE;<o:p></o:p></p>
<p class="MsoNormal"> sink->display_type = DEFAULT_DISPLAY_TYPE;<o:p></o:p></p>
<p class="MsoNormal"> sink->use_reflection = FALSE;<o:p></o:p></p>
<p class="MsoNormal">+ sink->images = NULL;<o:p></o:p></p>
<p class="MsoNormal">+ sink->surfaces = NULL;<o:p></o:p></p>
<p class="MsoNormal">+ sink->raw_yuv_stream = FALSE;<o:p></o:p></p>
<p class="MsoNormal">+ sink->images_reset = FALSE;<o:p></o:p></p>
<p class="MsoNormal">+ sink->surfaces_reset = FALSE;<o:p></o:p></p>
<p class="MsoNormal">+ sink->direct_rendering = G_MAXUINT32;<o:p></o:p></p>
<p class="MsoNormal">+ sink->direct_rendering_caps = 0;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal">diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h<o:p></o:p></p>
<p class="MsoNormal">old mode 100644<o:p></o:p></p>
<p class="MsoNormal">new mode 100755<o:p></o:p></p>
<p class="MsoNormal">index c5883b3..9445cd4<o:p></o:p></p>
<p class="MsoNormal">--- a/gst/vaapi/gstvaapisink.h<o:p></o:p></p>
<p class="MsoNormal">+++ b/gst/vaapi/gstvaapisink.h<o:p></o:p></p>
<p class="MsoNormal">@@ -76,11 +76,20 @@ struct _GstVaapiSink {<o:p></o:p></p>
<p class="MsoNormal"> guint video_height;<o:p></o:p></p>
<p class="MsoNormal"> gint video_par_n;<o:p></o:p></p>
<p class="MsoNormal"> gint video_par_d;<o:p></o:p></p>
<p class="MsoNormal">+ gint surface_width;<o:p></o:p></p>
<p class="MsoNormal">+ gint surface_height; // for yuv GstBuffer's surface pool<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiVideoPool *images;<o:p></o:p></p>
<p class="MsoNormal">+ GstVaapiVideoPool *surfaces;<o:p></o:p></p>
<p class="MsoNormal"> GstVaapiRectangle display_rect;<o:p></o:p></p>
<p class="MsoNormal">+ guint direct_rendering_caps;<o:p></o:p></p>
<p class="MsoNormal">+ guint direct_rendering;<o:p></o:p></p>
<p class="MsoNormal"> guint foreign_window : 1;<o:p></o:p></p>
<p class="MsoNormal"> guint fullscreen : 1;<o:p></o:p></p>
<p class="MsoNormal"> guint synchronous : 1;<o:p></o:p></p>
<p class="MsoNormal"> guint use_reflection : 1;<o:p></o:p></p>
<p class="MsoNormal">+ guint raw_yuv_stream : 1;<o:p></o:p></p>
<p class="MsoNormal">+ guint images_reset : 1;<o:p></o:p></p>
<p class="MsoNormal">+ guint surfaces_reset : 1;<o:p></o:p></p>
<p class="MsoNormal">};<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> struct _GstVaapiSinkClass {<o:p></o:p></p>
<p class="MsoNormal">-- <o:p></o:p></p>
<p class="MsoNormal">1.7.9.5<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>