import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -0,0 +1,445 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*!\file
* \brief Describes the decoder algorithm interface for algorithm
* implementations.
*
* This file defines the private structures and data types that are only
* relevant to implementing an algorithm, as opposed to using it.
*
* To create a decoder algorithm class, an interface structure is put
* into the global namespace:
* <pre>
* my_codec.c:
* vpx_codec_iface_t my_codec = {
* "My Codec v1.0",
* VPX_CODEC_ALG_ABI_VERSION,
* ...
* };
* </pre>
*
* An application instantiates a specific decoder instance by using
* vpx_codec_init() and a pointer to the algorithm's interface structure:
* <pre>
* my_app.c:
* extern vpx_codec_iface_t my_codec;
* {
* vpx_codec_ctx_t algo;
* res = vpx_codec_init(&algo, &my_codec);
* }
* </pre>
*
* Once initialized, the instance is manged using other functions from
* the vpx_codec_* family.
*/
#ifndef VPX_INTERNAL_VPX_CODEC_INTERNAL_H_
#define VPX_INTERNAL_VPX_CODEC_INTERNAL_H_
#include "../vpx_decoder.h"
#include "../vpx_encoder.h"
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif
/*!\brief Current ABI version number
*
* \internal
* If this file is altered in any way that changes the ABI, this value
* must be bumped. Examples include, but are not limited to, changing
* types, removing or reassigning enums, adding/removing/rearranging
* fields to structures
*/
#define VPX_CODEC_INTERNAL_ABI_VERSION (5) /**<\hideinitializer*/
typedef struct vpx_codec_alg_priv vpx_codec_alg_priv_t;
typedef struct vpx_codec_priv_enc_mr_cfg vpx_codec_priv_enc_mr_cfg_t;
/*!\brief init function pointer prototype
*
* Performs algorithm-specific initialization of the decoder context. This
* function is called by the generic vpx_codec_init() wrapper function, so
* plugins implementing this interface may trust the input parameters to be
* properly initialized.
*
* \param[in] ctx Pointer to this instance's context
* \retval #VPX_CODEC_OK
* The input stream was recognized and decoder initialized.
* \retval #VPX_CODEC_MEM_ERROR
* Memory operation failed.
*/
typedef vpx_codec_err_t (*vpx_codec_init_fn_t)(vpx_codec_ctx_t *ctx,
vpx_codec_priv_enc_mr_cfg_t *data);
/*!\brief destroy function pointer prototype
*
* Performs algorithm-specific destruction of the decoder context. This
* function is called by the generic vpx_codec_destroy() wrapper function,
* so plugins implementing this interface may trust the input parameters
* to be properly initialized.
*
* \param[in] ctx Pointer to this instance's context
* \retval #VPX_CODEC_OK
* The input stream was recognized and decoder initialized.
* \retval #VPX_CODEC_MEM_ERROR
* Memory operation failed.
*/
typedef vpx_codec_err_t (*vpx_codec_destroy_fn_t)(vpx_codec_alg_priv_t *ctx);
/*!\brief parse stream info function pointer prototype
*
* Performs high level parsing of the bitstream. This function is called by the
* generic vpx_codec_peek_stream_info() wrapper function, so plugins
* implementing this interface may trust the input parameters to be properly
* initialized.
*
* \param[in] data Pointer to a block of data to parse
* \param[in] data_sz Size of the data buffer
* \param[in,out] si Pointer to stream info to update. The size member
* \ref MUST be properly initialized, but \ref MAY be
* clobbered by the algorithm. This parameter \ref MAY
* be NULL.
*
* \retval #VPX_CODEC_OK
* Bitstream is parsable and stream information updated
*/
typedef vpx_codec_err_t (*vpx_codec_peek_si_fn_t)(const uint8_t *data,
unsigned int data_sz,
vpx_codec_stream_info_t *si);
/*!\brief Return information about the current stream.
*
* Returns information about the stream that has been parsed during decoding.
*
* \param[in] ctx Pointer to this instance's context
* \param[in,out] si Pointer to stream info to update. The size member
* \ref MUST be properly initialized, but \ref MAY be
* clobbered by the algorithm. This parameter \ref MAY
* be NULL.
*
* \retval #VPX_CODEC_OK
* Bitstream is parsable and stream information updated
*/
typedef vpx_codec_err_t (*vpx_codec_get_si_fn_t)(vpx_codec_alg_priv_t *ctx,
vpx_codec_stream_info_t *si);
/*!\brief control function pointer prototype
*
* This function is used to exchange algorithm specific data with the decoder
* instance. This can be used to implement features specific to a particular
* algorithm.
*
* This function is called by the generic vpx_codec_control() wrapper
* function, so plugins implementing this interface may trust the input
* parameters to be properly initialized. However, this interface does not
* provide type safety for the exchanged data or assign meanings to the
* control codes. Those details should be specified in the algorithm's
* header file. In particular, the ctrl_id parameter is guaranteed to exist
* in the algorithm's control mapping table, and the data parameter may be NULL.
*
*
* \param[in] ctx Pointer to this instance's context
* \param[in] ctrl_id Algorithm specific control identifier
* \param[in,out] data Data to exchange with algorithm instance.
*
* \retval #VPX_CODEC_OK
* The internal state data was deserialized.
*/
typedef vpx_codec_err_t (*vpx_codec_control_fn_t)(vpx_codec_alg_priv_t *ctx,
va_list ap);
/*!\brief control function pointer mapping
*
* This structure stores the mapping between control identifiers and
* implementing functions. Each algorithm provides a list of these
* mappings. This list is searched by the vpx_codec_control() wrapper
* function to determine which function to invoke. The special
* value {0, NULL} is used to indicate end-of-list, and must be
* present. The special value {0, <non-null>} can be used as a catch-all
* mapping. This implies that ctrl_id values chosen by the algorithm
* \ref MUST be non-zero.
*/
typedef const struct vpx_codec_ctrl_fn_map {
int ctrl_id;
vpx_codec_control_fn_t fn;
} vpx_codec_ctrl_fn_map_t;
/*!\brief decode data function pointer prototype
*
* Processes a buffer of coded data. If the processing results in a new
* decoded frame becoming available, #VPX_CODEC_CB_PUT_SLICE and
* #VPX_CODEC_CB_PUT_FRAME events are generated as appropriate. This
* function is called by the generic vpx_codec_decode() wrapper function,
* so plugins implementing this interface may trust the input parameters
* to be properly initialized.
*
* \param[in] ctx Pointer to this instance's context
* \param[in] data Pointer to this block of new coded data. If
* NULL, a #VPX_CODEC_CB_PUT_FRAME event is posted
* for the previously decoded frame.
* \param[in] data_sz Size of the coded data, in bytes.
*
* \return Returns #VPX_CODEC_OK if the coded data was processed completely
* and future pictures can be decoded without error. Otherwise,
* see the descriptions of the other error codes in ::vpx_codec_err_t
* for recoverability capabilities.
*/
typedef vpx_codec_err_t (*vpx_codec_decode_fn_t)(vpx_codec_alg_priv_t *ctx,
const uint8_t *data,
unsigned int data_sz,
void *user_priv,
long deadline);
/*!\brief Decoded frames iterator
*
* Iterates over a list of the frames available for display. The iterator
* storage should be initialized to NULL to start the iteration. Iteration is
* complete when this function returns NULL.
*
* The list of available frames becomes valid upon completion of the
* vpx_codec_decode call, and remains valid until the next call to vpx_codec_decode.
*
* \param[in] ctx Pointer to this instance's context
* \param[in out] iter Iterator storage, initialized to NULL
*
* \return Returns a pointer to an image, if one is ready for display. Frames
* produced will always be in PTS (presentation time stamp) order.
*/
typedef vpx_image_t *(*vpx_codec_get_frame_fn_t)(vpx_codec_alg_priv_t *ctx,
vpx_codec_iter_t *iter);
/*!\brief Pass in external frame buffers for the decoder to use.
*
* Registers functions to be called when libvpx needs a frame buffer
* to decode the current frame and a function to be called when libvpx does
* not internally reference the frame buffer. This set function must
* be called before the first call to decode or libvpx will assume the
* default behavior of allocating frame buffers internally.
*
* \param[in] ctx Pointer to this instance's context
* \param[in] cb_get Pointer to the get callback function
* \param[in] cb_release Pointer to the release callback function
* \param[in] cb_priv Callback's private data
*
* \retval #VPX_CODEC_OK
* External frame buffers will be used by libvpx.
* \retval #VPX_CODEC_INVALID_PARAM
* One or more of the callbacks were NULL.
* \retval #VPX_CODEC_ERROR
* Decoder context not initialized, or algorithm not capable of
* using external frame buffers.
*
* \note
* When decoding VP9, the application may be required to pass in at least
* #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS external frame
* buffers.
*/
typedef vpx_codec_err_t (*vpx_codec_set_fb_fn_t)(
vpx_codec_alg_priv_t *ctx,
vpx_get_frame_buffer_cb_fn_t cb_get,
vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv);
typedef vpx_codec_err_t (*vpx_codec_encode_fn_t)(vpx_codec_alg_priv_t *ctx,
const vpx_image_t *img,
vpx_codec_pts_t pts,
unsigned long duration,
vpx_enc_frame_flags_t flags,
unsigned long deadline);
typedef const vpx_codec_cx_pkt_t *(*vpx_codec_get_cx_data_fn_t)(vpx_codec_alg_priv_t *ctx,
vpx_codec_iter_t *iter);
typedef vpx_codec_err_t
(*vpx_codec_enc_config_set_fn_t)(vpx_codec_alg_priv_t *ctx,
const vpx_codec_enc_cfg_t *cfg);
typedef vpx_fixed_buf_t *
(*vpx_codec_get_global_headers_fn_t)(vpx_codec_alg_priv_t *ctx);
typedef vpx_image_t *
(*vpx_codec_get_preview_frame_fn_t)(vpx_codec_alg_priv_t *ctx);
typedef vpx_codec_err_t
(*vpx_codec_enc_mr_get_mem_loc_fn_t)(const vpx_codec_enc_cfg_t *cfg,
void **mem_loc);
/*!\brief usage configuration mapping
*
* This structure stores the mapping between usage identifiers and
* configuration structures. Each algorithm provides a list of these
* mappings. This list is searched by the vpx_codec_enc_config_default()
* wrapper function to determine which config to return. The special value
* {-1, {0}} is used to indicate end-of-list, and must be present. At least
* one mapping must be present, in addition to the end-of-list.
*
*/
typedef const struct vpx_codec_enc_cfg_map {
int usage;
vpx_codec_enc_cfg_t cfg;
} vpx_codec_enc_cfg_map_t;
/*!\brief Decoder algorithm interface interface
*
* All decoders \ref MUST expose a variable of this type.
*/
struct vpx_codec_iface {
const char *name; /**< Identification String */
int abi_version; /**< Implemented ABI version */
vpx_codec_caps_t caps; /**< Decoder capabilities */
vpx_codec_init_fn_t init; /**< \copydoc ::vpx_codec_init_fn_t */
vpx_codec_destroy_fn_t destroy; /**< \copydoc ::vpx_codec_destroy_fn_t */
vpx_codec_ctrl_fn_map_t *ctrl_maps; /**< \copydoc ::vpx_codec_ctrl_fn_map_t */
struct vpx_codec_dec_iface {
vpx_codec_peek_si_fn_t peek_si; /**< \copydoc ::vpx_codec_peek_si_fn_t */
vpx_codec_get_si_fn_t get_si; /**< \copydoc ::vpx_codec_get_si_fn_t */
vpx_codec_decode_fn_t decode; /**< \copydoc ::vpx_codec_decode_fn_t */
vpx_codec_get_frame_fn_t get_frame; /**< \copydoc ::vpx_codec_get_frame_fn_t */
vpx_codec_set_fb_fn_t set_fb_fn; /**< \copydoc ::vpx_codec_set_fb_fn_t */
} dec;
struct vpx_codec_enc_iface {
int cfg_map_count;
vpx_codec_enc_cfg_map_t *cfg_maps; /**< \copydoc ::vpx_codec_enc_cfg_map_t */
vpx_codec_encode_fn_t encode; /**< \copydoc ::vpx_codec_encode_fn_t */
vpx_codec_get_cx_data_fn_t get_cx_data; /**< \copydoc ::vpx_codec_get_cx_data_fn_t */
vpx_codec_enc_config_set_fn_t cfg_set; /**< \copydoc ::vpx_codec_enc_config_set_fn_t */
vpx_codec_get_global_headers_fn_t get_glob_hdrs; /**< \copydoc ::vpx_codec_get_global_headers_fn_t */
vpx_codec_get_preview_frame_fn_t get_preview; /**< \copydoc ::vpx_codec_get_preview_frame_fn_t */
vpx_codec_enc_mr_get_mem_loc_fn_t mr_get_mem_loc; /**< \copydoc ::vpx_codec_enc_mr_get_mem_loc_fn_t */
} enc;
};
/*!\brief Callback function pointer / user data pair storage */
typedef struct vpx_codec_priv_cb_pair {
union {
vpx_codec_put_frame_cb_fn_t put_frame;
vpx_codec_put_slice_cb_fn_t put_slice;
} u;
void *user_priv;
} vpx_codec_priv_cb_pair_t;
/*!\brief Instance private storage
*
* This structure is allocated by the algorithm's init function. It can be
* extended in one of two ways. First, a second, algorithm specific structure
* can be allocated and the priv member pointed to it. Alternatively, this
* structure can be made the first member of the algorithm specific structure,
* and the pointer cast to the proper type.
*/
struct vpx_codec_priv {
const char *err_detail;
vpx_codec_flags_t init_flags;
struct {
vpx_codec_priv_cb_pair_t put_frame_cb;
vpx_codec_priv_cb_pair_t put_slice_cb;
} dec;
struct {
vpx_fixed_buf_t cx_data_dst_buf;
unsigned int cx_data_pad_before;
unsigned int cx_data_pad_after;
vpx_codec_cx_pkt_t cx_data_pkt;
unsigned int total_encoders;
} enc;
};
/*
* Multi-resolution encoding internal configuration
*/
struct vpx_codec_priv_enc_mr_cfg
{
unsigned int mr_total_resolutions;
unsigned int mr_encoder_id;
struct vpx_rational mr_down_sampling_factor;
void* mr_low_res_mode_info;
};
#undef VPX_CTRL_USE_TYPE
#define VPX_CTRL_USE_TYPE(id, typ) \
static VPX_INLINE typ id##__value(va_list args) {return va_arg(args, typ);}
#undef VPX_CTRL_USE_TYPE_DEPRECATED
#define VPX_CTRL_USE_TYPE_DEPRECATED(id, typ) \
static VPX_INLINE typ id##__value(va_list args) {return va_arg(args, typ);}
#define CAST(id, arg) id##__value(arg)
/* CODEC_INTERFACE convenience macro
*
* By convention, each codec interface is a struct with extern linkage, where
* the symbol is suffixed with _algo. A getter function is also defined to
* return a pointer to the struct, since in some cases it's easier to work
* with text symbols than data symbols (see issue #169). This function has
* the same name as the struct, less the _algo suffix. The CODEC_INTERFACE
* macro is provided to define this getter function automatically.
*/
#define CODEC_INTERFACE(id)\
vpx_codec_iface_t* id(void) { return &id##_algo; }\
vpx_codec_iface_t id##_algo
/* Internal Utility Functions
*
* The following functions are intended to be used inside algorithms as
* utilities for manipulating vpx_codec_* data structures.
*/
struct vpx_codec_pkt_list {
unsigned int cnt;
unsigned int max;
struct vpx_codec_cx_pkt pkts[1];
};
#define vpx_codec_pkt_list_decl(n)\
union {struct vpx_codec_pkt_list head;\
struct {struct vpx_codec_pkt_list head;\
struct vpx_codec_cx_pkt pkts[n];} alloc;}
#define vpx_codec_pkt_list_init(m)\
(m)->alloc.head.cnt = 0,\
(m)->alloc.head.max = sizeof((m)->alloc.pkts) / sizeof((m)->alloc.pkts[0])
int
vpx_codec_pkt_list_add(struct vpx_codec_pkt_list *,
const struct vpx_codec_cx_pkt *);
const vpx_codec_cx_pkt_t *
vpx_codec_pkt_list_get(struct vpx_codec_pkt_list *list,
vpx_codec_iter_t *iter);
#include <stdio.h>
#include <setjmp.h>
struct vpx_internal_error_info {
vpx_codec_err_t error_code;
int has_detail;
char detail[80];
int setjmp;
jmp_buf jmp;
};
#define CLANG_ANALYZER_NORETURN
#if defined(__has_feature)
#if __has_feature(attribute_analyzer_noreturn)
#undef CLANG_ANALYZER_NORETURN
#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
#endif
#endif
void vpx_internal_error(struct vpx_internal_error_info *info,
vpx_codec_err_t error,
const char *fmt,
...) CLANG_ANALYZER_NORETURN;
#ifdef __cplusplus
} // extern "C"
#endif
#endif // VPX_INTERNAL_VPX_CODEC_INTERNAL_H_

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef VPX_INTERNAL_VPX_PSNR_H_
#define VPX_INTERNAL_VPX_PSNR_H_
#ifdef __cplusplus
extern "C" {
#endif
// TODO(dkovalev) change vpx_sse_to_psnr signature: double -> int64_t
/*!\brief Converts SSE to PSNR
*
* Converts sum of squared errros (SSE) to peak signal-to-noise ratio (PNSR).
*
* \param[in] samples Number of samples
* \param[in] peak Max sample value
* \param[in] sse Sum of squared errors
*/
double vpx_sse_to_psnr(double samples, double peak, double sse);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // VPX_INTERNAL_VPX_PSNR_H_

View file

@ -0,0 +1,663 @@
/*
* Copyright (c) 2013 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/**
* @file
* VP9 SVC encoding support via libvpx
*/
#include <assert.h>
#include <math.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define VPX_DISABLE_CTRL_TYPECHECKS 1
#include "./vpx_config.h"
#include "vpx/svc_context.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#include "vpx_mem/vpx_mem.h"
#include "vp9/common/vp9_onyxc_int.h"
#ifdef __MINGW32__
#define strtok_r strtok_s
#ifndef MINGW_HAS_SECURE_API
// proto from /usr/x86_64-w64-mingw32/include/sec_api/string_s.h
_CRTIMP char *__cdecl strtok_s(char *str, const char *delim, char **context);
#endif /* MINGW_HAS_SECURE_API */
#endif /* __MINGW32__ */
#ifdef _MSC_VER
#define strdup _strdup
#define strtok_r strtok_s
#endif
#define SVC_REFERENCE_FRAMES 8
#define SUPERFRAME_SLOTS (8)
#define SUPERFRAME_BUFFER_SIZE (SUPERFRAME_SLOTS * sizeof(uint32_t) + 2)
#define MAX_QUANTIZER 63
static const int DEFAULT_SCALE_FACTORS_NUM[VPX_SS_MAX_LAYERS] = {
4, 5, 7, 11, 16
};
static const int DEFAULT_SCALE_FACTORS_DEN[VPX_SS_MAX_LAYERS] = {
16, 16, 16, 16, 16
};
typedef enum {
QUANTIZER = 0,
BITRATE,
SCALE_FACTOR,
AUTO_ALT_REF,
ALL_OPTION_TYPES
} LAYER_OPTION_TYPE;
static const int option_max_values[ALL_OPTION_TYPES] = {
63, INT_MAX, INT_MAX, 1
};
static const int option_min_values[ALL_OPTION_TYPES] = {
0, 0, 1, 0
};
// One encoded frame
typedef struct FrameData {
void *buf; // compressed data buffer
size_t size; // length of compressed data
vpx_codec_frame_flags_t flags; /**< flags for this frame */
struct FrameData *next;
} FrameData;
static SvcInternal_t *get_svc_internal(SvcContext *svc_ctx) {
if (svc_ctx == NULL) return NULL;
if (svc_ctx->internal == NULL) {
SvcInternal_t *const si = (SvcInternal_t *)malloc(sizeof(*si));
if (si != NULL) {
memset(si, 0, sizeof(*si));
}
svc_ctx->internal = si;
}
return (SvcInternal_t *)svc_ctx->internal;
}
static const SvcInternal_t *get_const_svc_internal(
const SvcContext *svc_ctx) {
if (svc_ctx == NULL) return NULL;
return (const SvcInternal_t *)svc_ctx->internal;
}
static void svc_log_reset(SvcContext *svc_ctx) {
SvcInternal_t *const si = (SvcInternal_t *)svc_ctx->internal;
si->message_buffer[0] = '\0';
}
static int svc_log(SvcContext *svc_ctx, SVC_LOG_LEVEL level,
const char *fmt, ...) {
char buf[512];
int retval = 0;
va_list ap;
SvcInternal_t *const si = get_svc_internal(svc_ctx);
if (level > svc_ctx->log_level) {
return retval;
}
va_start(ap, fmt);
retval = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
if (svc_ctx->log_print) {
printf("%s", buf);
} else {
strncat(si->message_buffer, buf,
sizeof(si->message_buffer) - strlen(si->message_buffer) - 1);
}
if (level == SVC_LOG_ERROR) {
si->codec_ctx->err_detail = si->message_buffer;
}
return retval;
}
static vpx_codec_err_t extract_option(LAYER_OPTION_TYPE type,
char *input,
int *value0,
int *value1) {
if (type == SCALE_FACTOR) {
*value0 = strtol(input, &input, 10);
if (*input++ != '/')
return VPX_CODEC_INVALID_PARAM;
*value1 = strtol(input, &input, 10);
if (*value0 < option_min_values[SCALE_FACTOR] ||
*value1 < option_min_values[SCALE_FACTOR] ||
*value0 > option_max_values[SCALE_FACTOR] ||
*value1 > option_max_values[SCALE_FACTOR] ||
*value0 > *value1) // num shouldn't be greater than den
return VPX_CODEC_INVALID_PARAM;
} else {
*value0 = atoi(input);
if (*value0 < option_min_values[type] ||
*value0 > option_max_values[type])
return VPX_CODEC_INVALID_PARAM;
}
return VPX_CODEC_OK;
}
static vpx_codec_err_t parse_layer_options_from_string(SvcContext *svc_ctx,
LAYER_OPTION_TYPE type,
const char *input,
int *option0,
int *option1) {
int i;
vpx_codec_err_t res = VPX_CODEC_OK;
char *input_string;
char *token;
const char *delim = ",";
char *save_ptr;
if (input == NULL || option0 == NULL ||
(option1 == NULL && type == SCALE_FACTOR))
return VPX_CODEC_INVALID_PARAM;
input_string = strdup(input);
token = strtok_r(input_string, delim, &save_ptr);
for (i = 0; i < svc_ctx->spatial_layers; ++i) {
if (token != NULL) {
res = extract_option(type, token, option0 + i, option1 + i);
if (res != VPX_CODEC_OK)
break;
token = strtok_r(NULL, delim, &save_ptr);
} else {
break;
}
}
if (res == VPX_CODEC_OK && i != svc_ctx->spatial_layers) {
svc_log(svc_ctx, SVC_LOG_ERROR,
"svc: layer params type: %d %d values required, "
"but only %d specified\n", type, svc_ctx->spatial_layers, i);
res = VPX_CODEC_INVALID_PARAM;
}
free(input_string);
return res;
}
/**
* Parse SVC encoding options
* Format: encoding-mode=<svc_mode>,layers=<layer_count>
* scale-factors=<n1>/<d1>,<n2>/<d2>,...
* quantizers=<q1>,<q2>,...
* svc_mode = [i|ip|alt_ip|gf]
*/
static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) {
char *input_string;
char *option_name;
char *option_value;
char *input_ptr;
SvcInternal_t *const si = get_svc_internal(svc_ctx);
vpx_codec_err_t res = VPX_CODEC_OK;
int i, alt_ref_enabled = 0;
if (options == NULL) return VPX_CODEC_OK;
input_string = strdup(options);
// parse option name
option_name = strtok_r(input_string, "=", &input_ptr);
while (option_name != NULL) {
// parse option value
option_value = strtok_r(NULL, " ", &input_ptr);
if (option_value == NULL) {
svc_log(svc_ctx, SVC_LOG_ERROR, "option missing value: %s\n",
option_name);
res = VPX_CODEC_INVALID_PARAM;
break;
}
if (strcmp("spatial-layers", option_name) == 0) {
svc_ctx->spatial_layers = atoi(option_value);
} else if (strcmp("temporal-layers", option_name) == 0) {
svc_ctx->temporal_layers = atoi(option_value);
} else if (strcmp("scale-factors", option_name) == 0) {
res = parse_layer_options_from_string(svc_ctx, SCALE_FACTOR, option_value,
si->svc_params.scaling_factor_num,
si->svc_params.scaling_factor_den);
if (res != VPX_CODEC_OK) break;
} else if (strcmp("max-quantizers", option_name) == 0) {
res = parse_layer_options_from_string(svc_ctx, QUANTIZER, option_value,
si->svc_params.max_quantizers,
NULL);
if (res != VPX_CODEC_OK) break;
} else if (strcmp("min-quantizers", option_name) == 0) {
res = parse_layer_options_from_string(svc_ctx, QUANTIZER, option_value,
si->svc_params.min_quantizers,
NULL);
if (res != VPX_CODEC_OK) break;
} else if (strcmp("auto-alt-refs", option_name) == 0) {
res = parse_layer_options_from_string(svc_ctx, AUTO_ALT_REF, option_value,
si->enable_auto_alt_ref, NULL);
if (res != VPX_CODEC_OK) break;
} else if (strcmp("bitrates", option_name) == 0) {
res = parse_layer_options_from_string(svc_ctx, BITRATE, option_value,
si->bitrates, NULL);
if (res != VPX_CODEC_OK) break;
} else if (strcmp("multi-frame-contexts", option_name) == 0) {
si->use_multiple_frame_contexts = atoi(option_value);
} else {
svc_log(svc_ctx, SVC_LOG_ERROR, "invalid option: %s\n", option_name);
res = VPX_CODEC_INVALID_PARAM;
break;
}
option_name = strtok_r(NULL, "=", &input_ptr);
}
free(input_string);
for (i = 0; i < svc_ctx->spatial_layers; ++i) {
if (si->svc_params.max_quantizers[i] > MAX_QUANTIZER ||
si->svc_params.max_quantizers[i] < 0 ||
si->svc_params.min_quantizers[i] > si->svc_params.max_quantizers[i] ||
si->svc_params.min_quantizers[i] < 0)
res = VPX_CODEC_INVALID_PARAM;
}
if (si->use_multiple_frame_contexts &&
(svc_ctx->spatial_layers > 3 ||
svc_ctx->spatial_layers * svc_ctx->temporal_layers > 4))
res = VPX_CODEC_INVALID_PARAM;
for (i = 0; i < svc_ctx->spatial_layers; ++i)
alt_ref_enabled += si->enable_auto_alt_ref[i];
if (alt_ref_enabled > REF_FRAMES - svc_ctx->spatial_layers) {
svc_log(svc_ctx, SVC_LOG_ERROR,
"svc: auto alt ref: Maxinum %d(REF_FRAMES - layers) layers could"
"enabled auto alt reference frame, but % layers are enabled\n",
REF_FRAMES - svc_ctx->spatial_layers, alt_ref_enabled);
res = VPX_CODEC_INVALID_PARAM;
}
return res;
}
vpx_codec_err_t vpx_svc_set_options(SvcContext *svc_ctx,
const char *options) {
SvcInternal_t *const si = get_svc_internal(svc_ctx);
if (svc_ctx == NULL || options == NULL || si == NULL) {
return VPX_CODEC_INVALID_PARAM;
}
strncpy(si->options, options, sizeof(si->options));
si->options[sizeof(si->options) - 1] = '\0';
return VPX_CODEC_OK;
}
void assign_layer_bitrates(const SvcContext *svc_ctx,
vpx_codec_enc_cfg_t *const enc_cfg) {
int i;
const SvcInternal_t *const si = get_const_svc_internal(svc_ctx);
int sl, tl, spatial_layer_target;
if (svc_ctx->temporal_layering_mode != 0) {
if (si->bitrates[0] != 0) {
enc_cfg->rc_target_bitrate = 0;
for (sl = 0; sl < svc_ctx->spatial_layers; ++sl) {
enc_cfg->ss_target_bitrate[sl*svc_ctx->temporal_layers] = 0;
for (tl = 0; tl < svc_ctx->temporal_layers; ++tl) {
enc_cfg->ss_target_bitrate[sl*svc_ctx->temporal_layers]
+= (unsigned int)si->bitrates[sl * svc_ctx->temporal_layers + tl];
enc_cfg->layer_target_bitrate[sl*svc_ctx->temporal_layers + tl]
= si->bitrates[sl * svc_ctx->temporal_layers + tl];
}
}
} else {
float total = 0;
float alloc_ratio[VPX_MAX_LAYERS] = {0};
for (sl = 0; sl < svc_ctx->spatial_layers; ++sl) {
if (si->svc_params.scaling_factor_den[sl] > 0) {
alloc_ratio[sl] = (float)(si->svc_params.scaling_factor_num[sl] *
1.0 / si->svc_params.scaling_factor_den[sl]);
total += alloc_ratio[sl];
}
}
for (sl = 0; sl < svc_ctx->spatial_layers; ++sl) {
enc_cfg->ss_target_bitrate[sl] = spatial_layer_target =
(unsigned int)(enc_cfg->rc_target_bitrate *
alloc_ratio[sl] / total);
if (svc_ctx->temporal_layering_mode == 3) {
enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers] =
spatial_layer_target >> 1;
enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers + 1] =
(spatial_layer_target >> 1) + (spatial_layer_target >> 2);
enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers + 2] =
spatial_layer_target;
} else if (svc_ctx->temporal_layering_mode == 2) {
enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers] =
spatial_layer_target * 2 / 3;
enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers + 1] =
spatial_layer_target;
} else {
// User should explicitly assign bitrates in this case.
assert(0);
}
}
}
} else {
if (si->bitrates[0] != 0) {
enc_cfg->rc_target_bitrate = 0;
for (i = 0; i < svc_ctx->spatial_layers; ++i) {
enc_cfg->ss_target_bitrate[i] = (unsigned int)si->bitrates[i];
enc_cfg->rc_target_bitrate += si->bitrates[i];
}
} else {
float total = 0;
float alloc_ratio[VPX_MAX_LAYERS] = {0};
for (i = 0; i < svc_ctx->spatial_layers; ++i) {
if (si->svc_params.scaling_factor_den[i] > 0) {
alloc_ratio[i] = (float)(si->svc_params.scaling_factor_num[i] * 1.0 /
si->svc_params.scaling_factor_den[i]);
alloc_ratio[i] *= alloc_ratio[i];
total += alloc_ratio[i];
}
}
for (i = 0; i < VPX_SS_MAX_LAYERS; ++i) {
if (total > 0) {
enc_cfg->layer_target_bitrate[i] = (unsigned int)
(enc_cfg->rc_target_bitrate * alloc_ratio[i] / total);
}
}
}
}
}
vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
vpx_codec_iface_t *iface,
vpx_codec_enc_cfg_t *enc_cfg) {
vpx_codec_err_t res;
int i;
SvcInternal_t *const si = get_svc_internal(svc_ctx);
if (svc_ctx == NULL || codec_ctx == NULL || iface == NULL ||
enc_cfg == NULL) {
return VPX_CODEC_INVALID_PARAM;
}
if (si == NULL) return VPX_CODEC_MEM_ERROR;
si->codec_ctx = codec_ctx;
si->width = enc_cfg->g_w;
si->height = enc_cfg->g_h;
if (enc_cfg->kf_max_dist < 2) {
svc_log(svc_ctx, SVC_LOG_ERROR, "key frame distance too small: %d\n",
enc_cfg->kf_max_dist);
return VPX_CODEC_INVALID_PARAM;
}
si->kf_dist = enc_cfg->kf_max_dist;
if (svc_ctx->spatial_layers == 0)
svc_ctx->spatial_layers = VPX_SS_DEFAULT_LAYERS;
if (svc_ctx->spatial_layers < 1 ||
svc_ctx->spatial_layers > VPX_SS_MAX_LAYERS) {
svc_log(svc_ctx, SVC_LOG_ERROR, "spatial layers: invalid value: %d\n",
svc_ctx->spatial_layers);
return VPX_CODEC_INVALID_PARAM;
}
// Note: temporal_layering_mode only applies to one-pass CBR
// si->svc_params.temporal_layering_mode = svc_ctx->temporal_layering_mode;
if (svc_ctx->temporal_layering_mode == 3) {
svc_ctx->temporal_layers = 3;
} else if (svc_ctx->temporal_layering_mode == 2) {
svc_ctx->temporal_layers = 2;
}
for (i = 0; i < VPX_SS_MAX_LAYERS; ++i) {
si->svc_params.max_quantizers[i] = MAX_QUANTIZER;
si->svc_params.min_quantizers[i] = 0;
si->svc_params.scaling_factor_num[i] = DEFAULT_SCALE_FACTORS_NUM[i];
si->svc_params.scaling_factor_den[i] = DEFAULT_SCALE_FACTORS_DEN[i];
}
// Parse aggregate command line options. Options must start with
// "layers=xx" then followed by other options
res = parse_options(svc_ctx, si->options);
if (res != VPX_CODEC_OK) return res;
if (svc_ctx->spatial_layers < 1)
svc_ctx->spatial_layers = 1;
if (svc_ctx->spatial_layers > VPX_SS_MAX_LAYERS)
svc_ctx->spatial_layers = VPX_SS_MAX_LAYERS;
if (svc_ctx->temporal_layers < 1)
svc_ctx->temporal_layers = 1;
if (svc_ctx->temporal_layers > VPX_TS_MAX_LAYERS)
svc_ctx->temporal_layers = VPX_TS_MAX_LAYERS;
if (svc_ctx->temporal_layers * svc_ctx->spatial_layers > VPX_MAX_LAYERS) {
svc_log(svc_ctx, SVC_LOG_ERROR,
"spatial layers * temporal layers exceeds the maximum number of "
"allowed layers of %d\n",
svc_ctx->spatial_layers * svc_ctx->temporal_layers,
(int) VPX_MAX_LAYERS);
return VPX_CODEC_INVALID_PARAM;
}
assign_layer_bitrates(svc_ctx, enc_cfg);
#if CONFIG_SPATIAL_SVC
for (i = 0; i < svc_ctx->spatial_layers; ++i)
enc_cfg->ss_enable_auto_alt_ref[i] = si->enable_auto_alt_ref[i];
#endif
if (svc_ctx->temporal_layers > 1) {
int i;
for (i = 0; i < svc_ctx->temporal_layers; ++i) {
enc_cfg->ts_target_bitrate[i] = enc_cfg->rc_target_bitrate /
svc_ctx->temporal_layers;
enc_cfg->ts_rate_decimator[i] = 1 << (svc_ctx->temporal_layers - 1 - i);
}
}
if (svc_ctx->threads)
enc_cfg->g_threads = svc_ctx->threads;
// Modify encoder configuration
enc_cfg->ss_number_layers = svc_ctx->spatial_layers;
enc_cfg->ts_number_layers = svc_ctx->temporal_layers;
if (enc_cfg->rc_end_usage == VPX_CBR) {
enc_cfg->rc_resize_allowed = 0;
enc_cfg->rc_min_quantizer = 2;
enc_cfg->rc_max_quantizer = 63;
enc_cfg->rc_undershoot_pct = 50;
enc_cfg->rc_overshoot_pct = 50;
enc_cfg->rc_buf_initial_sz = 20;
enc_cfg->rc_buf_optimal_sz = 600;
enc_cfg->rc_buf_sz = 1000;
}
if (enc_cfg->g_error_resilient == 0 && si->use_multiple_frame_contexts == 0)
enc_cfg->g_error_resilient = 1;
// Initialize codec
res = vpx_codec_enc_init(codec_ctx, iface, enc_cfg, VPX_CODEC_USE_PSNR);
if (res != VPX_CODEC_OK) {
svc_log(svc_ctx, SVC_LOG_ERROR, "svc_enc_init error\n");
return res;
}
vpx_codec_control(codec_ctx, VP9E_SET_SVC, 1);
vpx_codec_control(codec_ctx, VP9E_SET_SVC_PARAMETERS, &si->svc_params);
return VPX_CODEC_OK;
}
/**
* Encode a frame into multiple layers
* Create a superframe containing the individual layers
*/
vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx,
vpx_codec_ctx_t *codec_ctx,
struct vpx_image *rawimg,
vpx_codec_pts_t pts,
int64_t duration, int deadline) {
vpx_codec_err_t res;
vpx_codec_iter_t iter;
const vpx_codec_cx_pkt_t *cx_pkt;
SvcInternal_t *const si = get_svc_internal(svc_ctx);
if (svc_ctx == NULL || codec_ctx == NULL || si == NULL) {
return VPX_CODEC_INVALID_PARAM;
}
svc_log_reset(svc_ctx);
res = vpx_codec_encode(codec_ctx, rawimg, pts, (uint32_t)duration, 0,
deadline);
if (res != VPX_CODEC_OK) {
return res;
}
// save compressed data
iter = NULL;
while ((cx_pkt = vpx_codec_get_cx_data(codec_ctx, &iter))) {
switch (cx_pkt->kind) {
#if VPX_ENCODER_ABI_VERSION > (5 + VPX_CODEC_ABI_VERSION)
#if CONFIG_SPATIAL_SVC
case VPX_CODEC_SPATIAL_SVC_LAYER_PSNR: {
int i;
for (i = 0; i < svc_ctx->spatial_layers; ++i) {
int j;
svc_log(svc_ctx, SVC_LOG_DEBUG,
"SVC frame: %d, layer: %d, PSNR(Total/Y/U/V): "
"%2.3f %2.3f %2.3f %2.3f \n",
si->psnr_pkt_received, i,
cx_pkt->data.layer_psnr[i].psnr[0],
cx_pkt->data.layer_psnr[i].psnr[1],
cx_pkt->data.layer_psnr[i].psnr[2],
cx_pkt->data.layer_psnr[i].psnr[3]);
svc_log(svc_ctx, SVC_LOG_DEBUG,
"SVC frame: %d, layer: %d, SSE(Total/Y/U/V): "
"%2.3f %2.3f %2.3f %2.3f \n",
si->psnr_pkt_received, i,
cx_pkt->data.layer_psnr[i].sse[0],
cx_pkt->data.layer_psnr[i].sse[1],
cx_pkt->data.layer_psnr[i].sse[2],
cx_pkt->data.layer_psnr[i].sse[3]);
for (j = 0; j < COMPONENTS; ++j) {
si->psnr_sum[i][j] +=
cx_pkt->data.layer_psnr[i].psnr[j];
si->sse_sum[i][j] += cx_pkt->data.layer_psnr[i].sse[j];
}
}
++si->psnr_pkt_received;
break;
}
case VPX_CODEC_SPATIAL_SVC_LAYER_SIZES: {
int i;
for (i = 0; i < svc_ctx->spatial_layers; ++i)
si->bytes_sum[i] += cx_pkt->data.layer_sizes[i];
break;
}
#endif
#endif
default: {
break;
}
}
}
return VPX_CODEC_OK;
}
const char *vpx_svc_get_message(const SvcContext *svc_ctx) {
const SvcInternal_t *const si = get_const_svc_internal(svc_ctx);
if (svc_ctx == NULL || si == NULL) return NULL;
return si->message_buffer;
}
static double calc_psnr(double d) {
if (d == 0) return 100;
return -10.0 * log(d) / log(10.0);
}
// dump accumulated statistics and reset accumulated values
const char *vpx_svc_dump_statistics(SvcContext *svc_ctx) {
int number_of_frames;
int i, j;
uint32_t bytes_total = 0;
double scale[COMPONENTS];
double psnr[COMPONENTS];
double mse[COMPONENTS];
double y_scale;
SvcInternal_t *const si = get_svc_internal(svc_ctx);
if (svc_ctx == NULL || si == NULL) return NULL;
svc_log_reset(svc_ctx);
number_of_frames = si->psnr_pkt_received;
if (number_of_frames <= 0) return vpx_svc_get_message(svc_ctx);
svc_log(svc_ctx, SVC_LOG_INFO, "\n");
for (i = 0; i < svc_ctx->spatial_layers; ++i) {
svc_log(svc_ctx, SVC_LOG_INFO,
"Layer %d Average PSNR=[%2.3f, %2.3f, %2.3f, %2.3f], Bytes=[%u]\n",
i, (double)si->psnr_sum[i][0] / number_of_frames,
(double)si->psnr_sum[i][1] / number_of_frames,
(double)si->psnr_sum[i][2] / number_of_frames,
(double)si->psnr_sum[i][3] / number_of_frames, si->bytes_sum[i]);
// the following psnr calculation is deduced from ffmpeg.c#print_report
y_scale = si->width * si->height * 255.0 * 255.0 * number_of_frames;
scale[1] = y_scale;
scale[2] = scale[3] = y_scale / 4; // U or V
scale[0] = y_scale * 1.5; // total
for (j = 0; j < COMPONENTS; j++) {
psnr[j] = calc_psnr(si->sse_sum[i][j] / scale[j]);
mse[j] = si->sse_sum[i][j] * 255.0 * 255.0 / scale[j];
}
svc_log(svc_ctx, SVC_LOG_INFO,
"Layer %d Overall PSNR=[%2.3f, %2.3f, %2.3f, %2.3f]\n", i, psnr[0],
psnr[1], psnr[2], psnr[3]);
svc_log(svc_ctx, SVC_LOG_INFO,
"Layer %d Overall MSE=[%2.3f, %2.3f, %2.3f, %2.3f]\n", i, mse[0],
mse[1], mse[2], mse[3]);
bytes_total += si->bytes_sum[i];
// Clear sums for next time.
si->bytes_sum[i] = 0;
for (j = 0; j < COMPONENTS; ++j) {
si->psnr_sum[i][j] = 0;
si->sse_sum[i][j] = 0;
}
}
// only display statistics once
si->psnr_pkt_received = 0;
svc_log(svc_ctx, SVC_LOG_INFO, "Total Bytes=[%u]\n", bytes_total);
return vpx_svc_get_message(svc_ctx);
}
void vpx_svc_release(SvcContext *svc_ctx) {
SvcInternal_t *si;
if (svc_ctx == NULL) return;
// do not use get_svc_internal as it will unnecessarily allocate an
// SvcInternal_t if it was not already allocated
si = (SvcInternal_t *)svc_ctx->internal;
if (si != NULL) {
free(si);
svc_ctx->internal = NULL;
}
}

