xref: /aosp_15_r20/external/libaom/aom/src/aom_encoder.c (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker  *
4*77c1e3ccSAndroid Build Coastguard Worker  * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker  * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker  * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker  */
11*77c1e3ccSAndroid Build Coastguard Worker 
12*77c1e3ccSAndroid Build Coastguard Worker /*!\file
13*77c1e3ccSAndroid Build Coastguard Worker  * \brief Provides the high level interface to wrap encoder algorithms.
14*77c1e3ccSAndroid Build Coastguard Worker  *
15*77c1e3ccSAndroid Build Coastguard Worker  */
16*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_config.h"
17*77c1e3ccSAndroid Build Coastguard Worker 
18*77c1e3ccSAndroid Build Coastguard Worker #if HAVE_FEXCEPT
19*77c1e3ccSAndroid Build Coastguard Worker #ifndef _GNU_SOURCE
20*77c1e3ccSAndroid Build Coastguard Worker #define _GNU_SOURCE
21*77c1e3ccSAndroid Build Coastguard Worker #endif
22*77c1e3ccSAndroid Build Coastguard Worker #include <fenv.h>
23*77c1e3ccSAndroid Build Coastguard Worker #endif
24*77c1e3ccSAndroid Build Coastguard Worker 
25*77c1e3ccSAndroid Build Coastguard Worker #include <limits.h>
26*77c1e3ccSAndroid Build Coastguard Worker #include <stdint.h>
27*77c1e3ccSAndroid Build Coastguard Worker #include <string.h>
28*77c1e3ccSAndroid Build Coastguard Worker 
29*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aom_encoder.h"
30*77c1e3ccSAndroid Build Coastguard Worker #include "aom/internal/aom_codec_internal.h"
31*77c1e3ccSAndroid Build Coastguard Worker 
32*77c1e3ccSAndroid Build Coastguard Worker #define SAVE_STATUS(ctx, var) (ctx ? (ctx->err = var) : var)
33*77c1e3ccSAndroid Build Coastguard Worker 
get_alg_priv(aom_codec_ctx_t * ctx)34*77c1e3ccSAndroid Build Coastguard Worker static aom_codec_alg_priv_t *get_alg_priv(aom_codec_ctx_t *ctx) {
35*77c1e3ccSAndroid Build Coastguard Worker   return (aom_codec_alg_priv_t *)ctx->priv;
36*77c1e3ccSAndroid Build Coastguard Worker }
37*77c1e3ccSAndroid Build Coastguard Worker 
aom_codec_enc_init_ver(aom_codec_ctx_t * ctx,aom_codec_iface_t * iface,const aom_codec_enc_cfg_t * cfg,aom_codec_flags_t flags,int ver)38*77c1e3ccSAndroid Build Coastguard Worker aom_codec_err_t aom_codec_enc_init_ver(aom_codec_ctx_t *ctx,
39*77c1e3ccSAndroid Build Coastguard Worker                                        aom_codec_iface_t *iface,
40*77c1e3ccSAndroid Build Coastguard Worker                                        const aom_codec_enc_cfg_t *cfg,
41*77c1e3ccSAndroid Build Coastguard Worker                                        aom_codec_flags_t flags, int ver) {
42*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_err_t res;
43*77c1e3ccSAndroid Build Coastguard Worker   // The value of AOM_ENCODER_ABI_VERSION in libaom v3.0.0 and v3.1.0 - v3.1.3.
44*77c1e3ccSAndroid Build Coastguard Worker   //
45*77c1e3ccSAndroid Build Coastguard Worker   // We are compatible with these older libaom releases. AOM_ENCODER_ABI_VERSION
46*77c1e3ccSAndroid Build Coastguard Worker   // was incremented after these releases for two reasons:
47*77c1e3ccSAndroid Build Coastguard Worker   // 1. AOM_ENCODER_ABI_VERSION takes contribution from
48*77c1e3ccSAndroid Build Coastguard Worker   //    AOM_EXT_PART_ABI_VERSION. The external partition API is still
49*77c1e3ccSAndroid Build Coastguard Worker   //    experimental, so it should not be considered as part of the stable ABI.
50*77c1e3ccSAndroid Build Coastguard Worker   //    fd9ed8366 External partition: Define APIs
51*77c1e3ccSAndroid Build Coastguard Worker   //    https://aomedia-review.googlesource.com/c/aom/+/135663
52*77c1e3ccSAndroid Build Coastguard Worker   // 2. As a way to detect the presence of speeds 7-9 in all-intra mode. I (wtc)
53*77c1e3ccSAndroid Build Coastguard Worker   //    suggested this change because I misunderstood how
54*77c1e3ccSAndroid Build Coastguard Worker   //    AOM_ENCODER_ABI_VERSION was used.
55*77c1e3ccSAndroid Build Coastguard Worker   //    bbdfa68d1 AllIntra: Redefine all-intra mode speed features for speed 7+
56*77c1e3ccSAndroid Build Coastguard Worker   //    https://aomedia-review.googlesource.com/c/aom/+/140624
57*77c1e3ccSAndroid Build Coastguard Worker   const int aom_encoder_abi_version_25 = 25;
58*77c1e3ccSAndroid Build Coastguard Worker 
59*77c1e3ccSAndroid Build Coastguard Worker   // TODO(bug aomedia:3228): Remove the check for aom_encoder_abi_version_25 in
60*77c1e3ccSAndroid Build Coastguard Worker   // libaom v4.0.0.
61*77c1e3ccSAndroid Build Coastguard Worker   if (ver != AOM_ENCODER_ABI_VERSION && ver != aom_encoder_abi_version_25)
62*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_ABI_MISMATCH;
63*77c1e3ccSAndroid Build Coastguard Worker   else if (!ctx || !iface || !cfg)
64*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_INVALID_PARAM;
65*77c1e3ccSAndroid Build Coastguard Worker   else if (iface->abi_version != AOM_CODEC_INTERNAL_ABI_VERSION)
66*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_ABI_MISMATCH;
67*77c1e3ccSAndroid Build Coastguard Worker   else if (!(iface->caps & AOM_CODEC_CAP_ENCODER))
68*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_INCAPABLE;
69*77c1e3ccSAndroid Build Coastguard Worker   else if ((flags & AOM_CODEC_USE_PSNR) && !(iface->caps & AOM_CODEC_CAP_PSNR))
70*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_INCAPABLE;
71*77c1e3ccSAndroid Build Coastguard Worker   else if ((flags & AOM_CODEC_USE_HIGHBITDEPTH) &&
72*77c1e3ccSAndroid Build Coastguard Worker            !(iface->caps & AOM_CODEC_CAP_HIGHBITDEPTH)) {
73*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_INCAPABLE;
74*77c1e3ccSAndroid Build Coastguard Worker   } else if (cfg->g_bit_depth > 8 &&
75*77c1e3ccSAndroid Build Coastguard Worker              (flags & AOM_CODEC_USE_HIGHBITDEPTH) == 0) {
76*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_INVALID_PARAM;
77*77c1e3ccSAndroid Build Coastguard Worker     ctx->err_detail =
78*77c1e3ccSAndroid Build Coastguard Worker         "High bit-depth used without the AOM_CODEC_USE_HIGHBITDEPTH flag.";
79*77c1e3ccSAndroid Build Coastguard Worker   } else {
80*77c1e3ccSAndroid Build Coastguard Worker     ctx->iface = iface;
81*77c1e3ccSAndroid Build Coastguard Worker     ctx->name = iface->name;
82*77c1e3ccSAndroid Build Coastguard Worker     ctx->priv = NULL;
83*77c1e3ccSAndroid Build Coastguard Worker     ctx->init_flags = flags;
84*77c1e3ccSAndroid Build Coastguard Worker     ctx->config.enc = cfg;
85*77c1e3ccSAndroid Build Coastguard Worker     res = ctx->iface->init(ctx);
86*77c1e3ccSAndroid Build Coastguard Worker 
87*77c1e3ccSAndroid Build Coastguard Worker     if (res) {
88*77c1e3ccSAndroid Build Coastguard Worker       // IMPORTANT: ctx->priv->err_detail must be null or point to a string
89*77c1e3ccSAndroid Build Coastguard Worker       // that remains valid after ctx->priv is destroyed, such as a C string
90*77c1e3ccSAndroid Build Coastguard Worker       // literal. This makes it safe to call aom_codec_error_detail() after
91*77c1e3ccSAndroid Build Coastguard Worker       // aom_codec_enc_init_ver() failed.
92*77c1e3ccSAndroid Build Coastguard Worker       ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
93*77c1e3ccSAndroid Build Coastguard Worker       aom_codec_destroy(ctx);
94*77c1e3ccSAndroid Build Coastguard Worker     }
95*77c1e3ccSAndroid Build Coastguard Worker   }
96*77c1e3ccSAndroid Build Coastguard Worker 
97*77c1e3ccSAndroid Build Coastguard Worker   return SAVE_STATUS(ctx, res);
98*77c1e3ccSAndroid Build Coastguard Worker }
99*77c1e3ccSAndroid Build Coastguard Worker 
aom_codec_enc_config_default(aom_codec_iface_t * iface,aom_codec_enc_cfg_t * cfg,unsigned int usage)100*77c1e3ccSAndroid Build Coastguard Worker aom_codec_err_t aom_codec_enc_config_default(aom_codec_iface_t *iface,
101*77c1e3ccSAndroid Build Coastguard Worker                                              aom_codec_enc_cfg_t *cfg,
102*77c1e3ccSAndroid Build Coastguard Worker                                              unsigned int usage) {
103*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_err_t res;
104*77c1e3ccSAndroid Build Coastguard Worker 
105*77c1e3ccSAndroid Build Coastguard Worker   if (!iface || !cfg)
106*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_INVALID_PARAM;
107*77c1e3ccSAndroid Build Coastguard Worker   else if (!(iface->caps & AOM_CODEC_CAP_ENCODER))
108*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_INCAPABLE;
109*77c1e3ccSAndroid Build Coastguard Worker   else {
110*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_INVALID_PARAM;
111*77c1e3ccSAndroid Build Coastguard Worker 
112*77c1e3ccSAndroid Build Coastguard Worker     for (int i = 0; i < iface->enc.cfg_count; ++i) {
113*77c1e3ccSAndroid Build Coastguard Worker       if (iface->enc.cfgs[i].g_usage == usage) {
114*77c1e3ccSAndroid Build Coastguard Worker         *cfg = iface->enc.cfgs[i];
115*77c1e3ccSAndroid Build Coastguard Worker         res = AOM_CODEC_OK;
116*77c1e3ccSAndroid Build Coastguard Worker         /* default values */
117*77c1e3ccSAndroid Build Coastguard Worker         memset(&cfg->encoder_cfg, 0, sizeof(cfg->encoder_cfg));
118*77c1e3ccSAndroid Build Coastguard Worker         cfg->encoder_cfg.super_block_size = 0;  // Dynamic
119*77c1e3ccSAndroid Build Coastguard Worker         cfg->encoder_cfg.max_partition_size = 128;
120*77c1e3ccSAndroid Build Coastguard Worker         cfg->encoder_cfg.min_partition_size = 4;
121*77c1e3ccSAndroid Build Coastguard Worker         cfg->encoder_cfg.disable_trellis_quant = 3;
122*77c1e3ccSAndroid Build Coastguard Worker         break;
123*77c1e3ccSAndroid Build Coastguard Worker       }
124*77c1e3ccSAndroid Build Coastguard Worker     }
125*77c1e3ccSAndroid Build Coastguard Worker   }
126*77c1e3ccSAndroid Build Coastguard Worker   return res;
127*77c1e3ccSAndroid Build Coastguard Worker }
128*77c1e3ccSAndroid Build Coastguard Worker 
129*77c1e3ccSAndroid Build Coastguard Worker #if AOM_ARCH_X86 || AOM_ARCH_X86_64
130*77c1e3ccSAndroid Build Coastguard Worker /* On X86, disable the x87 unit's internal 80 bit precision for better
131*77c1e3ccSAndroid Build Coastguard Worker  * consistency with the SSE unit's 64 bit precision.
132*77c1e3ccSAndroid Build Coastguard Worker  */
133*77c1e3ccSAndroid Build Coastguard Worker #include "aom_ports/x86.h"
134*77c1e3ccSAndroid Build Coastguard Worker #define FLOATING_POINT_SET_PRECISION \
135*77c1e3ccSAndroid Build Coastguard Worker   unsigned short x87_orig_mode = x87_set_double_precision();
136*77c1e3ccSAndroid Build Coastguard Worker #define FLOATING_POINT_RESTORE_PRECISION x87_set_control_word(x87_orig_mode);
137*77c1e3ccSAndroid Build Coastguard Worker #else
138*77c1e3ccSAndroid Build Coastguard Worker #define FLOATING_POINT_SET_PRECISION
139*77c1e3ccSAndroid Build Coastguard Worker #define FLOATING_POINT_RESTORE_PRECISION
140*77c1e3ccSAndroid Build Coastguard Worker #endif  // AOM_ARCH_X86 || AOM_ARCH_X86_64
141*77c1e3ccSAndroid Build Coastguard Worker 
142*77c1e3ccSAndroid Build Coastguard Worker #if HAVE_FEXCEPT && CONFIG_DEBUG
143*77c1e3ccSAndroid Build Coastguard Worker #define FLOATING_POINT_SET_EXCEPTIONS \
144*77c1e3ccSAndroid Build Coastguard Worker   const int float_excepts =           \
145*77c1e3ccSAndroid Build Coastguard Worker       feenableexcept(FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW);
146*77c1e3ccSAndroid Build Coastguard Worker #define FLOATING_POINT_RESTORE_EXCEPTIONS \
147*77c1e3ccSAndroid Build Coastguard Worker   if (float_excepts != -1) {              \
148*77c1e3ccSAndroid Build Coastguard Worker     fedisableexcept(FE_ALL_EXCEPT);       \
149*77c1e3ccSAndroid Build Coastguard Worker     feenableexcept(float_excepts);        \
150*77c1e3ccSAndroid Build Coastguard Worker   }
151*77c1e3ccSAndroid Build Coastguard Worker #else
152*77c1e3ccSAndroid Build Coastguard Worker #define FLOATING_POINT_SET_EXCEPTIONS
153*77c1e3ccSAndroid Build Coastguard Worker #define FLOATING_POINT_RESTORE_EXCEPTIONS
154*77c1e3ccSAndroid Build Coastguard Worker #endif  // HAVE_FEXCEPT && CONFIG_DEBUG
155*77c1e3ccSAndroid Build Coastguard Worker 
156*77c1e3ccSAndroid Build Coastguard Worker /* clang-format off */
157*77c1e3ccSAndroid Build Coastguard Worker #define FLOATING_POINT_INIT    \
158*77c1e3ccSAndroid Build Coastguard Worker   do {                         \
159*77c1e3ccSAndroid Build Coastguard Worker   FLOATING_POINT_SET_PRECISION \
160*77c1e3ccSAndroid Build Coastguard Worker   FLOATING_POINT_SET_EXCEPTIONS
161*77c1e3ccSAndroid Build Coastguard Worker 
162*77c1e3ccSAndroid Build Coastguard Worker #define FLOATING_POINT_RESTORE      \
163*77c1e3ccSAndroid Build Coastguard Worker   FLOATING_POINT_RESTORE_EXCEPTIONS \
164*77c1e3ccSAndroid Build Coastguard Worker   FLOATING_POINT_RESTORE_PRECISION  \
165*77c1e3ccSAndroid Build Coastguard Worker   } while (0);
166*77c1e3ccSAndroid Build Coastguard Worker /* clang-format on */
167*77c1e3ccSAndroid Build Coastguard Worker 
aom_codec_encode(aom_codec_ctx_t * ctx,const aom_image_t * img,aom_codec_pts_t pts,unsigned long duration,aom_enc_frame_flags_t flags)168*77c1e3ccSAndroid Build Coastguard Worker aom_codec_err_t aom_codec_encode(aom_codec_ctx_t *ctx, const aom_image_t *img,
169*77c1e3ccSAndroid Build Coastguard Worker                                  aom_codec_pts_t pts, unsigned long duration,
170*77c1e3ccSAndroid Build Coastguard Worker                                  aom_enc_frame_flags_t flags) {
171*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_err_t res = AOM_CODEC_OK;
172*77c1e3ccSAndroid Build Coastguard Worker 
173*77c1e3ccSAndroid Build Coastguard Worker   if (!ctx || (img && !duration))
174*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_INVALID_PARAM;
175*77c1e3ccSAndroid Build Coastguard Worker   else if (!ctx->iface || !ctx->priv)
176*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_ERROR;
177*77c1e3ccSAndroid Build Coastguard Worker   else if (!(ctx->iface->caps & AOM_CODEC_CAP_ENCODER))
178*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_INCAPABLE;
179*77c1e3ccSAndroid Build Coastguard Worker   else if (img && ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) != 0) !=
180*77c1e3ccSAndroid Build Coastguard Worker                       ((ctx->init_flags & AOM_CODEC_USE_HIGHBITDEPTH) != 0)) {
181*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_INVALID_PARAM;
182*77c1e3ccSAndroid Build Coastguard Worker #if ULONG_MAX > UINT32_MAX
183*77c1e3ccSAndroid Build Coastguard Worker   } else if (duration > UINT32_MAX) {
184*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_INVALID_PARAM;
185*77c1e3ccSAndroid Build Coastguard Worker #endif
186*77c1e3ccSAndroid Build Coastguard Worker   } else {
187*77c1e3ccSAndroid Build Coastguard Worker     /* Execute in a normalized floating point environment, if the platform
188*77c1e3ccSAndroid Build Coastguard Worker      * requires it.
189*77c1e3ccSAndroid Build Coastguard Worker      */
190*77c1e3ccSAndroid Build Coastguard Worker     FLOATING_POINT_INIT
191*77c1e3ccSAndroid Build Coastguard Worker     res = ctx->iface->enc.encode(get_alg_priv(ctx), img, pts, duration, flags);
192*77c1e3ccSAndroid Build Coastguard Worker     FLOATING_POINT_RESTORE
193*77c1e3ccSAndroid Build Coastguard Worker   }
194*77c1e3ccSAndroid Build Coastguard Worker 
195*77c1e3ccSAndroid Build Coastguard Worker   return SAVE_STATUS(ctx, res);
196*77c1e3ccSAndroid Build Coastguard Worker }
197*77c1e3ccSAndroid Build Coastguard Worker 
aom_codec_get_cx_data(aom_codec_ctx_t * ctx,aom_codec_iter_t * iter)198*77c1e3ccSAndroid Build Coastguard Worker const aom_codec_cx_pkt_t *aom_codec_get_cx_data(aom_codec_ctx_t *ctx,
199*77c1e3ccSAndroid Build Coastguard Worker                                                 aom_codec_iter_t *iter) {
200*77c1e3ccSAndroid Build Coastguard Worker   const aom_codec_cx_pkt_t *pkt = NULL;
201*77c1e3ccSAndroid Build Coastguard Worker 
202*77c1e3ccSAndroid Build Coastguard Worker   if (ctx) {
203*77c1e3ccSAndroid Build Coastguard Worker     if (!iter)
204*77c1e3ccSAndroid Build Coastguard Worker       ctx->err = AOM_CODEC_INVALID_PARAM;
205*77c1e3ccSAndroid Build Coastguard Worker     else if (!ctx->iface || !ctx->priv)
206*77c1e3ccSAndroid Build Coastguard Worker       ctx->err = AOM_CODEC_ERROR;
207*77c1e3ccSAndroid Build Coastguard Worker     else if (!(ctx->iface->caps & AOM_CODEC_CAP_ENCODER))
208*77c1e3ccSAndroid Build Coastguard Worker       ctx->err = AOM_CODEC_INCAPABLE;
209*77c1e3ccSAndroid Build Coastguard Worker     else
210*77c1e3ccSAndroid Build Coastguard Worker       pkt = ctx->iface->enc.get_cx_data(get_alg_priv(ctx), iter);
211*77c1e3ccSAndroid Build Coastguard Worker   }
212*77c1e3ccSAndroid Build Coastguard Worker 
213*77c1e3ccSAndroid Build Coastguard Worker   if (pkt && pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
214*77c1e3ccSAndroid Build Coastguard Worker     // If the application has specified a destination area for the
215*77c1e3ccSAndroid Build Coastguard Worker     // compressed data, and the codec has not placed the data there,
216*77c1e3ccSAndroid Build Coastguard Worker     // and it fits, copy it.
217*77c1e3ccSAndroid Build Coastguard Worker     aom_codec_priv_t *const priv = ctx->priv;
218*77c1e3ccSAndroid Build Coastguard Worker     char *const dst_buf = (char *)priv->enc.cx_data_dst_buf.buf;
219*77c1e3ccSAndroid Build Coastguard Worker 
220*77c1e3ccSAndroid Build Coastguard Worker     if (dst_buf && pkt->data.raw.buf != dst_buf &&
221*77c1e3ccSAndroid Build Coastguard Worker         pkt->data.raw.sz + priv->enc.cx_data_pad_before +
222*77c1e3ccSAndroid Build Coastguard Worker                 priv->enc.cx_data_pad_after <=
223*77c1e3ccSAndroid Build Coastguard Worker             priv->enc.cx_data_dst_buf.sz) {
224*77c1e3ccSAndroid Build Coastguard Worker       aom_codec_cx_pkt_t *modified_pkt = &priv->enc.cx_data_pkt;
225*77c1e3ccSAndroid Build Coastguard Worker 
226*77c1e3ccSAndroid Build Coastguard Worker       memcpy(dst_buf + priv->enc.cx_data_pad_before, pkt->data.raw.buf,
227*77c1e3ccSAndroid Build Coastguard Worker              pkt->data.raw.sz);
228*77c1e3ccSAndroid Build Coastguard Worker       *modified_pkt = *pkt;
229*77c1e3ccSAndroid Build Coastguard Worker       modified_pkt->data.raw.buf = dst_buf;
230*77c1e3ccSAndroid Build Coastguard Worker       modified_pkt->data.raw.sz +=
231*77c1e3ccSAndroid Build Coastguard Worker           priv->enc.cx_data_pad_before + priv->enc.cx_data_pad_after;
232*77c1e3ccSAndroid Build Coastguard Worker       pkt = modified_pkt;
233*77c1e3ccSAndroid Build Coastguard Worker     }
234*77c1e3ccSAndroid Build Coastguard Worker 
235*77c1e3ccSAndroid Build Coastguard Worker     if (dst_buf == pkt->data.raw.buf) {
236*77c1e3ccSAndroid Build Coastguard Worker       priv->enc.cx_data_dst_buf.buf = dst_buf + pkt->data.raw.sz;
237*77c1e3ccSAndroid Build Coastguard Worker       priv->enc.cx_data_dst_buf.sz -= pkt->data.raw.sz;
238*77c1e3ccSAndroid Build Coastguard Worker     }
239*77c1e3ccSAndroid Build Coastguard Worker   }
240*77c1e3ccSAndroid Build Coastguard Worker 
241*77c1e3ccSAndroid Build Coastguard Worker   return pkt;
242*77c1e3ccSAndroid Build Coastguard Worker }
243*77c1e3ccSAndroid Build Coastguard Worker 
aom_codec_set_cx_data_buf(aom_codec_ctx_t * ctx,const aom_fixed_buf_t * buf,unsigned int pad_before,unsigned int pad_after)244*77c1e3ccSAndroid Build Coastguard Worker aom_codec_err_t aom_codec_set_cx_data_buf(aom_codec_ctx_t *ctx,
245*77c1e3ccSAndroid Build Coastguard Worker                                           const aom_fixed_buf_t *buf,
246*77c1e3ccSAndroid Build Coastguard Worker                                           unsigned int pad_before,
247*77c1e3ccSAndroid Build Coastguard Worker                                           unsigned int pad_after) {
248*77c1e3ccSAndroid Build Coastguard Worker   if (!ctx || !ctx->priv) return AOM_CODEC_INVALID_PARAM;
249*77c1e3ccSAndroid Build Coastguard Worker 
250*77c1e3ccSAndroid Build Coastguard Worker   if (buf) {
251*77c1e3ccSAndroid Build Coastguard Worker     ctx->priv->enc.cx_data_dst_buf = *buf;
252*77c1e3ccSAndroid Build Coastguard Worker     ctx->priv->enc.cx_data_pad_before = pad_before;
253*77c1e3ccSAndroid Build Coastguard Worker     ctx->priv->enc.cx_data_pad_after = pad_after;
254*77c1e3ccSAndroid Build Coastguard Worker   } else {
255*77c1e3ccSAndroid Build Coastguard Worker     ctx->priv->enc.cx_data_dst_buf.buf = NULL;
256*77c1e3ccSAndroid Build Coastguard Worker     ctx->priv->enc.cx_data_dst_buf.sz = 0;
257*77c1e3ccSAndroid Build Coastguard Worker     ctx->priv->enc.cx_data_pad_before = 0;
258*77c1e3ccSAndroid Build Coastguard Worker     ctx->priv->enc.cx_data_pad_after = 0;
259*77c1e3ccSAndroid Build Coastguard Worker   }
260*77c1e3ccSAndroid Build Coastguard Worker 
261*77c1e3ccSAndroid Build Coastguard Worker   return AOM_CODEC_OK;
262*77c1e3ccSAndroid Build Coastguard Worker }
263*77c1e3ccSAndroid Build Coastguard Worker 
aom_codec_get_preview_frame(aom_codec_ctx_t * ctx)264*77c1e3ccSAndroid Build Coastguard Worker const aom_image_t *aom_codec_get_preview_frame(aom_codec_ctx_t *ctx) {
265*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *img = NULL;
266*77c1e3ccSAndroid Build Coastguard Worker 
267*77c1e3ccSAndroid Build Coastguard Worker   if (ctx) {
268*77c1e3ccSAndroid Build Coastguard Worker     if (!ctx->iface || !ctx->priv)
269*77c1e3ccSAndroid Build Coastguard Worker       ctx->err = AOM_CODEC_ERROR;
270*77c1e3ccSAndroid Build Coastguard Worker     else if (!(ctx->iface->caps & AOM_CODEC_CAP_ENCODER))
271*77c1e3ccSAndroid Build Coastguard Worker       ctx->err = AOM_CODEC_INCAPABLE;
272*77c1e3ccSAndroid Build Coastguard Worker     else if (!ctx->iface->enc.get_preview)
273*77c1e3ccSAndroid Build Coastguard Worker       ctx->err = AOM_CODEC_INCAPABLE;
274*77c1e3ccSAndroid Build Coastguard Worker     else
275*77c1e3ccSAndroid Build Coastguard Worker       img = ctx->iface->enc.get_preview(get_alg_priv(ctx));
276*77c1e3ccSAndroid Build Coastguard Worker   }
277*77c1e3ccSAndroid Build Coastguard Worker 
278*77c1e3ccSAndroid Build Coastguard Worker   return img;
279*77c1e3ccSAndroid Build Coastguard Worker }
280*77c1e3ccSAndroid Build Coastguard Worker 
aom_codec_get_global_headers(aom_codec_ctx_t * ctx)281*77c1e3ccSAndroid Build Coastguard Worker aom_fixed_buf_t *aom_codec_get_global_headers(aom_codec_ctx_t *ctx) {
282*77c1e3ccSAndroid Build Coastguard Worker   aom_fixed_buf_t *buf = NULL;
283*77c1e3ccSAndroid Build Coastguard Worker 
284*77c1e3ccSAndroid Build Coastguard Worker   if (ctx) {
285*77c1e3ccSAndroid Build Coastguard Worker     if (!ctx->iface || !ctx->priv)
286*77c1e3ccSAndroid Build Coastguard Worker       ctx->err = AOM_CODEC_ERROR;
287*77c1e3ccSAndroid Build Coastguard Worker     else if (!(ctx->iface->caps & AOM_CODEC_CAP_ENCODER))
288*77c1e3ccSAndroid Build Coastguard Worker       ctx->err = AOM_CODEC_INCAPABLE;
289*77c1e3ccSAndroid Build Coastguard Worker     else if (!ctx->iface->enc.get_glob_hdrs)
290*77c1e3ccSAndroid Build Coastguard Worker       ctx->err = AOM_CODEC_INCAPABLE;
291*77c1e3ccSAndroid Build Coastguard Worker     else
292*77c1e3ccSAndroid Build Coastguard Worker       buf = ctx->iface->enc.get_glob_hdrs(get_alg_priv(ctx));
293*77c1e3ccSAndroid Build Coastguard Worker   }
294*77c1e3ccSAndroid Build Coastguard Worker 
295*77c1e3ccSAndroid Build Coastguard Worker   return buf;
296*77c1e3ccSAndroid Build Coastguard Worker }
297*77c1e3ccSAndroid Build Coastguard Worker 
aom_codec_enc_config_set(aom_codec_ctx_t * ctx,const aom_codec_enc_cfg_t * cfg)298*77c1e3ccSAndroid Build Coastguard Worker aom_codec_err_t aom_codec_enc_config_set(aom_codec_ctx_t *ctx,
299*77c1e3ccSAndroid Build Coastguard Worker                                          const aom_codec_enc_cfg_t *cfg) {
300*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_err_t res;
301*77c1e3ccSAndroid Build Coastguard Worker 
302*77c1e3ccSAndroid Build Coastguard Worker   if (!ctx || !ctx->iface || !ctx->priv || !cfg)
303*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_INVALID_PARAM;
304*77c1e3ccSAndroid Build Coastguard Worker   else if (!(ctx->iface->caps & AOM_CODEC_CAP_ENCODER))
305*77c1e3ccSAndroid Build Coastguard Worker     res = AOM_CODEC_INCAPABLE;
306*77c1e3ccSAndroid Build Coastguard Worker   else
307*77c1e3ccSAndroid Build Coastguard Worker     res = ctx->iface->enc.cfg_set(get_alg_priv(ctx), cfg);
308*77c1e3ccSAndroid Build Coastguard Worker 
309*77c1e3ccSAndroid Build Coastguard Worker   return SAVE_STATUS(ctx, res);
310*77c1e3ccSAndroid Build Coastguard Worker }
311*77c1e3ccSAndroid Build Coastguard Worker 
aom_codec_pkt_list_add(struct aom_codec_pkt_list * list,const struct aom_codec_cx_pkt * pkt)312*77c1e3ccSAndroid Build Coastguard Worker int aom_codec_pkt_list_add(struct aom_codec_pkt_list *list,
313*77c1e3ccSAndroid Build Coastguard Worker                            const struct aom_codec_cx_pkt *pkt) {
314*77c1e3ccSAndroid Build Coastguard Worker   if (list->cnt < list->max) {
315*77c1e3ccSAndroid Build Coastguard Worker     list->pkts[list->cnt++] = *pkt;
316*77c1e3ccSAndroid Build Coastguard Worker     return 0;
317*77c1e3ccSAndroid Build Coastguard Worker   }
318*77c1e3ccSAndroid Build Coastguard Worker 
319*77c1e3ccSAndroid Build Coastguard Worker   return 1;
320*77c1e3ccSAndroid Build Coastguard Worker }
321*77c1e3ccSAndroid Build Coastguard Worker 
aom_codec_pkt_list_get(struct aom_codec_pkt_list * list,aom_codec_iter_t * iter)322*77c1e3ccSAndroid Build Coastguard Worker const aom_codec_cx_pkt_t *aom_codec_pkt_list_get(
323*77c1e3ccSAndroid Build Coastguard Worker     struct aom_codec_pkt_list *list, aom_codec_iter_t *iter) {
324*77c1e3ccSAndroid Build Coastguard Worker   const aom_codec_cx_pkt_t *pkt;
325*77c1e3ccSAndroid Build Coastguard Worker 
326*77c1e3ccSAndroid Build Coastguard Worker   if (!(*iter)) {
327*77c1e3ccSAndroid Build Coastguard Worker     *iter = list->pkts;
328*77c1e3ccSAndroid Build Coastguard Worker   }
329*77c1e3ccSAndroid Build Coastguard Worker 
330*77c1e3ccSAndroid Build Coastguard Worker   pkt = (const aom_codec_cx_pkt_t *)*iter;
331*77c1e3ccSAndroid Build Coastguard Worker 
332*77c1e3ccSAndroid Build Coastguard Worker   if ((size_t)(pkt - list->pkts) < list->cnt)
333*77c1e3ccSAndroid Build Coastguard Worker     *iter = pkt + 1;
334*77c1e3ccSAndroid Build Coastguard Worker   else
335*77c1e3ccSAndroid Build Coastguard Worker     pkt = NULL;
336*77c1e3ccSAndroid Build Coastguard Worker 
337*77c1e3ccSAndroid Build Coastguard Worker   return pkt;
338*77c1e3ccSAndroid Build Coastguard Worker }
339