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