<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>