vaapivideomemory: fix determination of the surface pool format.
[platform/upstream/gstreamer-vaapi.git] / gst / vaapi / gstvaapivideomemory.c
index 25c4bbf..9c0b5b9 100644 (file)
@@ -2,6 +2,7 @@
  *  gstvaapivideomemory.c - Gstreamer/VA video memory
  *
  *  Copyright (C) 2013 Intel Corporation
+ *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public License
@@ -50,6 +51,11 @@ ensure_image(GstVaapiVideoMemory *mem)
             GST_WARNING("failed to derive image, fallbacking to copy");
             mem->use_direct_rendering = FALSE;
         }
+        else if (gst_vaapi_surface_get_format(mem->surface) !=
+                 GST_VIDEO_INFO_FORMAT(mem->image_info)) {
+            gst_vaapi_object_replace(&mem->image, NULL);
+            mem->use_direct_rendering = FALSE;
+        }
     }
 
     if (!mem->image) {
@@ -111,10 +117,9 @@ ensure_surface(GstVaapiVideoMemory *mem)
                 return FALSE;
             gst_vaapi_video_meta_set_surface_proxy(mem->meta, mem->proxy);
         }
-        mem->surface = GST_VAAPI_SURFACE_PROXY_SURFACE(mem->proxy);
     }
-    g_return_val_if_fail(mem->surface != NULL, FALSE);
-    return TRUE;
+    mem->surface = GST_VAAPI_SURFACE_PROXY_SURFACE(mem->proxy);
+    return mem->surface != NULL;
 }
 
 gboolean
@@ -122,7 +127,7 @@ gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane,
     GstMapInfo *info, gpointer *data, gint *stride, GstMapFlags flags)
 {
     GstVaapiVideoMemory * const mem =
-        GST_VAAPI_VIDEO_MEMORY_CAST(gst_buffer_get_memory(meta->buffer, 0));
+        GST_VAAPI_VIDEO_MEMORY_CAST(gst_buffer_peek_memory(meta->buffer, 0));
 
     g_return_val_if_fail(mem, FALSE);
     g_return_val_if_fail(GST_VAAPI_IS_VIDEO_ALLOCATOR(mem->parent_instance.
@@ -141,10 +146,14 @@ gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane,
             goto error_ensure_image;
 
         // Check that we can actually map the surface, or image
-        if ((flags & GST_MAP_READWRITE) != GST_MAP_WRITE &&
+        if ((flags & GST_MAP_READWRITE) == GST_MAP_WRITE &&
             !mem->use_direct_rendering)
             goto error_unsupported_map;
 
+        // Load VA image from surface
+        if ((flags & GST_MAP_READ) && !mem->use_direct_rendering)
+            gst_vaapi_surface_get_image(mem->surface, mem->image);
+
         if (!gst_vaapi_image_map(mem->image))
             goto error_map_image;
         mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR;
@@ -195,7 +204,7 @@ gst_video_meta_unmap_vaapi_memory(GstVideoMeta *meta, guint plane,
     GstMapInfo *info)
 {
     GstVaapiVideoMemory * const mem =
-        GST_VAAPI_VIDEO_MEMORY_CAST(gst_buffer_get_memory(meta->buffer, 0));
+        GST_VAAPI_VIDEO_MEMORY_CAST(gst_buffer_peek_memory(meta->buffer, 0));
 
     g_return_val_if_fail(mem, FALSE);
     g_return_val_if_fail(GST_VAAPI_IS_VIDEO_ALLOCATOR(mem->parent_instance.
@@ -480,24 +489,20 @@ gst_video_info_update_from_image(GstVideoInfo *vip, GstVaapiImage *image)
 }
 
 GstAllocator *
-gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps)
+gst_vaapi_video_allocator_new(GstVaapiDisplay *display, const GstVideoInfo *vip)
 {
     GstVaapiVideoAllocator *allocator;
-    GstVideoInfo *vip;
     GstVaapiSurface *surface;
     GstVaapiImage *image;
 
     g_return_val_if_fail(display != NULL, NULL);
-    g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
+    g_return_val_if_fail(vip != NULL, NULL);
 
     allocator = g_object_new(GST_VAAPI_TYPE_VIDEO_ALLOCATOR, NULL);
     if (!allocator)
         return NULL;
 
-    vip = &allocator->video_info;
-    gst_video_info_init(vip);
-    gst_video_info_from_caps(vip, caps);
-
+    allocator->video_info = *vip;
     gst_video_info_set_format(&allocator->surface_info, GST_VIDEO_FORMAT_NV12,
         GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip));
 
@@ -510,12 +515,12 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps)
             image = gst_vaapi_surface_derive_image(surface);
             if (!image)
                 break;
-            if (GST_VAAPI_IMAGE_FORMAT(image) != GST_VIDEO_INFO_FORMAT(vip))
-                break;
             if (!gst_vaapi_image_map(image))
                 break;
             allocator->has_direct_rendering = gst_video_info_update_from_image(
                 &allocator->surface_info, image);
+            if (GST_VAAPI_IMAGE_FORMAT(image) != GST_VIDEO_INFO_FORMAT(vip))
+               allocator->has_direct_rendering = FALSE;
             gst_vaapi_image_unmap(image);
             GST_INFO("has direct-rendering for %s surfaces: %s",
                      GST_VIDEO_INFO_FORMAT_STRING(&allocator->surface_info),
@@ -534,7 +539,7 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps)
 
     allocator->image_info = *vip;
     if (GST_VIDEO_INFO_FORMAT(vip) == GST_VIDEO_FORMAT_ENCODED)
-        gst_video_info_set_format(&allocator->image_info, GST_VIDEO_FORMAT_NV12,
+        gst_video_info_set_format(&allocator->image_info, GST_VIDEO_FORMAT_I420,
             GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip));
 
     if (allocator->has_direct_rendering)