blob: b1b079cb26058f4b3f21edce611dc216bcf11ed0 [file] [log] [blame]
John Koleszar0ea50ce2010-05-18 11:58:33 -04001/*
John Koleszarc2140b82010-09-09 08:16:39 -04002 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar0ea50ce2010-05-18 11:58:33 -04003 *
John Koleszar94c52e42010-06-18 12:39:21 -04004 * Use of this source code is governed by a BSD-style license
John Koleszar09202d82010-06-04 16:19:40 -04005 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
John Koleszar94c52e42010-06-18 12:39:21 -04007 * in the file PATENTS. All contributing project authors may
John Koleszar09202d82010-06-04 16:19:40 -04008 * be found in the AUTHORS file in the root of the source tree.
John Koleszar0ea50ce2010-05-18 11:58:33 -04009 */
10
11
Minghai Shange8998592014-07-14 11:24:17 -070012#include "./vpx_config.h"
John Koleszara9c75972012-11-08 17:09:30 -080013#include "vp8_rtcd.h"
John Koleszarb7492342010-05-24 11:39:59 -040014#include "vpx/vpx_codec.h"
15#include "vpx/internal/vpx_codec_internal.h"
John Koleszar0ea50ce2010-05-18 11:58:33 -040016#include "vpx_version.h"
Dmitry Kovalevb08fab82014-09-02 18:26:53 -070017#include "vpx_mem/vpx_mem.h"
John Koleszar02321de2011-02-10 14:41:38 -050018#include "vp8/encoder/onyx_int.h"
John Koleszar2bf8fb52012-05-02 16:37:37 -070019#include "vpx/vp8cx.h"
John Koleszarbb7dd5b2010-10-14 16:40:12 -040020#include "vp8/encoder/firstpass.h"
John Koleszar02321de2011-02-10 14:41:38 -050021#include "vp8/common/onyx.h"
John Koleszar0ea50ce2010-05-18 11:58:33 -040022#include <stdlib.h>
23#include <string.h>
24
John Koleszar0ea50ce2010-05-18 11:58:33 -040025struct vp8_extracfg
26{
27 struct vpx_codec_pkt_list *pkt_list;
John Koleszar0ea50ce2010-05-18 11:58:33 -040028 int cpu_used; /** available cpu percentage in 1/16*/
29 unsigned int enable_auto_alt_ref; /** if encoder decides to uses alternate reference frame */
30 unsigned int noise_sensitivity;
31 unsigned int Sharpness;
32 unsigned int static_thresh;
33 unsigned int token_partitions;
34 unsigned int arnr_max_frames; /* alt_ref Noise Reduction Max Frame Count */
35 unsigned int arnr_strength; /* alt_ref Noise Reduction Strength */
36 unsigned int arnr_type; /* alt_ref filter type */
John Koleszarb0da9b32010-12-17 09:43:39 -050037 vp8e_tuning tuning;
Paul Wilkinse0846c92011-01-07 18:29:37 +000038 unsigned int cq_level; /* constrained quality level */
John Koleszar1654ae92011-07-28 09:17:32 -040039 unsigned int rc_max_intra_bitrate_pct;
John Koleszar0ea50ce2010-05-18 11:58:33 -040040
41};
42
Dmitry Kovalev48274c62014-08-21 11:21:18 -070043static struct vp8_extracfg default_extracfg = {
44 NULL,
John Koleszar0ea50ce2010-05-18 11:58:33 -040045#if !(CONFIG_REALTIME_ONLY)
Dmitry Kovalev48274c62014-08-21 11:21:18 -070046 0, /* cpu_used */
John Koleszar0ea50ce2010-05-18 11:58:33 -040047#else
Dmitry Kovalev48274c62014-08-21 11:21:18 -070048 4, /* cpu_used */
John Koleszar0ea50ce2010-05-18 11:58:33 -040049#endif
Dmitry Kovalev48274c62014-08-21 11:21:18 -070050 0, /* enable_auto_alt_ref */
51 0, /* noise_sensitivity */
52 0, /* Sharpness */
53 0, /* static_thresh */
Attila Nagy52cf4dc2012-02-09 12:37:03 +020054#if (CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
Dmitry Kovalev48274c62014-08-21 11:21:18 -070055 VP8_EIGHT_TOKENPARTITION,
Attila Nagy52cf4dc2012-02-09 12:37:03 +020056#else
Dmitry Kovalev48274c62014-08-21 11:21:18 -070057 VP8_ONE_TOKENPARTITION, /* token_partitions */
Attila Nagy52cf4dc2012-02-09 12:37:03 +020058#endif
Dmitry Kovalev48274c62014-08-21 11:21:18 -070059 0, /* arnr_max_frames */
60 3, /* arnr_strength */
61 3, /* arnr_type*/
62 0, /* tuning*/
63 10, /* cq_level */
64 0, /* rc_max_intra_bitrate_pct */
John Koleszar0ea50ce2010-05-18 11:58:33 -040065};
66
67struct vpx_codec_alg_priv
68{
69 vpx_codec_priv_t base;
70 vpx_codec_enc_cfg_t cfg;
71 struct vp8_extracfg vp8_cfg;
72 VP8_CONFIG oxcf;
John Koleszarb0056c32011-12-20 16:54:54 -080073 struct VP8_COMP *cpi;
John Koleszar0ea50ce2010-05-18 11:58:33 -040074 unsigned char *cx_data;
75 unsigned int cx_data_sz;
76 vpx_image_t preview_img;
77 unsigned int next_frame_flag;
78 vp8_postproc_cfg_t preview_ppcfg;
John Koleszar0164a1c2012-05-21 14:30:56 -070079 /* pkt_list size depends on the maximum number of lagged frames allowed. */
80 vpx_codec_pkt_list_decl(64) pkt_list;
John Koleszar0ea50ce2010-05-18 11:58:33 -040081 unsigned int fixed_kf_cntr;
82};
83
84
85static vpx_codec_err_t
86update_error_state(vpx_codec_alg_priv_t *ctx,
87 const struct vpx_internal_error_info *error)
88{
89 vpx_codec_err_t res;
90
91 if ((res = error->error_code))
92 ctx->base.err_detail = error->has_detail
93 ? error->detail
94 : NULL;
95
96 return res;
97}
98
99
John Koleszar79e2b1f2010-11-17 09:08:47 -0500100#undef ERROR
John Koleszar0ea50ce2010-05-18 11:58:33 -0400101#define ERROR(str) do {\
102 ctx->base.err_detail = str;\
103 return VPX_CODEC_INVALID_PARAM;\
104 } while(0)
105
106#define RANGE_CHECK(p,memb,lo,hi) do {\
Guillermo Ballester Valor5a726202010-06-11 14:33:49 -0400107 if(!(((p)->memb == lo || (p)->memb > (lo)) && (p)->memb <= hi)) \
John Koleszar0ea50ce2010-05-18 11:58:33 -0400108 ERROR(#memb " out of range ["#lo".."#hi"]");\
109 } while(0)
110
Guillermo Ballester Valor23690682010-06-11 14:33:49 -0400111#define RANGE_CHECK_HI(p,memb,hi) do {\
112 if(!((p)->memb <= (hi))) \
113 ERROR(#memb " out of range [.."#hi"]");\
114 } while(0)
115
John Koleszar0ea50ce2010-05-18 11:58:33 -0400116#define RANGE_CHECK_LO(p,memb,lo) do {\
117 if(!((p)->memb >= (lo))) \
118 ERROR(#memb " out of range ["#lo"..]");\
119 } while(0)
120
121#define RANGE_CHECK_BOOL(p,memb) do {\
122 if(!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean");\
123 } while(0)
124
125static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
126 const vpx_codec_enc_cfg_t *cfg,
James Berryc1c47e82011-12-07 15:48:00 -0500127 const struct vp8_extracfg *vp8_cfg,
128 int finalize)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400129{
Attila Nagy1aadced2011-04-12 15:01:22 +0300130 RANGE_CHECK(cfg, g_w, 1, 16383); /* 14 bits available */
131 RANGE_CHECK(cfg, g_h, 1, 16383); /* 14 bits available */
John Koleszar0ea50ce2010-05-18 11:58:33 -0400132 RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000);
133 RANGE_CHECK(cfg, g_timebase.num, 1, cfg->g_timebase.den);
Guillermo Ballester Valor23690682010-06-11 14:33:49 -0400134 RANGE_CHECK_HI(cfg, g_profile, 3);
Guillermo Ballester Valor23690682010-06-11 14:33:49 -0400135 RANGE_CHECK_HI(cfg, rc_max_quantizer, 63);
John Koleszar2d03f072011-01-28 11:56:18 -0500136 RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer);
Guillermo Ballester Valor23690682010-06-11 14:33:49 -0400137 RANGE_CHECK_HI(cfg, g_threads, 64);
Yunqing Wang7f009972012-07-11 11:43:51 -0700138#if CONFIG_REALTIME_ONLY
Guillermo Ballester Valor23690682010-06-11 14:33:49 -0400139 RANGE_CHECK_HI(cfg, g_lag_in_frames, 0);
Yunqing Wang7f009972012-07-11 11:43:51 -0700140#elif CONFIG_MULTI_RES_ENCODING
141 if (ctx->base.enc.total_encoders > 1)
142 RANGE_CHECK_HI(cfg, g_lag_in_frames, 0);
143#else
144 RANGE_CHECK_HI(cfg, g_lag_in_frames, 25);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400145#endif
Deb Mukherjeee378a892013-08-29 16:21:44 -0700146 RANGE_CHECK(cfg, rc_end_usage, VPX_VBR, VPX_Q);
John Koleszarc99f9d72011-04-11 11:29:23 -0400147 RANGE_CHECK_HI(cfg, rc_undershoot_pct, 1000);
148 RANGE_CHECK_HI(cfg, rc_overshoot_pct, 1000);
Guillermo Ballester Valor23690682010-06-11 14:33:49 -0400149 RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400150 RANGE_CHECK(cfg, kf_mode, VPX_KF_DISABLED, VPX_KF_AUTO);
Yunqing Wang7f009972012-07-11 11:43:51 -0700151
152/* TODO: add spatial re-sampling support and frame dropping in
153 * multi-res-encoder.*/
154#if CONFIG_MULTI_RES_ENCODING
155 if (ctx->base.enc.total_encoders > 1)
Yunqing Wang7f009972012-07-11 11:43:51 -0700156 RANGE_CHECK_HI(cfg, rc_resize_allowed, 0);
Yunqing Wang7f009972012-07-11 11:43:51 -0700157#else
158 RANGE_CHECK_BOOL(cfg, rc_resize_allowed);
Yunqing Wang7f009972012-07-11 11:43:51 -0700159#endif
Yunqing Wang4066c8b2012-06-08 11:17:50 -0400160 RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100);
Guillermo Ballester Valor23690682010-06-11 14:33:49 -0400161 RANGE_CHECK_HI(cfg, rc_resize_up_thresh, 100);
162 RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100);
Yunqing Wang7f009972012-07-11 11:43:51 -0700163
164#if CONFIG_REALTIME_ONLY
John Koleszar0ea50ce2010-05-18 11:58:33 -0400165 RANGE_CHECK(cfg, g_pass, VPX_RC_ONE_PASS, VPX_RC_ONE_PASS);
Yunqing Wang7f009972012-07-11 11:43:51 -0700166#elif CONFIG_MULTI_RES_ENCODING
167 if (ctx->base.enc.total_encoders > 1)
168 RANGE_CHECK(cfg, g_pass, VPX_RC_ONE_PASS, VPX_RC_ONE_PASS);
169#else
170 RANGE_CHECK(cfg, g_pass, VPX_RC_ONE_PASS, VPX_RC_LAST_PASS);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400171#endif
172
173 /* VP8 does not support a lower bound on the keyframe interval in
174 * automatic keyframe placement mode.
175 */
176 if (cfg->kf_mode != VPX_KF_DISABLED && cfg->kf_min_dist != cfg->kf_max_dist
177 && cfg->kf_min_dist > 0)
178 ERROR("kf_min_dist not supported in auto mode, use 0 "
179 "or kf_max_dist instead.");
180
181 RANGE_CHECK_BOOL(vp8_cfg, enable_auto_alt_ref);
Yunqing Wang4fd81a92011-04-11 15:55:04 -0400182 RANGE_CHECK(vp8_cfg, cpu_used, -16, 16);
John Koleszarc8f4c182012-05-08 11:23:42 -0700183
184#if CONFIG_REALTIME_ONLY && !CONFIG_TEMPORAL_DENOISING
185 RANGE_CHECK(vp8_cfg, noise_sensitivity, 0, 0);
186#else
187 RANGE_CHECK_HI(vp8_cfg, noise_sensitivity, 6);
Stefan Holmer9c411432012-03-06 10:48:18 +0100188#endif
John Koleszar0ea50ce2010-05-18 11:58:33 -0400189
Yunqing Wang7f009972012-07-11 11:43:51 -0700190 RANGE_CHECK(vp8_cfg, token_partitions, VP8_ONE_TOKENPARTITION,
191 VP8_EIGHT_TOKENPARTITION);
Guillermo Ballester Valor23690682010-06-11 14:33:49 -0400192 RANGE_CHECK_HI(vp8_cfg, Sharpness, 7);
Adrian Grange8ee72842010-09-30 10:06:09 +0100193 RANGE_CHECK(vp8_cfg, arnr_max_frames, 0, 15);
Frank Galligan15542722010-10-04 21:12:22 -0400194 RANGE_CHECK_HI(vp8_cfg, arnr_strength, 6);
Adrian Grange8ee72842010-09-30 10:06:09 +0100195 RANGE_CHECK(vp8_cfg, arnr_type, 1, 3);
Paul Wilkinse0846c92011-01-07 18:29:37 +0000196 RANGE_CHECK(vp8_cfg, cq_level, 0, 63);
Deb Mukherjeee378a892013-08-29 16:21:44 -0700197 if (finalize && (cfg->rc_end_usage == VPX_CQ || cfg->rc_end_usage == VPX_Q))
James Berryc1c47e82011-12-07 15:48:00 -0500198 RANGE_CHECK(vp8_cfg, cq_level,
199 cfg->rc_min_quantizer, cfg->rc_max_quantizer);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400200
Attila Nagycb791aa2011-01-10 11:14:10 +0200201#if !(CONFIG_REALTIME_ONLY)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400202 if (cfg->g_pass == VPX_RC_LAST_PASS)
203 {
Adrian Grangeed40ff92011-03-10 11:32:48 -0800204 size_t packet_sz = sizeof(FIRSTPASS_STATS);
Yaowu Xud71ba032012-08-17 10:05:35 -0700205 int n_packets = (int)(cfg->rc_twopass_stats_in.sz /
206 packet_sz);
John Koleszarbb7dd5b2010-10-14 16:40:12 -0400207 FIRSTPASS_STATS *stats;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400208
209 if (!cfg->rc_twopass_stats_in.buf)
210 ERROR("rc_twopass_stats_in.buf not set.");
211
John Koleszarbb7dd5b2010-10-14 16:40:12 -0400212 if (cfg->rc_twopass_stats_in.sz % packet_sz)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400213 ERROR("rc_twopass_stats_in.sz indicates truncated packet.");
214
John Koleszarbb7dd5b2010-10-14 16:40:12 -0400215 if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400216 ERROR("rc_twopass_stats_in requires at least two packets.");
217
John Koleszarbb7dd5b2010-10-14 16:40:12 -0400218 stats = (void*)((char *)cfg->rc_twopass_stats_in.buf
219 + (n_packets - 1) * packet_sz);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400220
John Koleszarbb7dd5b2010-10-14 16:40:12 -0400221 if ((int)(stats->count + 0.5) != n_packets - 1)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400222 ERROR("rc_twopass_stats_in missing EOS stats packet");
223 }
Attila Nagycb791aa2011-01-10 11:14:10 +0200224#endif
John Koleszar0ea50ce2010-05-18 11:58:33 -0400225
Adrian Grange217591f2011-10-06 15:49:11 -0700226 RANGE_CHECK(cfg, ts_number_layers, 1, 5);
227
228 if (cfg->ts_number_layers > 1)
229 {
Scott Graham92963df2012-05-08 11:45:35 -0700230 unsigned int i;
Adrian Grange217591f2011-10-06 15:49:11 -0700231 RANGE_CHECK_HI(cfg, ts_periodicity, 16);
232
233 for (i=1; i<cfg->ts_number_layers; i++)
234 if (cfg->ts_target_bitrate[i] <= cfg->ts_target_bitrate[i-1])
235 ERROR("ts_target_bitrate entries are not strictly increasing");
236
237 RANGE_CHECK(cfg, ts_rate_decimator[cfg->ts_number_layers-1], 1, 1);
238 for (i=cfg->ts_number_layers-2; i>0; i--)
239 if (cfg->ts_rate_decimator[i-1] != 2*cfg->ts_rate_decimator[i])
240 ERROR("ts_rate_decimator factors are not powers of 2");
241
242 RANGE_CHECK_HI(cfg, ts_layer_id[i], cfg->ts_number_layers-1);
243 }
244
Attila Nagy52cf4dc2012-02-09 12:37:03 +0200245#if (CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
246 if(cfg->g_threads > (1 << vp8_cfg->token_partitions))
247 ERROR("g_threads cannot be bigger than number of token partitions");
248#endif
249
John Koleszar0ea50ce2010-05-18 11:58:33 -0400250 return VPX_CODEC_OK;
251}
252
253
254static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx,
255 const vpx_image_t *img)
256{
257 switch (img->fmt)
258 {
James Zern6cd4a102010-05-20 23:22:39 -0400259 case VPX_IMG_FMT_YV12:
260 case VPX_IMG_FMT_I420:
261 case VPX_IMG_FMT_VPXI420:
262 case VPX_IMG_FMT_VPXYV12:
John Koleszar0ea50ce2010-05-18 11:58:33 -0400263 break;
264 default:
265 ERROR("Invalid image format. Only YV12 and I420 images are supported");
266 }
267
268 if ((img->d_w != ctx->cfg.g_w) || (img->d_h != ctx->cfg.g_h))
269 ERROR("Image size must match encoder init configuration size");
270
271 return VPX_CODEC_OK;
272}
273
274
275static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf,
276 vpx_codec_enc_cfg_t cfg,
Yunqing Wangaa7335e2011-10-25 15:14:16 -0400277 struct vp8_extracfg vp8_cfg,
278 vpx_codec_priv_enc_mr_cfg_t *mr_cfg)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400279{
280 oxcf->multi_threaded = cfg.g_threads;
281 oxcf->Version = cfg.g_profile;
282
283 oxcf->Width = cfg.g_w;
284 oxcf->Height = cfg.g_h;
John Koleszarbdd35c12011-11-11 10:47:20 -0800285 oxcf->timebase = cfg.g_timebase;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400286
Adrian Grange217591f2011-10-06 15:49:11 -0700287 oxcf->error_resilient_mode = cfg.g_error_resilient;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400288
289 switch (cfg.g_pass)
290 {
291 case VPX_RC_ONE_PASS:
292 oxcf->Mode = MODE_BESTQUALITY;
293 break;
294 case VPX_RC_FIRST_PASS:
295 oxcf->Mode = MODE_FIRSTPASS;
296 break;
297 case VPX_RC_LAST_PASS:
298 oxcf->Mode = MODE_SECONDPASS_BEST;
299 break;
300 }
301
James Zern7b0b6a22012-06-13 11:59:12 -0700302 if (cfg.g_pass == VPX_RC_FIRST_PASS || cfg.g_pass == VPX_RC_ONE_PASS)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400303 {
Adrian Grange217591f2011-10-06 15:49:11 -0700304 oxcf->allow_lag = 0;
305 oxcf->lag_in_frames = 0;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400306 }
307 else
308 {
Adrian Grange217591f2011-10-06 15:49:11 -0700309 oxcf->allow_lag = (cfg.g_lag_in_frames) > 0;
310 oxcf->lag_in_frames = cfg.g_lag_in_frames;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400311 }
312
313 oxcf->allow_df = (cfg.rc_dropframe_thresh > 0);
314 oxcf->drop_frames_water_mark = cfg.rc_dropframe_thresh;
315
316 oxcf->allow_spatial_resampling = cfg.rc_resize_allowed;
317 oxcf->resample_up_water_mark = cfg.rc_resize_up_thresh;
318 oxcf->resample_down_water_mark = cfg.rc_resize_down_thresh;
319
Deb Mukherjeee378a892013-08-29 16:21:44 -0700320 if (cfg.rc_end_usage == VPX_VBR) {
321 oxcf->end_usage = USAGE_LOCAL_FILE_PLAYBACK;
322 } else if (cfg.rc_end_usage == VPX_CBR) {
323 oxcf->end_usage = USAGE_STREAM_FROM_SERVER;
324 } else if (cfg.rc_end_usage == VPX_CQ) {
325 oxcf->end_usage = USAGE_CONSTRAINED_QUALITY;
326 } else if (cfg.rc_end_usage == VPX_Q) {
327 oxcf->end_usage = USAGE_CONSTANT_QUALITY;
Paul Wilkinse0846c92011-01-07 18:29:37 +0000328 }
John Koleszar0ea50ce2010-05-18 11:58:33 -0400329
Adrian Grange217591f2011-10-06 15:49:11 -0700330 oxcf->target_bandwidth = cfg.rc_target_bitrate;
John Koleszar1654ae92011-07-28 09:17:32 -0400331 oxcf->rc_max_intra_bitrate_pct = vp8_cfg.rc_max_intra_bitrate_pct;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400332
Adrian Grange217591f2011-10-06 15:49:11 -0700333 oxcf->best_allowed_q = cfg.rc_min_quantizer;
334 oxcf->worst_allowed_q = cfg.rc_max_quantizer;
335 oxcf->cq_level = vp8_cfg.cq_level;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400336 oxcf->fixed_q = -1;
337
Adrian Grange217591f2011-10-06 15:49:11 -0700338 oxcf->under_shoot_pct = cfg.rc_undershoot_pct;
339 oxcf->over_shoot_pct = cfg.rc_overshoot_pct;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400340
Adrian Grangee4793792012-01-13 14:09:40 -0800341 oxcf->maximum_buffer_size_in_ms = cfg.rc_buf_sz;
342 oxcf->starting_buffer_level_in_ms = cfg.rc_buf_initial_sz;
343 oxcf->optimal_buffer_level_in_ms = cfg.rc_buf_optimal_sz;
344
Adrian Grange217591f2011-10-06 15:49:11 -0700345 oxcf->maximum_buffer_size = cfg.rc_buf_sz;
346 oxcf->starting_buffer_level = cfg.rc_buf_initial_sz;
347 oxcf->optimal_buffer_level = cfg.rc_buf_optimal_sz;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400348
Adrian Grange217591f2011-10-06 15:49:11 -0700349 oxcf->two_pass_vbrbias = cfg.rc_2pass_vbr_bias_pct;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400350 oxcf->two_pass_vbrmin_section = cfg.rc_2pass_vbr_minsection_pct;
351 oxcf->two_pass_vbrmax_section = cfg.rc_2pass_vbr_maxsection_pct;
352
Adrian Grange217591f2011-10-06 15:49:11 -0700353 oxcf->auto_key = cfg.kf_mode == VPX_KF_AUTO
354 && cfg.kf_min_dist != cfg.kf_max_dist;
Adrian Grange217591f2011-10-06 15:49:11 -0700355 oxcf->key_freq = cfg.kf_max_dist;
356
357 oxcf->number_of_layers = cfg.ts_number_layers;
358 oxcf->periodicity = cfg.ts_periodicity;
359
360 if (oxcf->number_of_layers > 1)
361 {
362 memcpy (oxcf->target_bitrate, cfg.ts_target_bitrate,
363 sizeof(cfg.ts_target_bitrate));
364 memcpy (oxcf->rate_decimator, cfg.ts_rate_decimator,
365 sizeof(cfg.ts_rate_decimator));
366 memcpy (oxcf->layer_id, cfg.ts_layer_id, sizeof(cfg.ts_layer_id));
367 }
John Koleszar0ea50ce2010-05-18 11:58:33 -0400368
Yunqing Wangaa7335e2011-10-25 15:14:16 -0400369#if CONFIG_MULTI_RES_ENCODING
Yunqing Wangc647ec42011-12-16 16:50:29 -0500370 /* When mr_cfg is NULL, oxcf->mr_total_resolutions and oxcf->mr_encoder_id
371 * are both memset to 0, which ensures the correct logic under this
372 * situation.
373 */
Yunqing Wangaa7335e2011-10-25 15:14:16 -0400374 if(mr_cfg)
375 {
376 oxcf->mr_total_resolutions = mr_cfg->mr_total_resolutions;
377 oxcf->mr_encoder_id = mr_cfg->mr_encoder_id;
378 oxcf->mr_down_sampling_factor.num = mr_cfg->mr_down_sampling_factor.num;
379 oxcf->mr_down_sampling_factor.den = mr_cfg->mr_down_sampling_factor.den;
380 oxcf->mr_low_res_mode_info = mr_cfg->mr_low_res_mode_info;
381 }
382#endif
383
Adrian Grange217591f2011-10-06 15:49:11 -0700384 oxcf->cpu_used = vp8_cfg.cpu_used;
385 oxcf->encode_breakout = vp8_cfg.static_thresh;
386 oxcf->play_alternate = vp8_cfg.enable_auto_alt_ref;
387 oxcf->noise_sensitivity = vp8_cfg.noise_sensitivity;
388 oxcf->Sharpness = vp8_cfg.Sharpness;
389 oxcf->token_partitions = vp8_cfg.token_partitions;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400390
Adrian Grange217591f2011-10-06 15:49:11 -0700391 oxcf->two_pass_stats_in = cfg.rc_twopass_stats_in;
392 oxcf->output_pkt_list = vp8_cfg.pkt_list;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400393
Adrian Grange217591f2011-10-06 15:49:11 -0700394 oxcf->arnr_max_frames = vp8_cfg.arnr_max_frames;
395 oxcf->arnr_strength = vp8_cfg.arnr_strength;
396 oxcf->arnr_type = vp8_cfg.arnr_type;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400397
Adrian Grange217591f2011-10-06 15:49:11 -0700398 oxcf->tuning = vp8_cfg.tuning;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400399
400 /*
401 printf("Current VP8 Settings: \n");
402 printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
403 printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity);
404 printf("Sharpness: %d\n", oxcf->Sharpness);
405 printf("cpu_used: %d\n", oxcf->cpu_used);
406 printf("Mode: %d\n", oxcf->Mode);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400407 printf("auto_key: %d\n", oxcf->auto_key);
408 printf("key_freq: %d\n", oxcf->key_freq);
409 printf("end_usage: %d\n", oxcf->end_usage);
410 printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct);
John Koleszarc99f9d72011-04-11 11:29:23 -0400411 printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400412 printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level);
413 printf("optimal_buffer_level: %d\n", oxcf->optimal_buffer_level);
414 printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size);
415 printf("fixed_q: %d\n", oxcf->fixed_q);
416 printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q);
417 printf("best_allowed_q: %d\n", oxcf->best_allowed_q);
418 printf("allow_spatial_resampling: %d\n", oxcf->allow_spatial_resampling);
419 printf("resample_down_water_mark: %d\n", oxcf->resample_down_water_mark);
420 printf("resample_up_water_mark: %d\n", oxcf->resample_up_water_mark);
421 printf("allow_df: %d\n", oxcf->allow_df);
422 printf("drop_frames_water_mark: %d\n", oxcf->drop_frames_water_mark);
423 printf("two_pass_vbrbias: %d\n", oxcf->two_pass_vbrbias);
424 printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section);
425 printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section);
426 printf("allow_lag: %d\n", oxcf->allow_lag);
427 printf("lag_in_frames: %d\n", oxcf->lag_in_frames);
428 printf("play_alternate: %d\n", oxcf->play_alternate);
429 printf("Version: %d\n", oxcf->Version);
430 printf("multi_threaded: %d\n", oxcf->multi_threaded);
431 printf("encode_breakout: %d\n", oxcf->encode_breakout);
432 */
433 return VPX_CODEC_OK;
434}
435
436static vpx_codec_err_t vp8e_set_config(vpx_codec_alg_priv_t *ctx,
437 const vpx_codec_enc_cfg_t *cfg)
438{
439 vpx_codec_err_t res;
440
John Koleszar51acb012012-02-07 17:07:49 -0800441 if (((cfg->g_w != ctx->cfg.g_w) || (cfg->g_h != ctx->cfg.g_h))
John Koleszar410ae572012-05-23 12:07:53 -0700442 && (cfg->g_lag_in_frames > 1 || cfg->g_pass != VPX_RC_ONE_PASS))
John Koleszar0ea50ce2010-05-18 11:58:33 -0400443 ERROR("Cannot change width or height after initialization");
444
445 /* Prevent increasing lag_in_frames. This check is stricter than it needs
446 * to be -- the limit is not increasing past the first lag_in_frames
447 * value, but we don't track the initial config, only the last successful
448 * config.
449 */
450 if ((cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames))
451 ERROR("Cannot increase lag_in_frames");
452
James Berryc1c47e82011-12-07 15:48:00 -0500453 res = validate_config(ctx, cfg, &ctx->vp8_cfg, 0);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400454
455 if (!res)
456 {
457 ctx->cfg = *cfg;
Yunqing Wangaa7335e2011-10-25 15:14:16 -0400458 set_vp8e_config(&ctx->oxcf, ctx->cfg, ctx->vp8_cfg, NULL);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400459 vp8_change_config(ctx->cpi, &ctx->oxcf);
460 }
461
462 return res;
463}
464
John Koleszar0ea50ce2010-05-18 11:58:33 -0400465int vp8_reverse_trans(int);
466
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -0700467static vpx_codec_err_t get_quantizer(vpx_codec_alg_priv_t *ctx, va_list args)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400468{
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -0700469 int *const arg = va_arg(args, int *);
470 if (arg == NULL)
471 return VPX_CODEC_INVALID_PARAM;
472 *arg = vp8_get_quantizer(ctx->cpi);
473 return VPX_CODEC_OK;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400474}
475
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -0700476static vpx_codec_err_t get_quantizer64(vpx_codec_alg_priv_t *ctx, va_list args)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400477{
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -0700478 int *const arg = va_arg(args, int *);
479 if (arg == NULL)
480 return VPX_CODEC_INVALID_PARAM;
481 *arg = vp8_reverse_trans(vp8_get_quantizer(ctx->cpi));
482 return VPX_CODEC_OK;
483}
John Koleszar0ea50ce2010-05-18 11:58:33 -0400484
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -0700485static vpx_codec_err_t update_extracfg(vpx_codec_alg_priv_t *ctx,
486 const struct vp8_extracfg *extra_cfg)
487{
488 const vpx_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg, 0);
489 if (res == VPX_CODEC_OK) {
490 ctx->vp8_cfg = *extra_cfg;
491 set_vp8e_config(&ctx->oxcf, ctx->cfg, ctx->vp8_cfg, NULL);
492 vp8_change_config(ctx->cpi, &ctx->oxcf);
493 }
494 return res;
495}
John Koleszar0ea50ce2010-05-18 11:58:33 -0400496
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -0700497static vpx_codec_err_t set_cpu_used(vpx_codec_alg_priv_t *ctx, va_list args)
498{
499 struct vp8_extracfg extra_cfg = ctx->vp8_cfg;
500 extra_cfg.cpu_used = CAST(VP8E_SET_CPUUSED, args);
501 return update_extracfg(ctx, &extra_cfg);
502}
John Koleszar0ea50ce2010-05-18 11:58:33 -0400503
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -0700504static vpx_codec_err_t set_enable_auto_alt_ref(vpx_codec_alg_priv_t *ctx,
505 va_list args)
506{
507 struct vp8_extracfg extra_cfg = ctx->vp8_cfg;
508 extra_cfg.enable_auto_alt_ref = CAST(VP8E_SET_ENABLEAUTOALTREF, args);
509 return update_extracfg(ctx, &extra_cfg);
510}
John Koleszar0ea50ce2010-05-18 11:58:33 -0400511
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -0700512static vpx_codec_err_t set_noise_sensitivity(vpx_codec_alg_priv_t *ctx,
513 va_list args)
514{
515 struct vp8_extracfg extra_cfg = ctx->vp8_cfg;
516 extra_cfg.noise_sensitivity = CAST(VP8E_SET_NOISE_SENSITIVITY, args);
517 return update_extracfg(ctx, &extra_cfg);
518}
John Koleszar0ea50ce2010-05-18 11:58:33 -0400519
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -0700520static vpx_codec_err_t set_sharpness(vpx_codec_alg_priv_t *ctx, va_list args)
521{
522 struct vp8_extracfg extra_cfg = ctx->vp8_cfg;
523 extra_cfg.Sharpness = CAST(VP8E_SET_SHARPNESS, args);
524 return update_extracfg(ctx, &extra_cfg);
525}
John Koleszar0ea50ce2010-05-18 11:58:33 -0400526
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -0700527static vpx_codec_err_t set_static_thresh(vpx_codec_alg_priv_t *ctx,
528 va_list args)
529{
530 struct vp8_extracfg extra_cfg = ctx->vp8_cfg;
531 extra_cfg.static_thresh = CAST(VP8E_SET_STATIC_THRESHOLD, args);
532 return update_extracfg(ctx, &extra_cfg);
533}
John Koleszar0ea50ce2010-05-18 11:58:33 -0400534
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -0700535static vpx_codec_err_t set_token_partitions(vpx_codec_alg_priv_t *ctx,
536 va_list args)
537{
538 struct vp8_extracfg extra_cfg = ctx->vp8_cfg;
539 extra_cfg.token_partitions = CAST(VP8E_SET_TOKEN_PARTITIONS, args);
540 return update_extracfg(ctx, &extra_cfg);
541}
542
543static vpx_codec_err_t set_arnr_max_frames(vpx_codec_alg_priv_t *ctx,
544 va_list args)
545{
546 struct vp8_extracfg extra_cfg = ctx->vp8_cfg;
547 extra_cfg.arnr_max_frames = CAST(VP8E_SET_ARNR_MAXFRAMES, args);
548 return update_extracfg(ctx, &extra_cfg);
549}
550
551static vpx_codec_err_t set_arnr_strength(vpx_codec_alg_priv_t *ctx,
552 va_list args)
553{
554 struct vp8_extracfg extra_cfg = ctx->vp8_cfg;
555 extra_cfg.arnr_strength = CAST(VP8E_SET_ARNR_STRENGTH, args);
556 return update_extracfg(ctx, &extra_cfg);
557}
558
559static vpx_codec_err_t set_arnr_type(vpx_codec_alg_priv_t *ctx, va_list args)
560{
561 struct vp8_extracfg extra_cfg = ctx->vp8_cfg;
562 extra_cfg.arnr_type = CAST(VP8E_SET_ARNR_TYPE, args);
563 return update_extracfg(ctx, &extra_cfg);
564}
565
566static vpx_codec_err_t set_tuning(vpx_codec_alg_priv_t *ctx, va_list args)
567{
568 struct vp8_extracfg extra_cfg = ctx->vp8_cfg;
569 extra_cfg.tuning = CAST(VP8E_SET_TUNING, args);
570 return update_extracfg(ctx, &extra_cfg);
571}
572
573static vpx_codec_err_t set_cq_level(vpx_codec_alg_priv_t *ctx, va_list args)
574{
575 struct vp8_extracfg extra_cfg = ctx->vp8_cfg;
576 extra_cfg.cq_level = CAST(VP8E_SET_CQ_LEVEL, args);
577 return update_extracfg(ctx, &extra_cfg);
578}
579
580static vpx_codec_err_t set_rc_max_intra_bitrate_pct(vpx_codec_alg_priv_t *ctx,
581 va_list args)
582{
583 struct vp8_extracfg extra_cfg = ctx->vp8_cfg;
584 extra_cfg.rc_max_intra_bitrate_pct =
585 CAST(VP8E_SET_MAX_INTRA_BITRATE_PCT, args);
586 return update_extracfg(ctx, &extra_cfg);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400587}
Yunqing Wangaa7335e2011-10-25 15:14:16 -0400588
589static vpx_codec_err_t vp8e_mr_alloc_mem(const vpx_codec_enc_cfg_t *cfg,
590 void **mem_loc)
591{
Yunqing Wangad479a92012-05-23 13:40:24 -0400592 vpx_codec_err_t res = 0;
593
Yunqing Wangaa7335e2011-10-25 15:14:16 -0400594#if CONFIG_MULTI_RES_ENCODING
Yunqing Wang65dd1572012-05-16 15:06:42 -0400595 LOWER_RES_FRAME_INFO *shared_mem_loc;
Yunqing Wangaa7335e2011-10-25 15:14:16 -0400596 int mb_rows = ((cfg->g_w + 15) >>4);
597 int mb_cols = ((cfg->g_h + 15) >>4);
598
Yunqing Wang65dd1572012-05-16 15:06:42 -0400599 shared_mem_loc = calloc(1, sizeof(LOWER_RES_FRAME_INFO));
600 if(!shared_mem_loc)
Yunqing Wangaa7335e2011-10-25 15:14:16 -0400601 {
Yunqing Wangad479a92012-05-23 13:40:24 -0400602 res = VPX_CODEC_MEM_ERROR;
Yunqing Wang65dd1572012-05-16 15:06:42 -0400603 }
604
605 shared_mem_loc->mb_info = calloc(mb_rows*mb_cols, sizeof(LOWER_RES_MB_INFO));
606 if(!(shared_mem_loc->mb_info))
607 {
Yunqing Wangad479a92012-05-23 13:40:24 -0400608 res = VPX_CODEC_MEM_ERROR;
Yunqing Wangaa7335e2011-10-25 15:14:16 -0400609 }
610 else
Yunqing Wang65dd1572012-05-16 15:06:42 -0400611 {
612 *mem_loc = (void *)shared_mem_loc;
Yunqing Wangad479a92012-05-23 13:40:24 -0400613 res = VPX_CODEC_OK;
Yunqing Wang65dd1572012-05-16 15:06:42 -0400614 }
Yunqing Wangaa7335e2011-10-25 15:14:16 -0400615#endif
Yunqing Wangad479a92012-05-23 13:40:24 -0400616 return res;
Yunqing Wangaa7335e2011-10-25 15:14:16 -0400617}
618
619static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx,
620 vpx_codec_priv_enc_mr_cfg_t *mr_cfg)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400621{
John Koleszar2bf8fb52012-05-02 16:37:37 -0700622 vpx_codec_err_t res = VPX_CODEC_OK;
Dmitry Kovalevb08fab82014-09-02 18:26:53 -0700623
John Koleszar0ea50ce2010-05-18 11:58:33 -0400624
John Koleszara9c75972012-11-08 17:09:30 -0800625 vp8_rtcd();
John Koleszar8df79e92012-06-15 15:40:13 -0700626
John Koleszar0ea50ce2010-05-18 11:58:33 -0400627 if (!ctx->priv)
628 {
Dmitry Kovalevb08fab82014-09-02 18:26:53 -0700629 struct vpx_codec_alg_priv *priv =
630 (struct vpx_codec_alg_priv *)vpx_calloc(1, sizeof(*priv));
John Koleszar0ea50ce2010-05-18 11:58:33 -0400631
Attila Nagye6db21e2011-02-22 15:02:05 +0200632 if (!priv)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400633 {
Attila Nagye6db21e2011-02-22 15:02:05 +0200634 return VPX_CODEC_MEM_ERROR;
635 }
John Koleszar0ea50ce2010-05-18 11:58:33 -0400636
Dmitry Kovalev73edeb02014-08-20 17:02:10 -0700637 ctx->priv = (vpx_codec_priv_t *)priv;
Attila Nagye6db21e2011-02-22 15:02:05 +0200638 ctx->priv->init_flags = ctx->init_flags;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400639
Attila Nagye6db21e2011-02-22 15:02:05 +0200640 if (ctx->config.enc)
641 {
642 /* Update the reference to the config structure to an
643 * internal copy.
John Koleszar0ea50ce2010-05-18 11:58:33 -0400644 */
Dmitry Kovalev73edeb02014-08-20 17:02:10 -0700645 priv->cfg = *ctx->config.enc;
646 ctx->config.enc = &priv->cfg;
Attila Nagye6db21e2011-02-22 15:02:05 +0200647 }
John Koleszar0ea50ce2010-05-18 11:58:33 -0400648
Dmitry Kovalev48274c62014-08-21 11:21:18 -0700649 priv->vp8_cfg = default_extracfg;
Attila Nagye6db21e2011-02-22 15:02:05 +0200650 priv->vp8_cfg.pkt_list = &priv->pkt_list.head;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400651
Attila Nagye6db21e2011-02-22 15:02:05 +0200652 priv->cx_data_sz = priv->cfg.g_w * priv->cfg.g_h * 3 / 2 * 2;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400653
James Berrybac6c222011-10-24 11:50:27 -0400654 if (priv->cx_data_sz < 32768) priv->cx_data_sz = 32768;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400655
Attila Nagye6db21e2011-02-22 15:02:05 +0200656 priv->cx_data = malloc(priv->cx_data_sz);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400657
Attila Nagye6db21e2011-02-22 15:02:05 +0200658 if (!priv->cx_data)
659 {
660 return VPX_CODEC_MEM_ERROR;
661 }
John Koleszar0ea50ce2010-05-18 11:58:33 -0400662
Yunqing Wang7f009972012-07-11 11:43:51 -0700663 if(mr_cfg)
664 ctx->priv->enc.total_encoders = mr_cfg->mr_total_resolutions;
665 else
666 ctx->priv->enc.total_encoders = 1;
667
James Berryc1c47e82011-12-07 15:48:00 -0500668 res = validate_config(priv, &priv->cfg, &priv->vp8_cfg, 0);
Attila Nagye6db21e2011-02-22 15:02:05 +0200669
670 if (!res)
671 {
Dmitry Kovalev73edeb02014-08-20 17:02:10 -0700672 set_vp8e_config(&priv->oxcf, priv->cfg, priv->vp8_cfg, mr_cfg);
673 priv->cpi = vp8_create_compressor(&priv->oxcf);
674 if (!priv->cpi)
Attila Nagye6db21e2011-02-22 15:02:05 +0200675 res = VPX_CODEC_MEM_ERROR;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400676 }
677 }
678
679 return res;
680}
681
682static vpx_codec_err_t vp8e_destroy(vpx_codec_alg_priv_t *ctx)
683{
Yunqing Wangaa7335e2011-10-25 15:14:16 -0400684#if CONFIG_MULTI_RES_ENCODING
685 /* Free multi-encoder shared memory */
686 if (ctx->oxcf.mr_total_resolutions > 0 && (ctx->oxcf.mr_encoder_id == ctx->oxcf.mr_total_resolutions-1))
Yunqing Wang65dd1572012-05-16 15:06:42 -0400687 {
688 LOWER_RES_FRAME_INFO *shared_mem_loc = (LOWER_RES_FRAME_INFO *)ctx->oxcf.mr_low_res_mode_info;
689 free(shared_mem_loc->mb_info);
Yunqing Wangaa7335e2011-10-25 15:14:16 -0400690 free(ctx->oxcf.mr_low_res_mode_info);
Yunqing Wang65dd1572012-05-16 15:06:42 -0400691 }
Yunqing Wangaa7335e2011-10-25 15:14:16 -0400692#endif
John Koleszar0ea50ce2010-05-18 11:58:33 -0400693
694 free(ctx->cx_data);
695 vp8_remove_compressor(&ctx->cpi);
Dmitry Kovalevb08fab82014-09-02 18:26:53 -0700696 vpx_free(ctx);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400697 return VPX_CODEC_OK;
698}
699
700static vpx_codec_err_t image2yuvconfig(const vpx_image_t *img,
701 YV12_BUFFER_CONFIG *yv12)
702{
Johann69dc8762014-08-15 10:50:40 -0700703 const int y_w = img->d_w;
704 const int y_h = img->d_h;
705 const int uv_w = (img->d_w + 1) / 2;
706 const int uv_h = (img->d_h + 1) / 2;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400707 vpx_codec_err_t res = VPX_CODEC_OK;
John Koleszarb6c71912010-05-24 21:45:05 -0400708 yv12->y_buffer = img->planes[VPX_PLANE_Y];
709 yv12->u_buffer = img->planes[VPX_PLANE_U];
710 yv12->v_buffer = img->planes[VPX_PLANE_V];
John Koleszar0ea50ce2010-05-18 11:58:33 -0400711
Johann69dc8762014-08-15 10:50:40 -0700712 yv12->y_crop_width = y_w;
713 yv12->y_crop_height = y_h;
714 yv12->y_width = y_w;
715 yv12->y_height = y_h;
716 yv12->uv_crop_width = uv_w;
717 yv12->uv_crop_height = uv_h;
718 yv12->uv_width = uv_w;
719 yv12->uv_height = uv_h;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400720
John Koleszarb6c71912010-05-24 21:45:05 -0400721 yv12->y_stride = img->stride[VPX_PLANE_Y];
722 yv12->uv_stride = img->stride[VPX_PLANE_U];
John Koleszar0ea50ce2010-05-18 11:58:33 -0400723
John Koleszarb6c71912010-05-24 21:45:05 -0400724 yv12->border = (img->stride[VPX_PLANE_Y] - img->w) / 2;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400725 return res;
726}
727
728static void pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx,
729 unsigned long duration,
730 unsigned long deadline)
731{
732 unsigned int new_qc;
733
734#if !(CONFIG_REALTIME_ONLY)
735 /* Use best quality mode if no deadline is given. */
736 new_qc = MODE_BESTQUALITY;
737
738 if (deadline)
739 {
740 uint64_t duration_us;
741
742 /* Convert duration parameter from stream timebase to microseconds */
743 duration_us = (uint64_t)duration * 1000000
744 * (uint64_t)ctx->cfg.g_timebase.num
745 / (uint64_t)ctx->cfg.g_timebase.den;
746
747 /* If the deadline is more that the duration this frame is to be shown,
748 * use good quality mode. Otherwise use realtime mode.
749 */
750 new_qc = (deadline > duration_us) ? MODE_GOODQUALITY : MODE_REALTIME;
751 }
752
753#else
754 new_qc = MODE_REALTIME;
755#endif
756
John Koleszar0ea50ce2010-05-18 11:58:33 -0400757 if (ctx->cfg.g_pass == VPX_RC_FIRST_PASS)
758 new_qc = MODE_FIRSTPASS;
759 else if (ctx->cfg.g_pass == VPX_RC_LAST_PASS)
760 new_qc = (new_qc == MODE_BESTQUALITY)
761 ? MODE_SECONDPASS_BEST
762 : MODE_SECONDPASS;
763
764 if (ctx->oxcf.Mode != new_qc)
765 {
766 ctx->oxcf.Mode = new_qc;
767 vp8_change_config(ctx->cpi, &ctx->oxcf);
768 }
769}
770
771
772static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t *ctx,
773 const vpx_image_t *img,
774 vpx_codec_pts_t pts,
775 unsigned long duration,
776 vpx_enc_frame_flags_t flags,
777 unsigned long deadline)
778{
779 vpx_codec_err_t res = VPX_CODEC_OK;
780
John Koleszar25a36d62012-04-19 10:00:33 -0700781 if (!ctx->cfg.rc_target_bitrate)
782 return res;
783
John Koleszar0ea50ce2010-05-18 11:58:33 -0400784 if (img)
785 res = validate_img(ctx, img);
786
James Berryc1c47e82011-12-07 15:48:00 -0500787 if (!res)
788 res = validate_config(ctx, &ctx->cfg, &ctx->vp8_cfg, 1);
789
John Koleszar0ea50ce2010-05-18 11:58:33 -0400790 pick_quickcompress_mode(ctx, duration, deadline);
791 vpx_codec_pkt_list_init(&ctx->pkt_list);
792
793 /* Handle Flags */
794 if (((flags & VP8_EFLAG_NO_UPD_GF) && (flags & VP8_EFLAG_FORCE_GF))
795 || ((flags & VP8_EFLAG_NO_UPD_ARF) && (flags & VP8_EFLAG_FORCE_ARF)))
796 {
797 ctx->base.err_detail = "Conflicting flags.";
798 return VPX_CODEC_INVALID_PARAM;
799 }
800
801 if (flags & (VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF
802 | VP8_EFLAG_NO_REF_ARF))
803 {
804 int ref = 7;
805
806 if (flags & VP8_EFLAG_NO_REF_LAST)
Johann965d8682012-05-23 16:08:37 -0700807 ref ^= VP8_LAST_FRAME;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400808
809 if (flags & VP8_EFLAG_NO_REF_GF)
Johann965d8682012-05-23 16:08:37 -0700810 ref ^= VP8_GOLD_FRAME;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400811
812 if (flags & VP8_EFLAG_NO_REF_ARF)
Johann965d8682012-05-23 16:08:37 -0700813 ref ^= VP8_ALTR_FRAME;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400814
815 vp8_use_as_reference(ctx->cpi, ref);
816 }
817
818 if (flags & (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF
819 | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_FORCE_GF
820 | VP8_EFLAG_FORCE_ARF))
821 {
822 int upd = 7;
823
824 if (flags & VP8_EFLAG_NO_UPD_LAST)
Johann965d8682012-05-23 16:08:37 -0700825 upd ^= VP8_LAST_FRAME;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400826
827 if (flags & VP8_EFLAG_NO_UPD_GF)
Johann965d8682012-05-23 16:08:37 -0700828 upd ^= VP8_GOLD_FRAME;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400829
830 if (flags & VP8_EFLAG_NO_UPD_ARF)
Johann965d8682012-05-23 16:08:37 -0700831 upd ^= VP8_ALTR_FRAME;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400832
833 vp8_update_reference(ctx->cpi, upd);
834 }
835
836 if (flags & VP8_EFLAG_NO_UPD_ENTROPY)
837 {
838 vp8_update_entropy(ctx->cpi, 0);
839 }
840
841 /* Handle fixed keyframe intervals */
842 if (ctx->cfg.kf_mode == VPX_KF_AUTO
843 && ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist)
844 {
845 if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist)
846 {
847 flags |= VPX_EFLAG_FORCE_KF;
Andoni Morales Alastruey48140162011-02-07 18:04:02 +0100848 ctx->fixed_kf_cntr = 1;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400849 }
850 }
851
852 /* Initialize the encoder instance on the first frame*/
853 if (!res && ctx->cpi)
854 {
855 unsigned int lib_flags;
856 YV12_BUFFER_CONFIG sd;
James Zernb45065d2011-07-25 18:44:59 -0700857 int64_t dst_time_stamp, dst_end_time_stamp;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400858 unsigned long size, cx_data_sz;
859 unsigned char *cx_data;
James Berrybc715112011-10-12 11:18:50 -0400860 unsigned char *cx_data_end;
861 int comp_data_state = 0;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400862
863 /* Set up internal flags */
864 if (ctx->base.init_flags & VPX_CODEC_USE_PSNR)
865 ((VP8_COMP *)ctx->cpi)->b_calculate_psnr = 1;
866
Stefan Holmer7296b3f2011-06-13 16:42:27 +0200867 if (ctx->base.init_flags & VPX_CODEC_USE_OUTPUT_PARTITION)
868 ((VP8_COMP *)ctx->cpi)->output_partition = 1;
869
John Koleszar0ea50ce2010-05-18 11:58:33 -0400870 /* Convert API flags to internal codec lib flags */
871 lib_flags = (flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
872
873 /* vp8 use 10,000,000 ticks/second as time stamp */
874 dst_time_stamp = pts * 10000000 * ctx->cfg.g_timebase.num / ctx->cfg.g_timebase.den;
875 dst_end_time_stamp = (pts + duration) * 10000000 * ctx->cfg.g_timebase.num / ctx->cfg.g_timebase.den;
876
877 if (img != NULL)
878 {
879 res = image2yuvconfig(img, &sd);
880
881 if (vp8_receive_raw_frame(ctx->cpi, ctx->next_frame_flag | lib_flags,
882 &sd, dst_time_stamp, dst_end_time_stamp))
883 {
884 VP8_COMP *cpi = (VP8_COMP *)ctx->cpi;
885 res = update_error_state(ctx, &cpi->common.error);
886 }
887
888 /* reset for next frame */
889 ctx->next_frame_flag = 0;
890 }
891
892 cx_data = ctx->cx_data;
893 cx_data_sz = ctx->cx_data_sz;
James Berrybc715112011-10-12 11:18:50 -0400894 cx_data_end = ctx->cx_data + cx_data_sz;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400895 lib_flags = 0;
896
James Berrybc715112011-10-12 11:18:50 -0400897 while (cx_data_sz >= ctx->cx_data_sz / 2)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400898 {
James Berrybc715112011-10-12 11:18:50 -0400899 comp_data_state = vp8_get_compressed_data(ctx->cpi,
900 &lib_flags,
901 &size,
902 cx_data,
903 cx_data_end,
904 &dst_time_stamp,
905 &dst_end_time_stamp,
906 !img);
907
908 if(comp_data_state == VPX_CODEC_CORRUPT_FRAME)
909 return VPX_CODEC_CORRUPT_FRAME;
910 else if(comp_data_state == -1)
911 break;
912
John Koleszar0ea50ce2010-05-18 11:58:33 -0400913 if (size)
914 {
915 vpx_codec_pts_t round, delta;
916 vpx_codec_cx_pkt_t pkt;
917 VP8_COMP *cpi = (VP8_COMP *)ctx->cpi;
918
919 /* Add the frame packet to the list of returned packets. */
Dmitry Kovalev947748e2014-04-25 17:39:48 -0700920 round = (vpx_codec_pts_t)10000000
James Zern429743c2012-08-07 17:12:10 -0700921 * ctx->cfg.g_timebase.num / 2 - 1;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400922 delta = (dst_end_time_stamp - dst_time_stamp);
923 pkt.kind = VPX_CODEC_CX_FRAME_PKT;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400924 pkt.data.frame.pts =
925 (dst_time_stamp * ctx->cfg.g_timebase.den + round)
926 / ctx->cfg.g_timebase.num / 10000000;
Yaowu Xud71ba032012-08-17 10:05:35 -0700927 pkt.data.frame.duration = (unsigned long)
928 ((delta * ctx->cfg.g_timebase.den + round)
929 / ctx->cfg.g_timebase.num / 10000000);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400930 pkt.data.frame.flags = lib_flags << 16;
931
932 if (lib_flags & FRAMEFLAGS_KEY)
933 pkt.data.frame.flags |= VPX_FRAME_IS_KEY;
934
935 if (!cpi->common.show_frame)
936 {
937 pkt.data.frame.flags |= VPX_FRAME_IS_INVISIBLE;
938
John Koleszar0164a1c2012-05-21 14:30:56 -0700939 /* This timestamp should be as close as possible to the
940 * prior PTS so that if a decoder uses pts to schedule when
941 * to do this, we start right after last frame was decoded.
942 * Invisible frames have no duration.
943 */
Frank Galligan45e64942010-10-05 17:46:37 -0400944 pkt.data.frame.pts = ((cpi->last_time_stamp_seen
945 * ctx->cfg.g_timebase.den + round)
946 / ctx->cfg.g_timebase.num / 10000000) + 1;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400947 pkt.data.frame.duration = 0;
948 }
949
John Koleszar37de0b82011-07-07 10:38:23 -0400950 if (cpi->droppable)
951 pkt.data.frame.flags |= VPX_FRAME_IS_DROPPABLE;
952
Stefan Holmer7296b3f2011-06-13 16:42:27 +0200953 if (cpi->output_partition)
954 {
955 int i;
956 const int num_partitions =
957 (1 << cpi->common.multi_token_partition) + 1;
Attila Nagy0afcc762011-07-20 14:09:42 +0300958
959 pkt.data.frame.flags |= VPX_FRAME_IS_FRAGMENT;
960
Stefan Holmer7296b3f2011-06-13 16:42:27 +0200961 for (i = 0; i < num_partitions; ++i)
962 {
Attila Nagy52cf4dc2012-02-09 12:37:03 +0200963#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
964 pkt.data.frame.buf = cpi->partition_d[i];
965#else
Stefan Holmer7296b3f2011-06-13 16:42:27 +0200966 pkt.data.frame.buf = cx_data;
Attila Nagy52cf4dc2012-02-09 12:37:03 +0200967 cx_data += cpi->partition_sz[i];
968 cx_data_sz -= cpi->partition_sz[i];
969#endif
Stefan Holmer7296b3f2011-06-13 16:42:27 +0200970 pkt.data.frame.sz = cpi->partition_sz[i];
971 pkt.data.frame.partition_id = i;
972 /* don't set the fragment bit for the last partition */
Attila Nagy0afcc762011-07-20 14:09:42 +0300973 if (i == (num_partitions - 1))
974 pkt.data.frame.flags &= ~VPX_FRAME_IS_FRAGMENT;
Stefan Holmer7296b3f2011-06-13 16:42:27 +0200975 vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
Stefan Holmer7296b3f2011-06-13 16:42:27 +0200976 }
Attila Nagy52cf4dc2012-02-09 12:37:03 +0200977#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
978 /* In lagged mode the encoder can buffer multiple frames.
979 * We don't want this in partitioned output because
980 * partitions are spread all over the output buffer.
981 * So, force an exit!
982 */
983 cx_data_sz -= ctx->cx_data_sz / 2;
984#endif
Stefan Holmer7296b3f2011-06-13 16:42:27 +0200985 }
986 else
987 {
988 pkt.data.frame.buf = cx_data;
989 pkt.data.frame.sz = size;
990 pkt.data.frame.partition_id = -1;
991 vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
992 cx_data += size;
993 cx_data_sz -= size;
994 }
John Koleszar0ea50ce2010-05-18 11:58:33 -0400995 }
996 }
997 }
998
999 return res;
1000}
1001
1002
1003static const vpx_codec_cx_pkt_t *vp8e_get_cxdata(vpx_codec_alg_priv_t *ctx,
1004 vpx_codec_iter_t *iter)
1005{
1006 return vpx_codec_pkt_list_get(&ctx->pkt_list.head, iter);
1007}
1008
1009static vpx_codec_err_t vp8e_set_reference(vpx_codec_alg_priv_t *ctx,
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -07001010 va_list args)
John Koleszar0ea50ce2010-05-18 11:58:33 -04001011{
1012 vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
1013
1014 if (data)
1015 {
1016 vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
1017 YV12_BUFFER_CONFIG sd;
1018
1019 image2yuvconfig(&frame->img, &sd);
1020 vp8_set_reference(ctx->cpi, frame->frame_type, &sd);
1021 return VPX_CODEC_OK;
1022 }
1023 else
1024 return VPX_CODEC_INVALID_PARAM;
1025
1026}
1027
1028static vpx_codec_err_t vp8e_get_reference(vpx_codec_alg_priv_t *ctx,
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -07001029 va_list args)
John Koleszar0ea50ce2010-05-18 11:58:33 -04001030{
1031
1032 vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
1033
1034 if (data)
1035 {
1036 vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
1037 YV12_BUFFER_CONFIG sd;
1038
1039 image2yuvconfig(&frame->img, &sd);
1040 vp8_get_reference(ctx->cpi, frame->frame_type, &sd);
1041 return VPX_CODEC_OK;
1042 }
1043 else
1044 return VPX_CODEC_INVALID_PARAM;
1045}
1046
1047static vpx_codec_err_t vp8e_set_previewpp(vpx_codec_alg_priv_t *ctx,
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -07001048 va_list args)
John Koleszar0ea50ce2010-05-18 11:58:33 -04001049{
James Zern76640f82010-08-20 16:06:56 -04001050#if CONFIG_POSTPROC
John Koleszar0ea50ce2010-05-18 11:58:33 -04001051 vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *);
1052
1053 if (data)
1054 {
1055 ctx->preview_ppcfg = *((vp8_postproc_cfg_t *)data);
1056 return VPX_CODEC_OK;
1057 }
1058 else
1059 return VPX_CODEC_INVALID_PARAM;
James Zern76640f82010-08-20 16:06:56 -04001060#else
1061 (void)ctx;
James Zern76640f82010-08-20 16:06:56 -04001062 (void)args;
1063 return VPX_CODEC_INCAPABLE;
1064#endif
John Koleszar0ea50ce2010-05-18 11:58:33 -04001065}
1066
1067
1068static vpx_image_t *vp8e_get_preview(vpx_codec_alg_priv_t *ctx)
1069{
1070
1071 YV12_BUFFER_CONFIG sd;
Fritz Koenig647df002010-11-04 16:03:36 -07001072 vp8_ppflags_t flags = {0};
John Koleszar0ea50ce2010-05-18 11:58:33 -04001073
Fritz Koenig647df002010-11-04 16:03:36 -07001074 if (ctx->preview_ppcfg.post_proc_flag)
1075 {
1076 flags.post_proc_flag = ctx->preview_ppcfg.post_proc_flag;
1077 flags.deblocking_level = ctx->preview_ppcfg.deblocking_level;
1078 flags.noise_level = ctx->preview_ppcfg.noise_level;
1079 }
1080
1081 if (0 == vp8_get_preview_raw_frame(ctx->cpi, &sd, &flags))
John Koleszar0ea50ce2010-05-18 11:58:33 -04001082 {
1083
1084 /*
James Zern6cd4a102010-05-20 23:22:39 -04001085 vpx_img_wrap(&ctx->preview_img, VPX_IMG_FMT_YV12,
John Koleszar0ea50ce2010-05-18 11:58:33 -04001086 sd.y_width + 2*VP8BORDERINPIXELS,
1087 sd.y_height + 2*VP8BORDERINPIXELS,
1088 1,
1089 sd.buffer_alloc);
1090 vpx_img_set_rect(&ctx->preview_img,
1091 VP8BORDERINPIXELS, VP8BORDERINPIXELS,
1092 sd.y_width, sd.y_height);
1093 */
1094
1095 ctx->preview_img.bps = 12;
John Koleszarb6c71912010-05-24 21:45:05 -04001096 ctx->preview_img.planes[VPX_PLANE_Y] = sd.y_buffer;
1097 ctx->preview_img.planes[VPX_PLANE_U] = sd.u_buffer;
1098 ctx->preview_img.planes[VPX_PLANE_V] = sd.v_buffer;
John Koleszar0ea50ce2010-05-18 11:58:33 -04001099
James Zern4fc6c882013-07-12 14:11:53 -07001100 ctx->preview_img.fmt = VPX_IMG_FMT_I420;
John Koleszar0ea50ce2010-05-18 11:58:33 -04001101 ctx->preview_img.x_chroma_shift = 1;
1102 ctx->preview_img.y_chroma_shift = 1;
1103
James Berryddacf1c2011-02-08 14:23:18 -05001104 ctx->preview_img.d_w = sd.y_width;
1105 ctx->preview_img.d_h = sd.y_height;
John Koleszarb6c71912010-05-24 21:45:05 -04001106 ctx->preview_img.stride[VPX_PLANE_Y] = sd.y_stride;
1107 ctx->preview_img.stride[VPX_PLANE_U] = sd.uv_stride;
1108 ctx->preview_img.stride[VPX_PLANE_V] = sd.uv_stride;
John Koleszar0ea50ce2010-05-18 11:58:33 -04001109 ctx->preview_img.w = sd.y_width;
1110 ctx->preview_img.h = sd.y_height;
1111
1112 return &ctx->preview_img;
1113 }
1114 else
1115 return NULL;
1116}
1117
1118static vpx_codec_err_t vp8e_update_entropy(vpx_codec_alg_priv_t *ctx,
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -07001119 va_list args)
John Koleszar0ea50ce2010-05-18 11:58:33 -04001120{
1121 int update = va_arg(args, int);
1122 vp8_update_entropy(ctx->cpi, update);
1123 return VPX_CODEC_OK;
1124
1125}
1126
1127static vpx_codec_err_t vp8e_update_reference(vpx_codec_alg_priv_t *ctx,
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -07001128 va_list args)
John Koleszar0ea50ce2010-05-18 11:58:33 -04001129{
1130 int update = va_arg(args, int);
1131 vp8_update_reference(ctx->cpi, update);
1132 return VPX_CODEC_OK;
1133}
1134
1135static vpx_codec_err_t vp8e_use_reference(vpx_codec_alg_priv_t *ctx,
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -07001136 va_list args)
John Koleszar0ea50ce2010-05-18 11:58:33 -04001137{
1138 int reference_flag = va_arg(args, int);
1139 vp8_use_as_reference(ctx->cpi, reference_flag);
1140 return VPX_CODEC_OK;
1141}
1142
1143static vpx_codec_err_t vp8e_set_roi_map(vpx_codec_alg_priv_t *ctx,
John Koleszar0ea50ce2010-05-18 11:58:33 -04001144 va_list args)
1145{
1146 vpx_roi_map_t *data = va_arg(args, vpx_roi_map_t *);
1147
1148 if (data)
1149 {
1150 vpx_roi_map_t *roi = (vpx_roi_map_t *)data;
1151
1152 if (!vp8_set_roimap(ctx->cpi, roi->roi_map, roi->rows, roi->cols, roi->delta_q, roi->delta_lf, roi->static_threshold))
1153 return VPX_CODEC_OK;
1154 else
1155 return VPX_CODEC_INVALID_PARAM;
1156 }
1157 else
1158 return VPX_CODEC_INVALID_PARAM;
1159}
1160
1161
1162static vpx_codec_err_t vp8e_set_activemap(vpx_codec_alg_priv_t *ctx,
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -07001163 va_list args)
John Koleszar0ea50ce2010-05-18 11:58:33 -04001164{
1165 vpx_active_map_t *data = va_arg(args, vpx_active_map_t *);
1166
1167 if (data)
1168 {
1169
1170 vpx_active_map_t *map = (vpx_active_map_t *)data;
1171
1172 if (!vp8_set_active_map(ctx->cpi, map->active_map, map->rows, map->cols))
1173 return VPX_CODEC_OK;
1174 else
1175 return VPX_CODEC_INVALID_PARAM;
1176 }
1177 else
1178 return VPX_CODEC_INVALID_PARAM;
1179}
1180
1181static vpx_codec_err_t vp8e_set_scalemode(vpx_codec_alg_priv_t *ctx,
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -07001182 va_list args)
John Koleszar0ea50ce2010-05-18 11:58:33 -04001183{
1184
1185 vpx_scaling_mode_t *data = va_arg(args, vpx_scaling_mode_t *);
1186
1187 if (data)
1188 {
1189 int res;
1190 vpx_scaling_mode_t scalemode = *(vpx_scaling_mode_t *)data ;
Frank Galliganbc45f232013-01-11 15:34:05 -08001191 res = vp8_set_internal_size(ctx->cpi,
1192 (VPX_SCALING)scalemode.h_scaling_mode,
1193 (VPX_SCALING)scalemode.v_scaling_mode);
John Koleszar0ea50ce2010-05-18 11:58:33 -04001194
1195 if (!res)
1196 {
1197 /*force next frame a key frame to effect scaling mode */
1198 ctx->next_frame_flag |= FRAMEFLAGS_KEY;
1199 return VPX_CODEC_OK;
1200 }
1201 else
1202 return VPX_CODEC_INVALID_PARAM;
1203 }
1204 else
1205 return VPX_CODEC_INVALID_PARAM;
1206}
1207
1208
1209static vpx_codec_ctrl_fn_map_t vp8e_ctf_maps[] =
1210{
1211 {VP8_SET_REFERENCE, vp8e_set_reference},
1212 {VP8_COPY_REFERENCE, vp8e_get_reference},
1213 {VP8_SET_POSTPROC, vp8e_set_previewpp},
1214 {VP8E_UPD_ENTROPY, vp8e_update_entropy},
1215 {VP8E_UPD_REFERENCE, vp8e_update_reference},
1216 {VP8E_USE_REFERENCE, vp8e_use_reference},
1217 {VP8E_SET_ROI_MAP, vp8e_set_roi_map},
1218 {VP8E_SET_ACTIVEMAP, vp8e_set_activemap},
1219 {VP8E_SET_SCALEMODE, vp8e_set_scalemode},
Dmitry Kovalev8a8b6622014-05-27 16:45:58 -07001220 {VP8E_SET_CPUUSED, set_cpu_used},
1221 {VP8E_SET_NOISE_SENSITIVITY, set_noise_sensitivity},
1222 {VP8E_SET_ENABLEAUTOALTREF, set_enable_auto_alt_ref},
1223 {VP8E_SET_SHARPNESS, set_sharpness},
1224 {VP8E_SET_STATIC_THRESHOLD, set_static_thresh},
1225 {VP8E_SET_TOKEN_PARTITIONS, set_token_partitions},
1226 {VP8E_GET_LAST_QUANTIZER, get_quantizer},
1227 {VP8E_GET_LAST_QUANTIZER_64, get_quantizer64},
1228 {VP8E_SET_ARNR_MAXFRAMES, set_arnr_max_frames},
1229 {VP8E_SET_ARNR_STRENGTH , set_arnr_strength},
1230 {VP8E_SET_ARNR_TYPE , set_arnr_type},
1231 {VP8E_SET_TUNING, set_tuning},
1232 {VP8E_SET_CQ_LEVEL, set_cq_level},
1233 {VP8E_SET_MAX_INTRA_BITRATE_PCT, set_rc_max_intra_bitrate_pct},
John Koleszar0ea50ce2010-05-18 11:58:33 -04001234 { -1, NULL},
1235};
1236
1237static vpx_codec_enc_cfg_map_t vp8e_usage_cfg_map[] =
1238{
1239 {
1240 0,
1241 {
1242 0, /* g_usage */
1243 0, /* g_threads */
1244 0, /* g_profile */
1245
1246 320, /* g_width */
1247 240, /* g_height */
Deb Mukherjee5acfafb2014-08-26 12:35:15 -07001248 VPX_BITS_8, /* g_bit_depth */
1249 8, /* g_input_bit_depth */
1250
John Koleszar0ea50ce2010-05-18 11:58:33 -04001251 {1, 30}, /* g_timebase */
1252
1253 0, /* g_error_resilient */
1254
1255 VPX_RC_ONE_PASS, /* g_pass */
1256
1257 0, /* g_lag_in_frames */
1258
John Koleszar23216212010-09-02 09:32:03 -04001259 0, /* rc_dropframe_thresh */
John Koleszar0ea50ce2010-05-18 11:58:33 -04001260 0, /* rc_resize_allowed */
Adrian Grangef7bd1272014-04-09 14:51:29 -07001261 1, /* rc_scaled_width */
1262 1, /* rc_scaled_height */
John Koleszar0ea50ce2010-05-18 11:58:33 -04001263 60, /* rc_resize_down_thresold */
1264 30, /* rc_resize_up_thresold */
1265
1266 VPX_VBR, /* rc_end_usage */
1267#if VPX_ENCODER_ABI_VERSION > (1 + VPX_CODEC_ABI_VERSION)
1268 {0}, /* rc_twopass_stats_in */
Pengchong Jinf349b072014-07-14 09:13:38 -07001269 {0}, /* rc_firstpass_mb_stats_in */
John Koleszar0ea50ce2010-05-18 11:58:33 -04001270#endif
1271 256, /* rc_target_bandwidth */
John Koleszar0ea50ce2010-05-18 11:58:33 -04001272 4, /* rc_min_quantizer */
1273 63, /* rc_max_quantizer */
John Koleszarc99f9d72011-04-11 11:29:23 -04001274 100, /* rc_undershoot_pct */
1275 100, /* rc_overshoot_pct */
John Koleszar0ea50ce2010-05-18 11:58:33 -04001276
1277 6000, /* rc_max_buffer_size */
1278 4000, /* rc_buffer_initial_size; */
1279 5000, /* rc_buffer_optimal_size; */
1280
1281 50, /* rc_two_pass_vbrbias */
1282 0, /* rc_two_pass_vbrmin_section */
1283 400, /* rc_two_pass_vbrmax_section */
1284
1285 /* keyframing settings (kf) */
1286 VPX_KF_AUTO, /* g_kfmode*/
1287 0, /* kf_min_dist */
Ralph Giles2a0d7b12012-01-05 10:39:38 -06001288 128, /* kf_max_dist */
John Koleszar0ea50ce2010-05-18 11:58:33 -04001289
1290#if VPX_ENCODER_ABI_VERSION == (1 + VPX_CODEC_ABI_VERSION)
John Koleszar0ea50ce2010-05-18 11:58:33 -04001291 "vp8.fpf" /* first pass filename */
1292#endif
Ivan Maltz01b35c32013-09-05 08:55:47 -07001293 VPX_SS_DEFAULT_LAYERS, /* ss_number_layers */
Minghai Shange8998592014-07-14 11:24:17 -07001294 {0},
Minghai Shang8c196b22014-02-26 13:30:50 -08001295 {0}, /* ss_target_bitrate */
Adrian Grange217591f2011-10-06 15:49:11 -07001296 1, /* ts_number_layers */
1297 {0}, /* ts_target_bitrate */
1298 {0}, /* ts_rate_decimator */
1299 0, /* ts_periodicity */
1300 {0}, /* ts_layer_id */
John Koleszar0ea50ce2010-05-18 11:58:33 -04001301 }},
John Koleszar0ea50ce2010-05-18 11:58:33 -04001302};
1303
1304
1305#ifndef VERSION_STRING
1306#define VERSION_STRING
1307#endif
John Koleszarfa7a55b2010-09-21 10:35:52 -04001308CODEC_INTERFACE(vpx_codec_vp8_cx) =
John Koleszar0ea50ce2010-05-18 11:58:33 -04001309{
John Koleszar317a6662010-06-10 12:08:01 -04001310 "WebM Project VP8 Encoder" VERSION_STRING,
John Koleszar0ea50ce2010-05-18 11:58:33 -04001311 VPX_CODEC_INTERNAL_ABI_VERSION,
Stefan Holmer7296b3f2011-06-13 16:42:27 +02001312 VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR |
1313 VPX_CODEC_CAP_OUTPUT_PARTITION,
John Koleszar0ea50ce2010-05-18 11:58:33 -04001314 /* vpx_codec_caps_t caps; */
1315 vp8e_init, /* vpx_codec_init_fn_t init; */
1316 vp8e_destroy, /* vpx_codec_destroy_fn_t destroy; */
1317 vp8e_ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */
John Koleszar0ea50ce2010-05-18 11:58:33 -04001318 {
Dmitry Kovalevcd6d9842014-08-20 17:16:28 -07001319 NULL, /* vpx_codec_peek_si_fn_t peek_si; */
1320 NULL, /* vpx_codec_get_si_fn_t get_si; */
1321 NULL, /* vpx_codec_decode_fn_t decode; */
1322 NULL, /* vpx_codec_frame_get_fn_t frame_get; */
John Koleszar0ea50ce2010-05-18 11:58:33 -04001323 },
1324 {
Jim Bankoski8a774e12014-07-31 06:27:57 -07001325 1, /* 1 cfg map */
John Koleszar0ea50ce2010-05-18 11:58:33 -04001326 vp8e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t peek_si; */
1327 vp8e_encode, /* vpx_codec_encode_fn_t encode; */
1328 vp8e_get_cxdata, /* vpx_codec_get_cx_data_fn_t frame_get; */
1329 vp8e_set_config,
Dmitry Kovalevcd6d9842014-08-20 17:16:28 -07001330 NULL,
John Koleszar0ea50ce2010-05-18 11:58:33 -04001331 vp8e_get_preview,
Yunqing Wangaa7335e2011-10-25 15:14:16 -04001332 vp8e_mr_alloc_mem,
John Koleszar0ea50ce2010-05-18 11:58:33 -04001333 } /* encoder functions */
1334};