View file

@ -0,0 +1,158 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*!\file
* \brief Provides the high level interface to wrap decoder algorithms.
*
*/
#include <stdarg.h>
#include <stdlib.h>
#include "vpx/vpx_integer.h"
#include "vpx/internal/vpx_codec_internal.h"
#include "vpx_version.h"
#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
int vpx_codec_version(void) {
return VERSION_PACKED;
}
const char *vpx_codec_version_str(void) {
return VERSION_STRING_NOSP;
}
const char *vpx_codec_version_extra_str(void) {
return VERSION_EXTRA;
}
const char *vpx_codec_iface_name(vpx_codec_iface_t *iface) {
return iface ? iface->name : "<invalid interface>";
}
const char *vpx_codec_err_to_string(vpx_codec_err_t err) {
switch (err) {
case VPX_CODEC_OK:
return "Success";
case VPX_CODEC_ERROR:
return "Unspecified internal error";
case VPX_CODEC_MEM_ERROR:
return "Memory allocation error";
case VPX_CODEC_ABI_MISMATCH:
return "ABI version mismatch";
case VPX_CODEC_INCAPABLE:
return "Codec does not implement requested capability";
case VPX_CODEC_UNSUP_BITSTREAM:
return "Bitstream not supported by this decoder";
case VPX_CODEC_UNSUP_FEATURE:
return "Bitstream required feature not supported by this decoder";
case VPX_CODEC_CORRUPT_FRAME:
return "Corrupt frame detected";
case VPX_CODEC_INVALID_PARAM:
return "Invalid parameter";
case VPX_CODEC_LIST_END:
return "End of iterated list";
}
return "Unrecognized error code";
}
const char *vpx_codec_error(vpx_codec_ctx_t *ctx) {
return (ctx) ? vpx_codec_err_to_string(ctx->err)
: vpx_codec_err_to_string(VPX_CODEC_INVALID_PARAM);
}
const char *vpx_codec_error_detail(vpx_codec_ctx_t *ctx) {
if (ctx && ctx->err)
return ctx->priv ? ctx->priv->err_detail : ctx->err_detail;
return NULL;
}
vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx) {
vpx_codec_err_t res;
if (!ctx)
res = VPX_CODEC_INVALID_PARAM;
else if (!ctx->iface || !ctx->priv)
res = VPX_CODEC_ERROR;
else {
ctx->iface->destroy((vpx_codec_alg_priv_t *)ctx->priv);
ctx->iface = NULL;
ctx->name = NULL;
ctx->priv = NULL;
res = VPX_CODEC_OK;
}
return SAVE_STATUS(ctx, res);
}
vpx_codec_caps_t vpx_codec_get_caps(vpx_codec_iface_t *iface) {
return (iface) ? iface->caps : 0;
}
vpx_codec_err_t vpx_codec_control_(vpx_codec_ctx_t *ctx,
int ctrl_id,
...) {
vpx_codec_err_t res;
if (!ctx || !ctrl_id)
res = VPX_CODEC_INVALID_PARAM;
else if (!ctx->iface || !ctx->priv || !ctx->iface->ctrl_maps)
res = VPX_CODEC_ERROR;
else {
vpx_codec_ctrl_fn_map_t *entry;
res = VPX_CODEC_ERROR;
for (entry = ctx->iface->ctrl_maps; entry && entry->fn; entry++) {
if (!entry->ctrl_id || entry->ctrl_id == ctrl_id) {
va_list ap;
va_start(ap, ctrl_id);
res = entry->fn((vpx_codec_alg_priv_t *)ctx->priv, ap);
va_end(ap);
break;
}
}
}
return SAVE_STATUS(ctx, res);
}
void vpx_internal_error(struct vpx_internal_error_info *info,
vpx_codec_err_t error,
const char *fmt,
...) {
va_list ap;
info->error_code = error;
info->has_detail = 0;
if (fmt) {
size_t sz = sizeof(info->detail);
info->has_detail = 1;
va_start(ap, fmt);
vsnprintf(info->detail, sz - 1, fmt, ap);
va_end(ap);
info->detail[sz - 1] = '\0';
}
if (info->setjmp)
longjmp(info->jmp, info->error_code);
}

