brillcodec: enhancement plug-in structure 05/27805/3
authorSeokYeon Hwang <syeon.hwang@samsung.com>
Fri, 19 Sep 2014 09:08:31 +0000 (18:08 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Fri, 19 Sep 2014 13:00:58 +0000 (22:00 +0900)
DXVA2 plug-in is default disabled now.
VA-API plug-in check capability in runtime.

Change-Id: I4dadf524453c0db9174be401059fbac2c28c4d9f
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
tizen/src/Makefile
tizen/src/hw/pci/maru_brillcodec.c
tizen/src/hw/pci/maru_brillcodec_device.c
tizen/src/hw/pci/maru_brillcodec_plugin.h
tizen/src/hw/pci/maru_brillcodec_vaapi.c
tizen/src/hw/pci/maru_dxva2_plugin.c

index d77fd4d..9a66868 100644 (file)
@@ -19,9 +19,7 @@ ifndef CONFIG_LINUX
 TARGET_EXE += util/check-hax$(EXESUF)
 endif
 
-ifdef CONFIG_LINUX
-TARGET_DSO += hw/pci/brillcodec-vaapi$(DSOSUF)
-endif
+TARGET_DSO +=
 
 all: qemu skin_client $(TARGET_EXE) $(TARGET_DSO)
 qemu: $(TARGET_EXE) $(TARGET_DSO) build_info
@@ -31,13 +29,6 @@ qemu_clean:
 qemu_distclean:
        cd ../../ && $(MAKE) distclean
 
-# Building brillcodec-vaapi
-BRILLCODEC_VAAPI_CFLAGS = -c $(DSO_CFLAGS) $(LIBAV_CFLAGS) $(GLIB_CFLAGS) -I$(SRC_PATH) -I$(SRC_PATH)/include -I. -fPIC
-hw/pci/brillcodec-vaapi$(DSOSUF): hw/pci/maru_brillcodec_vaapi.o
-       gcc $< $(LDFLAGS_SHARED) -o $@ -lva -lva-x11
-hw/pci/maru_brillcodec_vaapi.o: %.o: %.c
-       gcc $< $(BRILLCODEC_VAAPI_CFLAGS) -o $@
-
 # Building check-gl
 CHECK_GL_OBJS = util/check_gl.o util/check_gl_core.o
 CHECK_GL_CFLAGS = -c -I$(SRC_PATH)/hw/yagl/yagl_inc
index 18caf4e..a10238d 100644 (file)
@@ -54,6 +54,9 @@ MULTI_DEBUG_CHANNEL(qemu, brillcodec);
 
 #define DEFAULT_VIDEO_GOP_SIZE 15
 
+// misc
+#define OFFSET_PICTURE_BUFFER (0x100)
+
 //
 // COMMON
 //
index e71f50d..ff028c5 100644 (file)
  *
  */
 
-//FIXME
-//#define CONFIG_VAAPI
-
 #define SUPPORT_MEMORY_MONOPOLIZING
 //#define ENCODE_VIDEO_USE_MEMORY_MONOPOLIZING
 
-#ifdef CONFIG_VAAPI
-#include "dlfcn.h"
-#endif
-
 #include "qemu/main-loop.h"
 #include "hw/pci/pci.h"
 
@@ -58,10 +51,6 @@ MULTI_DEBUG_CHANNEL(qemu, brillcodec);
 #define CODEC_REG_SIZE              (256)
 #define DEFAULT_WORKER_THREAD_CNT   8
 
-#ifdef CONFIG_DXVA2
-extern CodecPlugin dxva_plugin;
-#endif
-
 enum device_cmd {
     DEVICE_CMD_API_INDEX             = 0,
     DEVICE_CMD_CONTEXT_INDEX,
@@ -262,39 +251,6 @@ static const MemoryRegionOps brillcodec_mmio_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-#define NUM_PLUGINS     2
-static CodecPlugin *probe_plugin(void) {
-    CodecPlugin *plugins[NUM_PLUGINS] = { NULL, };
-    int i = 0;
-
-#if defined(CONFIG_VAAPI)
-    {
-        void *handle;
-
-        handle = dlopen("brillcodec-vaapi.so", RTLD_NOW);
-        if (!handle) {
-            INFO("plugin load failed : %s\n", dlerror());
-            return NULL;
-        }
-
-        plugins[i++] = dlsym(handle, "vaapi_plugin");
-
-    }
-#elif defined(CONFIG_DXVA2)
-    {
-        plugins[i++] = &dxva_plugin;
-    }
-#endif
-
-    for (i = 0; i < NUM_PLUGINS; ++i) {
-        if (plugins[i] && plugins[i]->probe && plugins[i]->probe()) {
-            return plugins[i];
-        }
-    }
-
-    return NULL;
-}
-
 static int brillcodec_initfn(PCIDevice *dev)
 {
     MaruBrillCodecState *s = DO_UPCAST(MaruBrillCodecState, dev, dev);
@@ -326,7 +282,7 @@ static int brillcodec_initfn(PCIDevice *dev)
 
     // register plugins
     if ((s->hwaccel_plugin = probe_plugin())) {
-        INFO("VA-API extension is enabled.\n");
+        INFO("%s extension is enabled.\n", s->hwaccel_plugin->name);
     }
 
     // configurations
index 70e15c2..cfbf52d 100644 (file)
@@ -33,9 +33,8 @@
 
 #include "stdbool.h"
 
-#define OFFSET_PICTURE_BUFFER (0x100)
-
 typedef struct CodecPlugin {
+    char const          *name;
     enum PixelFormat    pix_fmt;
     enum PixelFormat    output_pix_fmt;
     bool                (*probe)(void);
@@ -45,4 +44,37 @@ typedef struct CodecPlugin {
     void                (*get_picture)(void *dst, void *src);
 } CodecPlugin;
 
+#define NUM_PLUGINS     2
+
+#ifdef CONFIG_VAAPI
+extern CodecPlugin vaapi_plugin;
+#endif
+#ifdef CONFIG_DXVA2
+extern CodecPlugin dxva_plugin;
+#endif
+
+static inline CodecPlugin *probe_plugin(void) {
+    CodecPlugin *plugins[NUM_PLUGINS] = { NULL, };
+    int i = 0;
+
+#if defined(CONFIG_VAAPI)
+    {
+        plugins[i++] = &vaapi_plugin;
+    }
+#endif
+#if defined(CONFIG_DXVA2)
+    {
+        plugins[i++] = &dxva_plugin;
+    }
+#endif
+
+    for (i = 0; i < NUM_PLUGINS; ++i) {
+        if (plugins[i] && plugins[i]->probe && plugins[i]->probe()) {
+            return plugins[i];
+        }
+    }
+
+    return NULL;
+}
+
 #endif //__MARU_BRILLCODEC_PLUGIN_H__
index f9171d7..45a6118 100644 (file)
 #include "libavutil/imgutils.h"
 #include "va/va.h"
 #include "va/va_x11.h"
+#include "dlfcn.h"
 
 #include "maru_brillcodec_plugin.h"
 
 #define SURFACE_COUNT   4
 
-#ifndef VA_SURFACE_ATTRIB_SETTABLE
-#define vaCreateSurfaces(d, f, w, h, s, ns, a, na) \
-    vaCreateSurfaces(d, w, h, f, ns, s)
-#endif
-
-
 typedef struct VAPluginContext {
+    VAContextID context_id;
     VASurfaceID surface_id[SURFACE_COUNT];
     bool surface_is_occupied[SURFACE_COUNT];
 
@@ -60,10 +56,131 @@ typedef struct VAPluginContext {
 } VAPluginContext;
 
 static void *va_display;
+static int va_major_version, va_minor_version;
 
 // FIXME
 static VAPluginContext *va_ctx = &(VAPluginContext) {};
 
+
+// fuction pointers to VAAPI
+VADisplay (*_vaGetDisplay)(Display *);
+VAStatus (*_vaInitialize)(VADisplay, int *, int *);
+int (*_vaMaxNumProfiles)(VADisplay);
+VAStatus (*_vaQueryConfigProfiles)(VADisplay, VAProfile *, int *);
+VAStatus (*_vaGetConfigAttributes)(VADisplay, VAProfile, VAEntrypoint, VAConfigAttrib *, int);
+VAStatus (*_vaCreateConfig)(VADisplay, VAProfile, VAEntrypoint, VAConfigAttrib *, int, VAConfigID *);
+
+void (*_vaCreateSurfaces)(void);
+// for VAAPI version >= 0.34
+typedef VAStatus (*_vaCreateSurfaces8)(VADisplay, unsigned int, unsigned int, unsigned int, VASurfaceID *,
+            unsigned int, VASurfaceAttrib *, unsigned int);
+// for VAAPI version < 0.34
+typedef VAStatus (*_vaCreateSurfaces6)(VADisplay, int, int, int, int, VASurfaceID *);
+
+VAStatus (*_vaCreateContext)(VADisplay, VAConfigID, int, int, int, VASurfaceID *, int, VAContextID *);
+int (*_vaMaxNumImageFormats)(VADisplay dpy);
+VAStatus (*_vaQueryImageFormats)(VADisplay, VAImageFormat *, int *);
+VAStatus (*_vaDeriveImage)(VADisplay, VASurfaceID, VAImage *);
+VAStatus (*_vaCreateImage)(VADisplay, VAImageFormat *, int, int, VAImage *);
+VAStatus (*_vaDestroyImage)(VADisplay, VAImageID);
+
+void (*_vaSyncSurface)(void);
+// for VAAPI version >= 0.31
+typedef VAStatus (*_vaSyncSurface2)(VADisplay, VASurfaceID);
+// for VAAPI version < 0.31
+typedef VAStatus (*_vaSyncSurface3)(VADisplay, VAContextID, VASurfaceID);
+
+VAStatus (*_vaGetImage)(VADisplay, VASurfaceID, int, int, unsigned int, unsigned int, VAImageID);
+VAStatus (*_vaMapBuffer)(VADisplay, VABufferID, void **);
+VAStatus (*_vaUnmapBuffer)(VADisplay, VABufferID);
+
+static inline bool check_version(int major, int minor)
+{
+    if (va_major_version > major ||
+        (va_major_version == major && va_minor_version >= minor)) {
+        return true;
+    }
+
+    return false;
+}
+
+static bool initialize(void)
+{
+    if (!va_display) {
+        Display *display = XOpenDisplay(NULL);
+        if (!display)
+        {
+            printf("Could not connect to x server\n");
+            return false;
+        }
+
+        va_display = _vaGetDisplay(display);
+        if (!va_display)
+        {
+            printf("Could not get a VAAPI device\n");
+            return false;
+        }
+
+        if (_vaInitialize(va_display, &va_major_version, &va_minor_version))
+        {
+            va_display = NULL;
+            printf("Failed to initialize the VAAPI device\n");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+#define DLSYM(func) \
+    { _##func = dlsym(handle, #func); \
+                    if (!_##func) { goto error; } }
+
+static bool probe(void)
+{
+    void *handle = dlopen("libva-x11.so", RTLD_NOW);
+    if (!handle) {
+        goto error;
+    }
+
+    DLSYM(vaGetDisplay);
+
+    handle = dlopen("libva.so", RTLD_NOW);
+    if (!handle) {
+        goto error;
+    }
+
+    DLSYM(vaInitialize);
+    DLSYM(vaMaxNumProfiles);
+    DLSYM(vaQueryConfigProfiles);
+    DLSYM(vaGetConfigAttributes);
+    DLSYM(vaCreateConfig);
+    DLSYM(vaCreateSurfaces);
+    DLSYM(vaCreateContext);
+    DLSYM(vaMaxNumImageFormats);
+    DLSYM(vaQueryImageFormats);
+    DLSYM(vaDeriveImage);
+    DLSYM(vaCreateImage);
+    DLSYM(vaDestroyImage);
+    DLSYM(vaSyncSurface);
+    DLSYM(vaGetImage);
+    DLSYM(vaMapBuffer);
+    DLSYM(vaUnmapBuffer);
+
+    // we initialize vaapi now for sure...
+    if (!initialize()) {
+        printf("Can not initialize VA-API\n");
+        return false;
+    }
+
+    return true;
+
+error:
+    printf("plugin load failed : %s\n", dlerror());
+
+    return false;
+}
+
 static int create_surfaces(AVCodecContext *ctx, int width, int height, VAProfile profile)
 {
     assert(width > 0 && height > 0);
@@ -74,7 +191,7 @@ static int create_surfaces(AVCodecContext *ctx, int width, int height, VAProfile
     VAConfigAttrib attrib;
     memset(&attrib, 0, sizeof(attrib));
     attrib.type = VAConfigAttribRTFormat;
-    if (vaGetConfigAttributes(va_display,
+    if (_vaGetConfigAttributes(va_display,
                                profile, VAEntrypointVLD, &attrib, 1)) {
         goto error;
     }
@@ -83,53 +200,60 @@ static int create_surfaces(AVCodecContext *ctx, int width, int height, VAProfile
     if ((attrib.value & VA_RT_FORMAT_YUV420) == 0)
         goto error;
 
-    if (vaCreateConfig(va_display,
+    if (_vaCreateConfig(va_display,
                         profile, VAEntrypointVLD, &attrib, 1, &config_id)) {
         goto error;
     }
 
     /* Create surfaces */
-    if (vaCreateSurfaces(va_display, VA_RT_FORMAT_YUV420, width, height,
-                          va_ctx->surface_id, SURFACE_COUNT, NULL, 0)) {
-        goto error;
+    if (check_version(0, 34)) {
+        if (((_vaCreateSurfaces8)_vaCreateSurfaces)(va_display, VA_RT_FORMAT_YUV420, width, height,
+                    va_ctx->surface_id, SURFACE_COUNT, NULL, 0)) {
+            goto error;
+        }
+    } else {
+        if (((_vaCreateSurfaces6)_vaCreateSurfaces)(va_display, width, height, VA_RT_FORMAT_YUV420,
+                    SURFACE_COUNT, va_ctx->surface_id)) {
+            goto error;
+        }
     }
 
-    VAContextID context_id = VA_INVALID_ID;
+    va_ctx->context_id = VA_INVALID_ID;
     /* Create a context */
-    if (vaCreateContext(va_display, config_id,
+    if (_vaCreateContext(va_display, config_id,
                          width, height, VA_PROGRESSIVE,
-                         va_ctx->surface_id, SURFACE_COUNT, &context_id)) {
+                         va_ctx->surface_id, SURFACE_COUNT, &va_ctx->context_id)) {
         goto error;
     }
 
-    int fmt_count = vaMaxNumImageFormats(va_display);
-    VAImageFormat *p_fmt = calloc(fmt_count, sizeof(*p_fmt));
+    int fmt_count = _vaMaxNumImageFormats(va_display);
+    VAImageFormat *p_fmt = g_malloc0_n(fmt_count, sizeof(*p_fmt));
     if (!p_fmt) {
         goto error;
     }
 
-    if (vaQueryImageFormats(va_display, p_fmt, &fmt_count)) {
-        free( p_fmt );
+    if (_vaQueryImageFormats(va_display, p_fmt, &fmt_count)) {
+        g_free(p_fmt);
         goto error;
     }
 
     VAImage test_image;
-    if (vaDeriveImage(va_display, va_ctx->surface_id[0], &test_image) == VA_STATUS_SUCCESS) {
+    if (_vaDeriveImage(va_display, va_ctx->surface_id[0], &test_image) == VA_STATUS_SUCCESS) {
         va_ctx->is_supports_derive = true;
-        vaDestroyImage(va_display, test_image.image_id);
+        _vaDestroyImage(va_display, test_image.image_id);
     }
 
     int i;
     for (i = 0; i < fmt_count; ++i) {
         if (p_fmt[i].fourcc == VA_FOURCC_YV12) { // we support only VA_FOURCC_YV12 for now...
-            if (vaCreateImage(va_display, &p_fmt[i], width, height, &va_ctx->image )) {
+            if (_vaCreateImage(va_display, &p_fmt[i], width, height, &va_ctx->image )) {
                 goto error;
             }
         }
     }
 
     if (va_ctx->is_supports_derive) {
-        vaDestroyImage(va_display, va_ctx->image.image_id);
+        _vaDestroyImage(va_display, va_ctx->image.image_id);
         va_ctx->image.image_id = VA_INVALID_ID;
     }
 
@@ -139,7 +263,7 @@ static int create_surfaces(AVCodecContext *ctx, int width, int height, VAProfile
 
     hw_context->display    = va_display;
     hw_context->config_id  = config_id;
-    hw_context->context_id = context_id;
+    hw_context->context_id = va_ctx->context_id;
 
     return 0;
 
@@ -149,26 +273,6 @@ error:
 }
 
 static bool setup(AVCodecContext *ctx, int width, int height) {
-    if (!va_display) {
-        Display *display = XOpenDisplay(NULL);
-        if(!display)
-        {
-            printf("Could not connect to x server\n");
-        }
-
-        va_display = vaGetDisplay(display);
-        if(!va_display)
-        {
-            printf("Could not get a VAAPI device\n");
-        }
-
-        int major, minor;
-        if(vaInitialize(va_display, &major, &minor))
-        {
-            printf("Failed to initialize the VAAPI device\n");
-        }
-    }
-
     VAProfile profile;
 
     int codec_id = ctx->codec_id;
@@ -194,8 +298,8 @@ static bool setup(AVCodecContext *ctx, int width, int height) {
         goto error;
     }
 
-    int num_profiles = vaMaxNumProfiles(va_display);
-    VAProfile *profiles_list = calloc(num_profiles, sizeof(VAProfile));
+    int num_profiles = _vaMaxNumProfiles(va_display);
+    VAProfile *profiles_list = g_malloc0_n(num_profiles, sizeof(VAProfile));
     bool is_supported_profile;
     int i;
 
@@ -203,7 +307,7 @@ static bool setup(AVCodecContext *ctx, int width, int height) {
         goto error;
     }
 
-    VAStatus status = vaQueryConfigProfiles(va_display, profiles_list, &num_profiles);
+    VAStatus status = _vaQueryConfigProfiles(va_display, profiles_list, &num_profiles);
     if (status == VA_STATUS_SUCCESS) {
         for (i = 0; i < num_profiles; ++i) {
             if (profiles_list[i] == profile) {
@@ -212,7 +316,7 @@ static bool setup(AVCodecContext *ctx, int width, int height) {
             }
         }
     }
-    free(profiles_list);
+    g_free(profiles_list);
     if (!is_supported_profile)
     {
         printf("Codec and profile not supported by the VAAPI device");
@@ -263,21 +367,22 @@ static void extract(void* dst, void *src)
     AVFrame *frame = (AVFrame *)src;
     VASurfaceID surface_id = (VASurfaceID)(uintptr_t)frame->data[3];
 
-#if VA_CHECK_VERSION(0,31,0)
-    if (vaSyncSurface(va_display, surface_id))
-#else
-#error
-#endif
-    {
-        return;
+    if (check_version(0, 31)) {
+        if (((_vaSyncSurface2)_vaSyncSurface)(va_display, surface_id)) {
+            return;
+        }
+    } else {
+        if (((_vaSyncSurface3)_vaSyncSurface)(va_display, va_ctx->context_id, surface_id)) {
+            return;
+        }
     }
 
     if (va_ctx->is_supports_derive) {
-        if (vaDeriveImage(va_display, surface_id, &va_ctx->image) != VA_STATUS_SUCCESS) {
+        if (_vaDeriveImage(va_display, surface_id, &va_ctx->image) != VA_STATUS_SUCCESS) {
             return;
         }
     } else {
-        if (vaGetImage(va_display, surface_id,
+        if (_vaGetImage(va_display, surface_id,
                       0, 0, frame->width, frame->height,
                       va_ctx->image.image_id)) {
             return;
@@ -285,7 +390,7 @@ static void extract(void* dst, void *src)
     }
 
     void *p_base;
-    if (vaMapBuffer(va_display, va_ctx->image.buf, &p_base)) {
+    if (_vaMapBuffer(va_display, va_ctx->image.buf, &p_base)) {
         return;
     }
 
@@ -312,13 +417,13 @@ static void extract(void* dst, void *src)
         return;
     }
 
-    if (vaUnmapBuffer(va_display, va_ctx->image.buf)) {
+    if (_vaUnmapBuffer(va_display, va_ctx->image.buf)) {
         return;
     }
 
     if (va_ctx->is_supports_derive)
     {
-        vaDestroyImage(va_display, va_ctx->image.image_id);
+        _vaDestroyImage(va_display, va_ctx->image.image_id);
         va_ctx->image.image_id = VA_INVALID_ID;
     }
 
@@ -358,8 +463,10 @@ static void release_surface(AVCodecContext *p_context,
 }
 
 CodecPlugin vaapi_plugin = {
+    .name = "VA-API",
     .pix_fmt = PIX_FMT_VAAPI_VLD,
     .output_pix_fmt = PIX_FMT_YUV420P,
+    .probe = probe,
     .setup = setup,
     .get_buffer = get_surface,
     .release_buffer = release_surface,
index 3fdbd6a..0a6f180 100644 (file)
@@ -990,8 +990,10 @@ static void extract(void *dst, void *src)
 }
 
 CodecPlugin dxva_plugin = {
+    .name = "DXVA2",
     .pix_fmt = PIX_FMT_DXVA2_VLD,
     .output_pix_fmt = PIX_FMT_YUV420P,
+    .probe = NULL;
     .setup = dxva_setup,
     .get_buffer = dxva_get_surface,
     .release_buffer = dxva_release_surface,