Commit 83b1d907 authored by John Koleszar's avatar John Koleszar

vpx: merge with master

Change-Id: I44b3ad780cef6f448fa17ff8e28fea87ef9cd518
parent 807acf17
......@@ -13,20 +13,14 @@
#include "vpx/internal/vpx_codec_internal.h"
#include "vpx_version.h"
#include "vp9/encoder/onyx_int.h"
#include "vpx/vp8e.h"
#include "vpx/vp8cx.h"
#include "vp9/encoder/firstpass.h"
#include "vp9/common/onyx.h"
#include <stdlib.h>
#include <string.h>
/* This value is a sentinel for determining whether the user has set a mode
* directly through the deprecated VP8E_SET_ENCODING_MODE control.
*/
#define NO_MODE_SET 255
struct vp8_extracfg {
struct vpx_codec_pkt_list *pkt_list;
vp8e_encoding_mode encoding_mode; /** best, good, realtime */
int cpu_used; /** available cpu percentage in 1/16*/
unsigned int enable_auto_alt_ref; /** if encoder decides to uses alternate reference frame */
unsigned int noise_sensitivity;
......@@ -40,7 +34,9 @@ struct vp8_extracfg {
vp8e_tuning tuning;
unsigned int cq_level; /* constrained quality level */
unsigned int rc_max_intra_bitrate_pct;
#if CONFIG_LOSSLESS
unsigned int lossless;
#endif
};
struct extraconfig_map {
......@@ -53,7 +49,6 @@ static const struct extraconfig_map extracfg_map[] = {
0,
{
NULL,
VP8_BEST_QUALITY_ENCODING, /* Encoding Mode */
0, /* cpu_used */
0, /* enable_auto_alt_ref */
0, /* noise_sensitivity */
......@@ -67,6 +62,9 @@ static const struct extraconfig_map extracfg_map[] = {
0, /* tuning*/
10, /* cq_level */
0, /* rc_max_intra_bitrate_pct */
#if CONFIG_LOSSLESS
0, /* lossless */
#endif
}
}
};
......@@ -83,7 +81,6 @@ struct vpx_codec_alg_priv {
unsigned int next_frame_flag;
vp8_postproc_cfg_t preview_ppcfg;
vpx_codec_pkt_list_decl(64) pkt_list; // changed to accomendate the maximum number of lagged frames allowed
int deprecated_mode;
unsigned int fixed_kf_cntr;
};
......@@ -135,8 +132,17 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000);
RANGE_CHECK(cfg, g_timebase.num, 1, cfg->g_timebase.den);
RANGE_CHECK_HI(cfg, g_profile, 3);
RANGE_CHECK_HI(cfg, rc_max_quantizer, 63);
RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer);
#if CONFIG_LOSSLESS
RANGE_CHECK_BOOL(vp8_cfg, lossless);
if (vp8_cfg->lossless) {
RANGE_CHECK_HI(cfg, rc_max_quantizer, 0);
RANGE_CHECK_HI(cfg, rc_min_quantizer, 0);
}
#endif
RANGE_CHECK_HI(cfg, g_threads, 64);
RANGE_CHECK_HI(cfg, g_lag_in_frames, MAX_LAG_BUFFERS);
RANGE_CHECK(cfg, rc_end_usage, VPX_VBR, VPX_CQ);
......@@ -162,7 +168,6 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
RANGE_CHECK_BOOL(vp8_cfg, enable_auto_alt_ref);
RANGE_CHECK(vp8_cfg, cpu_used, -16, 16);
RANGE_CHECK(vp8_cfg, encoding_mode, VP8_BEST_QUALITY_ENCODING, VP8_REAL_TIME_ENCODING);
RANGE_CHECK_HI(vp8_cfg, noise_sensitivity, 6);
RANGE_CHECK(vp8_cfg, token_partitions, VP8_ONE_TOKENPARTITION, VP8_EIGHT_TOKENPARTITION);
......@@ -303,7 +308,7 @@ static vpx_codec_err_t set_vp8e_config(VP9_CONFIG *oxcf,
oxcf->tuning = vp8_cfg.tuning;
#if CONFIG_LOSSLESS
oxcf->lossless = cfg.lossless;
oxcf->lossless = vp8_cfg.lossless;
#endif
/*
......@@ -397,7 +402,6 @@ static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx,
#define MAP(id, var) case id: var = CAST(id, args); break;
switch (ctrl_id) {
MAP(VP8E_SET_ENCODING_MODE, ctx->deprecated_mode);
MAP(VP8E_SET_CPUUSED, xcfg.cpu_used);
MAP(VP8E_SET_ENABLEAUTOALTREF, xcfg.enable_auto_alt_ref);
MAP(VP8E_SET_NOISE_SENSITIVITY, xcfg.noise_sensitivity);
......@@ -411,7 +415,9 @@ static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx,
MAP(VP8E_SET_TUNING, xcfg.tuning);
MAP(VP8E_SET_CQ_LEVEL, xcfg.cq_level);
MAP(VP8E_SET_MAX_INTRA_BITRATE_PCT, xcfg.rc_max_intra_bitrate_pct);
#if CONFIG_LOSSLESS
MAP(VP9E_SET_LOSSLESS, xcfg.lossless);
#endif
}
res = validate_config(ctx, &ctx->cfg, &xcfg);
......@@ -429,7 +435,7 @@ static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx,
static vpx_codec_err_t vp8e_common_init(vpx_codec_ctx_t *ctx,
int experimental) {
vpx_codec_err_t res = VPX_DEC_OK;
vpx_codec_err_t res = VPX_CODEC_OK;
struct vpx_codec_alg_priv *priv;
vpx_codec_enc_cfg_t *cfg;
unsigned int i;
......@@ -448,6 +454,7 @@ static vpx_codec_err_t vp8e_common_init(vpx_codec_ctx_t *ctx,
ctx->priv->iface = ctx->iface;
ctx->priv->alg_priv = priv;
ctx->priv->init_flags = ctx->init_flags;
ctx->priv->enc.total_encoders = 1;
if (ctx->config.enc) {
/* Update the reference to the config structure to an
......@@ -481,8 +488,6 @@ static vpx_codec_err_t vp8e_common_init(vpx_codec_ctx_t *ctx,
return VPX_CODEC_MEM_ERROR;
}
priv->deprecated_mode = NO_MODE_SET;
vp9_initialize_enc();
res = validate_config(priv, &priv->cfg, &priv->vp8_cfg);
......@@ -504,13 +509,15 @@ static vpx_codec_err_t vp8e_common_init(vpx_codec_ctx_t *ctx,
}
static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx) {
static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx,
vpx_codec_priv_enc_mr_cfg_t *data) {
return vp8e_common_init(ctx, 0);
}
#if CONFIG_EXPERIMENTAL
static vpx_codec_err_t vp8e_exp_init(vpx_codec_ctx_t *ctx) {
static vpx_codec_err_t vp8e_exp_init(vpx_codec_ctx_t *ctx,
vpx_codec_priv_enc_mr_cfg_t *data) {
return vp8e_common_init(ctx, 1);
}
#endif
......@@ -957,7 +964,6 @@ static vpx_codec_ctrl_fn_map_t vp8e_ctf_maps[] = {
{VP8E_SET_ROI_MAP, vp8e_set_roi_map},
{VP8E_SET_ACTIVEMAP, vp8e_set_activemap},
{VP8E_SET_SCALEMODE, vp8e_set_scalemode},
{VP8E_SET_ENCODING_MODE, set_param},
{VP8E_SET_CPUUSED, set_param},
{VP8E_SET_NOISE_SENSITIVITY, set_param},
{VP8E_SET_ENABLEAUTOALTREF, set_param},
......@@ -972,6 +978,9 @@ static vpx_codec_ctrl_fn_map_t vp8e_ctf_maps[] = {
{VP8E_SET_TUNING, set_param},
{VP8E_SET_CQ_LEVEL, set_param},
{VP8E_SET_MAX_INTRA_BITRATE_PCT, set_param},
#if CONFIG_LOSSLESS
{VP9E_SET_LOSSLESS, set_param},
#endif
{ -1, NULL},
};
......@@ -1090,80 +1099,3 @@ CODEC_INTERFACE(vpx_codec_vp8x_cx) = {
} /* encoder functions */
};
#endif
/*
* BEGIN BACKWARDS COMPATIBILITY SHIM.
*/
#define FORCE_KEY 2
static vpx_codec_err_t api1_control(vpx_codec_alg_priv_t *ctx,
int ctrl_id,
va_list args) {
vpx_codec_ctrl_fn_map_t *entry;
switch (ctrl_id) {
case VP8E_SET_FLUSHFLAG:
/* VP8 sample code did VP8E_SET_FLUSHFLAG followed by
* vpx_codec_get_cx_data() rather than vpx_codec_encode().
*/
return vp8e_encode(ctx, NULL, 0, 0, 0, 0);
case VP8E_SET_FRAMETYPE:
ctx->base.enc.tbd |= FORCE_KEY;
return VPX_CODEC_OK;
}
for (entry = vp8e_ctf_maps; entry && entry->fn; entry++) {
if (!entry->ctrl_id || entry->ctrl_id == ctrl_id) {
return entry->fn(ctx, ctrl_id, args);
}
}
return VPX_CODEC_ERROR;
}
static vpx_codec_ctrl_fn_map_t api1_ctrl_maps[] = {
{0, api1_control},
{ -1, NULL}
};
static vpx_codec_err_t api1_encode(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) {
int force = ctx->base.enc.tbd;
ctx->base.enc.tbd = 0;
return vp8e_encode
(ctx,
img,
pts,
duration,
flags | ((force & FORCE_KEY) ? VPX_EFLAG_FORCE_KF : 0),
deadline);
}
vpx_codec_iface_t vpx_enc_vp8_algo = {
"WebM Project VP8 Encoder (Deprecated API)" VERSION_STRING,
VPX_CODEC_INTERNAL_ABI_VERSION,
VPX_CODEC_CAP_ENCODER,
/* vpx_codec_caps_t caps; */
vp8e_init, /* vpx_codec_init_fn_t init; */
vp8e_destroy, /* vpx_codec_destroy_fn_t destroy; */
api1_ctrl_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */
NOT_IMPLEMENTED, /* vpx_codec_get_mmap_fn_t get_mmap; */
NOT_IMPLEMENTED, /* vpx_codec_set_mmap_fn_t set_mmap; */
{NOT_IMPLEMENTED}, /* decoder functions */
{
vp8e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t peek_si; */
api1_encode, /* vpx_codec_encode_fn_t encode; */
vp8e_get_cxdata, /* vpx_codec_get_cx_data_fn_t frame_get; */
vp8e_set_config,
NOT_IMPLEMENTED,
vp8e_get_preview,
} /* encoder functions */
};
......@@ -163,7 +163,8 @@ static void vp8_finalize_mmaps(vpx_codec_alg_priv_t *ctx) {
/* nothing to clean up */
}
static vpx_codec_err_t vp8_init(vpx_codec_ctx_t *ctx) {
static vpx_codec_err_t vp8_init(vpx_codec_ctx_t *ctx,
vpx_codec_priv_enc_mr_cfg_t *data) {
vpx_codec_err_t res = VPX_CODEC_OK;
/* This function only allocates space for the vpx_codec_alg_priv_t
......@@ -504,7 +505,7 @@ static vpx_codec_err_t vp8_xma_set_mmap(vpx_codec_ctx_t *ctx,
if (done && !res) {
vp8_finalize_mmaps(ctx->priv->alg_priv);
res = ctx->iface->init(ctx);
res = ctx->iface->init(ctx, NULL);
}
return res;
......@@ -661,37 +662,6 @@ static vpx_codec_ctrl_fn_map_t ctf_maps[] = {
CODEC_INTERFACE(vpx_codec_vp8_dx) = {
"WebM Project VP8 Decoder" VERSION_STRING,
VPX_CODEC_INTERNAL_ABI_VERSION,
VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC |
VPX_CODEC_CAP_INPUT_PARTITION,
/* vpx_codec_caps_t caps; */
vp8_init, /* vpx_codec_init_fn_t init; */
vp8_destroy, /* vpx_codec_destroy_fn_t destroy; */
ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */
vp8_xma_get_mmap, /* vpx_codec_get_mmap_fn_t get_mmap; */
vp8_xma_set_mmap, /* vpx_codec_set_mmap_fn_t set_mmap; */
{
vp8_peek_si, /* vpx_codec_peek_si_fn_t peek_si; */
vp8_get_si, /* vpx_codec_get_si_fn_t get_si; */
vp8_decode, /* vpx_codec_decode_fn_t decode; */
vp8_get_frame, /* vpx_codec_frame_get_fn_t frame_get; */
},
{
/* encoder functions */
NOT_IMPLEMENTED,
NOT_IMPLEMENTED,
NOT_IMPLEMENTED,
NOT_IMPLEMENTED,
NOT_IMPLEMENTED,
NOT_IMPLEMENTED
}
};
/*
* BEGIN BACKWARDS COMPATIBILITY SHIM.
*/
vpx_codec_iface_t vpx_codec_vp8_algo = {
"WebM Project VP8 Decoder (Deprecated API)" VERSION_STRING,
VPX_CODEC_INTERNAL_ABI_VERSION,
VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC,
/* vpx_codec_caps_t caps; */
vp8_init, /* vpx_codec_init_fn_t init; */
......
......@@ -56,9 +56,10 @@
* types, removing or reassigning enums, adding/removing/rearranging
* fields to structures
*/
#define VPX_CODEC_INTERNAL_ABI_VERSION (3) /**<\hideinitializer*/
#define VPX_CODEC_INTERNAL_ABI_VERSION (4) /**<\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
*
......@@ -73,7 +74,8 @@ typedef struct vpx_codec_alg_priv vpx_codec_alg_priv_t;
* \retval #VPX_CODEC_MEM_ERROR
* Memory operation failed.
*/
typedef vpx_codec_err_t (*vpx_codec_init_fn_t)(vpx_codec_ctx_t *ctx);
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
*
......@@ -163,7 +165,7 @@ typedef vpx_codec_err_t (*vpx_codec_control_fn_t)(vpx_codec_alg_priv_t *ctx,
* mapping. This implies that ctrl_id values chosen by the algorithm
* \ref MUST be non-zero.
*/
typedef const struct {
typedef const struct vpx_codec_ctrl_fn_map {
int ctrl_id;
vpx_codec_control_fn_t fn;
} vpx_codec_ctrl_fn_map_t;
......@@ -263,6 +265,10 @@ typedef vpx_fixed_buf_t *
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
......@@ -273,7 +279,7 @@ typedef vpx_image_t *
* one mapping must be present, in addition to the end-of-list.
*
*/
typedef const struct {
typedef const struct vpx_codec_enc_cfg_map {
int usage;
vpx_codec_enc_cfg_t cfg;
} vpx_codec_enc_cfg_map_t;
......@@ -293,19 +299,20 @@ struct vpx_codec_iface {
vpx_codec_ctrl_fn_map_t *ctrl_maps; /**< \copydoc ::vpx_codec_ctrl_fn_map_t */
vpx_codec_get_mmap_fn_t get_mmap; /**< \copydoc ::vpx_codec_get_mmap_fn_t */
vpx_codec_set_mmap_fn_t set_mmap; /**< \copydoc ::vpx_codec_set_mmap_fn_t */
struct {
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_peek_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 */
} dec;
struct {
struct vpx_codec_enc_iface {
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_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;
};
......@@ -343,9 +350,20 @@ struct vpx_codec_priv {
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 typ id##__value(va_list args) {return va_arg(args, typ);} \
......
......@@ -35,8 +35,11 @@ vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t *ctx,
res = VPX_CODEC_INCAPABLE;
else if ((flags & VPX_CODEC_USE_POSTPROC) && !(iface->caps & VPX_CODEC_CAP_POSTPROC))
res = VPX_CODEC_INCAPABLE;
else if ((flags & VPX_CODEC_USE_INPUT_PARTITION) &&
!(iface->caps & VPX_CODEC_CAP_INPUT_PARTITION))
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;
......@@ -50,7 +53,7 @@ vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t *ctx,
res = VPX_CODEC_OK;
if (!(flags & VPX_CODEC_USE_XMA)) {
res = ctx->iface->init(ctx);
res = ctx->iface->init(ctx, NULL);
if (res) {
ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
......
/*
* 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 <stdlib.h>
#include <string.h>
#include "vpx/vpx_decoder.h"
#include "vpx/internal/vpx_codec_internal.h"
#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
const char *vpx_dec_iface_name(vpx_dec_iface_t *iface) {
return vpx_codec_iface_name((vpx_codec_iface_t *)iface);
}
const char *vpx_dec_err_to_string(vpx_dec_err_t err) {
return vpx_codec_err_to_string(err);
}
const char *vpx_dec_error(vpx_dec_ctx_t *ctx) {
return vpx_codec_error((vpx_codec_ctx_t *)ctx);
}
const char *vpx_dec_error_detail(vpx_dec_ctx_t *ctx) {
return vpx_codec_error_detail((vpx_codec_ctx_t *)ctx);
}
vpx_dec_err_t vpx_dec_init_ver(vpx_dec_ctx_t *ctx,
vpx_dec_iface_t *iface,
int ver) {
return vpx_codec_dec_init_ver((vpx_codec_ctx_t *)ctx,
(vpx_codec_iface_t *)iface,
NULL,
0,
ver);
}
vpx_dec_err_t vpx_dec_destroy(vpx_dec_ctx_t *ctx) {
return vpx_codec_destroy((vpx_codec_ctx_t *)ctx);
}
vpx_dec_caps_t vpx_dec_get_caps(vpx_dec_iface_t *iface) {
return vpx_codec_get_caps((vpx_codec_iface_t *)iface);
}
vpx_dec_err_t vpx_dec_peek_stream_info(vpx_dec_iface_t *iface,
const uint8_t *data,
unsigned int data_sz,
vpx_dec_stream_info_t *si) {
return vpx_codec_peek_stream_info((vpx_codec_iface_t *)iface, data, data_sz,
(vpx_codec_stream_info_t *)si);
}
vpx_dec_err_t vpx_dec_get_stream_info(vpx_dec_ctx_t *ctx,
vpx_dec_stream_info_t *si) {
return vpx_codec_get_stream_info((vpx_codec_ctx_t *)ctx,
(vpx_codec_stream_info_t *)si);
}
vpx_dec_err_t vpx_dec_control(vpx_dec_ctx_t *ctx,
int ctrl_id,
void *data) {
return vpx_codec_control_((vpx_codec_ctx_t *)ctx, ctrl_id, data);
}
vpx_dec_err_t vpx_dec_decode(vpx_dec_ctx_t *ctx,
uint8_t *data,
unsigned int data_sz,
void *user_priv,
int rel_pts) {
(void)rel_pts;
return vpx_codec_decode((vpx_codec_ctx_t *)ctx, data, data_sz, user_priv,
0);
}
vpx_image_t *vpx_dec_get_frame(vpx_dec_ctx_t *ctx,
vpx_dec_iter_t *iter) {
return vpx_codec_get_frame((vpx_codec_ctx_t *)ctx, iter);
}
vpx_dec_err_t vpx_dec_register_put_frame_cb(vpx_dec_ctx_t *ctx,
vpx_dec_put_frame_cb_fn_t cb,
void *user_priv) {
return vpx_codec_register_put_frame_cb((vpx_codec_ctx_t *)ctx, cb,
user_priv);
}
vpx_dec_err_t vpx_dec_register_put_slice_cb(vpx_dec_ctx_t *ctx,
vpx_dec_put_slice_cb_fn_t cb,
void *user_priv) {
return vpx_codec_register_put_slice_cb((vpx_codec_ctx_t *)ctx, cb,
user_priv);
}
vpx_dec_err_t vpx_dec_xma_init_ver(vpx_dec_ctx_t *ctx,
vpx_dec_iface_t *iface,
int ver) {
return vpx_codec_dec_init_ver((vpx_codec_ctx_t *)ctx,
(vpx_codec_iface_t *)iface,
NULL,
VPX_CODEC_USE_XMA,
ver);
}
vpx_dec_err_t vpx_dec_get_mem_map(vpx_dec_ctx_t *ctx_,
vpx_dec_mmap_t *mmap,
const vpx_dec_stream_info_t *si,
vpx_dec_iter_t *iter) {
vpx_codec_ctx_t *ctx = (vpx_codec_ctx_t *)ctx_;
vpx_dec_err_t res = VPX_DEC_OK;
if (!ctx || !mmap || !si || !iter || !ctx->iface)
res = VPX_DEC_INVALID_PARAM;
else if (!(ctx->iface->caps & VPX_DEC_CAP_XMA))
res = VPX_DEC_ERROR;
else {
if (!ctx->config.dec) {
ctx->config.dec = malloc(sizeof(vpx_codec_dec_cfg_t));
ctx->config.dec->w = si->w;
ctx->config.dec->h = si->h;
}
res = ctx->iface->get_mmap(ctx, mmap, iter);
}
return SAVE_STATUS(ctx, res);
}
vpx_dec_err_t vpx_dec_set_mem_map(vpx_dec_ctx_t *ctx_,
vpx_dec_mmap_t *mmap,
unsigned int num_maps) {
vpx_codec_ctx_t *ctx = (vpx_codec_ctx_t *)ctx_;
vpx_dec_err_t res = VPX_DEC_MEM_ERROR;
if (!ctx || !mmap || !ctx->iface)
res = VPX_DEC_INVALID_PARAM;
else if (!(ctx->iface->caps & VPX_DEC_CAP_XMA))
res = VPX_DEC_ERROR;
else {
void *save = (ctx->priv) ? NULL : ctx->config.dec;
unsigned int i;
for (i = 0; i < num_maps; i++, mmap++) {
if (!mmap->base)
break;
/* Everything look ok, set the mmap in the decoder */
res = ctx->iface->set_mmap(ctx, mmap);
if (res)
break;
}
if (save) free(save);
}
return SAVE_STATUS(ctx, res);
}
......@@ -49,7 +49,7 @@ vpx_codec_err_t vpx_codec_enc_init_ver(vpx_codec_ctx_t *ctx,
ctx->priv = NULL;
ctx->init_flags = flags;
ctx->config.enc = cfg;
res = ctx->iface->init(ctx);
res = ctx->iface->init(ctx, NULL);
if (res) {
ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
......@@ -63,6 +63,97 @@ vpx_codec_err_t vpx_codec_enc_init_ver(vpx_codec_ctx_t *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 = 0;
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_XMA) && !(iface->caps & VPX_CODEC_CAP_XMA))
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 (ctx->priv)
ctx->priv->iface = ctx->iface;
if (res)
break;
ctx++;
cfg++;
dsf++;
}
}
}
return SAVE_STATUS(ctx, res);
}
vpx_codec_err_t vpx_codec_enc_config_default(vpx_codec_iface_t *iface,
......@@ -115,7 +206,7 @@ vpx_codec_err_t vpx_codec_encode(vpx_codec_ctx_t *ctx,
unsigned long duration,
vpx_enc_frame_flags_t flags,
unsigned long deadline) {
vpx_codec_err_t res;
vpx_codec_err_t res = 0;
if (!ctx || (img && !duration))
res = VPX_CODEC_INVALID_PARAM;
......@@ -127,9 +218,35 @@ vpx_codec_err_t vpx_codec_encode(vpx_codec_ctx_t *ctx,
/* Execute in a normalized floating point environment, if the platform
* requires it.
*/
unsigned int num_enc = ctx->priv->enc.total_encoders;
FLOATING_POINT_INIT();
res = ctx->iface->enc.encode(ctx->priv->alg_priv, img, pts,
duration, flags, deadline);
if (num_enc == 1)
res = ctx->iface->enc.encode(ctx->priv->alg_priv, 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;