blob: 6ea69519888a55f65d8f70d37cf0a02f5f0264a5 [file] [log] [blame]
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Module Overview: Starboard Decode Target module
//
// A target for decoding image and video data into. This corresponds roughly to
// an EGLImage, but that extension may not be fully supported on all GL
// platforms. SbDecodeTarget supports multi-plane targets. We need a mechanism
// for SbBlitter as well, and this is able to more-or-less unify the two.
//
// An SbDecodeTarget can be passed into any function which decodes video or
// image data. This allows the application to allocate fast graphics memory, and
// have decoding done directly into this memory, avoiding unnecessary memory
// copies, and also avoiding pushing data between CPU and GPU memory
// unnecessarily.
//
// #### SbDecodeTargetFormat
//
// SbDecodeTargets support several different formats that can be used to decode
// into and render from. Some formats may be easier to decode into, and others
// may be easier to render. Some may take less memory. Each decoder needs to
// support the SbDecodeTargetFormat passed into it, or the decode will produce
// an error. Each decoder provides a way to check if a given
// SbDecodeTargetFormat is supported by that decoder.
//
// #### SbDecodeTargetProvider
//
// Some components may need to acquire SbDecodeTargets compatible with a certain
// rendering context, which may need to be created on a particular thread. The
// SbDecodeTargetProvider is a way for the primary rendering context to provide
// an interface that can create SbDecodeTargets on demand by other system.
//
// The primary usage is likely to be the the SbPlayer implementation on some
// platforms.
//
// #### SbDecodeTarget Example
//
// Let's say there's an image decoder for .foo files:
//
// bool SbImageDecodeFooSupportsFormat(SbDecodeTargetFormat format);
// bool SbImageDecodeFoo(void *data, int data_size, SbDecodeTarget target);
//
// First, the client should enumerate which SbDecodeTargetFormats are supported
// by that decoder.
//
// SbDecodeTargetFormat kPreferredFormats[] = {
// kSbDecodeTargetFormat3PlaneYUVI420,
// kSbDecodeTargetFormat1PlaneRGBA,
// kSbDecodeTargetFormat1PlaneBGRA,
// };
//
// SbDecodeTargetFormat format = kSbDecodeTargetFormatInvalid;
// for (int i = 0; i < SB_ARRAY_SIZE_INT(kPreferredFormats); ++i) {
// if (SbImageDecodeFooSupportsFormat(kPreferredFormats[i])) {
// format = kPreferredFormats[i];
// break;
// }
// }
//
// Now that the client has a format, it can create a decode target that it will
// use to decode the .foo file into. Let's assume format is
// kSbDecodeTargetFormat1PlaneRGBA, and that we are on an EGL/GLES2 platform.
// Also, we won't do any error checking, to keep things even simpler.
//
// // Allocate a sized texture of the right format.
// GLuint texture_handle;
// glGenTextures(1, &texture_handle);
// glBindTexture(GL_TEXTURE_2D, texture_handle);
// glTexImage2D(GL_TEXTURE_2D, 0 /*level*/, GL_RGBA, width, height,
// 0 /*border*/, GL_RGBA8, GL_UNSIGNED_BYTE, NULL /*data*/);
// glBindTexture(GL_TEXTURE_2D, 0);
//
// // Create an SbDecodeTarget wrapping the new texture handle.
// SbDecodeTarget target =
// SbDecodeTargetCreate(display, context, format, &texture_handle);
//
// // Now pass the SbDecodeTarget into the decoder.
// SbImageDecodeFoo(encoded_foo_data, encoded_foo_data_size, target);
//
// // If the decode works, you can get the texture out and render it.
// GLuint texture =
// SbDecodeTargetGetPlane(target, kSbDecodeTargetPlaneRGBA);
//
#ifndef STARBOARD_DECODE_TARGET_H_
#define STARBOARD_DECODE_TARGET_H_
#include "starboard/configuration.h"
#include "starboard/export.h"
#include "starboard/types.h"
#if SB_VERSION(3) && SB_HAS(GRAPHICS)
#if SB_HAS(BLITTER)
#include "starboard/blitter.h"
#else
#include <EGL/egl.h>
#include <GL/gl.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
// --- Types -----------------------------------------------------------------
// Private structure representing a target for image data decoding.
typedef struct SbDecodeTargetPrivate SbDecodeTargetPrivate;
// A handle to a target for image data decoding.
typedef SbDecodeTargetPrivate* SbDecodeTarget;
// The list of all possible decoder target formats. An SbDecodeTarget consists
// of one or more planes of data, each plane corresponding with a surface. For
// some formats, different planes will be different sizes for the same
// dimensions.
//
// NOTE: For enumeration entries with an alpha component, the alpha will always
// be premultiplied unless otherwise explicitly specified.
typedef enum SbDecodeTargetFormat {
// A decoder target format consisting of a single RGBA plane, in that channel
// order.
kSbDecodeTargetFormat1PlaneRGBA,
// A decoder target format consisting of a single BGRA plane, in that channel
// order.
kSbDecodeTargetFormat1PlaneBGRA,
// A decoder target format consisting of Y and interleaved UV planes, in that
// plane and channel order.
kSbDecodeTargetFormat2PlaneYUVNV12,
// A decoder target format consisting of Y, U, and V planes, in that order.
kSbDecodeTargetFormat3PlaneYUVI420,
// An invalid decode target format.
kSbDecodeTargetFormatInvalid,
} SbDecodeTargetFormat;
// All the planes supported by SbDecodeTarget.
typedef enum SbDecodeTargetPlane {
// The RGBA plane for the RGBA format.
kSbDecodeTargetPlaneRGBA = 0,
// The BGRA plane for the BGRA format.
kSbDecodeTargetPlaneBGRA = 0,
// The Y plane for multi-plane YUV formats.
kSbDecodeTargetPlaneY = 0,
// The UV plane for 2-plane YUV formats.
kSbDecodeTargetPlaneUV = 1,
// The U plane for 3-plane YUV formats.
kSbDecodeTargetPlaneU = 1,
// The V plane for 3-plane YUV formats.
kSbDecodeTargetPlaneV = 2,
} SbDecodeTargetPlane;
// A function that can produce an SbDecodeTarget of the given |format|, |width|,
// and |height|.
typedef SbDecodeTarget (*SbDecodeTargetAcquireFunction)(
void* context,
SbDecodeTargetFormat format,
int width,
int height);
// A function that can reclaim an SbDecodeTarget allocated with an
// SbDecodeTargetAcquireFunction.
typedef void (*SbDecodeTargetReleaseFunction)(void* context,
SbDecodeTarget decode_target);
// An object that can acquire and release SbDecodeTarget instances.
typedef struct SbDecodeTargetProvider {
// The function to acquire a new SbDecodeTarget from the provider.
SbDecodeTargetAcquireFunction acquire;
// The function to release an acquired SbDecodeTarget back to the provider.
SbDecodeTargetReleaseFunction release;
} SbDecodeTargetProvider;
// --- Constants -------------------------------------------------------------
// Well-defined value for an invalid decode target handle.
#define kSbDecodeTargetInvalid ((SbDecodeTarget)NULL)
// --- Functions -------------------------------------------------------------
// Returns whether the given file handle is valid.
static SB_C_INLINE bool SbDecodeTargetIsValid(SbDecodeTarget handle) {
return handle != kSbDecodeTargetInvalid;
}
#if SB_HAS(BLITTER)
// Creates a new SbBlitter-compatible SbDecodeTarget from one or more |planes|
// created from |display|.
//
// |format|: The format of the decode target being created.
// |planes|: An array of SbBlitterSurface handles to be bundled into an
// SbDecodeTarget. Must not be NULL. Is expected to have the same number of
// entries as the number of planes for |format|, in the order and size expected
// by that format.
SB_EXPORT SbDecodeTarget SbDecodeTargetCreate(SbDecodeTargetFormat format,
SbBlitterSurface* planes);
// Gets the surface that represents the given plane.
SB_EXPORT SbBlitterSurface SbDecodeTargetGetPlane(SbDecodeTarget decode_target,
SbDecodeTargetPlane plane);
#else // SB_HAS(BLITTER)
// Creates a new EGL/GLES2-compatible SbDecodeTarget from one or more |planes|
// owned by |context|, created from |display|. Must be called from a thread
// where |context| is current.
//
// |display|: The EGLDisplay being targeted.
// |context|: The EGLContext used for this operation, or EGL_NO_CONTEXT if a
// context is not required.
// |format|: The format of the decode target being created.
// |planes|: An array of GLES Texture handles to be bundled into an
// SbDecodeTarget. Must not be NULL. Is expected to have the same number of
// entries as the number of planes for |format|, in the order and size expected
// by that format.
SB_EXPORT SbDecodeTarget SbDecodeTargetCreate(EGLDisplay display,
EGLContext context,
SbDecodeTargetFormat format,
GLuint* planes);
// Gets the texture that represents the given plane.
SB_EXPORT GLuint SbDecodeTargetGetPlane(SbDecodeTarget decode_target,
SbDecodeTargetPlane plane);
#endif // SB_HAS(BLITTER)
// Destroys the given SbDecodeTarget and all associated surfaces.
SB_EXPORT void SbDecodeTargetDestroy(SbDecodeTarget decode_target);
// Gets the format that |decode_target| was created with.
SB_EXPORT SbDecodeTargetFormat
SbDecodeTargetGetFormat(SbDecodeTarget decode_target);
// Registers |provider| as the SbDecodeTargetProvider with the given |context|,
// displacing any previous registered provider. The provider is expected to be
// kept alive by the caller until unregistered, so this function is NOT passing
// ownership in any way. |context| will be passed into every call to
// SbDecodeTargetProvider::acquire or SbDecodeTargetProvider::release. May be
// called from any thread.
SB_EXPORT bool SbDecodeTargetRegisterProvider(SbDecodeTargetProvider* provider,
void* context);
// Unregisters |provider| as the SbDecodeTargetProvider, with |context|, if it
// is the current registered provider-context. This is checked by comparing the
// pointer values of both |provider| and |context| to the currently registered
// provider. May be called from any thread.
SB_EXPORT void SbDecodeTargetUnregisterProvider(
SbDecodeTargetProvider* provider,
void* context);
// Acquires a decode target from the registered SbDecodeTargetProvider,
// returning NULL if none is registered. May be called from any thread.
SB_EXPORT SbDecodeTarget
SbDecodeTargetAcquireFromProvider(SbDecodeTargetFormat format,
int width,
int height);
// Releases |decode_target| back to the registered SbDecodeTargetProvider. If no
// provider is registered, just calls SbDecodeTargetDestroy on |decode_target|.
// May be called from any thread.
SB_EXPORT void SbDecodeTargetReleaseToProvider(SbDecodeTarget decode_target);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // SB_VERSION(3) && SB_HAS(GRAPHICS)
#endif // STARBOARD_DECODE_TARGET_H_