View file

@ -0,0 +1,197 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*!\file
* \brief Provides the high level interface to wrap decoder algorithms.
*
*/
#include <string.h>
#include "vpx/internal/vpx_codec_internal.h"
#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
static vpx_codec_alg_priv_t *get_alg_priv(vpx_codec_ctx_t *ctx) {
return (vpx_codec_alg_priv_t *)ctx->priv;
}
vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t *ctx,
vpx_codec_iface_t *iface,
const vpx_codec_dec_cfg_t *cfg,
vpx_codec_flags_t flags,
int ver) {
vpx_codec_err_t res;
if (ver != VPX_DECODER_ABI_VERSION)
res = VPX_CODEC_ABI_MISMATCH;
else if (!ctx || !iface)
res = VPX_CODEC_INVALID_PARAM;
else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION)
res = VPX_CODEC_ABI_MISMATCH;
else if ((flags & VPX_CODEC_USE_POSTPROC) && !(iface->caps & VPX_CODEC_CAP_POSTPROC))
res = VPX_CODEC_INCAPABLE;
else if ((flags & VPX_CODEC_USE_ERROR_CONCEALMENT) &&
!(iface->caps & VPX_CODEC_CAP_ERROR_CONCEALMENT))
res = VPX_CODEC_INCAPABLE;
else if ((flags & VPX_CODEC_USE_INPUT_FRAGMENTS) &&
!(iface->caps & VPX_CODEC_CAP_INPUT_FRAGMENTS))
res = VPX_CODEC_INCAPABLE;
else if (!(iface->caps & VPX_CODEC_CAP_DECODER))
res = VPX_CODEC_INCAPABLE;
else {
memset(ctx, 0, sizeof(*ctx));
ctx->iface = iface;
ctx->name = iface->name;
ctx->priv = NULL;
ctx->init_flags = flags;
ctx->config.dec = cfg;
res = ctx->iface->init(ctx, NULL);
if (res) {
ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
vpx_codec_destroy(ctx);
}
}
return SAVE_STATUS(ctx, res);
}
vpx_codec_err_t vpx_codec_peek_stream_info(vpx_codec_iface_t *iface,
const uint8_t *data,
unsigned int data_sz,
vpx_codec_stream_info_t *si) {
vpx_codec_err_t res;
if (!iface || !data || !data_sz || !si
|| si->sz < sizeof(vpx_codec_stream_info_t))
res = VPX_CODEC_INVALID_PARAM;
else {
/* Set default/unknown values */
si->w = 0;
si->h = 0;
res = iface->dec.peek_si(data, data_sz, si);
}
return res;
}
vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t *ctx,
vpx_codec_stream_info_t *si) {
vpx_codec_err_t res;
if (!ctx || !si || si->sz < sizeof(vpx_codec_stream_info_t))
res = VPX_CODEC_INVALID_PARAM;
else if (!ctx->iface || !ctx->priv)
res = VPX_CODEC_ERROR;
else {
/* Set default/unknown values */
si->w = 0;
si->h = 0;
res = ctx->iface->dec.get_si(get_alg_priv(ctx), si);
}
return SAVE_STATUS(ctx, res);
}
vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx,
const uint8_t *data,
unsigned int data_sz,
void *user_priv,
long deadline) {
vpx_codec_err_t res;
/* Sanity checks */
/* NULL data ptr allowed if data_sz is 0 too */
if (!ctx || (!data && data_sz) || (data && !data_sz))
res = VPX_CODEC_INVALID_PARAM;
else if (!ctx->iface || !ctx->priv)
res = VPX_CODEC_ERROR;
else {
res = ctx->iface->dec.decode(get_alg_priv(ctx), data, data_sz, user_priv,
deadline);
}
return SAVE_STATUS(ctx, res);
}
vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t *ctx,
vpx_codec_iter_t *iter) {
vpx_image_t *img;
if (!ctx || !iter || !ctx->iface || !ctx->priv)
img = NULL;
else
img = ctx->iface->dec.get_frame(get_alg_priv(ctx), iter);
return img;
}
vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t *ctx,
vpx_codec_put_frame_cb_fn_t cb,
void *user_priv) {
vpx_codec_err_t res;
if (!ctx || !cb)
res = VPX_CODEC_INVALID_PARAM;
else if (!ctx->iface || !ctx->priv
|| !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
res = VPX_CODEC_ERROR;
else {
ctx->priv->dec.put_frame_cb.u.put_frame = cb;
ctx->priv->dec.put_frame_cb.user_priv = user_priv;
res = VPX_CODEC_OK;
}
return SAVE_STATUS(ctx, res);
}
vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t *ctx,
vpx_codec_put_slice_cb_fn_t cb,
void *user_priv) {
vpx_codec_err_t res;
if (!ctx || !cb)
res = VPX_CODEC_INVALID_PARAM;
else if (!ctx->iface || !ctx->priv
|| !(ctx->iface->caps & VPX_CODEC_CAP_PUT_SLICE))
res = VPX_CODEC_ERROR;
else {
ctx->priv->dec.put_slice_cb.u.put_slice = cb;
ctx->priv->dec.put_slice_cb.user_priv = user_priv;
res = VPX_CODEC_OK;
}
return SAVE_STATUS(ctx, res);
}
vpx_codec_err_t vpx_codec_set_frame_buffer_functions(
vpx_codec_ctx_t *ctx, vpx_get_frame_buffer_cb_fn_t cb_get,
vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
vpx_codec_err_t res;
if (!ctx || !cb_get || !cb_release) {
res = VPX_CODEC_INVALID_PARAM;
} else if (!ctx->iface || !ctx->priv ||
!(ctx->iface->caps & VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER)) {
res = VPX_CODEC_ERROR;
} else {
res = ctx->iface->dec.set_fb_fn(get_alg_priv(ctx), cb_get, cb_release,
cb_priv);
}
return SAVE_STATUS(ctx, res);
}

View file

