[x265] [PATCH RFC] api: introduce a less version strict API query
Steve Borho
steve at borho.org
Thu May 14 19:53:01 CEST 2015
# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1431625954 18000
# Thu May 14 12:52:34 2015 -0500
# Node ID 6c0bd18d02eaf8b141368c5ecee417ba61f7ed85
# Parent 8592bf81d0848279fa79cd1487406cb516dffe99
api: introduce a less version strict API query
The intention is to allow applications to use libx265 libraries with different
X265_BUILD numbers than the x265.h header they were compiled with by keeping
a little more information about the nature of each API bump.
This should have no effect on existing applications, X265_BUILD will still be
incremented each time the public API is changed, but applications which use
this new x265_get_api_build() method will be able to dlopen() and use any
version of libx265 that returns an API pointer that passes validation checks:
1. check api->api_major_version == X265_MAJOR_VERSION
2. check api->sizeof_param == sizeof(x265_param) if param is dereferenced
3. check api->sizeof_picture == sizeof(x265_picture)
4. check api->sizeof_analysis_data ..
etc.
apps that use param_alloc()/param_free()/param_parse() can skip step 2 and
thus ignore the primary cause of most X265_BUILD bumps.
The only additional work for x265 developers is to increment X265_MAJOR_VERSION
when warranted (which should hopefully be very rarely).
Since this commit is modifying x265_api, we take the opportunity to rename
max_bit_depth to the more accurate bit_depth, since each API will only be
capable of encoding at a single bit depth. Obviously this commit would also
need to bump X265_BUILD before being pushed.
diff -r 8592bf81d084 -r 6c0bd18d02ea source/encoder/api.cpp
--- a/source/encoder/api.cpp Thu May 14 17:12:14 2015 +0530
+++ b/source/encoder/api.cpp Thu May 14 12:52:34 2015 -0500
@@ -253,6 +253,18 @@
static const x265_api libapi =
{
+ X265_MAJOR_VERSION,
+ X265_BUILD,
+ sizeof(x265_param),
+ sizeof(x265_picture),
+ sizeof(x265_analysis_data),
+ sizeof(x265_zone),
+ sizeof(x265_stats),
+
+ x265_max_bit_depth,
+ x265_version_str,
+ x265_build_info_str,
+
&x265_param_alloc,
&x265_param_free,
&x265_param_default,
@@ -271,9 +283,6 @@
&x265_encoder_log,
&x265_encoder_close,
&x265_cleanup,
- x265_version_str,
- x265_build_info_str,
- x265_max_bit_depth,
};
typedef const x265_api* (*api_get_func)(int bitDepth);
@@ -337,7 +346,7 @@
x265_log(NULL, X265_LOG_WARNING, "Unable to open %s\n", libname);
#endif
- if (api && bitDepth != api->max_bit_depth)
+ if (api && bitDepth != api->bit_depth)
{
x265_log(NULL, X265_LOG_WARNING, "%s does not support requested bitDepth %d\n", libname, bitDepth);
return NULL;
diff -r 8592bf81d084 -r 6c0bd18d02ea source/x265.cpp
--- a/source/x265.cpp Thu May 14 17:12:14 2015 +0530
+++ b/source/x265.cpp Thu May 14 12:52:34 2015 -0500
@@ -318,9 +318,9 @@
return true;
}
- if (param->internalBitDepth != api->max_bit_depth)
+ if (param->internalBitDepth != api->bit_depth)
{
- x265_log(param, X265_LOG_ERROR, "Only bit depths of %d are supported in this build\n", api->max_bit_depth);
+ x265_log(param, X265_LOG_ERROR, "Only bit depths of %d are supported in this build\n", api->bit_depth);
return true;
}
diff -r 8592bf81d084 -r 6c0bd18d02ea source/x265.def.in
--- a/source/x265.def.in Thu May 14 17:12:14 2015 +0530
+++ b/source/x265.def.in Thu May 14 12:52:34 2015 -0500
@@ -21,3 +21,4 @@
x265_encoder_close
x265_cleanup
x265_api_get_${X265_BUILD}
+x265_api_get_build
diff -r 8592bf81d084 -r 6c0bd18d02ea source/x265.h
--- a/source/x265.h Thu May 14 17:12:14 2015 +0530
+++ b/source/x265.h Thu May 14 12:52:34 2015 -0500
@@ -1278,15 +1278,28 @@
* release library static allocations, reset configured CTU size */
void x265_cleanup(void);
+#define X265_MAJOR_VERSION 1
/* === Multi-lib API ===
- * By using this method to gain access to the libx265 interfaces, you allow shim
- * implementations of x265_api_get() to choose between various available libx265
- * libraries based on the encoder parameters. The most likely use case is to
- * choose between 8bpp and 16bpp builds of libx265. */
+ * By using this method to gain access to the libx265 interfaces, you allow run-
+ * time selection between various available libx265 libraries based on the
+ * encoder parameters. The most likely use case is to choose between 8bpp and
+ * 16bpp builds of libx265. */
typedef struct x265_api
{
+ int api_major_version; /* X265_MAJOR_VERSION */
+ int api_minor_version; /* X265_BUILD (soname) */
+ int sizeof_param; /* sizeof(x265_param) */
+ int sizeof_picture; /* sizeof(x265_picture) */
+ int sizeof_analysis_data; /* sizeof(x265_analysis_data) */
+ int sizeof_zone; /* sizeof(x265_zone) */
+ int sizeof_stats; /* sizeof(x265_stats) */
+
+ int bit_depth;
+ const char* version_str;
+ const char* build_info_str;
+
/* libx265 public API functions, documented above with x265_ prefixes */
x265_param* (*param_alloc)(void);
void (*param_free)(x265_param*);
@@ -1306,9 +1319,7 @@
void (*encoder_log)(x265_encoder*, int, char**);
void (*encoder_close)(x265_encoder*);
void (*cleanup)(void);
- const char* version_str;
- const char* build_info_str;
- int max_bit_depth;
+ /* add new pointers to the end, or increment X265_MAJOR_VERSION */
} x265_api;
/* Force a link error in the case of linking against an incompatible API version.
@@ -1332,6 +1343,29 @@
* Obviously the shared library file extension is platform specific */
const x265_api* x265_api_get(int bitDepth);
+/* x265_api_get_build:
+ * Retrieve the programming interface for a linked x265 library, like
+ * x265_api_get(), except this function accepts X265_BUILD as the second
+ * argument rather than using the build number as part of the function name.
+ * Applications which dynamically link to libx265 can use this interface to
+ * query the library API and achieve a relative amount of version skew
+ * flexibility. The function may return NULL if the library determines that
+ * the apiVersion that your application was compiled against is not compatible
+ * with the library you have linked with.
+ *
+ * api_major_version will be incremented any time struct x265_api is changed,
+ * or if any non-backward compatible changes are made to any other public
+ * structures or functions. If api_major_version does not match
+ * X265_MAJOR_VERSION from the x265.h your application compiled against, your
+ * application must not use the returned x265_api pointer.
+ *
+ * Users of this API *must* also validate the sizes of any structures which
+ * are not treated as opaque in application code. For instance, if your
+ * application dereferences a x265_param pointer, then it must check that
+ * api->sizeof_param matches the sizeof(x265_param) that your application
+ * compiled with. */
+const x265_api* x265_api_get_build(int bitDepth, int apiVersion);
+
#ifdef __cplusplus
}
#endif
More information about the x265-devel
mailing list