1474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org/* 2474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * 4474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * Use of this source code is governed by a BSD-style license 5474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * that can be found in the LICENSE file in the root of the source 6474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * tree. An additional intellectual property rights grant can be found 7474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * in the file PATENTS. All contributing project authors may 8474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * be found in the AUTHORS file in the root of the source tree. 9474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org */ 10474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 11474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 12474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org/*!\file 13474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * \brief Provides the high level interface to wrap encoder algorithms. 14474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * 15474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org */ 16474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include <limits.h> 17474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include <string.h> 18474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "vpx/internal/vpx_codec_internal.h" 19474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "vpx_config.h" 20474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 21474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var) 22474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 23474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvpx_codec_err_t vpx_codec_enc_init_ver(vpx_codec_ctx_t *ctx, 24474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org vpx_codec_iface_t *iface, 25474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org vpx_codec_enc_cfg_t *cfg, 26474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org vpx_codec_flags_t flags, 276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int ver) { 286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vpx_codec_err_t res; 296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (ver != VPX_ENCODER_ABI_VERSION) 316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_ABI_MISMATCH; 326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (!ctx || !iface || !cfg) 336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INVALID_PARAM; 346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION) 356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_ABI_MISMATCH; 366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (!(iface->caps & VPX_CODEC_CAP_ENCODER)) 376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INCAPABLE; 386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if ((flags & VPX_CODEC_USE_XMA) && !(iface->caps & VPX_CODEC_CAP_XMA)) 396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INCAPABLE; 406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if ((flags & VPX_CODEC_USE_PSNR) 416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org && !(iface->caps & VPX_CODEC_CAP_PSNR)) 426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INCAPABLE; 436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if ((flags & VPX_CODEC_USE_OUTPUT_PARTITION) 446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org && !(iface->caps & VPX_CODEC_CAP_OUTPUT_PARTITION)) 456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INCAPABLE; 466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else { 476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->iface = iface; 486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->name = iface->name; 496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->priv = NULL; 506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->init_flags = flags; 516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->config.enc = cfg; 526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = ctx->iface->init(ctx, NULL); 536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (res) { 556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL; 566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vpx_codec_destroy(ctx); 57474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org } 58474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (ctx->priv) 606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->priv->iface = ctx->iface; 616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return SAVE_STATUS(ctx, res); 64474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 65474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 66167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.orgvpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx, 67167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org vpx_codec_iface_t *iface, 68167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org vpx_codec_enc_cfg_t *cfg, 69167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org int num_enc, 70167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org vpx_codec_flags_t flags, 71167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org vpx_rational_t *dsf, 726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int ver) { 7376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org vpx_codec_err_t res = VPX_CODEC_OK; 746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (ver != VPX_ENCODER_ABI_VERSION) 766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_ABI_MISMATCH; 776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (!ctx || !iface || !cfg || (num_enc > 16 || num_enc < 1)) 786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INVALID_PARAM; 796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION) 806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_ABI_MISMATCH; 816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (!(iface->caps & VPX_CODEC_CAP_ENCODER)) 826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INCAPABLE; 836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if ((flags & VPX_CODEC_USE_XMA) && !(iface->caps & VPX_CODEC_CAP_XMA)) 846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INCAPABLE; 856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if ((flags & VPX_CODEC_USE_PSNR) 866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org && !(iface->caps & VPX_CODEC_CAP_PSNR)) 876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INCAPABLE; 886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if ((flags & VPX_CODEC_USE_OUTPUT_PARTITION) 896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org && !(iface->caps & VPX_CODEC_CAP_OUTPUT_PARTITION)) 906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INCAPABLE; 916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else { 926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int i; 936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org void *mem_loc = NULL; 946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (!(res = iface->enc.mr_get_mem_loc(cfg, &mem_loc))) { 966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org for (i = 0; i < num_enc; i++) { 976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vpx_codec_priv_enc_mr_cfg_t mr_cfg; 986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org /* Validate down-sampling factor. */ 1006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (dsf->num < 1 || dsf->num > 4096 || dsf->den < 1 || 1016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org dsf->den > dsf->num) { 1026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INVALID_PARAM; 1036fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org break; 104167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org } 1056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org mr_cfg.mr_low_res_mode_info = mem_loc; 1076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org mr_cfg.mr_total_resolutions = num_enc; 1086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org mr_cfg.mr_encoder_id = num_enc - 1 - i; 1096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org mr_cfg.mr_down_sampling_factor.num = dsf->num; 1106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org mr_cfg.mr_down_sampling_factor.den = dsf->den; 1116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org /* Force Key-frame synchronization. Namely, encoder at higher 1136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * resolution always use the same frame_type chosen by the 1146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * lowest-resolution encoder. 1156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org */ 1166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (mr_cfg.mr_encoder_id) 1176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org cfg->kf_mode = VPX_KF_DISABLED; 1186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->iface = iface; 1206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->name = iface->name; 1216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->priv = NULL; 1226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->init_flags = flags; 1236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->config.enc = cfg; 1246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = ctx->iface->init(ctx, &mr_cfg); 1256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (res) { 1276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org const char *error_detail = 1286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->priv ? ctx->priv->err_detail : NULL; 1296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org /* Destroy current ctx */ 1306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->err_detail = error_detail; 1316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vpx_codec_destroy(ctx); 1326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org /* Destroy already allocated high-level ctx */ 1346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org while (i) { 1356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx--; 1366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->err_detail = error_detail; 1376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vpx_codec_destroy(ctx); 1386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org i--; 1396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 1406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 1416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (ctx->priv) 1436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->priv->iface = ctx->iface; 1446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (res) 1466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org break; 1476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx++; 1496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org cfg++; 1506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org dsf++; 1516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 1520e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org ctx--; 153167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org } 1546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 155167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org 1566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return SAVE_STATUS(ctx, res); 157167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org} 158474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 159474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 160474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvpx_codec_err_t vpx_codec_enc_config_default(vpx_codec_iface_t *iface, 1616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vpx_codec_enc_cfg_t *cfg, 1626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org unsigned int usage) { 1636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vpx_codec_err_t res; 1646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vpx_codec_enc_cfg_map_t *map; 1656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (!iface || !cfg || usage > INT_MAX) 1676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INVALID_PARAM; 1686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (!(iface->caps & VPX_CODEC_CAP_ENCODER)) 1696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INCAPABLE; 1706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else { 1716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INVALID_PARAM; 1726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org for (map = iface->enc.cfg_maps; map->usage >= 0; map++) { 1746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (map->usage == (int)usage) { 1756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *cfg = map->cfg; 1766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org cfg->g_usage = usage; 1776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_OK; 1786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org break; 1796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 180474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org } 1816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 182474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 1836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return res; 184474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 185474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 186474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 187474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if ARCH_X86 || ARCH_X86_64 188474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org/* On X86, disable the x87 unit's internal 80 bit precision for better 189474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * consistency with the SSE unit's 64 bit precision. 190474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org */ 191474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "vpx_ports/x86.h" 192474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define FLOATING_POINT_INIT() do {\ 1936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org unsigned short x87_orig_mode = x87_set_double_precision(); 194474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define FLOATING_POINT_RESTORE() \ 1956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org x87_set_control_word(x87_orig_mode); }while(0) 196474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 197474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 198474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#else 199474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void FLOATING_POINT_INIT() {} 200474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void FLOATING_POINT_RESTORE() {} 201474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif 202474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 203474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 204474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvpx_codec_err_t vpx_codec_encode(vpx_codec_ctx_t *ctx, 205474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org const vpx_image_t *img, 206474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org vpx_codec_pts_t pts, 207474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org unsigned long duration, 208474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org vpx_enc_frame_flags_t flags, 2096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org unsigned long deadline) { 21076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org vpx_codec_err_t res = VPX_CODEC_OK; 2116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (!ctx || (img && !duration)) 2136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INVALID_PARAM; 2146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (!ctx->iface || !ctx->priv) 2156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_ERROR; 2166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER)) 2176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INCAPABLE; 2186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else { 2199c920af5cd2f78ab30bb06f01f4a4d9d30d5c92bfgalligan@chromium.org unsigned int num_enc = ctx->priv->enc.total_encoders; 2209c920af5cd2f78ab30bb06f01f4a4d9d30d5c92bfgalligan@chromium.org 2216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org /* Execute in a normalized floating point environment, if the platform 2226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * requires it. 2236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org */ 2246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org FLOATING_POINT_INIT(); 2256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (num_enc == 1) 2276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = ctx->iface->enc.encode(ctx->priv->alg_priv, img, pts, 2286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org duration, flags, deadline); 2296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else { 2306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org /* Multi-resolution encoding: 2316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * Encode multi-levels in reverse order. For example, 2326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * if mr_total_resolutions = 3, first encode level 2, 2336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * then encode level 1, and finally encode level 0. 2346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org */ 2356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int i; 2366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx += num_enc - 1; 2386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (img) img += num_enc - 1; 2396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org for (i = num_enc - 1; i >= 0; i--) { 2416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if ((res = ctx->iface->enc.encode(ctx->priv->alg_priv, img, pts, 2426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org duration, flags, deadline))) 2436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org break; 2446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx--; 2466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (img) img--; 2476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 2486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx++; 249474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org } 250474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 2516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org FLOATING_POINT_RESTORE(); 2526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 2536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return SAVE_STATUS(ctx, res); 255474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 256474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 257474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 258411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.orgconst vpx_codec_cx_pkt_t *vpx_codec_get_cx_data(vpx_codec_ctx_t *ctx, 259411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org vpx_codec_iter_t *iter) { 2606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org const vpx_codec_cx_pkt_t *pkt = NULL; 261474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 2626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (ctx) { 2636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (!iter) 2646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->err = VPX_CODEC_INVALID_PARAM; 2656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (!ctx->iface || !ctx->priv) 2666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->err = VPX_CODEC_ERROR; 2676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER)) 2686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->err = VPX_CODEC_INCAPABLE; 2696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else 2706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org pkt = ctx->iface->enc.get_cx_data(ctx->priv->alg_priv, iter); 2716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 2726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (pkt && pkt->kind == VPX_CODEC_CX_FRAME_PKT) { 274411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org // If the application has specified a destination area for the 275411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org // compressed data, and the codec has not placed the data there, 276411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org // and it fits, copy it. 277411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org vpx_codec_priv_t *const priv = ctx->priv; 278411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org char *const dst_buf = (char *)priv->enc.cx_data_dst_buf.buf; 279411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org 280411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org if (dst_buf && 281411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org pkt->data.raw.buf != dst_buf && 282411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org pkt->data.raw.sz + priv->enc.cx_data_pad_before + 283411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org priv->enc.cx_data_pad_after <= priv->enc.cx_data_dst_buf.sz) { 284411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org vpx_codec_cx_pkt_t *modified_pkt = &priv->enc.cx_data_pkt; 285411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org 286411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org memcpy(dst_buf + priv->enc.cx_data_pad_before, pkt->data.raw.buf, 287411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org pkt->data.raw.sz); 2886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *modified_pkt = *pkt; 2896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org modified_pkt->data.raw.buf = dst_buf; 290411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org modified_pkt->data.raw.sz += priv->enc.cx_data_pad_before + 291411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org priv->enc.cx_data_pad_after; 2926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org pkt = modified_pkt; 2936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 294474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 2956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (dst_buf == pkt->data.raw.buf) { 296411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org priv->enc.cx_data_dst_buf.buf = dst_buf + pkt->data.raw.sz; 297411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org priv->enc.cx_data_dst_buf.sz -= pkt->data.raw.sz; 298474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org } 2996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 300474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 3016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return pkt; 302474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 303474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 304474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 305474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvpx_codec_err_t vpx_codec_set_cx_data_buf(vpx_codec_ctx_t *ctx, 3066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org const vpx_fixed_buf_t *buf, 3076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org unsigned int pad_before, 3086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org unsigned int pad_after) { 3096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (!ctx || !ctx->priv) 3106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return VPX_CODEC_INVALID_PARAM; 3116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 3126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (buf) { 3136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->priv->enc.cx_data_dst_buf = *buf; 3146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->priv->enc.cx_data_pad_before = pad_before; 3156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->priv->enc.cx_data_pad_after = pad_after; 3166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } else { 3176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->priv->enc.cx_data_dst_buf.buf = NULL; 3186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->priv->enc.cx_data_dst_buf.sz = 0; 3196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->priv->enc.cx_data_pad_before = 0; 3206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->priv->enc.cx_data_pad_after = 0; 3216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 3226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 3236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return VPX_CODEC_OK; 324474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 325474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 326474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 3276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgconst vpx_image_t *vpx_codec_get_preview_frame(vpx_codec_ctx_t *ctx) { 3286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vpx_image_t *img = NULL; 329474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 3306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (ctx) { 3316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (!ctx->iface || !ctx->priv) 3326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->err = VPX_CODEC_ERROR; 3336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER)) 3346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->err = VPX_CODEC_INCAPABLE; 3356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (!ctx->iface->enc.get_preview) 3366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->err = VPX_CODEC_INCAPABLE; 3376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else 3386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org img = ctx->iface->enc.get_preview(ctx->priv->alg_priv); 3396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 3406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 3416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return img; 342474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 343474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 344474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 3456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgvpx_fixed_buf_t *vpx_codec_get_global_headers(vpx_codec_ctx_t *ctx) { 3466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vpx_fixed_buf_t *buf = NULL; 347474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 3486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (ctx) { 3496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (!ctx->iface || !ctx->priv) 3506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->err = VPX_CODEC_ERROR; 3516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER)) 3526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->err = VPX_CODEC_INCAPABLE; 3536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (!ctx->iface->enc.get_glob_hdrs) 3546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ctx->err = VPX_CODEC_INCAPABLE; 3556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else 3566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org buf = ctx->iface->enc.get_glob_hdrs(ctx->priv->alg_priv); 3576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 3586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 3596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return buf; 360474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 361474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 362474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 363474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvpx_codec_err_t vpx_codec_enc_config_set(vpx_codec_ctx_t *ctx, 3646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org const vpx_codec_enc_cfg_t *cfg) { 3656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vpx_codec_err_t res; 366474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 3676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (!ctx || !ctx->iface || !ctx->priv || !cfg) 3686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INVALID_PARAM; 3696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER)) 3706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = VPX_CODEC_INCAPABLE; 3716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else 3726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org res = ctx->iface->enc.cfg_set(ctx->priv->alg_priv, cfg); 373474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 3746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return SAVE_STATUS(ctx, res); 375474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 376474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 377474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 378474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgint vpx_codec_pkt_list_add(struct vpx_codec_pkt_list *list, 3796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org const struct vpx_codec_cx_pkt *pkt) { 3806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (list->cnt < list->max) { 3816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org list->pkts[list->cnt++] = *pkt; 3826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return 0; 3836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 384474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 3856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return 1; 386474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 387474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 388474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 389474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgconst vpx_codec_cx_pkt_t *vpx_codec_pkt_list_get(struct vpx_codec_pkt_list *list, 3906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vpx_codec_iter_t *iter) { 3916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org const vpx_codec_cx_pkt_t *pkt; 392474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 3936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (!(*iter)) { 3946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *iter = list->pkts; 3956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 396474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 39793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pkt = (const vpx_codec_cx_pkt_t *)*iter; 398474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 3996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if ((size_t)(pkt - list->pkts) < list->cnt) 4006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *iter = pkt + 1; 4016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else 4026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org pkt = NULL; 403474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 4046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return pkt; 405474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 406