LCOV - code coverage report
Current view: top level - third_party/aom/aom/src - aom_encoder.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 192 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016, Alliance for Open Media. All rights reserved
       3             :  *
       4             :  * This source code is subject to the terms of the BSD 2 Clause License and
       5             :  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
       6             :  * was not distributed with this source code in the LICENSE file, you can
       7             :  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
       8             :  * Media Patent License 1.0 was not distributed with this source code in the
       9             :  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
      10             :  */
      11             : 
      12             : /*!\file
      13             :  * \brief Provides the high level interface to wrap encoder algorithms.
      14             :  *
      15             :  */
      16             : #include "./aom_config.h"
      17             : 
      18             : #if HAVE_FEXCEPT
      19             : #define _GNU_SOURCE
      20             : #include <fenv.h>
      21             : #endif
      22             : 
      23             : #include <limits.h>
      24             : #include <string.h>
      25             : #include "aom/internal/aom_codec_internal.h"
      26             : 
      27             : #define SAVE_STATUS(ctx, var) (ctx ? (ctx->err = var) : var)
      28             : 
      29           0 : static aom_codec_alg_priv_t *get_alg_priv(aom_codec_ctx_t *ctx) {
      30           0 :   return (aom_codec_alg_priv_t *)ctx->priv;
      31             : }
      32             : 
      33           0 : aom_codec_err_t aom_codec_enc_init_ver(aom_codec_ctx_t *ctx,
      34             :                                        aom_codec_iface_t *iface,
      35             :                                        const aom_codec_enc_cfg_t *cfg,
      36             :                                        aom_codec_flags_t flags, int ver) {
      37             :   aom_codec_err_t res;
      38             : 
      39           0 :   if (ver != AOM_ENCODER_ABI_VERSION)
      40           0 :     res = AOM_CODEC_ABI_MISMATCH;
      41           0 :   else if (!ctx || !iface || !cfg)
      42           0 :     res = AOM_CODEC_INVALID_PARAM;
      43           0 :   else if (iface->abi_version != AOM_CODEC_INTERNAL_ABI_VERSION)
      44           0 :     res = AOM_CODEC_ABI_MISMATCH;
      45           0 :   else if (!(iface->caps & AOM_CODEC_CAP_ENCODER))
      46           0 :     res = AOM_CODEC_INCAPABLE;
      47           0 :   else if ((flags & AOM_CODEC_USE_PSNR) && !(iface->caps & AOM_CODEC_CAP_PSNR))
      48           0 :     res = AOM_CODEC_INCAPABLE;
      49           0 :   else if ((flags & AOM_CODEC_USE_OUTPUT_PARTITION) &&
      50           0 :            !(iface->caps & AOM_CODEC_CAP_OUTPUT_PARTITION))
      51           0 :     res = AOM_CODEC_INCAPABLE;
      52             :   else {
      53           0 :     ctx->iface = iface;
      54           0 :     ctx->name = iface->name;
      55           0 :     ctx->priv = NULL;
      56           0 :     ctx->init_flags = flags;
      57           0 :     ctx->config.enc = cfg;
      58           0 :     res = ctx->iface->init(ctx, NULL);
      59             : 
      60           0 :     if (res) {
      61           0 :       ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
      62           0 :       aom_codec_destroy(ctx);
      63             :     }
      64             :   }
      65             : 
      66           0 :   return SAVE_STATUS(ctx, res);
      67             : }
      68             : 
      69           0 : aom_codec_err_t aom_codec_enc_init_multi_ver(
      70             :     aom_codec_ctx_t *ctx, aom_codec_iface_t *iface, aom_codec_enc_cfg_t *cfg,
      71             :     int num_enc, aom_codec_flags_t flags, aom_rational_t *dsf, int ver) {
      72           0 :   aom_codec_err_t res = AOM_CODEC_OK;
      73             : 
      74           0 :   if (ver != AOM_ENCODER_ABI_VERSION)
      75           0 :     res = AOM_CODEC_ABI_MISMATCH;
      76           0 :   else if (!ctx || !iface || !cfg || (num_enc > 16 || num_enc < 1))
      77           0 :     res = AOM_CODEC_INVALID_PARAM;
      78           0 :   else if (iface->abi_version != AOM_CODEC_INTERNAL_ABI_VERSION)
      79           0 :     res = AOM_CODEC_ABI_MISMATCH;
      80           0 :   else if (!(iface->caps & AOM_CODEC_CAP_ENCODER))
      81           0 :     res = AOM_CODEC_INCAPABLE;
      82           0 :   else if ((flags & AOM_CODEC_USE_PSNR) && !(iface->caps & AOM_CODEC_CAP_PSNR))
      83           0 :     res = AOM_CODEC_INCAPABLE;
      84           0 :   else if ((flags & AOM_CODEC_USE_OUTPUT_PARTITION) &&
      85           0 :            !(iface->caps & AOM_CODEC_CAP_OUTPUT_PARTITION))
      86           0 :     res = AOM_CODEC_INCAPABLE;
      87             :   else {
      88             :     int i;
      89           0 :     void *mem_loc = NULL;
      90             : 
      91           0 :     if (!(res = iface->enc.mr_get_mem_loc(cfg, &mem_loc))) {
      92           0 :       for (i = 0; i < num_enc; i++) {
      93             :         aom_codec_priv_enc_mr_cfg_t mr_cfg;
      94             : 
      95             :         /* Validate down-sampling factor. */
      96           0 :         if (dsf->num < 1 || dsf->num > 4096 || dsf->den < 1 ||
      97           0 :             dsf->den > dsf->num) {
      98           0 :           res = AOM_CODEC_INVALID_PARAM;
      99           0 :           break;
     100             :         }
     101             : 
     102           0 :         mr_cfg.mr_low_res_mode_info = mem_loc;
     103           0 :         mr_cfg.mr_total_resolutions = num_enc;
     104           0 :         mr_cfg.mr_encoder_id = num_enc - 1 - i;
     105           0 :         mr_cfg.mr_down_sampling_factor.num = dsf->num;
     106           0 :         mr_cfg.mr_down_sampling_factor.den = dsf->den;
     107             : 
     108             :         /* Force Key-frame synchronization. Namely, encoder at higher
     109             :          * resolution always use the same frame_type chosen by the
     110             :          * lowest-resolution encoder.
     111             :          */
     112           0 :         if (mr_cfg.mr_encoder_id) cfg->kf_mode = AOM_KF_DISABLED;
     113             : 
     114           0 :         ctx->iface = iface;
     115           0 :         ctx->name = iface->name;
     116           0 :         ctx->priv = NULL;
     117           0 :         ctx->init_flags = flags;
     118           0 :         ctx->config.enc = cfg;
     119           0 :         res = ctx->iface->init(ctx, &mr_cfg);
     120             : 
     121           0 :         if (res) {
     122           0 :           const char *error_detail = ctx->priv ? ctx->priv->err_detail : NULL;
     123             :           /* Destroy current ctx */
     124           0 :           ctx->err_detail = error_detail;
     125           0 :           aom_codec_destroy(ctx);
     126             : 
     127             :           /* Destroy already allocated high-level ctx */
     128           0 :           while (i) {
     129           0 :             ctx--;
     130           0 :             ctx->err_detail = error_detail;
     131           0 :             aom_codec_destroy(ctx);
     132           0 :             i--;
     133             :           }
     134             :         }
     135             : 
     136           0 :         if (res) break;
     137             : 
     138           0 :         ctx++;
     139           0 :         cfg++;
     140           0 :         dsf++;
     141             :       }
     142           0 :       ctx--;
     143             :     }
     144             :   }
     145             : 
     146           0 :   return SAVE_STATUS(ctx, res);
     147             : }
     148             : 
     149           0 : aom_codec_err_t aom_codec_enc_config_default(aom_codec_iface_t *iface,
     150             :                                              aom_codec_enc_cfg_t *cfg,
     151             :                                              unsigned int usage) {
     152             :   aom_codec_err_t res;
     153             :   aom_codec_enc_cfg_map_t *map;
     154             :   int i;
     155             : 
     156           0 :   if (!iface || !cfg || usage > INT_MAX)
     157           0 :     res = AOM_CODEC_INVALID_PARAM;
     158           0 :   else if (!(iface->caps & AOM_CODEC_CAP_ENCODER))
     159           0 :     res = AOM_CODEC_INCAPABLE;
     160             :   else {
     161           0 :     res = AOM_CODEC_INVALID_PARAM;
     162             : 
     163           0 :     for (i = 0; i < iface->enc.cfg_map_count; ++i) {
     164           0 :       map = iface->enc.cfg_maps + i;
     165           0 :       if (map->usage == (int)usage) {
     166           0 :         *cfg = map->cfg;
     167           0 :         cfg->g_usage = usage;
     168           0 :         res = AOM_CODEC_OK;
     169           0 :         break;
     170             :       }
     171             :     }
     172             :   }
     173             : 
     174           0 :   return res;
     175             : }
     176             : 
     177             : /* clang-format off */
     178             : #define FLOATING_POINT_BEGIN_SCOPE do {
     179             : #define FLOATING_POINT_END_SCOPE } while (0);
     180             : /* clang-format on */
     181             : 
     182             : #if ARCH_X86 || ARCH_X86_64
     183             : /* On X86, disable the x87 unit's internal 80 bit precision for better
     184             :  * consistency with the SSE unit's 64 bit precision.
     185             :  */
     186             : #include "aom_ports/x86.h"
     187             : #define FLOATING_POINT_SET_PRECISION \
     188             :   unsigned short x87_orig_mode = x87_set_double_precision();
     189             : #define FLOATING_POINT_RESTORE_PRECISION x87_set_control_word(x87_orig_mode);
     190             : #else
     191             : #define FLOATING_POINT_SET_PRECISION
     192             : #define FLOATING_POINT_RESTORE_PRECISION
     193             : #endif  // ARCH_X86 || ARCH_X86_64
     194             : 
     195             : #if HAVE_FEXCEPT && CONFIG_DEBUG
     196             : #define FLOATING_POINT_SET_EXCEPTIONS \
     197             :   const int float_excepts = feenableexcept(FE_DIVBYZERO);
     198             : #define FLOATING_POINT_RESTORE_EXCEPTIONS feenableexcept(float_excepts);
     199             : #else
     200             : #define FLOATING_POINT_SET_EXCEPTIONS
     201             : #define FLOATING_POINT_RESTORE_EXCEPTIONS
     202             : #endif  // HAVE_FEXCEPT && CONFIG_DEBUG
     203             : 
     204             : #define FLOATING_POINT_INIT    \
     205             :   FLOATING_POINT_BEGIN_SCOPE   \
     206             :   FLOATING_POINT_SET_PRECISION \
     207             :   FLOATING_POINT_SET_EXCEPTIONS
     208             : 
     209             : #define FLOATING_POINT_RESTORE      \
     210             :   FLOATING_POINT_RESTORE_EXCEPTIONS \
     211             :   FLOATING_POINT_RESTORE_PRECISION  \
     212             :   FLOATING_POINT_END_SCOPE
     213             : 
     214           0 : aom_codec_err_t aom_codec_encode(aom_codec_ctx_t *ctx, const aom_image_t *img,
     215             :                                  aom_codec_pts_t pts, unsigned long duration,
     216             :                                  aom_enc_frame_flags_t flags,
     217             :                                  unsigned long deadline) {
     218           0 :   aom_codec_err_t res = AOM_CODEC_OK;
     219             : 
     220           0 :   if (!ctx || (img && !duration))
     221           0 :     res = AOM_CODEC_INVALID_PARAM;
     222           0 :   else if (!ctx->iface || !ctx->priv)
     223           0 :     res = AOM_CODEC_ERROR;
     224           0 :   else if (!(ctx->iface->caps & AOM_CODEC_CAP_ENCODER))
     225           0 :     res = AOM_CODEC_INCAPABLE;
     226             :   else {
     227           0 :     unsigned int num_enc = ctx->priv->enc.total_encoders;
     228             : 
     229             :     /* Execute in a normalized floating point environment, if the platform
     230             :      * requires it.
     231             :      */
     232           0 :     FLOATING_POINT_INIT
     233             : 
     234           0 :     if (num_enc == 1)
     235           0 :       res = ctx->iface->enc.encode(get_alg_priv(ctx), img, pts, duration, flags,
     236             :                                    deadline);
     237             :     else {
     238             :       /* Multi-resolution encoding:
     239             :        * Encode multi-levels in reverse order. For example,
     240             :        * if mr_total_resolutions = 3, first encode level 2,
     241             :        * then encode level 1, and finally encode level 0.
     242             :        */
     243             :       int i;
     244             : 
     245           0 :       ctx += num_enc - 1;
     246           0 :       if (img) img += num_enc - 1;
     247             : 
     248           0 :       for (i = num_enc - 1; i >= 0; i--) {
     249           0 :         if ((res = ctx->iface->enc.encode(get_alg_priv(ctx), img, pts, duration,
     250             :                                           flags, deadline)))
     251           0 :           break;
     252             : 
     253           0 :         ctx--;
     254           0 :         if (img) img--;
     255             :       }
     256           0 :       ctx++;
     257             :     }
     258             : 
     259           0 :     FLOATING_POINT_RESTORE
     260             :   }
     261             : 
     262           0 :   return SAVE_STATUS(ctx, res);
     263             : }
     264             : 
     265           0 : const aom_codec_cx_pkt_t *aom_codec_get_cx_data(aom_codec_ctx_t *ctx,
     266             :                                                 aom_codec_iter_t *iter) {
     267           0 :   const aom_codec_cx_pkt_t *pkt = NULL;
     268             : 
     269           0 :   if (ctx) {
     270           0 :     if (!iter)
     271           0 :       ctx->err = AOM_CODEC_INVALID_PARAM;
     272           0 :     else if (!ctx->iface || !ctx->priv)
     273           0 :       ctx->err = AOM_CODEC_ERROR;
     274           0 :     else if (!(ctx->iface->caps & AOM_CODEC_CAP_ENCODER))
     275           0 :       ctx->err = AOM_CODEC_INCAPABLE;
     276             :     else
     277           0 :       pkt = ctx->iface->enc.get_cx_data(get_alg_priv(ctx), iter);
     278             :   }
     279             : 
     280           0 :   if (pkt && pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
     281             :     // If the application has specified a destination area for the
     282             :     // compressed data, and the codec has not placed the data there,
     283             :     // and it fits, copy it.
     284           0 :     aom_codec_priv_t *const priv = ctx->priv;
     285           0 :     char *const dst_buf = (char *)priv->enc.cx_data_dst_buf.buf;
     286             : 
     287           0 :     if (dst_buf && pkt->data.raw.buf != dst_buf &&
     288           0 :         pkt->data.raw.sz + priv->enc.cx_data_pad_before +
     289           0 :                 priv->enc.cx_data_pad_after <=
     290           0 :             priv->enc.cx_data_dst_buf.sz) {
     291           0 :       aom_codec_cx_pkt_t *modified_pkt = &priv->enc.cx_data_pkt;
     292             : 
     293           0 :       memcpy(dst_buf + priv->enc.cx_data_pad_before, pkt->data.raw.buf,
     294             :              pkt->data.raw.sz);
     295           0 :       *modified_pkt = *pkt;
     296           0 :       modified_pkt->data.raw.buf = dst_buf;
     297           0 :       modified_pkt->data.raw.sz +=
     298           0 :           priv->enc.cx_data_pad_before + priv->enc.cx_data_pad_after;
     299           0 :       pkt = modified_pkt;
     300             :     }
     301             : 
     302           0 :     if (dst_buf == pkt->data.raw.buf) {
     303           0 :       priv->enc.cx_data_dst_buf.buf = dst_buf + pkt->data.raw.sz;
     304           0 :       priv->enc.cx_data_dst_buf.sz -= pkt->data.raw.sz;
     305             :     }
     306             :   }
     307             : 
     308           0 :   return pkt;
     309             : }
     310             : 
     311           0 : aom_codec_err_t aom_codec_set_cx_data_buf(aom_codec_ctx_t *ctx,
     312             :                                           const aom_fixed_buf_t *buf,
     313             :                                           unsigned int pad_before,
     314             :                                           unsigned int pad_after) {
     315           0 :   if (!ctx || !ctx->priv) return AOM_CODEC_INVALID_PARAM;
     316             : 
     317           0 :   if (buf) {
     318           0 :     ctx->priv->enc.cx_data_dst_buf = *buf;
     319           0 :     ctx->priv->enc.cx_data_pad_before = pad_before;
     320           0 :     ctx->priv->enc.cx_data_pad_after = pad_after;
     321             :   } else {
     322           0 :     ctx->priv->enc.cx_data_dst_buf.buf = NULL;
     323           0 :     ctx->priv->enc.cx_data_dst_buf.sz = 0;
     324           0 :     ctx->priv->enc.cx_data_pad_before = 0;
     325           0 :     ctx->priv->enc.cx_data_pad_after = 0;
     326             :   }
     327             : 
     328           0 :   return AOM_CODEC_OK;
     329             : }
     330             : 
     331           0 : const aom_image_t *aom_codec_get_preview_frame(aom_codec_ctx_t *ctx) {
     332           0 :   aom_image_t *img = NULL;
     333             : 
     334           0 :   if (ctx) {
     335           0 :     if (!ctx->iface || !ctx->priv)
     336           0 :       ctx->err = AOM_CODEC_ERROR;
     337           0 :     else if (!(ctx->iface->caps & AOM_CODEC_CAP_ENCODER))
     338           0 :       ctx->err = AOM_CODEC_INCAPABLE;
     339           0 :     else if (!ctx->iface->enc.get_preview)
     340           0 :       ctx->err = AOM_CODEC_INCAPABLE;
     341             :     else
     342           0 :       img = ctx->iface->enc.get_preview(get_alg_priv(ctx));
     343             :   }
     344             : 
     345           0 :   return img;
     346             : }
     347             : 
     348           0 : aom_fixed_buf_t *aom_codec_get_global_headers(aom_codec_ctx_t *ctx) {
     349           0 :   aom_fixed_buf_t *buf = NULL;
     350             : 
     351           0 :   if (ctx) {
     352           0 :     if (!ctx->iface || !ctx->priv)
     353           0 :       ctx->err = AOM_CODEC_ERROR;
     354           0 :     else if (!(ctx->iface->caps & AOM_CODEC_CAP_ENCODER))
     355           0 :       ctx->err = AOM_CODEC_INCAPABLE;
     356           0 :     else if (!ctx->iface->enc.get_glob_hdrs)
     357           0 :       ctx->err = AOM_CODEC_INCAPABLE;
     358             :     else
     359           0 :       buf = ctx->iface->enc.get_glob_hdrs(get_alg_priv(ctx));
     360             :   }
     361             : 
     362           0 :   return buf;
     363             : }
     364             : 
     365           0 : aom_codec_err_t aom_codec_enc_config_set(aom_codec_ctx_t *ctx,
     366             :                                          const aom_codec_enc_cfg_t *cfg) {
     367             :   aom_codec_err_t res;
     368             : 
     369           0 :   if (!ctx || !ctx->iface || !ctx->priv || !cfg)
     370           0 :     res = AOM_CODEC_INVALID_PARAM;
     371           0 :   else if (!(ctx->iface->caps & AOM_CODEC_CAP_ENCODER))
     372           0 :     res = AOM_CODEC_INCAPABLE;
     373             :   else
     374           0 :     res = ctx->iface->enc.cfg_set(get_alg_priv(ctx), cfg);
     375             : 
     376           0 :   return SAVE_STATUS(ctx, res);
     377             : }
     378             : 
     379           0 : int aom_codec_pkt_list_add(struct aom_codec_pkt_list *list,
     380             :                            const struct aom_codec_cx_pkt *pkt) {
     381           0 :   if (list->cnt < list->max) {
     382           0 :     list->pkts[list->cnt++] = *pkt;
     383           0 :     return 0;
     384             :   }
     385             : 
     386           0 :   return 1;
     387             : }
     388             : 
     389           0 : const aom_codec_cx_pkt_t *aom_codec_pkt_list_get(
     390             :     struct aom_codec_pkt_list *list, aom_codec_iter_t *iter) {
     391             :   const aom_codec_cx_pkt_t *pkt;
     392             : 
     393           0 :   if (!(*iter)) {
     394           0 :     *iter = list->pkts;
     395             :   }
     396             : 
     397           0 :   pkt = (const aom_codec_cx_pkt_t *)*iter;
     398             : 
     399           0 :   if ((size_t)(pkt - list->pkts) < list->cnt)
     400           0 :     *iter = pkt + 1;
     401             :   else
     402           0 :     pkt = NULL;
     403             : 
     404           0 :   return pkt;
     405             : }

Generated by: LCOV version 1.13