@ -0,0 +1,401 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*!\file
* \brief Provides the high level interface to wrap encoder algorithms.
*
*/
#include <limits.h>
#include <string.h>
#include "vpx_config.h"
#include "vpx/internal/vpx_codec_internal.h"
#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
static vpx_codec_alg_priv_t *get_alg_priv(vpx_codec_ctx_t *ctx) {
return (vpx_codec_alg_priv_t *)ctx->priv;
}
vpx_codec_err_t vpx_codec_enc_init_ver(vpx_codec_ctx_t *ctx,
vpx_codec_iface_t *iface,
const vpx_codec_enc_cfg_t *cfg,
vpx_codec_flags_t flags,
int ver) {
vpx_codec_err_t res;
if (ver != VPX_ENCODER_ABI_VERSION)
res = VPX_CODEC_ABI_MISMATCH;
else if (!ctx || !iface || !cfg)
res = VPX_CODEC_INVALID_PARAM;
else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION)
res = VPX_CODEC_ABI_MISMATCH;
else if (!(iface->caps & VPX_CODEC_CAP_ENCODER))
res = VPX_CODEC_INCAPABLE;
else if ((flags & VPX_CODEC_USE_PSNR)
&& !(iface->caps & VPX_CODEC_CAP_PSNR))
res = VPX_CODEC_INCAPABLE;
else if ((flags & VPX_CODEC_USE_OUTPUT_PARTITION)
&& !(iface->caps & VPX_CODEC_CAP_OUTPUT_PARTITION))
res = VPX_CODEC_INCAPABLE;
else {
ctx->iface = iface;
ctx->name = iface->name;
ctx->priv = NULL;
ctx->init_flags = flags;
ctx->config.enc = cfg;
res = ctx->iface->init(ctx, NULL);
if (res) {
ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
vpx_codec_destroy(ctx);
}
}
return SAVE_STATUS(ctx, res);
}
vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx,
vpx_codec_iface_t *iface,
vpx_codec_enc_cfg_t *cfg,
int num_enc,
vpx_codec_flags_t flags,
vpx_rational_t *dsf,
int ver) {
vpx_codec_err_t res = VPX_CODEC_OK;
if (ver != VPX_ENCODER_ABI_VERSION)
res = VPX_CODEC_ABI_MISMATCH;
else if (!ctx || !iface || !cfg || (num_enc > 16 || num_enc < 1))
res = VPX_CODEC_INVALID_PARAM;
else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION)
res = VPX_CODEC_ABI_MISMATCH;
else if (!(iface->caps & VPX_CODEC_CAP_ENCODER))
res = VPX_CODEC_INCAPABLE;
else if ((flags & VPX_CODEC_USE_PSNR)
&& !(iface->caps & VPX_CODEC_CAP_PSNR))
res = VPX_CODEC_INCAPABLE;
else if ((flags & VPX_CODEC_USE_OUTPUT_PARTITION)
&& !(iface->caps & VPX_CODEC_CAP_OUTPUT_PARTITION))
res = VPX_CODEC_INCAPABLE;
else {
int i;
void *mem_loc = NULL;
if (!(res = iface->enc.mr_get_mem_loc(cfg, &mem_loc))) {
for (i = 0; i < num_enc; i++) {
vpx_codec_priv_enc_mr_cfg_t mr_cfg;
/* Validate down-sampling factor. */
if (dsf->num < 1 || dsf->num > 4096 || dsf->den < 1 ||
dsf->den > dsf->num) {
res = VPX_CODEC_INVALID_PARAM;
break;
}
mr_cfg.mr_low_res_mode_info = mem_loc;
mr_cfg.mr_total_resolutions = num_enc;
mr_cfg.mr_encoder_id = num_enc - 1 - i;
mr_cfg.mr_down_sampling_factor.num = dsf->num;
mr_cfg.mr_down_sampling_factor.den = dsf->den;
/* Force Key-frame synchronization. Namely, encoder at higher
* resolution always use the same frame_type chosen by the
* lowest-resolution encoder.
*/
if (mr_cfg.mr_encoder_id)
cfg->kf_mode = VPX_KF_DISABLED;
ctx->iface = iface;
ctx->name = iface->name;
ctx->priv = NULL;
ctx->init_flags = flags;
ctx->config.enc = cfg;
res = ctx->iface->init(ctx, &mr_cfg);
if (res) {
const char *error_detail =
ctx->priv ? ctx->priv->err_detail : NULL;
/* Destroy current ctx */
ctx->err_detail = error_detail;
vpx_codec_destroy(ctx);
/* Destroy already allocated high-level ctx */
while (i) {
ctx--;
ctx->err_detail = error_detail;
vpx_codec_destroy(ctx);
i--;
}
}
if (res)
break;
ctx++;
cfg++;
dsf++;
}
ctx--;
}
}
return SAVE_STATUS(ctx, res);
}
vpx_codec_err_t vpx_codec_enc_config_default(vpx_codec_iface_t *iface,
vpx_codec_enc_cfg_t *cfg,
unsigned int usage) {
vpx_codec_err_t res;
vpx_codec_enc_cfg_map_t *map;
int i;
if (!iface || !cfg || usage > INT_MAX)
res = VPX_CODEC_INVALID_PARAM;
else if (!(iface->caps & VPX_CODEC_CAP_ENCODER))
res = VPX_CODEC_INCAPABLE;
else {
res = VPX_CODEC_INVALID_PARAM;
for (i = 0; i < iface->enc.cfg_map_count; ++i) {
map = iface->enc.cfg_maps + i;
if (map->usage == (int)usage) {
*cfg = map->cfg;
cfg->g_usage = usage;
res = VPX_CODEC_OK;
break;
}
}
}
return res;
}
#if ARCH_X86 || ARCH_X86_64
/* On X86, disable the x87 unit's internal 80 bit precision for better
* consistency with the SSE unit's 64 bit precision.
*/
#include "vpx_ports/x86.h"
#define FLOATING_POINT_INIT() do {\
unsigned short x87_orig_mode = x87_set_double_precision();
#define FLOATING_POINT_RESTORE() \
x87_set_control_word(x87_orig_mode); }while(0)
#else
static void FLOATING_POINT_INIT() {}
static void FLOATING_POINT_RESTORE() {}
#endif
vpx_codec_err_t vpx_codec_encode(vpx_codec_ctx_t *ctx,
const vpx_image_t *img,
vpx_codec_pts_t pts,
unsigned long duration,
vpx_enc_frame_flags_t flags,
unsigned long deadline) {
vpx_codec_err_t res = VPX_CODEC_OK;
if (!ctx || (img && !duration))
res = VPX_CODEC_INVALID_PARAM;
else if (!ctx->iface || !ctx->priv)
res = VPX_CODEC_ERROR;
else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
res = VPX_CODEC_INCAPABLE;
else {
unsigned int num_enc = ctx->priv->enc.total_encoders;
/* Execute in a normalized floating point environment, if the platform
* requires it.
*/
FLOATING_POINT_INIT();
if (num_enc == 1)
res = ctx->iface->enc.encode(get_alg_priv(ctx), img, pts,
duration, flags, deadline);
else {
/* Multi-resolution encoding:
* Encode multi-levels in reverse order. For example,
* if mr_total_resolutions = 3, first encode level 2,
* then encode level 1, and finally encode level 0.
*/
int i;
ctx += num_enc - 1;
if (img) img += num_enc - 1;
for (i = num_enc - 1; i >= 0; i--) {
if ((res = ctx->iface->enc.encode(get_alg_priv(ctx), img, pts,
duration, flags, deadline)))
break;
ctx--;
if (img) img--;
}
ctx++;
}
FLOATING_POINT_RESTORE();
}
return SAVE_STATUS(ctx, res);
}
const vpx_codec_cx_pkt_t *vpx_codec_get_cx_data(vpx_codec_ctx_t *ctx,
vpx_codec_iter_t *iter) {
const vpx_codec_cx_pkt_t *pkt = NULL;
if (ctx) {
if (!iter)
ctx->err = VPX_CODEC_INVALID_PARAM;
else if (!ctx->iface || !ctx->priv)
ctx->err = VPX_CODEC_ERROR;
else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
ctx->err = VPX_CODEC_INCAPABLE;
else
pkt = ctx->iface->enc.get_cx_data(get_alg_priv(ctx), iter);
}
if (pkt && pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
// If the application has specified a destination area for the
// compressed data, and the codec has not placed the data there,
// and it fits, copy it.
vpx_codec_priv_t *const priv = ctx->priv;
char *const dst_buf = (char *)priv->enc.cx_data_dst_buf.buf;
if (dst_buf &&
pkt->data.raw.buf != dst_buf &&
pkt->data.raw.sz + priv->enc.cx_data_pad_before +
priv->enc.cx_data_pad_after <= priv->enc.cx_data_dst_buf.sz) {
vpx_codec_cx_pkt_t *modified_pkt = &priv->enc.cx_data_pkt;
memcpy(dst_buf + priv->enc.cx_data_pad_before, pkt->data.raw.buf,
pkt->data.raw.sz);
*modified_pkt = *pkt;
modified_pkt->data.raw.buf = dst_buf;
modified_pkt->data.raw.sz += priv->enc.cx_data_pad_before +
priv->enc.cx_data_pad_after;
pkt = modified_pkt;
}
if (dst_buf == pkt->data.raw.buf) {
priv->enc.cx_data_dst_buf.buf = dst_buf + pkt->data.raw.sz;
priv->enc.cx_data_dst_buf.sz -= pkt->data.raw.sz;
}
}
return pkt;
}
vpx_codec_err_t vpx_codec_set_cx_data_buf(vpx_codec_ctx_t *ctx,
const vpx_fixed_buf_t *buf,
unsigned int pad_before,
unsigned int pad_after) {
if (!ctx || !ctx->priv)
return VPX_CODEC_INVALID_PARAM;
if (buf) {
ctx->priv->enc.cx_data_dst_buf = *buf;
ctx->priv->enc.cx_data_pad_before = pad_before;
ctx->priv->enc.cx_data_pad_after = pad_after;
} else {
ctx->priv->enc.cx_data_dst_buf.buf = NULL;
ctx->priv->enc.cx_data_dst_buf.sz = 0;
ctx->priv->enc.cx_data_pad_before = 0;
ctx->priv->enc.cx_data_pad_after = 0;
}
return VPX_CODEC_OK;
}
const vpx_image_t *vpx_codec_get_preview_frame(vpx_codec_ctx_t *ctx) {
vpx_image_t *img = NULL;
if (ctx) {
if (!ctx->iface || !ctx->priv)
ctx->err = VPX_CODEC_ERROR;
else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
ctx->err = VPX_CODEC_INCAPABLE;
else if (!ctx->iface->enc.get_preview)
ctx->err = VPX_CODEC_INCAPABLE;
else
img = ctx->iface->enc.get_preview(get_alg_priv(ctx));
}
return img;
}
vpx_fixed_buf_t *vpx_codec_get_global_headers(vpx_codec_ctx_t *ctx) {
vpx_fixed_buf_t *buf = NULL;
if (ctx) {
if (!ctx->iface || !ctx->priv)
ctx->err = VPX_CODEC_ERROR;
else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
ctx->err = VPX_CODEC_INCAPABLE;
else if (!ctx->iface->enc.get_glob_hdrs)
ctx->err = VPX_CODEC_INCAPABLE;
else
buf = ctx->iface->enc.get_glob_hdrs(get_alg_priv(ctx));
}
return buf;
}
vpx_codec_err_t vpx_codec_enc_config_set(vpx_codec_ctx_t *ctx,
const vpx_codec_enc_cfg_t *cfg) {
vpx_codec_err_t res;
if (!ctx || !ctx->iface || !ctx->priv || !cfg)
res = VPX_CODEC_INVALID_PARAM;
else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
res = VPX_CODEC_INCAPABLE;
else
res = ctx->iface->enc.cfg_set(get_alg_priv(ctx), cfg);
return SAVE_STATUS(ctx, res);
}
int vpx_codec_pkt_list_add(struct vpx_codec_pkt_list *list,
const struct vpx_codec_cx_pkt *pkt) {
if (list->cnt < list->max) {
list->pkts[list->cnt++] = *pkt;
return 0;
}
return 1;
}
const vpx_codec_cx_pkt_t *vpx_codec_pkt_list_get(struct vpx_codec_pkt_list *list,
vpx_codec_iter_t *iter) {
const vpx_codec_cx_pkt_t *pkt;
if (!(*iter)) {
*iter = list->pkts;
}
pkt = (const vpx_codec_cx_pkt_t *)*iter;
if ((size_t)(pkt - list->pkts) < list->cnt)
*iter = pkt + 1;
else
pkt = NULL;
return pkt;
}

View file

@ -0,0 +1,285 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <stdlib.h>
#include <string.h>
#include "vpx/vpx_image.h"
#include "vpx/vpx_integer.h"
#include "vpx_mem/vpx_mem.h"
static vpx_image_t *img_alloc_helper(vpx_image_t *img,
vpx_img_fmt_t fmt,
unsigned int d_w,
unsigned int d_h,
unsigned int buf_align,
unsigned int stride_align,
unsigned char *img_data) {
unsigned int h, w, s, xcs, ycs, bps;
unsigned int stride_in_bytes;
int align;
/* Treat align==0 like align==1 */
if (!buf_align)
buf_align = 1;
/* Validate alignment (must be power of 2) */
if (buf_align & (buf_align - 1))
goto fail;
/* Treat align==0 like align==1 */
if (!stride_align)
stride_align = 1;
/* Validate alignment (must be power of 2) */
if (stride_align & (stride_align - 1))
goto fail;
/* Get sample size for this format */
switch (fmt) {
case VPX_IMG_FMT_RGB32:
case VPX_IMG_FMT_RGB32_LE:
case VPX_IMG_FMT_ARGB:
case VPX_IMG_FMT_ARGB_LE:
bps = 32;
break;
case VPX_IMG_FMT_RGB24:
case VPX_IMG_FMT_BGR24:
bps = 24;
break;
case VPX_IMG_FMT_RGB565:
case VPX_IMG_FMT_RGB565_LE:
case VPX_IMG_FMT_RGB555:
case VPX_IMG_FMT_RGB555_LE:
case VPX_IMG_FMT_UYVY:
case VPX_IMG_FMT_YUY2:
case VPX_IMG_FMT_YVYU:
bps = 16;
break;
case VPX_IMG_FMT_I420:
case VPX_IMG_FMT_YV12:
case VPX_IMG_FMT_VPXI420:
case VPX_IMG_FMT_VPXYV12:
bps = 12;
break;
case VPX_IMG_FMT_I422:
case VPX_IMG_FMT_I440:
bps = 16;
break;
case VPX_IMG_FMT_I444:
bps = 24;
break;
case VPX_IMG_FMT_I42016:
bps = 24;
break;
case VPX_IMG_FMT_I42216:
case VPX_IMG_FMT_I44016:
bps = 32;
break;
case VPX_IMG_FMT_I44416:
bps = 48;
break;
default:
bps = 16;
break;
}
/* Get chroma shift values for this format */
switch (fmt) {
case VPX_IMG_FMT_I420:
case VPX_IMG_FMT_YV12:
case VPX_IMG_FMT_VPXI420:
case VPX_IMG_FMT_VPXYV12:
case VPX_IMG_FMT_I422:
case VPX_IMG_FMT_I42016:
case VPX_IMG_FMT_I42216:
xcs = 1;
break;
default:
xcs = 0;
break;
}
switch (fmt) {
case VPX_IMG_FMT_I420:
case VPX_IMG_FMT_I440:
case VPX_IMG_FMT_YV12:
case VPX_IMG_FMT_VPXI420:
case VPX_IMG_FMT_VPXYV12:
case VPX_IMG_FMT_I42016:
case VPX_IMG_FMT_I44016:
ycs = 1;
break;
default:
ycs = 0;
break;
}
/* Calculate storage sizes given the chroma subsampling */
align = (1 << xcs) - 1;
w = (d_w + align) & ~align;
align = (1 << ycs) - 1;
h = (d_h + align) & ~align;
s = (fmt & VPX_IMG_FMT_PLANAR) ? w : bps * w / 8;
s = (s + stride_align - 1) & ~(stride_align - 1);
stride_in_bytes = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? s * 2 : s;
/* Allocate the new image */
if (!img) {
img = (vpx_image_t *)calloc(1, sizeof(vpx_image_t));
if (!img)
goto fail;
img->self_allocd = 1;
} else {
memset(img, 0, sizeof(vpx_image_t));
}
img->img_data = img_data;
if (!img_data) {
const uint64_t alloc_size = (fmt & VPX_IMG_FMT_PLANAR) ?
(uint64_t)h * s * bps / 8 : (uint64_t)h * s;
if (alloc_size != (size_t)alloc_size)
goto fail;
img->img_data = (uint8_t *)vpx_memalign(buf_align, (size_t)alloc_size);
img->img_data_owner = 1;
}
if (!img->img_data)
goto fail;
img->fmt = fmt;
img->bit_depth = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 16 : 8;
img->w = w;
img->h = h;
img->x_chroma_shift = xcs;
img->y_chroma_shift = ycs;
img->bps = bps;
/* Calculate strides */
img->stride[VPX_PLANE_Y] = img->stride[VPX_PLANE_ALPHA] = stride_in_bytes;
img->stride[VPX_PLANE_U] = img->stride[VPX_PLANE_V] = stride_in_bytes >> xcs;
/* Default viewport to entire image */
if (!vpx_img_set_rect(img, 0, 0, d_w, d_h))
return img;
fail:
vpx_img_free(img);
return NULL;
}
vpx_image_t *vpx_img_alloc(vpx_image_t *img,
vpx_img_fmt_t fmt,
unsigned int d_w,
unsigned int d_h,
unsigned int align) {
return img_alloc_helper(img, fmt, d_w, d_h, align, align, NULL);
}
vpx_image_t *vpx_img_wrap(vpx_image_t *img,
vpx_img_fmt_t fmt,
unsigned int d_w,
unsigned int d_h,
unsigned int stride_align,
unsigned char *img_data) {
/* By setting buf_align = 1, we don't change buffer alignment in this
* function. */
return img_alloc_helper(img, fmt, d_w, d_h, 1, stride_align, img_data);
}
int vpx_img_set_rect(vpx_image_t *img,
unsigned int x,
unsigned int y,
unsigned int w,
unsigned int h) {
unsigned char *data;
if (x + w <= img->w && y + h <= img->h) {
img->d_w = w;
img->d_h = h;
/* Calculate plane pointers */
if (!(img->fmt & VPX_IMG_FMT_PLANAR)) {
img->planes[VPX_PLANE_PACKED] =
img->img_data + x * img->bps / 8 + y * img->stride[VPX_PLANE_PACKED];
} else {
const int bytes_per_sample =
(img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
data = img->img_data;
if (img->fmt & VPX_IMG_FMT_HAS_ALPHA) {
img->planes[VPX_PLANE_ALPHA] =
data + x * bytes_per_sample + y * img->stride[VPX_PLANE_ALPHA];
data += img->h * img->stride[VPX_PLANE_ALPHA];
}
img->planes[VPX_PLANE_Y] = data + x * bytes_per_sample +
y * img->stride[VPX_PLANE_Y];
data += img->h * img->stride[VPX_PLANE_Y];
if (!(img->fmt & VPX_IMG_FMT_UV_FLIP)) {
img->planes[VPX_PLANE_U] =
data + (x >> img->x_chroma_shift) * bytes_per_sample +
(y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
data += (img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
img->planes[VPX_PLANE_V] =
data + (x >> img->x_chroma_shift) * bytes_per_sample +
(y >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
} else {
img->planes[VPX_PLANE_V] =
data + (x >> img->x_chroma_shift) * bytes_per_sample +
(y >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
data += (img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
img->planes[VPX_PLANE_U] =
data + (x >> img->x_chroma_shift) * bytes_per_sample +
(y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
}
}
return 0;
}
return -1;
}
void vpx_img_flip(vpx_image_t *img) {
/* Note: In the calculation pointer adjustment calculation, we want the
* rhs to be promoted to a signed type. Section 6.3.1.8 of the ISO C99
* standard indicates that if the adjustment parameter is unsigned, the
* stride parameter will be promoted to unsigned, causing errors when
* the lhs is a larger type than the rhs.
*/
img->planes[VPX_PLANE_Y] += (signed)(img->d_h - 1) * img->stride[VPX_PLANE_Y];
img->stride[VPX_PLANE_Y] = -img->stride[VPX_PLANE_Y];
img->planes[VPX_PLANE_U] += (signed)((img->d_h >> img->y_chroma_shift) - 1)
* img->stride[VPX_PLANE_U];
img->stride[VPX_PLANE_U] = -img->stride[VPX_PLANE_U];
img->planes[VPX_PLANE_V] += (signed)((img->d_h >> img->y_chroma_shift) - 1)
* img->stride[VPX_PLANE_V];
img->stride[VPX_PLANE_V] = -img->stride[VPX_PLANE_V];
img->planes[VPX_PLANE_ALPHA] += (signed)(img->d_h - 1) * img->stride[VPX_PLANE_ALPHA];
img->stride[VPX_PLANE_ALPHA] = -img->stride[VPX_PLANE_ALPHA];
}
void vpx_img_free(vpx_image_t *img) {
if (img) {
if (img->img_data && img->img_data_owner)
vpx_free(img->img_data);
if (img->self_allocd)
free(img);
}
}

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <math.h>
#include "vpx/internal/vpx_psnr.h"
#define MAX_PSNR 100.0
double vpx_sse_to_psnr(double samples, double peak, double sse) {
if (sse > 0.0) {
const double psnr = 10.0 * log10(samples * peak * peak / sse);
return psnr > MAX_PSNR ? MAX_PSNR : psnr;
} else {
return MAX_PSNR;
}
}

View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2013 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/**
* SvcContext - input parameters and state to encode a multi-layered
* spatial SVC frame
*/
#ifndef VPX_SVC_CONTEXT_H_
#define VPX_SVC_CONTEXT_H_
#include "./vp8cx.h"
#include "./vpx_encoder.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum SVC_LOG_LEVEL {
SVC_LOG_ERROR,
SVC_LOG_INFO,
SVC_LOG_DEBUG
} SVC_LOG_LEVEL;
typedef struct {
// public interface to svc_command options
int spatial_layers; // number of spatial layers
int temporal_layers; // number of temporal layers
int temporal_layering_mode;
SVC_LOG_LEVEL log_level; // amount of information to display
int log_print; // when set, printf log messages instead of returning the
// message with svc_get_message
int output_rc_stat; // for outputting rc stats
int speed; // speed setting for codec
int threads;
// private storage for vpx_svc_encode
void *internal;
} SvcContext;
#define OPTION_BUFFER_SIZE 1024
#define COMPONENTS 4 // psnr & sse statistics maintained for total, y, u, v
typedef struct SvcInternal {
char options[OPTION_BUFFER_SIZE]; // set by vpx_svc_set_options
// values extracted from option, quantizers
vpx_svc_extra_cfg_t svc_params;
int enable_auto_alt_ref[VPX_SS_MAX_LAYERS];
int bitrates[VPX_SS_MAX_LAYERS];
// accumulated statistics
double psnr_sum[VPX_SS_MAX_LAYERS][COMPONENTS]; // total/Y/U/V
uint64_t sse_sum[VPX_SS_MAX_LAYERS][COMPONENTS];
uint32_t bytes_sum[VPX_SS_MAX_LAYERS];
// codec encoding values
int width; // width of highest layer
int height; // height of highest layer
int kf_dist; // distance between keyframes
// state variables
int psnr_pkt_received;
int layer;
int use_multiple_frame_contexts;
char message_buffer[2048];
vpx_codec_ctx_t *codec_ctx;
} SvcInternal_t;
/**
* Set SVC options
* options are supplied as a single string separated by spaces
* Format: encoding-mode=<i|ip|alt-ip|gf>
* layers=<layer_count>
* scaling-factors=<n1>/<d1>,<n2>/<d2>,...
* quantizers=<q1>,<q2>,...
*/
vpx_codec_err_t vpx_svc_set_options(SvcContext *svc_ctx, const char *options);
/**
* initialize SVC encoding
*/
vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx,
vpx_codec_ctx_t *codec_ctx,
vpx_codec_iface_t *iface,
vpx_codec_enc_cfg_t *cfg);
/**
* encode a frame of video with multiple layers
*/
vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx,
vpx_codec_ctx_t *codec_ctx,
struct vpx_image *rawimg,
vpx_codec_pts_t pts,
int64_t duration, int deadline);
/**
* finished with svc encoding, release allocated resources
*/
void vpx_svc_release(SvcContext *svc_ctx);
/**
* dump accumulated statistics and reset accumulated values
*/
const char *vpx_svc_dump_statistics(SvcContext *svc_ctx);
/**
* get status message from previous encode
*/
const char *vpx_svc_get_message(const SvcContext *svc_ctx);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // VPX_SVC_CONTEXT_H_

138
media/libvpx/vpx/vp8.h Normal file
View file

@ -0,0 +1,138 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*!\defgroup vp8 VP8
* \ingroup codecs
* VP8 is vpx's newest video compression algorithm that uses motion
* compensated prediction, Discrete Cosine Transform (DCT) coding of the
* prediction error signal and context dependent entropy coding techniques
* based on arithmetic principles. It features:
* - YUV 4:2:0 image format
* - Macro-block based coding (16x16 luma plus two 8x8 chroma)
* - 1/4 (1/8) pixel accuracy motion compensated prediction
* - 4x4 DCT transform
* - 128 level linear quantizer
* - In loop deblocking filter
* - Context-based entropy coding
*
* @{
*/
/*!\file
* \brief Provides controls common to both the VP8 encoder and decoder.
*/
#ifndef VPX_VP8_H_
#define VPX_VP8_H_
#include "./vpx_codec.h"
#include "./vpx_image.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!\brief Control functions
*
* The set of macros define the control functions of VP8 interface
*/
enum vp8_com_control_id {
VP8_SET_REFERENCE = 1, /**< pass in an external frame into decoder to be used as reference frame */
VP8_COPY_REFERENCE = 2, /**< get a copy of reference frame from the decoder */
VP8_SET_POSTPROC = 3, /**< set the decoder's post processing settings */
VP8_SET_DBG_COLOR_REF_FRAME = 4, /**< set the reference frames to color for each macroblock */
VP8_SET_DBG_COLOR_MB_MODES = 5, /**< set which macro block modes to color */
VP8_SET_DBG_COLOR_B_MODES = 6, /**< set which blocks modes to color */
VP8_SET_DBG_DISPLAY_MV = 7, /**< set which motion vector modes to draw */
/* TODO(jkoleszar): The encoder incorrectly reuses some of these values (5+)
* for its control ids. These should be migrated to something like the
* VP8_DECODER_CTRL_ID_START range next time we're ready to break the ABI.
*/
VP9_GET_REFERENCE = 128, /**< get a pointer to a reference frame */
VP8_COMMON_CTRL_ID_MAX,
VP8_DECODER_CTRL_ID_START = 256
};
/*!\brief post process flags
*
* The set of macros define VP8 decoder post processing flags
*/
enum vp8_postproc_level {
VP8_NOFILTERING = 0,
VP8_DEBLOCK = 1 << 0,
VP8_DEMACROBLOCK = 1 << 1,
VP8_ADDNOISE = 1 << 2,
VP8_DEBUG_TXT_FRAME_INFO = 1 << 3, /**< print frame information */
VP8_DEBUG_TXT_MBLK_MODES = 1 << 4, /**< print macro block modes over each macro block */
VP8_DEBUG_TXT_DC_DIFF = 1 << 5, /**< print dc diff for each macro block */
VP8_DEBUG_TXT_RATE_INFO = 1 << 6, /**< print video rate info (encoder only) */
VP8_MFQE = 1 << 10
};
/*!\brief post process flags
*
* This define a structure that describe the post processing settings. For
* the best objective measure (using the PSNR metric) set post_proc_flag
* to VP8_DEBLOCK and deblocking_level to 1.
*/
typedef struct vp8_postproc_cfg {
int post_proc_flag; /**< the types of post processing to be done, should be combination of "vp8_postproc_level" */
int deblocking_level; /**< the strength of deblocking, valid range [0, 16] */
int noise_level; /**< the strength of additive noise, valid range [0, 16] */
} vp8_postproc_cfg_t;
/*!\brief reference frame type
*
* The set of macros define the type of VP8 reference frames
*/
typedef enum vpx_ref_frame_type {
VP8_LAST_FRAME = 1,
VP8_GOLD_FRAME = 2,
VP8_ALTR_FRAME = 4
} vpx_ref_frame_type_t;
/*!\brief reference frame data struct
*
* Define the data struct to access vp8 reference frames.
*/
typedef struct vpx_ref_frame {
vpx_ref_frame_type_t frame_type; /**< which reference frame */
vpx_image_t img; /**< reference frame data in image format */
} vpx_ref_frame_t;
/*!\brief VP9 specific reference frame data struct
*
* Define the data struct to access vp9 reference frames.
*/
typedef struct vp9_ref_frame {
int idx; /**< frame index to get (input) */
vpx_image_t img; /**< img structure to populate (output) */
} vp9_ref_frame_t;
/*!\brief vp8 decoder control function parameter type
*
* defines the data type for each of VP8 decoder control function requires
*/
VPX_CTRL_USE_TYPE(VP8_SET_REFERENCE, vpx_ref_frame_t *)
VPX_CTRL_USE_TYPE(VP8_COPY_REFERENCE, vpx_ref_frame_t *)
VPX_CTRL_USE_TYPE(VP8_SET_POSTPROC, vp8_postproc_cfg_t *)
VPX_CTRL_USE_TYPE(VP8_SET_DBG_COLOR_REF_FRAME, int)
VPX_CTRL_USE_TYPE(VP8_SET_DBG_COLOR_MB_MODES, int)
VPX_CTRL_USE_TYPE(VP8_SET_DBG_COLOR_B_MODES, int)
VPX_CTRL_USE_TYPE(VP8_SET_DBG_DISPLAY_MV, int)
VPX_CTRL_USE_TYPE(VP9_GET_REFERENCE, vp9_ref_frame_t *)
/*! @} - end defgroup vp8 */
#ifdef __cplusplus
} // extern "C"
#endif
#endif // VPX_VP8_H_

725
media/libvpx/vpx/vp8cx.h Normal file
View file

@ -0,0 +1,725 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef VPX_VP8CX_H_
#define VPX_VP8CX_H_
/*!\defgroup vp8_encoder WebM VP8/VP9 Encoder
* \ingroup vp8
*
* @{
*/
#include "./vp8.h"
#include "./vpx_encoder.h"
/*!\file
* \brief Provides definitions for using VP8 or VP9 encoder algorithm within the
* vpx Codec Interface.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*!\name Algorithm interface for VP8
*
* This interface provides the capability to encode raw VP8 streams.
* @{
*/
extern vpx_codec_iface_t vpx_codec_vp8_cx_algo;
extern vpx_codec_iface_t *vpx_codec_vp8_cx(void);
/*!@} - end algorithm interface member group*/
/*!\name Algorithm interface for VP9
*
* This interface provides the capability to encode raw VP9 streams.
* @{
*/
extern vpx_codec_iface_t vpx_codec_vp9_cx_algo;
extern vpx_codec_iface_t *vpx_codec_vp9_cx(void);
/*!@} - end algorithm interface member group*/
/*
* Algorithm Flags
*/
/*!\brief Don't reference the last frame
*
* When this flag is set, the encoder will not use the last frame as a
* predictor. When not set, the encoder will choose whether to use the
* last frame or not automatically.
*/
#define VP8_EFLAG_NO_REF_LAST (1<<16)
/*!\brief Don't reference the golden frame
*
* When this flag is set, the encoder will not use the golden frame as a
* predictor. When not set, the encoder will choose whether to use the
* golden frame or not automatically.
*/
#define VP8_EFLAG_NO_REF_GF (1<<17)
/*!\brief Don't reference the alternate reference frame
*
* When this flag is set, the encoder will not use the alt ref frame as a
* predictor. When not set, the encoder will choose whether to use the
* alt ref frame or not automatically.
*/
#define VP8_EFLAG_NO_REF_ARF (1<<21)
/*!\brief Don't update the last frame
*
* When this flag is set, the encoder will not update the last frame with
* the contents of the current frame.
*/
#define VP8_EFLAG_NO_UPD_LAST (1<<18)
/*!\brief Don't update the golden frame
*
* When this flag is set, the encoder will not update the golden frame with
* the contents of the current frame.
*/
#define VP8_EFLAG_NO_UPD_GF (1<<22)
/*!\brief Don't update the alternate reference frame
*
* When this flag is set, the encoder will not update the alt ref frame with
* the contents of the current frame.
*/
#define VP8_EFLAG_NO_UPD_ARF (1<<23)
/*!\brief Force golden frame update
*
* When this flag is set, the encoder copy the contents of the current frame
* to the golden frame buffer.
*/
#define VP8_EFLAG_FORCE_GF (1<<19)
/*!\brief Force alternate reference frame update
*
* When this flag is set, the encoder copy the contents of the current frame
* to the alternate reference frame buffer.
*/
#define VP8_EFLAG_FORCE_ARF (1<<24)
/*!\brief Disable entropy update
*
* When this flag is set, the encoder will not update its internal entropy
* model based on the entropy of this frame.
*/
#define VP8_EFLAG_NO_UPD_ENTROPY (1<<20)
/*!\brief VPx encoder control functions
*
* This set of macros define the control functions available for VPx
* encoder interface.
*
* \sa #vpx_codec_control
*/
enum vp8e_enc_control_id {
/*!\brief Codec control function to set mode of entropy update in encoder.
*
* Supported in codecs: VP8, VP9
*/
VP8E_UPD_ENTROPY = 5,
/*!\brief Codec control function to set reference update mode in encoder.
*
* Supported in codecs: VP8, VP9
*/
VP8E_UPD_REFERENCE,
/*!\brief Codec control function to set which reference frame encoder can use.
*
* Supported in codecs: VP8, VP9
*/
VP8E_USE_REFERENCE,
/*!\brief Codec control function to pass an ROI map to encoder.
*
* Supported in codecs: VP8, VP9
*/
VP8E_SET_ROI_MAP,
/*!\brief Codec control function to pass an Active map to encoder.
*
* Supported in codecs: VP8, VP9
*/
VP8E_SET_ACTIVEMAP,
/*!\brief Codec control function to set encoder scaling mode.
*
* Supported in codecs: VP8, VP9
*/
VP8E_SET_SCALEMODE = 11,
/*!\brief Codec control function to set encoder internal speed settings.
*
* Changes in this value influences, among others, the encoder's selection
* of motion estimation methods. Values greater than 0 will increase encoder
* speed at the expense of quality.
*
* \note Valid range for VP8: -16..16
* \note Valid range for VP9: -8..8
*
* Supported in codecs: VP8, VP9
*/
VP8E_SET_CPUUSED = 13,
/*!\brief Codec control function to enable automatic set and use alf frames.
*
* Supported in codecs: VP8, VP9
*/
VP8E_SET_ENABLEAUTOALTREF,
/*!\brief control function to set noise sensitivity
*
* 0: off, 1: OnYOnly, 2: OnYUV,
* 3: OnYUVAggressive, 4: Adaptive
*
* Supported in codecs: VP8
*/
VP8E_SET_NOISE_SENSITIVITY,
/*!\brief Codec control function to set sharpness.
*
* Supported in codecs: VP8, VP9
*/
VP8E_SET_SHARPNESS,
/*!\brief Codec control function to set the threshold for MBs treated static.
*
* Supported in codecs: VP8, VP9
*/
VP8E_SET_STATIC_THRESHOLD,
/*!\brief Codec control function to set the number of token partitions.
*
* Supported in codecs: VP8
*/
VP8E_SET_TOKEN_PARTITIONS,
/*!\brief Codec control function to get last quantizer chosen by the encoder.
*
* Return value uses internal quantizer scale defined by the codec.
*
* Supported in codecs: VP8, VP9
*/
VP8E_GET_LAST_QUANTIZER,
/*!\brief Codec control function to get last quantizer chosen by the encoder.
*
* Return value uses the 0..63 scale as used by the rc_*_quantizer config
* parameters.
*
* Supported in codecs: VP8, VP9
*/
VP8E_GET_LAST_QUANTIZER_64,
/*!\brief Codec control function to set the max no of frames to create arf.
*
* Supported in codecs: VP8, VP9
*/
VP8E_SET_ARNR_MAXFRAMES,
/*!\brief Codec control function to set the filter strength for the arf.
*
* Supported in codecs: VP8, VP9
*/
VP8E_SET_ARNR_STRENGTH,
/*!\deprecated control function to set the filter type to use for the arf. */
VP8E_SET_ARNR_TYPE,
/*!\brief Codec control function to set visual tuning.
*
* Supported in codecs: VP8, VP9
*/
VP8E_SET_TUNING,
/*!\brief Codec control function to set constrained quality level.
*
* \attention For this value to be used vpx_codec_enc_cfg_t::g_usage must be
* set to #VPX_CQ.
* \note Valid range: 0..63
*
* Supported in codecs: VP8, VP9
*/
VP8E_SET_CQ_LEVEL,
/*!\brief Codec control function to set Max data rate for Intra frames.
*
* This value controls additional clamping on the maximum size of a
* keyframe. It is expressed as a percentage of the average
* per-frame bitrate, with the special (and default) value 0 meaning
* unlimited, or no additional clamping beyond the codec's built-in
* algorithm.
*
* For example, to allocate no more than 4.5 frames worth of bitrate
* to a keyframe, set this to 450.
*
* Supported in codecs: VP8, VP9
*/
VP8E_SET_MAX_INTRA_BITRATE_PCT,
/*!\brief Codec control function to set reference and update frame flags.
*
* Supported in codecs: VP8
*/
VP8E_SET_FRAME_FLAGS,
/*!\brief Codec control function to set max data rate for Inter frames.
*
* This value controls additional clamping on the maximum size of an
* inter frame. It is expressed as a percentage of the average
* per-frame bitrate, with the special (and default) value 0 meaning
* unlimited, or no additional clamping beyond the codec's built-in
* algorithm.
*
* For example, to allow no more than 4.5 frames worth of bitrate
* to an inter frame, set this to 450.
*
* Supported in codecs: VP9
*/
VP9E_SET_MAX_INTER_BITRATE_PCT,
/*!\brief Boost percentage for Golden Frame in CBR mode.
*
* This value controls the amount of boost given to Golden Frame in
* CBR mode. It is expressed as a percentage of the average
* per-frame bitrate, with the special (and default) value 0 meaning
* the feature is off, i.e., no golden frame boost in CBR mode and
* average bitrate target is used.
*
* For example, to allow 100% more bits, i.e, 2X, in a golden frame
* than average frame, set this to 100.
*
* Supported in codecs: VP9
*/
VP9E_SET_GF_CBR_BOOST_PCT,
/*!\brief Codec control function to set the temporal layer id.
*
* For temporal scalability: this control allows the application to set the
* layer id for each frame to be encoded. Note that this control must be set
* for every frame prior to encoding. The usage of this control function
* supersedes the internal temporal pattern counter, which is now deprecated.
*
* Supported in codecs: VP8
*/
VP8E_SET_TEMPORAL_LAYER_ID,
/*!\brief Codec control function to set encoder screen content mode.
*
* 0: off, 1: On, 2: On with more aggressive rate control.
*
* Supported in codecs: VP8
*/
VP8E_SET_SCREEN_CONTENT_MODE,
/*!\brief Codec control function to set lossless encoding mode.
*
* VP9 can operate in lossless encoding mode, in which the bitstream
* produced will be able to decode and reconstruct a perfect copy of
* input source. This control function provides a mean to switch encoder
* into lossless coding mode(1) or normal coding mode(0) that may be lossy.
* 0 = lossy coding mode
* 1 = lossless coding mode
*
* By default, encoder operates in normal coding mode (maybe lossy).
*
* Supported in codecs: VP9
*/
VP9E_SET_LOSSLESS,
/*!\brief Codec control function to set number of tile columns.
*
* In encoding and decoding, VP9 allows an input image frame be partitioned
* into separated vertical tile columns, which can be encoded or decoded
* independently. This enables easy implementation of parallel encoding and
* decoding. This control requests the encoder to use column tiles in
* encoding an input frame, with number of tile columns (in Log2 unit) as
* the parameter:
* 0 = 1 tile column
* 1 = 2 tile columns
* 2 = 4 tile columns
* .....
* n = 2**n tile columns
* The requested tile columns will be capped by encoder based on image size
* limitation (The minimum width of a tile column is 256 pixel, the maximum
* is 4096).
*
* By default, the value is 0, i.e. one single column tile for entire image.
*
* Supported in codecs: VP9
*/
VP9E_SET_TILE_COLUMNS,
/*!\brief Codec control function to set number of tile rows.
*
* In encoding and decoding, VP9 allows an input image frame be partitioned
* into separated horizontal tile rows. Tile rows are encoded or decoded
* sequentially. Even though encoding/decoding of later tile rows depends on
* earlier ones, this allows the encoder to output data packets for tile rows
* prior to completely processing all tile rows in a frame, thereby reducing
* the latency in processing between input and output. The parameter
* for this control describes the number of tile rows, which has a valid
* range [0, 2]:
* 0 = 1 tile row
* 1 = 2 tile rows
* 2 = 4 tile rows
*
* By default, the value is 0, i.e. one single row tile for entire image.
*
* Supported in codecs: VP9
*/
VP9E_SET_TILE_ROWS,
/*!\brief Codec control function to enable frame parallel decoding feature.
*
* VP9 has a bitstream feature to reduce decoding dependency between frames
* by turning off backward update of probability context used in encoding
* and decoding. This allows staged parallel processing of more than one
* video frames in the decoder. This control function provides a mean to
* turn this feature on or off for bitstreams produced by encoder.
*
* By default, this feature is off.
*
* Supported in codecs: VP9
*/
VP9E_SET_FRAME_PARALLEL_DECODING,
/*!\brief Codec control function to set adaptive quantization mode.
*
* VP9 has a segment based feature that allows encoder to adaptively change
* quantization parameter for each segment within a frame to improve the
* subjective quality. This control makes encoder operate in one of the
* several AQ_modes supported.
*
* By default, encoder operates with AQ_Mode 0(adaptive quantization off).
*
* Supported in codecs: VP9
*/
VP9E_SET_AQ_MODE,
/*!\brief Codec control function to enable/disable periodic Q boost.
*
* One VP9 encoder speed feature is to enable quality boost by lowering
* frame level Q periodically. This control function provides a mean to
* turn on/off this feature.
* 0 = off
* 1 = on
*
* By default, the encoder is allowed to use this feature for appropriate
* encoding modes.
*
* Supported in codecs: VP9
*/
VP9E_SET_FRAME_PERIODIC_BOOST,
/*!\brief Codec control function to set noise sensitivity.
*
* 0: off, 1: On(YOnly)
*
* Supported in codecs: VP9
*/
VP9E_SET_NOISE_SENSITIVITY,
/*!\brief Codec control function to turn on/off SVC in encoder.
* \note Return value is VPX_CODEC_INVALID_PARAM if the encoder does not
* support SVC in its current encoding mode
* 0: off, 1: on
*
* Supported in codecs: VP9
*/
VP9E_SET_SVC,
/*!\brief Codec control function to set parameters for SVC.
* \note Parameters contain min_q, max_q, scaling factor for each of the
* SVC layers.
*
* Supported in codecs: VP9
*/
VP9E_SET_SVC_PARAMETERS,
/*!\brief Codec control function to set svc layer for spatial and temporal.
* \note Valid ranges: 0..#vpx_codec_enc_cfg::ss_number_layers for spatial
* layer and 0..#vpx_codec_enc_cfg::ts_number_layers for
* temporal layer.
*
* Supported in codecs: VP9
*/
VP9E_SET_SVC_LAYER_ID,
/*!\brief Codec control function to set content type.
* \note Valid parameter range:
* VP9E_CONTENT_DEFAULT = Regular video content (Default)
* VP9E_CONTENT_SCREEN = Screen capture content
*
* Supported in codecs: VP9
*/
VP9E_SET_TUNE_CONTENT,
/*!\brief Codec control function to get svc layer ID.
* \note The layer ID returned is for the data packet from the registered
* callback function.
*
* Supported in codecs: VP9
*/
VP9E_GET_SVC_LAYER_ID,
/*!\brief Codec control function to register callback to get per layer packet.
* \note Parameter for this control function is a structure with a callback
* function and a pointer to private data used by the callback.
*
* Supported in codecs: VP9
*/
VP9E_REGISTER_CX_CALLBACK,
/*!\brief Codec control function to set color space info.
* \note Valid ranges: 0..7, default is "UNKNOWN".
* 0 = UNKNOWN,
* 1 = BT_601
* 2 = BT_709
* 3 = SMPTE_170
* 4 = SMPTE_240
* 5 = BT_2020
* 6 = RESERVED
* 7 = SRGB
*
* Supported in codecs: VP9
*/
VP9E_SET_COLOR_SPACE,
/*!\brief Codec control function to set temporal layering mode.
* \note Valid ranges: 0..3, default is "0" (VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING).
* 0 = VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING
* 1 = VP9E_TEMPORAL_LAYERING_MODE_BYPASS
* 2 = VP9E_TEMPORAL_LAYERING_MODE_0101
* 3 = VP9E_TEMPORAL_LAYERING_MODE_0212
*
* Supported in codecs: VP9
*/
VP9E_SET_TEMPORAL_LAYERING_MODE,
/*!\brief Codec control function to get an Active map back from the encoder.
*
* Supported in codecs: VP9
*/
VP9E_GET_ACTIVEMAP,
};
/*!\brief vpx 1-D scaling mode
*
* This set of constants define 1-D vpx scaling modes
*/
typedef enum vpx_scaling_mode_1d {
VP8E_NORMAL = 0,
VP8E_FOURFIVE = 1,
VP8E_THREEFIVE = 2,
VP8E_ONETWO = 3
} VPX_SCALING_MODE;
/*!\brief Temporal layering mode enum for VP9 SVC.
*
* This set of macros define the different temporal layering modes.
* Supported codecs: VP9 (in SVC mode)
*
*/
typedef enum vp9e_temporal_layering_mode {
/*!\brief No temporal layering.
* Used when only spatial layering is used.
*/
VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING = 0,
/*!\brief Bypass mode.
* Used when application needs to control temporal layering.
* This will only work when the number of spatial layers equals 1.
*/
VP9E_TEMPORAL_LAYERING_MODE_BYPASS = 1,
/*!\brief 0-1-0-1... temporal layering scheme with two temporal layers.
*/
VP9E_TEMPORAL_LAYERING_MODE_0101 = 2,
/*!\brief 0-2-1-2... temporal layering scheme with three temporal layers.
*/
VP9E_TEMPORAL_LAYERING_MODE_0212 = 3
} VP9E_TEMPORAL_LAYERING_MODE;
/*!\brief vpx region of interest map
*
* These defines the data structures for the region of interest map
*
*/
typedef struct vpx_roi_map {
/*! An id between 0 and 3 for each 16x16 region within a frame. */
unsigned char *roi_map;
unsigned int rows; /**< Number of rows. */
unsigned int cols; /**< Number of columns. */
// TODO(paulwilkins): broken for VP9 which has 8 segments
// q and loop filter deltas for each segment
// (see MAX_MB_SEGMENTS)
int delta_q[4]; /**< Quantizer deltas. */
int delta_lf[4]; /**< Loop filter deltas. */
/*! Static breakout threshold for each segment. */
unsigned int static_threshold[4];
} vpx_roi_map_t;
/*!\brief vpx active region map
*
* These defines the data structures for active region map
*
*/
typedef struct vpx_active_map {
unsigned char *active_map; /**< specify an on (1) or off (0) each 16x16 region within a frame */
unsigned int rows; /**< number of rows */
unsigned int cols; /**< number of cols */
} vpx_active_map_t;
/*!\brief vpx image scaling mode
*
* This defines the data structure for image scaling mode
*
*/
typedef struct vpx_scaling_mode {
VPX_SCALING_MODE h_scaling_mode; /**< horizontal scaling mode */
VPX_SCALING_MODE v_scaling_mode; /**< vertical scaling mode */
} vpx_scaling_mode_t;
/*!\brief VP8 token partition mode
*
* This defines VP8 partitioning mode for compressed data, i.e., the number of
* sub-streams in the bitstream. Used for parallelized decoding.
*
*/
typedef enum {
VP8_ONE_TOKENPARTITION = 0,
VP8_TWO_TOKENPARTITION = 1,
VP8_FOUR_TOKENPARTITION = 2,
VP8_EIGHT_TOKENPARTITION = 3
} vp8e_token_partitions;
/*!brief VP9 encoder content type */
typedef enum {
VP9E_CONTENT_DEFAULT,
VP9E_CONTENT_SCREEN,
VP9E_CONTENT_INVALID
} vp9e_tune_content;
/*!\brief VP8 model tuning parameters
*
* Changes the encoder to tune for certain types of input material.
*
*/
typedef enum {
VP8_TUNE_PSNR,
VP8_TUNE_SSIM
} vp8e_tuning;
/*!\brief vp9 svc layer parameters
*
* This defines the spatial and temporal layer id numbers for svc encoding.
* This is used with the #VP9E_SET_SVC_LAYER_ID control to set the spatial and
* temporal layer id for the current frame.
*
*/
typedef struct vpx_svc_layer_id {
int spatial_layer_id; /**< Spatial layer id number. */
int temporal_layer_id; /**< Temporal layer id number. */
} vpx_svc_layer_id_t;
/*!\brief VP8 encoder control function parameter type
*
* Defines the data types that VP8E control functions take. Note that
* additional common controls are defined in vp8.h
*
*/
/* These controls have been deprecated in favor of the flags parameter to
* vpx_codec_encode(). See the definition of VP8_EFLAG_* above.
*/
VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_UPD_ENTROPY, int)
VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_UPD_REFERENCE, int)
VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_USE_REFERENCE, int)
VPX_CTRL_USE_TYPE(VP8E_SET_FRAME_FLAGS, int)
VPX_CTRL_USE_TYPE(VP8E_SET_TEMPORAL_LAYER_ID, int)
VPX_CTRL_USE_TYPE(VP8E_SET_ROI_MAP, vpx_roi_map_t *)
VPX_CTRL_USE_TYPE(VP8E_SET_ACTIVEMAP, vpx_active_map_t *)
VPX_CTRL_USE_TYPE(VP8E_SET_SCALEMODE, vpx_scaling_mode_t *)
VPX_CTRL_USE_TYPE(VP9E_SET_SVC, int)
VPX_CTRL_USE_TYPE(VP9E_SET_SVC_PARAMETERS, void *)
VPX_CTRL_USE_TYPE(VP9E_REGISTER_CX_CALLBACK, void *)
VPX_CTRL_USE_TYPE(VP9E_SET_SVC_LAYER_ID, vpx_svc_layer_id_t *)
VPX_CTRL_USE_TYPE(VP8E_SET_CPUUSED, int)
VPX_CTRL_USE_TYPE(VP8E_SET_ENABLEAUTOALTREF, unsigned int)
VPX_CTRL_USE_TYPE(VP8E_SET_NOISE_SENSITIVITY, unsigned int)
VPX_CTRL_USE_TYPE(VP8E_SET_SHARPNESS, unsigned int)
VPX_CTRL_USE_TYPE(VP8E_SET_STATIC_THRESHOLD, unsigned int)
VPX_CTRL_USE_TYPE(VP8E_SET_TOKEN_PARTITIONS, int) /* vp8e_token_partitions */
VPX_CTRL_USE_TYPE(VP8E_SET_ARNR_MAXFRAMES, unsigned int)
VPX_CTRL_USE_TYPE(VP8E_SET_ARNR_STRENGTH, unsigned int)
VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_SET_ARNR_TYPE, unsigned int)
VPX_CTRL_USE_TYPE(VP8E_SET_TUNING, int) /* vp8e_tuning */
VPX_CTRL_USE_TYPE(VP8E_SET_CQ_LEVEL, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_SET_TILE_COLUMNS, int)
VPX_CTRL_USE_TYPE(VP9E_SET_TILE_ROWS, int)
VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER, int *)
VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER_64, int *)
VPX_CTRL_USE_TYPE(VP9E_GET_SVC_LAYER_ID, vpx_svc_layer_id_t *)
VPX_CTRL_USE_TYPE(VP8E_SET_MAX_INTRA_BITRATE_PCT, unsigned int)
VPX_CTRL_USE_TYPE(VP8E_SET_MAX_INTER_BITRATE_PCT, unsigned int)
VPX_CTRL_USE_TYPE(VP8E_SET_SCREEN_CONTENT_MODE, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_SET_GF_CBR_BOOST_PCT, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_SET_LOSSLESS, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_SET_FRAME_PARALLEL_DECODING, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_SET_AQ_MODE, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_SET_FRAME_PERIODIC_BOOST, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_SET_NOISE_SENSITIVITY, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_SET_TUNE_CONTENT, int) /* vp9e_tune_content */
VPX_CTRL_USE_TYPE(VP9E_SET_COLOR_SPACE, int)
VPX_CTRL_USE_TYPE(VP9E_GET_ACTIVEMAP, vpx_active_map_t *)
/*! @} - end defgroup vp8_encoder */
#ifdef __cplusplus
} // extern "C"
#endif
#endif // VPX_VP8CX_H_

166
media/libvpx/vpx/vp8dx.h Normal file
View file

@ -0,0 +1,166 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*!\defgroup vp8_decoder WebM VP8/VP9 Decoder
* \ingroup vp8
*
* @{
*/
/*!\file
* \brief Provides definitions for using VP8 or VP9 within the vpx Decoder
* interface.
*/
#ifndef VPX_VP8DX_H_
#define VPX_VP8DX_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Include controls common to both the encoder and decoder */
#include "./vp8.h"
/*!\name Algorithm interface for VP8
*
* This interface provides the capability to decode VP8 streams.
* @{
*/
extern vpx_codec_iface_t vpx_codec_vp8_dx_algo;
extern vpx_codec_iface_t *vpx_codec_vp8_dx(void);
/*!@} - end algorithm interface member group*/
/*!\name Algorithm interface for VP9
*
* This interface provides the capability to decode VP9 streams.
* @{
*/
extern vpx_codec_iface_t vpx_codec_vp9_dx_algo;
extern vpx_codec_iface_t *vpx_codec_vp9_dx(void);
/*!@} - end algorithm interface member group*/
/*!\enum vp8_dec_control_id
* \brief VP8 decoder control functions
*
* This set of macros define the control functions available for the VP8
* decoder interface.
*
* \sa #vpx_codec_control
*/
enum vp8_dec_control_id {
/** control function to get info on which reference frames were updated
* by the last decode
*/
VP8D_GET_LAST_REF_UPDATES = VP8_DECODER_CTRL_ID_START,
/** check if the indicated frame is corrupted */
VP8D_GET_FRAME_CORRUPTED,
/** control function to get info on which reference frames were used
* by the last decode
*/
VP8D_GET_LAST_REF_USED,
/** decryption function to decrypt encoded buffer data immediately
* before decoding. Takes a vpx_decrypt_init, which contains
* a callback function and opaque context pointer.
*/
VPXD_SET_DECRYPTOR,
VP8D_SET_DECRYPTOR = VPXD_SET_DECRYPTOR,
/** control function to get the dimensions that the current frame is decoded
* at. This may be different to the intended display size for the frame as
* specified in the wrapper or frame header (see VP9D_GET_DISPLAY_SIZE). */
VP9D_GET_FRAME_SIZE,
/** control function to get the current frame's intended display dimensions
* (as specified in the wrapper or frame header). This may be different to
* the decoded dimensions of this frame (see VP9D_GET_FRAME_SIZE). */
VP9D_GET_DISPLAY_SIZE,
/** control function to get the bit depth of the stream. */
VP9D_GET_BIT_DEPTH,
/** control function to set the byte alignment of the planes in the reference
* buffers. Valid values are power of 2, from 32 to 1024. A value of 0 sets
* legacy alignment. I.e. Y plane is aligned to 32 bytes, U plane directly
* follows Y plane, and V plane directly follows U plane. Default value is 0.
*/
VP9_SET_BYTE_ALIGNMENT,
/** control function to invert the decoding order to from right to left. The
* function is used in a test to confirm the decoding independence of tile
* columns. The function may be used in application where this order
* of decoding is desired.
*
* TODO(yaowu): Rework the unit test that uses this control, and in a future
* release, this test-only control shall be removed.
*/
VP9_INVERT_TILE_DECODE_ORDER,
/** control function to set the skip loop filter flag. Valid values are
* integers. The decoder will skip the loop filter when its value is set to
* nonzero. If the loop filter is skipped the decoder may accumulate decode
* artifacts. The default value is 0.
*/
VP9_SET_SKIP_LOOP_FILTER,
VP8_DECODER_CTRL_ID_MAX
};
/** Decrypt n bytes of data from input -> output, using the decrypt_state
* passed in VPXD_SET_DECRYPTOR.
*/
typedef void (*vpx_decrypt_cb)(void *decrypt_state, const unsigned char *input,
unsigned char *output, int count);
/*!\brief Structure to hold decryption state
*
* Defines a structure to hold the decryption state and access function.
*/
typedef struct vpx_decrypt_init {
/*! Decrypt callback. */
vpx_decrypt_cb decrypt_cb;
/*! Decryption state. */
void *decrypt_state;
} vpx_decrypt_init;
/*!\brief A deprecated alias for vpx_decrypt_init.
*/
typedef vpx_decrypt_init vp8_decrypt_init;
/*!\brief VP8 decoder control function parameter type
*
* Defines the data types that VP8D control functions take. Note that
* additional common controls are defined in vp8.h
*
*/
VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_UPDATES, int *)
VPX_CTRL_USE_TYPE(VP8D_GET_FRAME_CORRUPTED, int *)
VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_USED, int *)
VPX_CTRL_USE_TYPE(VPXD_SET_DECRYPTOR, vpx_decrypt_init *)
VPX_CTRL_USE_TYPE(VP8D_SET_DECRYPTOR, vpx_decrypt_init *)
VPX_CTRL_USE_TYPE(VP9D_GET_DISPLAY_SIZE, int *)
VPX_CTRL_USE_TYPE(VP9D_GET_BIT_DEPTH, unsigned int *)
VPX_CTRL_USE_TYPE(VP9D_GET_FRAME_SIZE, int *)
VPX_CTRL_USE_TYPE(VP9_INVERT_TILE_DECODE_ORDER, int)
/*! @} - end defgroup vp8_decoder */
#ifdef __cplusplus
} // extern "C"
#endif
#endif // VPX_VP8DX_H_

View file

@ -0,0 +1,479 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*!\defgroup codec Common Algorithm Interface
* This abstraction allows applications to easily support multiple video
* formats with minimal code duplication. This section describes the interface
* common to all codecs (both encoders and decoders).
* @{
*/
/*!\file
* \brief Describes the codec algorithm interface to applications.
*
* This file describes the interface between an application and a
* video codec algorithm.
*
* An application instantiates a specific codec instance by using
* vpx_codec_init() and a pointer to the algorithm's interface structure:
* <pre>
* my_app.c:
* extern vpx_codec_iface_t my_codec;
* {
* vpx_codec_ctx_t algo;
* res = vpx_codec_init(&algo, &my_codec);
* }
* </pre>
*
* Once initialized, the instance is manged using other functions from
* the vpx_codec_* family.
*/
#ifndef VPX_VPX_CODEC_H_
#define VPX_VPX_CODEC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "./vpx_integer.h"
#include "./vpx_image.h"
/*!\brief Decorator indicating a function is deprecated */
#ifndef DEPRECATED
#if defined(__GNUC__) && __GNUC__
#define DEPRECATED __attribute__ ((deprecated))
#elif defined(_MSC_VER)
#define DEPRECATED
#else
#define DEPRECATED
#endif
#endif /* DEPRECATED */
#ifndef DECLSPEC_DEPRECATED
#if defined(__GNUC__) && __GNUC__
#define DECLSPEC_DEPRECATED /**< \copydoc #DEPRECATED */
#elif defined(_MSC_VER)
#define DECLSPEC_DEPRECATED __declspec(deprecated) /**< \copydoc #DEPRECATED */
#else
#define DECLSPEC_DEPRECATED /**< \copydoc #DEPRECATED */
#endif
#endif /* DECLSPEC_DEPRECATED */
/*!\brief Decorator indicating a function is potentially unused */
#ifdef UNUSED
#elif __GNUC__
#define UNUSED __attribute__ ((unused))
#else
#define UNUSED
#endif
/*!\brief Current ABI version number
*
* \internal
* If this file is altered in any way that changes the ABI, this value
* must be bumped. Examples include, but are not limited to, changing
* types, removing or reassigning enums, adding/removing/rearranging
* fields to structures
*/
#define VPX_CODEC_ABI_VERSION (3 + VPX_IMAGE_ABI_VERSION) /**<\hideinitializer*/
/*!\brief Algorithm return codes */
typedef enum {
/*!\brief Operation completed without error */
VPX_CODEC_OK,
/*!\brief Unspecified error */
VPX_CODEC_ERROR,
/*!\brief Memory operation failed */
VPX_CODEC_MEM_ERROR,
/*!\brief ABI version mismatch */
VPX_CODEC_ABI_MISMATCH,
/*!\brief Algorithm does not have required capability */
VPX_CODEC_INCAPABLE,
/*!\brief The given bitstream is not supported.
*
* The bitstream was unable to be parsed at the highest level. The decoder
* is unable to proceed. This error \ref SHOULD be treated as fatal to the
* stream. */
VPX_CODEC_UNSUP_BITSTREAM,
/*!\brief Encoded bitstream uses an unsupported feature
*
* The decoder does not implement a feature required by the encoder. This
* return code should only be used for features that prevent future
* pictures from being properly decoded. This error \ref MAY be treated as
* fatal to the stream or \ref MAY be treated as fatal to the current GOP.
*/
VPX_CODEC_UNSUP_FEATURE,
/*!\brief The coded data for this stream is corrupt or incomplete
*
* There was a problem decoding the current frame. This return code
* should only be used for failures that prevent future pictures from
* being properly decoded. This error \ref MAY be treated as fatal to the
* stream or \ref MAY be treated as fatal to the current GOP. If decoding
* is continued for the current GOP, artifacts may be present.
*/
VPX_CODEC_CORRUPT_FRAME,
/*!\brief An application-supplied parameter is not valid.
*
*/
VPX_CODEC_INVALID_PARAM,
/*!\brief An iterator reached the end of list.
*
*/
VPX_CODEC_LIST_END
}
vpx_codec_err_t;
/*! \brief Codec capabilities bitfield
*
* Each codec advertises the capabilities it supports as part of its
* ::vpx_codec_iface_t interface structure. Capabilities are extra interfaces
* or functionality, and are not required to be supported.
*
* The available flags are specified by VPX_CODEC_CAP_* defines.
*/
typedef long vpx_codec_caps_t;
#define VPX_CODEC_CAP_DECODER 0x1 /**< Is a decoder */
#define VPX_CODEC_CAP_ENCODER 0x2 /**< Is an encoder */
/*! \brief Initialization-time Feature Enabling
*
* Certain codec features must be known at initialization time, to allow for
* proper memory allocation.
*
* The available flags are specified by VPX_CODEC_USE_* defines.
*/
typedef long vpx_codec_flags_t;
/*!\brief Codec interface structure.
*
* Contains function pointers and other data private to the codec
* implementation. This structure is opaque to the application.
*/
typedef const struct vpx_codec_iface vpx_codec_iface_t;
/*!\brief Codec private data structure.
*
* Contains data private to the codec implementation. This structure is opaque
* to the application.
*/
typedef struct vpx_codec_priv vpx_codec_priv_t;
/*!\brief Iterator
*
* Opaque storage used for iterating over lists.
*/
typedef const void *vpx_codec_iter_t;
/*!\brief Codec context structure
*
* All codecs \ref MUST support this context structure fully. In general,
* this data should be considered private to the codec algorithm, and
* not be manipulated or examined by the calling application. Applications
* may reference the 'name' member to get a printable description of the
* algorithm.
*/
typedef struct vpx_codec_ctx {
const char *name; /**< Printable interface name */
vpx_codec_iface_t *iface; /**< Interface pointers */
vpx_codec_err_t err; /**< Last returned error */
const char *err_detail; /**< Detailed info, if available */
vpx_codec_flags_t init_flags; /**< Flags passed at init time */
union {
/**< Decoder Configuration Pointer */
const struct vpx_codec_dec_cfg *dec;
/**< Encoder Configuration Pointer */
const struct vpx_codec_enc_cfg *enc;
const void *raw;
} config; /**< Configuration pointer aliasing union */
vpx_codec_priv_t *priv; /**< Algorithm private storage */
} vpx_codec_ctx_t;
/*!\brief Bit depth for codec
* *
* This enumeration determines the bit depth of the codec.
*/
typedef enum vpx_bit_depth {
VPX_BITS_8 = 8, /**< 8 bits */
VPX_BITS_10 = 10, /**< 10 bits */
VPX_BITS_12 = 12, /**< 12 bits */
} vpx_bit_depth_t;
/*
* Library Version Number Interface
*
* For example, see the following sample return values:
* vpx_codec_version() (1<<16 | 2<<8 | 3)
* vpx_codec_version_str() "v1.2.3-rc1-16-gec6a1ba"
* vpx_codec_version_extra_str() "rc1-16-gec6a1ba"
*/
/*!\brief Return the version information (as an integer)
*
* Returns a packed encoding of the library version number. This will only include
* the major.minor.patch component of the version number. Note that this encoded
* value should be accessed through the macros provided, as the encoding may change
* in the future.
*
*/
int vpx_codec_version(void);
#define VPX_VERSION_MAJOR(v) ((v>>16)&0xff) /**< extract major from packed version */
#define VPX_VERSION_MINOR(v) ((v>>8)&0xff) /**< extract minor from packed version */
#define VPX_VERSION_PATCH(v) ((v>>0)&0xff) /**< extract patch from packed version */
/*!\brief Return the version major number */
#define vpx_codec_version_major() ((vpx_codec_version()>>16)&0xff)
/*!\brief Return the version minor number */
#define vpx_codec_version_minor() ((vpx_codec_version()>>8)&0xff)
/*!\brief Return the version patch number */
#define vpx_codec_version_patch() ((vpx_codec_version()>>0)&0xff)
/*!\brief Return the version information (as a string)
*
* Returns a printable string containing the full library version number. This may
* contain additional text following the three digit version number, as to indicate
* release candidates, prerelease versions, etc.
*
*/
const char *vpx_codec_version_str(void);
/*!\brief Return the version information (as a string)
*
* Returns a printable "extra string". This is the component of the string returned
* by vpx_codec_version_str() following the three digit version number.
*
*/
const char *vpx_codec_version_extra_str(void);
/*!\brief Return the build configuration
*
* Returns a printable string containing an encoded version of the build
* configuration. This may be useful to vpx support.
*
*/
const char *vpx_codec_build_config(void);
/*!\brief Return the name for a given interface
*
* Returns a human readable string for name of the given codec interface.
*
* \param[in] iface Interface pointer
*
*/
const char *vpx_codec_iface_name(vpx_codec_iface_t *iface);
/*!\brief Convert error number to printable string
*
* Returns a human readable string for the last error returned by the
* algorithm. The returned error will be one line and will not contain
* any newline characters.
*
*
* \param[in] err Error number.
*
*/
const char *vpx_codec_err_to_string(vpx_codec_err_t err);
/*!\brief Retrieve error synopsis for codec context
*
* Returns a human readable string for the last error returned by the
* algorithm. The returned error will be one line and will not contain
* any newline characters.
*
*
* \param[in] ctx Pointer to this instance's context.
*
*/
const char *vpx_codec_error(vpx_codec_ctx_t *ctx);
/*!\brief Retrieve detailed error information for codec context
*
* Returns a human readable string providing detailed information about
* the last error.
*
* \param[in] ctx Pointer to this instance's context.
*
* \retval NULL
* No detailed information is available.
*/
const char *vpx_codec_error_detail(vpx_codec_ctx_t *ctx);
/* REQUIRED FUNCTIONS
*
* The following functions are required to be implemented for all codecs.
* They represent the base case functionality expected of all codecs.
*/
/*!\brief Destroy a codec instance
*
* Destroys a codec context, freeing any associated memory buffers.
*
* \param[in] ctx Pointer to this instance's context
*
* \retval #VPX_CODEC_OK
* The codec algorithm initialized.
* \retval #VPX_CODEC_MEM_ERROR
* Memory allocation failed.
*/
vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx);
/*!\brief Get the capabilities of an algorithm.
*
* Retrieves the capabilities bitfield from the algorithm's interface.
*
* \param[in] iface Pointer to the algorithm interface
*
*/
vpx_codec_caps_t vpx_codec_get_caps(vpx_codec_iface_t *iface);
/*!\brief Control algorithm
*
* This function is used to exchange algorithm specific data with the codec
* instance. This can be used to implement features specific to a particular
* algorithm.
*
* This wrapper function dispatches the request to the helper function
* associated with the given ctrl_id. It tries to call this function
* transparently, but will return #VPX_CODEC_ERROR if the request could not
* be dispatched.
*
* Note that this function should not be used directly. Call the
* #vpx_codec_control wrapper macro instead.
*
* \param[in] ctx Pointer to this instance's context
* \param[in] ctrl_id Algorithm specific control identifier
*
* \retval #VPX_CODEC_OK
* The control request was processed.
* \retval #VPX_CODEC_ERROR
* The control request was not processed.
* \retval #VPX_CODEC_INVALID_PARAM
* The data was not valid.
*/
vpx_codec_err_t vpx_codec_control_(vpx_codec_ctx_t *ctx,
int ctrl_id,
...);
#if defined(VPX_DISABLE_CTRL_TYPECHECKS) && VPX_DISABLE_CTRL_TYPECHECKS
# define vpx_codec_control(ctx,id,data) vpx_codec_control_(ctx,id,data)
# define VPX_CTRL_USE_TYPE(id, typ)
# define VPX_CTRL_USE_TYPE_DEPRECATED(id, typ)
# define VPX_CTRL_VOID(id, typ)
#else
/*!\brief vpx_codec_control wrapper macro
*
* This macro allows for type safe conversions across the variadic parameter
* to vpx_codec_control_().
*
* \internal
* It works by dispatching the call to the control function through a wrapper
* function named with the id parameter.
*/
# define vpx_codec_control(ctx,id,data) vpx_codec_control_##id(ctx,id,data)\
/**<\hideinitializer*/
/*!\brief vpx_codec_control type definition macro
*
* This macro allows for type safe conversions across the variadic parameter
* to vpx_codec_control_(). It defines the type of the argument for a given
* control identifier.
*
* \internal
* It defines a static function with
* the correctly typed arguments as a wrapper to the type-unsafe internal
* function.
*/
# define VPX_CTRL_USE_TYPE(id, typ) \
static vpx_codec_err_t \
vpx_codec_control_##id(vpx_codec_ctx_t*, int, typ) UNUSED;\
\
static vpx_codec_err_t \
vpx_codec_control_##id(vpx_codec_ctx_t *ctx, int ctrl_id, typ data) {\
return vpx_codec_control_(ctx, ctrl_id, data);\
} /**<\hideinitializer*/
/*!\brief vpx_codec_control deprecated type definition macro
*
* Like #VPX_CTRL_USE_TYPE, but indicates that the specified control is
* deprecated and should not be used. Consult the documentation for your
* codec for more information.
*
* \internal
* It defines a static function with the correctly typed arguments as a
* wrapper to the type-unsafe internal function.
*/
# define VPX_CTRL_USE_TYPE_DEPRECATED(id, typ) \
DECLSPEC_DEPRECATED static vpx_codec_err_t \
vpx_codec_control_##id(vpx_codec_ctx_t*, int, typ) DEPRECATED UNUSED;\
\
DECLSPEC_DEPRECATED static vpx_codec_err_t \
vpx_codec_control_##id(vpx_codec_ctx_t *ctx, int ctrl_id, typ data) {\
return vpx_codec_control_(ctx, ctrl_id, data);\
} /**<\hideinitializer*/
/*!\brief vpx_codec_control void type definition macro
*
* This macro allows for type safe conversions across the variadic parameter
* to vpx_codec_control_(). It indicates that a given control identifier takes
* no argument.
*
* \internal
* It defines a static function without a data argument as a wrapper to the
* type-unsafe internal function.
*/
# define VPX_CTRL_VOID(id) \
static vpx_codec_err_t \
vpx_codec_control_##id(vpx_codec_ctx_t*, int) UNUSED;\
\
static vpx_codec_err_t \
vpx_codec_control_##id(vpx_codec_ctx_t *ctx, int ctrl_id) {\
return vpx_codec_control_(ctx, ctrl_id);\
} /**<\hideinitializer*/
#endif
/*!@} - end defgroup codec*/
#ifdef __cplusplus
}
#endif
#endif // VPX_VPX_CODEC_H_

View file

@ -0,0 +1,378 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef VPX_VPX_DECODER_H_
#define VPX_VPX_DECODER_H_
/*!\defgroup decoder Decoder Algorithm Interface
* \ingroup codec
* This abstraction allows applications using this decoder to easily support
* multiple video formats with minimal code duplication. This section describes
* the interface common to all decoders.
* @{
*/
/*!\file
* \brief Describes the decoder algorithm interface to applications.
*
* This file describes the interface between an application and a
* video decoder algorithm.
*
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "./vpx_codec.h"
#include "./vpx_frame_buffer.h"
/*!\brief Current ABI version number
*
* \internal
* If this file is altered in any way that changes the ABI, this value
* must be bumped. Examples include, but are not limited to, changing
* types, removing or reassigning enums, adding/removing/rearranging
* fields to structures
*/
#define VPX_DECODER_ABI_VERSION (3 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/
/*! \brief Decoder capabilities bitfield
*
* Each decoder advertises the capabilities it supports as part of its
* ::vpx_codec_iface_t interface structure. Capabilities are extra interfaces
* or functionality, and are not required to be supported by a decoder.
*
* The available flags are specified by VPX_CODEC_CAP_* defines.
*/
#define VPX_CODEC_CAP_PUT_SLICE 0x10000 /**< Will issue put_slice callbacks */
#define VPX_CODEC_CAP_PUT_FRAME 0x20000 /**< Will issue put_frame callbacks */
#define VPX_CODEC_CAP_POSTPROC 0x40000 /**< Can postprocess decoded frame */
#define VPX_CODEC_CAP_ERROR_CONCEALMENT 0x80000 /**< Can conceal errors due to
packet loss */
#define VPX_CODEC_CAP_INPUT_FRAGMENTS 0x100000 /**< Can receive encoded frames
one fragment at a time */
/*! \brief Initialization-time Feature Enabling
*
* Certain codec features must be known at initialization time, to allow for
* proper memory allocation.
*
* The available flags are specified by VPX_CODEC_USE_* defines.
*/
#define VPX_CODEC_CAP_FRAME_THREADING 0x200000 /**< Can support frame-based
multi-threading */
#define VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER 0x400000 /**< Can support external
frame buffers */
#define VPX_CODEC_USE_POSTPROC 0x10000 /**< Postprocess decoded frame */
#define VPX_CODEC_USE_ERROR_CONCEALMENT 0x20000 /**< Conceal errors in decoded
frames */
#define VPX_CODEC_USE_INPUT_FRAGMENTS 0x40000 /**< The input frame should be
passed to the decoder one
fragment at a time */
#define VPX_CODEC_USE_FRAME_THREADING 0x80000 /**< Enable frame-based
multi-threading */
/*!\brief Stream properties
*
* This structure is used to query or set properties of the decoded
* stream. Algorithms may extend this structure with data specific
* to their bitstream by setting the sz member appropriately.
*/
typedef struct vpx_codec_stream_info {
unsigned int sz; /**< Size of this structure */
unsigned int w; /**< Width (or 0 for unknown/default) */
unsigned int h; /**< Height (or 0 for unknown/default) */
unsigned int is_kf; /**< Current frame is a keyframe */
} vpx_codec_stream_info_t;
/* REQUIRED FUNCTIONS
*
* The following functions are required to be implemented for all decoders.
* They represent the base case functionality expected of all decoders.
*/
/*!\brief Initialization Configurations
*
* This structure is used to pass init time configuration options to the
* decoder.
*/
typedef struct vpx_codec_dec_cfg {
unsigned int threads; /**< Maximum number of threads to use, default 1 */
unsigned int w; /**< Width */
unsigned int h; /**< Height */
} vpx_codec_dec_cfg_t; /**< alias for struct vpx_codec_dec_cfg */
/*!\brief Initialize a decoder instance
*
* Initializes a decoder context using the given interface. Applications
* should call the vpx_codec_dec_init convenience macro instead of this
* function directly, to ensure that the ABI version number parameter
* is properly initialized.
*
* If the library was configured with --disable-multithread, this call
* is not thread safe and should be guarded with a lock if being used
* in a multithreaded context.
*
* \param[in] ctx Pointer to this instance's context.
* \param[in] iface Pointer to the algorithm interface to use.
* \param[in] cfg Configuration to use, if known. May be NULL.
* \param[in] flags Bitfield of VPX_CODEC_USE_* flags
* \param[in] ver ABI version number. Must be set to
* VPX_DECODER_ABI_VERSION
* \retval #VPX_CODEC_OK
* The decoder algorithm initialized.
* \retval #VPX_CODEC_MEM_ERROR
* Memory allocation failed.
*/
vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t *ctx,
vpx_codec_iface_t *iface,
const vpx_codec_dec_cfg_t *cfg,
vpx_codec_flags_t flags,
int ver);
/*!\brief Convenience macro for vpx_codec_dec_init_ver()
*
* Ensures the ABI version parameter is properly set.
*/
#define vpx_codec_dec_init(ctx, iface, cfg, flags) \
vpx_codec_dec_init_ver(ctx, iface, cfg, flags, VPX_DECODER_ABI_VERSION)
/*!\brief Parse stream info from a buffer
*
* Performs high level parsing of the bitstream. Construction of a decoder
* context is not necessary. Can be used to determine if the bitstream is
* of the proper format, and to extract information from the stream.
*
* \param[in] iface Pointer to the algorithm interface
* \param[in] data Pointer to a block of data to parse
* \param[in] data_sz Size of the data buffer
* \param[in,out] si Pointer to stream info to update. The size member
* \ref MUST be properly initialized, but \ref MAY be
* clobbered by the algorithm. This parameter \ref MAY
* be NULL.
*
* \retval #VPX_CODEC_OK
* Bitstream is parsable and stream information updated
*/
vpx_codec_err_t vpx_codec_peek_stream_info(vpx_codec_iface_t *iface,
const uint8_t *data,
unsigned int data_sz,
vpx_codec_stream_info_t *si);
/*!\brief Return information about the current stream.
*
* Returns information about the stream that has been parsed during decoding.
*
* \param[in] ctx Pointer to this instance's context
* \param[in,out] si Pointer to stream info to update. The size member
* \ref MUST be properly initialized, but \ref MAY be
* clobbered by the algorithm. This parameter \ref MAY
* be NULL.
*
* \retval #VPX_CODEC_OK
* Bitstream is parsable and stream information updated
*/
vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t *ctx,
vpx_codec_stream_info_t *si);
/*!\brief Decode data
*
* Processes a buffer of coded data. If the processing results in a new
* decoded frame becoming available, PUT_SLICE and PUT_FRAME events may be
* generated, as appropriate. Encoded data \ref MUST be passed in DTS (decode
* time stamp) order. Frames produced will always be in PTS (presentation
* time stamp) order.
* If the decoder is configured with VPX_CODEC_USE_INPUT_FRAGMENTS enabled,
* data and data_sz can contain a fragment of the encoded frame. Fragment
* \#n must contain at least partition \#n, but can also contain subsequent
* partitions (\#n+1 - \#n+i), and if so, fragments \#n+1, .., \#n+i must
* be empty. When no more data is available, this function should be called
* with NULL as data and 0 as data_sz. The memory passed to this function
* must be available until the frame has been decoded.
*
* \param[in] ctx Pointer to this instance's context
* \param[in] data Pointer to this block of new coded data. If
* NULL, a VPX_CODEC_CB_PUT_FRAME event is posted
* for the previously decoded frame.
* \param[in] data_sz Size of the coded data, in bytes.
* \param[in] user_priv Application specific data to associate with
* this frame.
* \param[in] deadline Soft deadline the decoder should attempt to meet,
* in us. Set to zero for unlimited.
*
* \return Returns #VPX_CODEC_OK if the coded data was processed completely
* and future pictures can be decoded without error. Otherwise,
* see the descriptions of the other error codes in ::vpx_codec_err_t
* for recoverability capabilities.
*/
vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx,
const uint8_t *data,
unsigned int data_sz,
void *user_priv,
long deadline);
/*!\brief Decoded frames iterator
*
* Iterates over a list of the frames available for display. The iterator
* storage should be initialized to NULL to start the iteration. Iteration is
* complete when this function returns NULL.
*
* The list of available frames becomes valid upon completion of the
* vpx_codec_decode call, and remains valid until the next call to vpx_codec_decode.
*
* \param[in] ctx Pointer to this instance's context
* \param[in,out] iter Iterator storage, initialized to NULL
*
* \return Returns a pointer to an image, if one is ready for display. Frames
* produced will always be in PTS (presentation time stamp) order.
*/
vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t *ctx,
vpx_codec_iter_t *iter);
/*!\defgroup cap_put_frame Frame-Based Decoding Functions
*
* The following functions are required to be implemented for all decoders
* that advertise the VPX_CODEC_CAP_PUT_FRAME capability. Calling these functions
* for codecs that don't advertise this capability will result in an error
* code being returned, usually VPX_CODEC_ERROR
* @{
*/
/*!\brief put frame callback prototype
*
* This callback is invoked by the decoder to notify the application of
* the availability of decoded image data.
*/
typedef void (*vpx_codec_put_frame_cb_fn_t)(void *user_priv,
const vpx_image_t *img);
/*!\brief Register for notification of frame completion.
*
* Registers a given function to be called when a decoded frame is
* available.
*
* \param[in] ctx Pointer to this instance's context
* \param[in] cb Pointer to the callback function
* \param[in] user_priv User's private data
*
* \retval #VPX_CODEC_OK
* Callback successfully registered.
* \retval #VPX_CODEC_ERROR
* Decoder context not initialized, or algorithm not capable of
* posting slice completion.
*/
vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t *ctx,
vpx_codec_put_frame_cb_fn_t cb,
void *user_priv);
/*!@} - end defgroup cap_put_frame */
/*!\defgroup cap_put_slice Slice-Based Decoding Functions
*
* The following functions are required to be implemented for all decoders
* that advertise the VPX_CODEC_CAP_PUT_SLICE capability. Calling these functions
* for codecs that don't advertise this capability will result in an error
* code being returned, usually VPX_CODEC_ERROR
* @{
*/
/*!\brief put slice callback prototype
*
* This callback is invoked by the decoder to notify the application of
* the availability of partially decoded image data. The
*/
typedef void (*vpx_codec_put_slice_cb_fn_t)(void *user_priv,
const vpx_image_t *img,
const vpx_image_rect_t *valid,
const vpx_image_rect_t *update);
/*!\brief Register for notification of slice completion.
*
* Registers a given function to be called when a decoded slice is
* available.
*
* \param[in] ctx Pointer to this instance's context
* \param[in] cb Pointer to the callback function
* \param[in] user_priv User's private data
*
* \retval #VPX_CODEC_OK
* Callback successfully registered.
* \retval #VPX_CODEC_ERROR
* Decoder context not initialized, or algorithm not capable of
* posting slice completion.
*/
vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t *ctx,
vpx_codec_put_slice_cb_fn_t cb,
void *user_priv);
/*!@} - end defgroup cap_put_slice*/
/*!\defgroup cap_external_frame_buffer External Frame Buffer Functions
*
* The following section is required to be implemented for all decoders
* that advertise the VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER capability.
* Calling this function for codecs that don't advertise this capability
* will result in an error code being returned, usually VPX_CODEC_ERROR.
*
* \note
* Currently this only works with VP9.
* @{
*/
/*!\brief Pass in external frame buffers for the decoder to use.
*
* Registers functions to be called when libvpx needs a frame buffer
* to decode the current frame and a function to be called when libvpx does
* not internally reference the frame buffer. This set function must
* be called before the first call to decode or libvpx will assume the
* default behavior of allocating frame buffers internally.
*
* \param[in] ctx Pointer to this instance's context
* \param[in] cb_get Pointer to the get callback function
* \param[in] cb_release Pointer to the release callback function
* \param[in] cb_priv Callback's private data
*
* \retval #VPX_CODEC_OK
* External frame buffers will be used by libvpx.
* \retval #VPX_CODEC_INVALID_PARAM
* One or more of the callbacks were NULL.
* \retval #VPX_CODEC_ERROR
* Decoder context not initialized, or algorithm not capable of
* using external frame buffers.
*
* \note
* When decoding VP9, the application may be required to pass in at least
* #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS external frame
* buffers.
*/
vpx_codec_err_t vpx_codec_set_frame_buffer_functions(
vpx_codec_ctx_t *ctx,
vpx_get_frame_buffer_cb_fn_t cb_get,
vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv);
/*!@} - end defgroup cap_external_frame_buffer */
/*!@} - end defgroup decoder*/
#ifdef __cplusplus
}
#endif
#endif // VPX_VPX_DECODER_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef VPX_VPX_FRAME_BUFFER_H_
#define VPX_VPX_FRAME_BUFFER_H_
/*!\file
* \brief Describes the decoder external frame buffer interface.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "./vpx_integer.h"
/*!\brief The maximum number of work buffers used by libvpx.
* Support maximum 4 threads to decode video in parallel.
* Each thread will use one work buffer.
* TODO(hkuang): Add support to set number of worker threads dynamically.
*/
#define VPX_MAXIMUM_WORK_BUFFERS 8
/*!\brief The maximum number of reference buffers that a VP9 encoder may use.
*/
#define VP9_MAXIMUM_REF_BUFFERS 8
/*!\brief External frame buffer
*
* This structure holds allocated frame buffers used by the decoder.
*/
typedef struct vpx_codec_frame_buffer {
uint8_t *data; /**< Pointer to the data buffer */
size_t size; /**< Size of data in bytes */
void *priv; /**< Frame's private data */
} vpx_codec_frame_buffer_t;
/*!\brief get frame buffer callback prototype
*
* This callback is invoked by the decoder to retrieve data for the frame
* buffer in order for the decode call to complete. The callback must
* allocate at least min_size in bytes and assign it to fb->data. The callback
* must zero out all the data allocated. Then the callback must set fb->size
* to the allocated size. The application does not need to align the allocated
* data. The callback is triggered when the decoder needs a frame buffer to
* decode a compressed image into. This function may be called more than once
* for every call to vpx_codec_decode. The application may set fb->priv to
* some data which will be passed back in the ximage and the release function
* call. |fb| is guaranteed to not be NULL. On success the callback must
* return 0. Any failure the callback must return a value less than 0.
*
* \param[in] priv Callback's private data
* \param[in] new_size Size in bytes needed by the buffer
* \param[in,out] fb Pointer to vpx_codec_frame_buffer_t
*/
typedef int (*vpx_get_frame_buffer_cb_fn_t)(
void *priv, size_t min_size, vpx_codec_frame_buffer_t *fb);
/*!\brief release frame buffer callback prototype
*
* This callback is invoked by the decoder when the frame buffer is not
* referenced by any other buffers. |fb| is guaranteed to not be NULL. On
* success the callback must return 0. Any failure the callback must return
* a value less than 0.
*
* \param[in] priv Callback's private data
* \param[in] fb Pointer to vpx_codec_frame_buffer_t
*/
typedef int (*vpx_release_frame_buffer_cb_fn_t)(
void *priv, vpx_codec_frame_buffer_t *fb);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // VPX_VPX_FRAME_BUFFER_H_

View file

@ -0,0 +1,224 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*!\file
* \brief Describes the vpx image descriptor and associated operations
*
*/
#ifndef VPX_VPX_IMAGE_H_
#define VPX_VPX_IMAGE_H_
#ifdef __cplusplus
extern "C" {
#endif
/*!\brief Current ABI version number
*
* \internal
* If this file is altered in any way that changes the ABI, this value
* must be bumped. Examples include, but are not limited to, changing
* types, removing or reassigning enums, adding/removing/rearranging
* fields to structures
*/
#define VPX_IMAGE_ABI_VERSION (3) /**<\hideinitializer*/
#define VPX_IMG_FMT_PLANAR 0x100 /**< Image is a planar format. */
#define VPX_IMG_FMT_UV_FLIP 0x200 /**< V plane precedes U in memory. */
#define VPX_IMG_FMT_HAS_ALPHA 0x400 /**< Image has an alpha channel. */
#define VPX_IMG_FMT_HIGHBITDEPTH 0x800 /**< Image uses 16bit framebuffer. */
/*!\brief List of supported image formats */
typedef enum vpx_img_fmt {
VPX_IMG_FMT_NONE,
VPX_IMG_FMT_RGB24, /**< 24 bit per pixel packed RGB */
VPX_IMG_FMT_RGB32, /**< 32 bit per pixel packed 0RGB */
VPX_IMG_FMT_RGB565, /**< 16 bit per pixel, 565 */
VPX_IMG_FMT_RGB555, /**< 16 bit per pixel, 555 */
VPX_IMG_FMT_UYVY, /**< UYVY packed YUV */
VPX_IMG_FMT_YUY2, /**< YUYV packed YUV */
VPX_IMG_FMT_YVYU, /**< YVYU packed YUV */
VPX_IMG_FMT_BGR24, /**< 24 bit per pixel packed BGR */
VPX_IMG_FMT_RGB32_LE, /**< 32 bit packed BGR0 */
VPX_IMG_FMT_ARGB, /**< 32 bit packed ARGB, alpha=255 */
VPX_IMG_FMT_ARGB_LE, /**< 32 bit packed BGRA, alpha=255 */
VPX_IMG_FMT_RGB565_LE, /**< 16 bit per pixel, gggbbbbb rrrrrggg */
VPX_IMG_FMT_RGB555_LE, /**< 16 bit per pixel, gggbbbbb 0rrrrrgg */
VPX_IMG_FMT_YV12 = VPX_IMG_FMT_PLANAR | VPX_IMG_FMT_UV_FLIP | 1, /**< planar YVU */
VPX_IMG_FMT_I420 = VPX_IMG_FMT_PLANAR | 2,
VPX_IMG_FMT_VPXYV12 = VPX_IMG_FMT_PLANAR | VPX_IMG_FMT_UV_FLIP | 3, /** < planar 4:2:0 format with vpx color space */
VPX_IMG_FMT_VPXI420 = VPX_IMG_FMT_PLANAR | 4,
VPX_IMG_FMT_I422 = VPX_IMG_FMT_PLANAR | 5,
VPX_IMG_FMT_I444 = VPX_IMG_FMT_PLANAR | 6,
VPX_IMG_FMT_I440 = VPX_IMG_FMT_PLANAR | 7,
VPX_IMG_FMT_444A = VPX_IMG_FMT_PLANAR | VPX_IMG_FMT_HAS_ALPHA | 6,
VPX_IMG_FMT_I42016 = VPX_IMG_FMT_I420 | VPX_IMG_FMT_HIGHBITDEPTH,
VPX_IMG_FMT_I42216 = VPX_IMG_FMT_I422 | VPX_IMG_FMT_HIGHBITDEPTH,
VPX_IMG_FMT_I44416 = VPX_IMG_FMT_I444 | VPX_IMG_FMT_HIGHBITDEPTH,
VPX_IMG_FMT_I44016 = VPX_IMG_FMT_I440 | VPX_IMG_FMT_HIGHBITDEPTH
} vpx_img_fmt_t; /**< alias for enum vpx_img_fmt */
/*!\brief List of supported color spaces */
typedef enum vpx_color_space {
VPX_CS_UNKNOWN = 0, /**< Unknown */
VPX_CS_BT_601 = 1, /**< BT.601 */
VPX_CS_BT_709 = 2, /**< BT.709 */
VPX_CS_SMPTE_170 = 3, /**< SMPTE.170 */
VPX_CS_SMPTE_240 = 4, /**< SMPTE.240 */
VPX_CS_BT_2020 = 5, /**< BT.2020 */
VPX_CS_RESERVED = 6, /**< Reserved */
VPX_CS_SRGB = 7 /**< sRGB */
} vpx_color_space_t; /**< alias for enum vpx_color_space */
/**\brief Image Descriptor */
typedef struct vpx_image {
vpx_img_fmt_t fmt; /**< Image Format */
vpx_color_space_t cs; /**< Color Space */
/* Image storage dimensions */
unsigned int w; /**< Stored image width */
unsigned int h; /**< Stored image height */
unsigned int bit_depth; /**< Stored image bit-depth */
/* Image display dimensions */
unsigned int d_w; /**< Displayed image width */
unsigned int d_h; /**< Displayed image height */
/* Chroma subsampling info */
unsigned int x_chroma_shift; /**< subsampling order, X */
unsigned int y_chroma_shift; /**< subsampling order, Y */
/* Image data pointers. */
#define VPX_PLANE_PACKED 0 /**< To be used for all packed formats */
#define VPX_PLANE_Y 0 /**< Y (Luminance) plane */
#define VPX_PLANE_U 1 /**< U (Chroma) plane */
#define VPX_PLANE_V 2 /**< V (Chroma) plane */
#define VPX_PLANE_ALPHA 3 /**< A (Transparency) plane */
unsigned char *planes[4]; /**< pointer to the top left pixel for each plane */
int stride[4]; /**< stride between rows for each plane */
int bps; /**< bits per sample (for packed formats) */
/* The following member may be set by the application to associate data
* with this image.
*/
void *user_priv; /**< may be set by the application to associate data
* with this image. */
/* The following members should be treated as private. */
unsigned char *img_data; /**< private */
int img_data_owner; /**< private */
int self_allocd; /**< private */
void *fb_priv; /**< Frame buffer data associated with the image. */
} vpx_image_t; /**< alias for struct vpx_image */
/**\brief Representation of a rectangle on a surface */
typedef struct vpx_image_rect {
unsigned int x; /**< leftmost column */
unsigned int y; /**< topmost row */
unsigned int w; /**< width */
unsigned int h; /**< height */
} vpx_image_rect_t; /**< alias for struct vpx_image_rect */
/*!\brief Open a descriptor, allocating storage for the underlying image
*
* Returns a descriptor for storing an image of the given format. The
* storage for the descriptor is allocated on the heap.
*
* \param[in] img Pointer to storage for descriptor. If this parameter
* is NULL, the storage for the descriptor will be
* allocated on the heap.
* \param[in] fmt Format for the image
* \param[in] d_w Width of the image
* \param[in] d_h Height of the image
* \param[in] align Alignment, in bytes, of the image buffer and
* each row in the image(stride).
*
* \return Returns a pointer to the initialized image descriptor. If the img
* parameter is non-null, the value of the img parameter will be
* returned.
*/
vpx_image_t *vpx_img_alloc(vpx_image_t *img,
vpx_img_fmt_t fmt,
unsigned int d_w,
unsigned int d_h,
unsigned int align);
/*!\brief Open a descriptor, using existing storage for the underlying image
*
* Returns a descriptor for storing an image of the given format. The
* storage for descriptor has been allocated elsewhere, and a descriptor is
* desired to "wrap" that storage.
*
* \param[in] img Pointer to storage for descriptor. If this parameter
* is NULL, the storage for the descriptor will be
* allocated on the heap.
* \param[in] fmt Format for the image
* \param[in] d_w Width of the image
* \param[in] d_h Height of the image
* \param[in] align Alignment, in bytes, of each row in the image.
* \param[in] img_data Storage to use for the image
*
* \return Returns a pointer to the initialized image descriptor. If the img
* parameter is non-null, the value of the img parameter will be
* returned.
*/
vpx_image_t *vpx_img_wrap(vpx_image_t *img,
vpx_img_fmt_t fmt,
unsigned int d_w,
unsigned int d_h,
unsigned int align,
unsigned char *img_data);
/*!\brief Set the rectangle identifying the displayed portion of the image
*
* Updates the displayed rectangle (aka viewport) on the image surface to
* match the specified coordinates and size.
*
* \param[in] img Image descriptor
* \param[in] x leftmost column
* \param[in] y topmost row
* \param[in] w width
* \param[in] h height
*
* \return 0 if the requested rectangle is valid, nonzero otherwise.
*/
int vpx_img_set_rect(vpx_image_t *img,
unsigned int x,
unsigned int y,
unsigned int w,
unsigned int h);
/*!\brief Flip the image vertically (top for bottom)
*
* Adjusts the image descriptor's pointers and strides to make the image
* be referenced upside-down.
*
* \param[in] img Image descriptor
*/
void vpx_img_flip(vpx_image_t *img);
/*!\brief Close an image descriptor
*
* Frees all allocated storage associated with an image descriptor.
*
* \param[in] img Image descriptor
*/
void vpx_img_free(vpx_image_t *img);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // VPX_VPX_IMAGE_H_

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef VPX_VPX_INTEGER_H_
#define VPX_VPX_INTEGER_H_
/* get ptrdiff_t, size_t, wchar_t, NULL */
#include <stddef.h>
#if defined(_MSC_VER)
#define VPX_FORCE_INLINE __forceinline
#define VPX_INLINE __inline
#else
#define VPX_FORCE_INLINE __inline__ __attribute__(always_inline)
// TODO(jbb): Allow a way to force inline off for older compilers.
#define VPX_INLINE inline
#endif
#if !defined(VPX_DONT_DEFINE_STDINT_TYPES)
#if (defined(_MSC_VER) && (_MSC_VER < 1600)) || defined(VPX_EMULATE_INTTYPES)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#if (defined(_MSC_VER) && (_MSC_VER < 1600))
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#define INT64_MAX _I64_MAX
#define INT32_MAX _I32_MAX
#define INT32_MIN _I32_MIN
#define INT16_MAX _I16_MAX
#define INT16_MIN _I16_MIN
#endif
#ifndef _UINTPTR_T_DEFINED
typedef size_t uintptr_t;
#endif
#else
/* Most platforms have the C99 standard integer types. */
#if defined(__cplusplus)
# if !defined(__STDC_FORMAT_MACROS)
# define __STDC_FORMAT_MACROS
# endif
# if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS
# endif
#endif // __cplusplus
#include <stdint.h>
#endif
#endif // VPX_DONT_DEFINE_STDINT_TYPES
/* VS2010 defines stdint.h, but not inttypes.h */
#if defined(_MSC_VER) && _MSC_VER < 1800
#define PRId64 "I64d"
#else
#include <inttypes.h>
#endif
#endif // VPX_VPX_INTEGER_H_