summaryrefslogtreecommitdiffstats
path: root/libmpv
diff options
context:
space:
mode:
Diffstat (limited to 'libmpv')
-rw-r--r--libmpv/client.h13
-rw-r--r--libmpv/mpv.def6
-rw-r--r--libmpv/opengl_cb.h11
-rw-r--r--libmpv/render.h309
-rw-r--r--libmpv/render_gl.h155
5 files changed, 491 insertions, 3 deletions
diff --git a/libmpv/client.h b/libmpv/client.h
index 424bf0613d..07237c9d4d 100644
--- a/libmpv/client.h
+++ b/libmpv/client.h
@@ -210,7 +210,7 @@ extern "C" {
* relational operators (<, >, <=, >=).
*/
#define MPV_MAKE_VERSION(major, minor) (((major) << 16) | (minor) | 0UL)
-#define MPV_CLIENT_API_VERSION MPV_MAKE_VERSION(1, 27)
+#define MPV_CLIENT_API_VERSION MPV_MAKE_VERSION(1, 28)
/**
* The API user is allowed to "#define MPV_ENABLE_DEPRECATED 0" before
@@ -1691,6 +1691,11 @@ int mpv_get_wakeup_pipe(mpv_handle *ctx);
*/
void mpv_wait_async_requests(mpv_handle *ctx);
+#if MPV_ENABLE_DEPRECATED
+
+/**
+ * @deprecated use render.h
+ */
typedef enum mpv_sub_api {
/**
* For using mpv's OpenGL renderer on an external OpenGL context.
@@ -1698,6 +1703,8 @@ typedef enum mpv_sub_api {
* This context can be used with mpv_opengl_cb_* functions.
* Will return NULL if unavailable (if OpenGL support was not compiled in).
* See opengl_cb.h for details.
+ *
+ * @deprecated use render.h
*/
MPV_SUB_API_OPENGL_CB = 1
} mpv_sub_api;
@@ -1705,9 +1712,13 @@ typedef enum mpv_sub_api {
/**
* This is used for additional APIs that are not strictly part of the core API.
* See the individual mpv_sub_api member values.
+ *
+ * @deprecated use render.h
*/
void *mpv_get_sub_api(mpv_handle *ctx, mpv_sub_api sub_api);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/libmpv/mpv.def b/libmpv/mpv.def
index 0384c7db9d..5299f69c9a 100644
--- a/libmpv/mpv.def
+++ b/libmpv/mpv.def
@@ -28,6 +28,12 @@ mpv_opengl_cb_report_flip
mpv_opengl_cb_render
mpv_opengl_cb_set_update_callback
mpv_opengl_cb_uninit_gl
+mpv_render_context_create
+mpv_render_context_free
+mpv_render_context_render
+mpv_render_context_report_swap
+mpv_render_context_set_parameter
+mpv_render_context_set_update_callback
mpv_request_event
mpv_request_log_messages
mpv_resume
diff --git a/libmpv/opengl_cb.h b/libmpv/opengl_cb.h
index 384372b617..ce88a8570a 100644
--- a/libmpv/opengl_cb.h
+++ b/libmpv/opengl_cb.h
@@ -18,6 +18,10 @@
#include "client.h"
+#if !MPV_ENABLE_DEPRECATED
+#error "This header and all API provided by it is deprecated. Use render.h instead."
+#else
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -27,6 +31,9 @@ extern "C" {
* Overview
* --------
*
+ * Warning: this API is deprecated. A very similar API is provided by render.h
+ * and render_gl.h. The deprecated API is emulated with the new API.
+ *
* This API can be used to make mpv render into a foreign OpenGL context. It
* can be used to handle video display.
*
@@ -328,7 +335,6 @@ int mpv_opengl_cb_init_gl(mpv_opengl_cb_context *ctx, const char *exts,
*/
int mpv_opengl_cb_draw(mpv_opengl_cb_context *ctx, int fbo, int w, int h);
-#if MPV_ENABLE_DEPRECATED
/**
* Deprecated. Use mpv_opengl_cb_draw(). This function is equivalent to:
*
@@ -341,7 +347,6 @@ int mpv_opengl_cb_draw(mpv_opengl_cb_context *ctx, int fbo, int w, int h);
* was never marked as stable).
*/
int mpv_opengl_cb_render(mpv_opengl_cb_context *ctx, int fbo, int vp[4]);
-#endif
/**
* Tell the renderer that a frame was flipped at the given time. This is
@@ -375,4 +380,6 @@ int mpv_opengl_cb_uninit_gl(mpv_opengl_cb_context *ctx);
}
#endif
+#endif /* else #if MPV_ENABLE_DEPRECATED */
+
#endif
diff --git a/libmpv/render.h b/libmpv/render.h
new file mode 100644
index 0000000000..64a317d73c
--- /dev/null
+++ b/libmpv/render.h
@@ -0,0 +1,309 @@
+/* Copyright (C) 2018 the mpv developers
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef MPV_CLIENT_API_RENDER_H_
+#define MPV_CLIENT_API_RENDER_H_
+
+#include "client.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Overview
+ * --------
+ *
+ * This API can be used to make mpv render using supported graphic APIs (such
+ * as OpenGL). It can be used to handle video display.
+ *
+ * The renderer needs to be created with mpv_render_context_create() before
+ * you start playback (or otherwise cause a VO to be created). Then (with most
+ * backends) mpv_render_context_render() can be used to explicitly render the
+ * current video frame. Use mpv_render_context_set_update_callback() to get
+ * notified when there is a new frame to draw.
+ *
+ * Preferably rendering should be done in a separate thread. If you call
+ * normal libmpv API functions on the renderer thread, deadlocks can result
+ * (these are made non-fatal with timeouts, but user experience will obviously
+ * suffer).
+ *
+ * You can output and embed video without this API by setting the mpv "wid"
+ * option to a native window handle (see "Embedding the video window" section
+ * in the client.h header). In general, using the render API is recommended,
+ * because window embedding can cause various issues, especially with GUI
+ * toolkits and certain platforms.
+ *
+ * Supported backends
+ * ------------------
+ *
+ * OpenGL: via MPV_RENDER_API_TYPE_OPENGL, see render_gl.h header.
+ *
+ * Threading
+ * ---------
+ *
+ * The mpv_render_* functions can be called from any thread, under the
+ * following conditions:
+ * - only one of the mpv_render_* functions can be called at the same time
+ * (unless they belong to different mpv cores created by mpv_create())
+ * - never can be called from within the callbacks set with
+ * mpv_set_wakeup_callback() or mpv_render_context_set_update_callback()
+ * - if the OpenGL backend is used, for all functions the OpenGL context
+ * must be "current" in the calling thread, and it must be the same OpenGL
+ * context as the mpv_render_context was created with. Otherwise, undefined
+ * behavior will occur.
+ *
+ * Context and handle lifecycle
+ * ----------------------------
+ *
+ * Video initialization will fail if the render context was not initialized yet
+ * (with mpv_render_context_create()), or it will revert to a VO that creates
+ * its own window.
+ *
+ * Calling mpv_render_context_free() while a VO is using the render context is
+ * active will disable video.
+ *
+ * You must free the context with mpv_render_context_free() before the mpv core
+ * is destroyed. If this doesn't happen, undefined behavior will result.
+ */
+
+/**
+ * Opaque context, returned by mpv_render_context_create().
+ */
+typedef struct mpv_render_context mpv_render_context;
+
+/**
+ * Parameters for mpv_render_param (which is used in a few places such as
+ * mpv_render_context_create().
+ *
+ * Also see mpv_render_param for conventions and how to use it.
+ */
+typedef enum mpv_render_param_type {
+ /**
+ * Not a valid value, but also used to terminate a params array. Its value
+ * is always guaranteed to be 0 (even if the ABI changes in the future).
+ */
+ MPV_RENDER_PARAM_INVALID = 0,
+ /**
+ * The render API to use. Valid for mpv_render_context_create().
+ *
+ * Type: char*
+ *
+ * Defined APIs:
+ *
+ * MPV_RENDER_API_TYPE_OPENGL:
+ * OpenGL desktop 2.1 or later (preferably core profile compatible to
+ * OpenGL 3.2), or OpenGLES 2.0 or later.
+ * Providing MPV_RENDER_PARAM_OPENGL_INIT_PARAMS is required.
+ * It is expected that an OpenGL context is valid and "current" when
+ * calling mpv_render_* functions (unless specified otherwise). It
+ * must be the same context for the same mpv_render_context.
+ */
+ MPV_RENDER_PARAM_API_TYPE = 1,
+ /**
+ * Required parameters for initializing the OpenGL renderer. Valid for
+ * mpv_render_context_create().
+ * Type: mpv_opengl_init_params*
+ */
+ MPV_RENDER_PARAM_OPENGL_INIT_PARAMS = 2,
+ /**
+ * Describes a GL render target. Valid for mpv_render_context_render().
+ * Type: mpv_opengl_fbo*
+ */
+ MPV_RENDER_PARAM_OPENGL_FBO = 3,
+ /**
+ * Control flipped rendering. Valid for mpv_render_context_render().
+ * Type: int*
+ * If the value is set to 0, render normally. Otherwise, render it flipped,
+ * which is needed e.g. when rendering to an OpenGL default framebuffer
+ * (which has a flipped coordinate system).
+ */
+ MPV_RENDER_PARAM_FLIP_Y = 4,
+ /**
+ * Control surface depth. Valid for mpv_render_context_render().
+ * Type: int*
+ * This implies the depth of the surface passed to the render function in
+ * bits per channel. If omitted or set to 0, the renderer will assume 8.
+ * Typically used to control dithering.
+ */
+ MPV_RENDER_PARAM_DEPTH = 5,
+ /**
+ * ICC profile blob. Valid for mpv_render_context_set_parameter().
+ * Type: mpv_byte_array*
+ * Set an ICC profile for use with the "icc-profile-auto" option. (If the
+ * option is not enabled, the ICC data will not be used.)
+ */
+ MPV_RENDER_PARAM_ICC_PROFILE = 6,
+ /**
+ * Ambient light in lux. Valid for mpv_render_context_set_parameter().
+ * Type: int*
+ * This can be used for automatic gamma correction.
+ */
+ MPV_RENDER_PARAM_AMBIENT_LIGHT = 7,
+} mpv_render_param_type;
+
+/**
+ * Predefined values for MPV_RENDER_PARAM_API_TYPE.
+ */
+#define MPV_RENDER_API_TYPE_OPENGL "opengl"
+
+/**
+ * Used to pass arbitrary parameters to some mpv_render_* functions. The
+ * meaning of the data parameter is determined by the type, and each
+ * MPV_RENDER_PARAM_* documents what type the value must point to.
+ *
+ * Each value documents the required data type as the pointer you cast to
+ * void* and set on mpv_render_param.data. For example, if MPV_RENDER_PARAM_FOO
+ * documents the type as Something* , then the code should look like this:
+ *
+ * Something foo = {...};
+ * mpv_render_param param;
+ * param.type = MPV_RENDER_PARAM_FOO;
+ * param.data = & foo;
+ *
+ * Normally, the data field points to exactly 1 object. If the type is char*,
+ * it points to a 0-terminated string.
+ *
+ * In all cases (unless documented otherwise) the pointers need to remain
+ * valid during the call only. Unless otherwise documented, the API functions
+ * will not write to the params array or any data pointed to it.
+ *
+ * As a convention, parameter arrays are always terminated by type==0. There
+ * is no specific order of the parameters required. The order of fields is
+ * guaranteed (even after ABI changes).
+ */
+typedef struct mpv_render_param {
+ enum mpv_render_param_type type;
+ void *data;
+} mpv_render_param;
+
+/**
+ * Initialize the renderer state. Depending on the backend used, this will
+ * access the underlying GPU API and initialize its own objects.
+ *
+ * You must free the context with mpv_render_context_free(). Not doing so before
+ * the mpv core is destroyed may result in memory leaks or crashes.
+ *
+ * Currently, only at most 1 context can exists per mpv core (it represents the
+ * main video output).
+ *
+ * @param res set to the context (on success) or NULL (on failure). The value
+ * is never read and always overwritten.
+ * @param mpv handle used to get the core (the mpv_render_context won't depend
+ * on this specific handle, only the core referenced by it)
+ * @param params an array of parameters, terminated by type==0. It's left
+ * unspecified what happens with unknown parameters. At least
+ * MPV_RENDER_PARAM_API_TYPE is required, and most backends will
+ * require another backend-specific parameter.
+ * @return error code, including but not limited to:
+ * MPV_ERROR_UNSUPPORTED: the OpenGL version is not supported
+ * (or required extensions are missing)
+ * MPV_ERROR_NOT_IMPLEMENTED: an unknown API type was provided, or
+ * support for the requested API was not
+ * built in the used libmpv binary.
+ * MPV_ERROR_INVALID_PARAMETER: at least one of the provided parameters was
+ * not valid.
+ */
+int mpv_render_context_create(mpv_render_context **res, mpv_handle *mpv,
+ mpv_render_param *params);
+
+/**
+ * Attempt to change a single parameter. Not all backends and parameter types
+ * support all kinds of changes.
+ *
+ * @param ctx a valid render context
+ * @param param the parameter type and data that should be set
+ * @return error code. If a parameter could actually be changed, this returns
+ * success, otherwise an error code depending on the parameter type
+ * and situation.
+ */
+int mpv_render_context_set_parameter(mpv_render_context *ctx,
+ mpv_render_param param);
+
+typedef void (*mpv_render_update_fn)(void *cb_ctx);
+
+/**
+ * Set the callback that notifies you when a new video frame is available, or
+ * if the video display configuration somehow changed and requires a redraw.
+ * Similar to mpv_set_wakeup_callback(), you must not call any mpv API from
+ * the callback, and all the other listed restrictions apply (such as not
+ * exiting the callback by throwing exceptions).
+ *
+ * This can be called from any thread, except from an update callback. In case
+ * of the OpenGL backend, no OpenGL state or API is accessed.
+ *
+ * @param callback callback(callback_ctx) is called if the frame should be
+ * redrawn
+ * @param callback_ctx opaque argument to the callback
+ */
+void mpv_render_context_set_update_callback(mpv_render_context *ctx,
+ mpv_render_update_fn callback,
+ void *callback_ctx);
+
+/**
+ * Render video.
+ *
+ * Typically renders the video to a target surface provided via mpv_render_param
+ * (the details depend on the backend in use). Options like "panscan" are
+ * applied to determine which part of the video should be visible and how the
+ * video should be scaled. You can change these options at runtime by using the
+ * mpv property API.
+ *
+ * The renderer will reconfigure itself every time the target surface
+ * configuration (such as size) is changed.
+ *
+ * This function implicitly pulls a video frame from the internal queue and
+ * renders it. If no new frame is available, the previous frame is redrawn.
+ * The update callback set with mpv_render_context_set_update_callback()
+ * notifies you when a new frame was added. The details potentially depend on
+ * the backends and the provided parameters.
+ *
+ * @param ctx a valid render context
+ * @param params an array of parameters, terminated by type==0. Which parameters
+ * are required depends on the backend. It's left unspecified what
+ * happens with unknown parameters.
+ * @return error code
+ */
+int mpv_render_context_render(mpv_render_context *ctx, mpv_render_param *params);
+
+/**
+ * Tell the renderer that a frame was flipped at the given time. This is
+ * optional, but can help the player to achieve better timing.
+ *
+ * Note that calling this at least once informs libmpv that you will use this
+ * function. If you use it inconsistently, expect bad video playback.
+ *
+ * If this is called while no video is initialized, it is ignored.
+ *
+ * @param ctx a valid render context
+ */
+void mpv_render_context_report_swap(mpv_render_context *ctx);
+
+/**
+ * Destroy the mpv renderer state.
+ *
+ * If video is still active (e.g. a file playing), video will be disabled
+ * forcefully.
+ *
+ * @param ctx a valid render context. After this function returns, this is not
+ * a valid pointer anymore. NULL is also allowed and does nothing.
+ */
+void mpv_render_context_free(mpv_render_context *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libmpv/render_gl.h b/libmpv/render_gl.h
new file mode 100644
index 0000000000..01c09e80df
--- /dev/null
+++ b/libmpv/render_gl.h
@@ -0,0 +1,155 @@
+/* Copyright (C) 2018 the mpv developers
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef MPV_CLIENT_API_RENDER_GL_H_
+#define MPV_CLIENT_API_RENDER_GL_H_
+
+#include "render.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * OpenGL backend
+ * --------------
+ *
+ * This header contains definitions for using OpenGL with the render.h API.
+ *
+ * OpenGL interop
+ * --------------
+ *
+ * The OpenGL backend has some special rules, because OpenGL itself uses
+ * implicit per-thread contexts, which causes additional API problems.
+ *
+ * This assumes the OpenGL context lives on a certain thread controlled by the
+ * API user. All mpv_render_* APIs have to be assumed to implicitly use the
+ * OpenGL context if you pass a mpv_render_context using the OpenGL backend,
+ * unless specified otherwise.
+ *
+ * The OpenGL context is indirectly accessed through the OpenGL function
+ * pointers returned by the get_proc_address callback in mpv_opengl_init_params.
+ * Generally, mpv will not load the system OpenGL library when using this API.
+ *
+ * OpenGL state
+ * ------------
+ *
+ * OpenGL has a large amount of implicit state. All the mpv functions mentioned
+ * above expect that the OpenGL state is reasonably set to OpenGL standard
+ * defaults. Likewise, mpv will attempt to leave the OpenGL context with
+ * standard defaults. The following state is excluded from this:
+ *
+ * - the glViewport state
+ * - the glScissor state (but GL_SCISSOR_TEST is in its default value)
+ * - glBlendFuncSeparate() state (but GL_BLEND is in its default value)
+ * - glClearColor() state
+ * - mpv may overwrite the callback set with glDebugMessageCallback()
+ * - mpv always disables GL_DITHER at init
+ *
+ * Messing with the state could be avoided by creating shared OpenGL contexts,
+ * but this is avoided for the sake of compatibility and interoperability.
+ *
+ * On OpenGL 2.1, mpv will strictly call functions like glGenTextures() to
+ * create OpenGL objects. You will have to do the same. This ensures that
+ * objects created by mpv and the API users don't clash. Also, legacy state
+ * must be either in its defaults, or not interfere with core state.
+ *
+ * API use
+ * -------
+ *
+ * The mpv_render_* API is used. That API supports multiple backends, and this
+ * section documents specifics for the OpenGL backend.
+ *
+ * Use mpv_render_context_create() with MPV_RENDER_PARAM_API_TYPE set to
+ * MPV_RENDER_API_TYPE_OPENGL, and MPV_RENDER_PARAM_OPENGL_INIT_PARAMS provided.
+ *
+ * Call mpv_render_context_render() with MPV_RENDER_PARAM_OPENGL_FBO to render
+ * the video frame to an FBO.
+ *
+ * Hardware decoding
+ * -----------------
+ *
+ * Hardware decoding via this API is fully supported, but requires some
+ * additional setup. (At least if direct hardware decoding modes are wanted,
+ * instead of copying back surface data from GPU to CPU RAM.)
+ *
+ * There may be certain requirements on the OpenGL implementation:
+ *
+ * - Windows: ANGLE is required (although in theory GL/DX interop could be used)
+ * - Intel/Linux: EGL is required, and also a glMPGetNativeDisplay() callback
+ * must be provided (see sections below)
+ * - nVidia/Linux: Both GLX and EGL should work (GLX is required if vdpau is
+ * used, e.g. due to old drivers.)
+ * - OSX: CGL is required (CGLGetCurrentContext() returning non-NULL)
+ * - iOS: EAGL is required (EAGLContext.currentContext returning non-nil)
+ *
+ * Once these things are setup, hardware decoding can be enabled/disabled at
+ * any time by setting the "hwdec" property.
+ */
+
+/**
+ * For initializing the mpv OpenGL state via MPV_RENDER_PARAM_OPENGL_INIT_PARAMS.
+ */
+typedef struct mpv_opengl_init_params {
+ /**
+ * This retrieves OpenGL function pointers, and will use them in subsequent
+ * operation.
+ * Usually, GL context APIs do this for you (e.g. with glXGetProcAddressARB
+ * or wglGetProcAddress), but some APIs do not always return pointers for
+ * all standard functions (even if present); in this case you have to
+ * compensate by looking up these functions yourself and returning them
+ * from this callback.
+ */
+ void *(*get_proc_address)(void *ctx, const char *name);
+ /**
+ * Value passed as ctx parameter to get_proc_address().
+ */
+ void *get_proc_address_ctx;
+ /**
+ * This should not be used. The main purpose is signaling support for
+ * "GL_MP_MPGetNativeDisplay", which is needed for compatibility with the
+ * opengl_cb API only. Thus it's deprecated and will be removed or ignored
+ * when the opengl_cb API is removed.
+ */
+ const char *extra_exts;
+} mpv_opengl_init_params;
+
+/**
+ * For MPV_RENDER_PARAM_OPENGL_FBO.
+ */
+typedef struct mpv_opengl_fbo {
+ /**
+ * Framebuffer object name. This must be either a valid FBO generated by
+ * glGenFramebuffers() that is complete and color-renderable, or 0. If the
+ * value is 0, this refers to the OpenGL default framebuffer.
+ */
+ int fbo;
+ /**
+ * Valid dimensions. This must refer to the size of the framebuffer. This
+ * must always be set.
+ */
+ int w, h;
+ /**
+ * Underlying texture internal format (e.g. GL_RGBA8), or 0 if unknown. If
+ * this is the default framebuffer, this can be an equivalent.
+ */
+ int internal_format;
+} mpv_opengl_fbo;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif