opencl: add spec opencl device APIs 20130411
authorhighgod0401 <highgod0401@gmail.com>
Thu, 11 Apr 2013 04:57:52 +0000 (12:57 +0800)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 11 Apr 2013 10:46:34 +0000 (12:46 +0200)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
doc/all-components.texi
doc/ffmpeg-utils.texi
doc/libavutil.texi
doc/opencl.texi [new file with mode: 0644]
libavfilter/deshake_opencl.c
libavutil/opencl.c
libavutil/opencl.h
libavutil/version.h

index a0f1134..6800db9 100644 (file)
@@ -3,6 +3,7 @@
 @ifset config-avutil
 @include syntax.texi
 @include eval.texi
+@include opencl.texi
 @end ifset
 
 @ifset config-avcodec
index c5822a8..d8f0d0d 100644 (file)
@@ -19,6 +19,7 @@ by the libavutil library.
 
 @include syntax.texi
 @include eval.texi
+@include opencl.texi
 
 @chapter See Also
 
index 50b0d0e..e48dd7f 100644 (file)
@@ -33,6 +33,7 @@ ffmpeg-utils(1)
 @end ifnothtml
 
 @include authors.texi
+@include opencl.texi
 
 @ignore
 
diff --git a/doc/opencl.texi b/doc/opencl.texi
new file mode 100644 (file)
index 0000000..40a7e31
--- /dev/null
@@ -0,0 +1,20 @@
+@chapter OpenCL Options
+@c man begin OPENCL OPTIONS
+
+When FFmpeg is configured with @code{--enable-opencl}, it is possible
+to set the options to set in the global OpenCL context. The list of
+supported options follows:
+
+@table @option
+@item build_options
+Set build options which used to compiled kernels, see reference "OpenCL Specification Version: 1.2 chapter 5.6.4"
+
+@item platform_idx
+Select platform to run OpenCL code, the platform_idx is the index of platform in device list which can be getted by function av_opencl_get_device_list().
+
+@item device_idx
+Select device to run OpenCL code, the device_idx is the index of device in device list which can be getted by function av_opencl_get_device_list().
+
+@end table
+
+@c man end OPENCL OPTIONS
index 63d144a..0f6dcc4 100644 (file)
@@ -98,10 +98,7 @@ int ff_opencl_deshake_init(AVFilterContext *ctx)
 {
     int ret = 0;
     DeshakeContext *deshake = ctx->priv;
-    AVDictionary *options = NULL;
-    av_dict_set(&options, "build_options", "-I.", 0);
-    ret = av_opencl_init(options, NULL);
-    av_dict_free(&options);
+    ret = av_opencl_init(NULL);
     if (ret < 0)
         return ret;
     deshake->opencl_ctx.matrix_size = MATRIX_SIZE;
index a01eab8..aeccc07 100644 (file)
@@ -24,6 +24,7 @@
 #include "avstring.h"
 #include "log.h"
 #include "avassert.h"
+#include "opt.h"
 
 #if HAVE_PTHREADS
 
@@ -73,10 +74,23 @@ typedef struct {
     const AVClass *class;
     int log_offset;
     void *log_ctx;
+    int init_flag;
+    int platform_idx;
+    int device_idx;
+    char *build_options;
 } OpenclUtils;
 
+#define OFFSET(x) offsetof(OpenclUtils, x)
+
+static const AVOption opencl_options[] = {
+     { "platform_idx",        "set platform index value",  OFFSET(platform_idx),  AV_OPT_TYPE_INT,    {.i64=-1}, -1, INT_MAX},
+     { "device_idx",          "set device index value",    OFFSET(device_idx),    AV_OPT_TYPE_INT,    {.i64=-1}, -1, INT_MAX},
+     { "build_options",       "build options of opencl",   OFFSET(build_options), AV_OPT_TYPE_STRING, {.str="-I."},  CHAR_MIN, CHAR_MAX},
+};
+
 static const AVClass openclutils_class = {
     .class_name                = "OPENCLUTILS",
+    .option                    = opencl_options,
     .item_name                 = av_default_item_name,
     .version                   = LIBAVUTIL_VERSION_INT,
     .log_level_offset_offset   = offsetof(OpenclUtils, log_offset),
@@ -311,6 +325,36 @@ void av_opencl_free_device_list(AVOpenCLDeviceList **device_list)
     av_freep(device_list);
 }
 
+int av_opencl_set_option(const char *key, const char *val)
+{
+    int ret = 0;
+    LOCK_OPENCL
+    if (!openclutils.init_flag) {
+        av_opt_set_defaults(&openclutils);
+        openclutils.init_flag = 1;
+    }
+    ret = av_opt_set(&openclutils, key, val, 0);
+    UNLOCK_OPENCL
+    return ret;
+}
+
+int av_opencl_get_option(const char *key, uint8_t **out_val)
+{
+    int ret = 0;
+    LOCK_OPENCL
+    ret = av_opt_get(&openclutils, key, 0, out_val);
+    UNLOCK_OPENCL
+    return ret;
+}
+
+void av_opencl_free_option(void)
+{
+    /*FIXME: free openclutils context*/
+    LOCK_OPENCL
+    av_opt_free(&openclutils);
+    UNLOCK_OPENCL
+}
+
 AVOpenCLExternalEnv *av_opencl_alloc_external_env(void)
 {
     AVOpenCLExternalEnv *ext = av_mallocz(sizeof(AVOpenCLExternalEnv));
@@ -561,46 +605,22 @@ end:
     return ret;
 }
 
-int av_opencl_init(AVDictionary *options, AVOpenCLExternalEnv *ext_opencl_env)
+int av_opencl_init(AVOpenCLExternalEnv *ext_opencl_env)
 {
     int ret = 0;
-    AVDictionaryEntry *opt_build_entry;
-    AVDictionaryEntry *opt_platform_entry;
-    AVDictionaryEntry *opt_device_entry;
-    char *pos;
     LOCK_OPENCL
     if (!gpu_env.init_count) {
-        opt_platform_entry = av_dict_get(options, "platform_idx", NULL, 0);
-        opt_device_entry   = av_dict_get(options, "device_idx", NULL, 0);
-        /* initialize devices, context, command_queue */
-        gpu_env.platform_idx = -1;
-        gpu_env.device_idx = -1;
-        if (opt_platform_entry) {
-            gpu_env.platform_idx = strtol(opt_platform_entry->value, &pos, 10);
-            if (pos == opt_platform_entry->value) {
-                av_log(&openclutils, AV_LOG_ERROR, "Platform index should be a number\n");
-                ret = AVERROR(EINVAL);
-                goto end;
-            }
-        }
-        if (opt_device_entry) {
-            gpu_env.device_idx = strtol(opt_device_entry->value, &pos, 10);
-            if (pos == opt_platform_entry->value) {
-                av_log(&openclutils, AV_LOG_ERROR, "Device index should be a number\n");
-                ret = AVERROR(EINVAL);
-                goto end;
-            }
+        if (!openclutils.init_flag) {
+            av_opt_set_defaults(&openclutils);
+            openclutils.init_flag = 1;
         }
+        gpu_env.device_idx   = openclutils.device_idx;
+        gpu_env.platform_idx = openclutils.platform_idx;
         ret = init_opencl_env(&gpu_env, ext_opencl_env);
         if (ret < 0)
             goto end;
     }
-    /*initialize program, kernel_name, kernel_count*/
-    opt_build_entry = av_dict_get(options, "build_options", NULL, 0);
-    if (opt_build_entry)
-        ret = compile_kernel_file(&gpu_env, opt_build_entry->value);
-    else
-        ret = compile_kernel_file(&gpu_env, NULL);
+    ret = compile_kernel_file(&gpu_env, openclutils.build_options);
     if (ret < 0)
         goto end;
     if (gpu_env.kernel_code_count <= 0) {
@@ -654,6 +674,8 @@ void av_opencl_uninit(void)
     }
     free_device_list(&gpu_env.device_list);
 end:
+    if ((gpu_env.init_count <= 0) && (gpu_env.kernel_count <= 0))
+        av_opt_free(&openclutils); //FIXME: free openclutils context
     UNLOCK_OPENCL
 }
 
index bcb25ed..acafe36 100644 (file)
@@ -97,6 +97,43 @@ int av_opencl_get_device_list(AVOpenCLDeviceList **device_list);
 void av_opencl_free_device_list(AVOpenCLDeviceList **device_list);
 
 /**
+ * Set option in the global OpenCL context.
+ *
+ * This options affect the operation performed by the next
+ * av_opencl_init() operation.
+ *
+ * The currently accepted options are:
+ * - build_options: set options to compile registered kernels code
+ * - platform: set index of platform in device list
+ * - device: set index of device in device list
+ *
+ * See reference "OpenCL Specification Version: 1.2 chapter 5.6.4".
+ *
+ * @param key                 option key
+ * @param val                 option value
+ * @return >=0 on success, a negative error code in case of failure
+ * @see av_opencl_get_option()
+ */
+int av_opencl_set_option(const char *key, const char *val);
+
+/**
+ * Get option value from the global OpenCL context.
+ *
+ * @param key        option key
+ * @param out_val  pointer to location where option value will be
+ *                         written, must be freed with av_freep()
+ * @return  >=0 on success, a negative error code in case of failure
+ * @see av_opencl_set_option()
+ */
+int av_opencl_get_option(const char *key, uint8_t **out_val);
+
+/**
+ * Free option values of the global OpenCL context.
+ *
+ */
+void av_opencl_free_option(void);
+
+/**
  * Allocate OpenCL external environment.
  *
  * It must be freed with av_opencl_free_external_env().
@@ -128,16 +165,11 @@ int av_opencl_register_kernel_code(const char *kernel_code);
  * Initialize the run time OpenCL environment and compile the kernel
  * code registered with av_opencl_register_kernel_code().
  *
- * Currently, the only accepted option is "build_options", used to set
- * options to compile registered kernels code. See reference "OpenCL
- * Specification Version: 1.2 chapter 5.6.4".
- *
- * @param options        dictionary of key/value options
  * @param ext_opencl_env external OpenCL environment, created by an
  *                       application program, ignored if set to NULL
  * @return >=0 on success, a negative error code in case of failure
  */
- int av_opencl_init(AVDictionary *options, AVOpenCLExternalEnv *ext_opencl_env);
+ int av_opencl_init(AVOpenCLExternalEnv *ext_opencl_env);
 
 /**
  * Create kernel object in the specified kernel environment.
index 7d1ab9c..6531397 100644 (file)
@@ -75,7 +75,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  52
-#define LIBAVUTIL_VERSION_MINOR  25
+#define LIBAVUTIL_VERSION_MINOR  26
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \