diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 10b44492cadf0d896f9fb8c9f4af2cc4b5909481..6272587446a4bf09d38799c341df7ca3027b7bd2 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -40,6 +40,7 @@ #include "vp9/encoder/vp9_temporal_filter.h" #include "vp9/encoder/vp9_vaq.h" #include "vp9/encoder/vp9_resize.h" +#include "vp9/encoder/vp9_svc_layercontext.h" void vp9_coef_tree_initialize(); @@ -1109,10 +1110,9 @@ static void update_frame_size(VP9_COMP *cpi) { } } - // Table that converts 0-63 Q range values passed in outside to the Qindex // range used internally. -static const int q_trans[] = { +const int q_trans[] = { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, @@ -1181,7 +1181,7 @@ void vp9_new_framerate(VP9_COMP *cpi, double framerate) { rc->max_gf_interval = rc->static_scene_max_gf_interval; } -static int64_t rescale(int64_t val, int64_t num, int denom) { +int64_t vp9_rescale(int64_t val, int64_t num, int denom) { int64_t llnum = num; int64_t llden = denom; int64_t llval = val; @@ -1189,124 +1189,6 @@ static int64_t rescale(int64_t val, int64_t num, int denom) { return (llval * llnum / llden); } -// Initialize layer context data from init_config(). -static void init_layer_context(VP9_COMP *const cpi) { - const VP9_CONFIG *const oxcf = &cpi->oxcf; - int temporal_layer = 0; - cpi->svc.spatial_layer_id = 0; - cpi->svc.temporal_layer_id = 0; - for (temporal_layer = 0; temporal_layer < cpi->svc.number_temporal_layers; - ++temporal_layer) { - LAYER_CONTEXT *const lc = &cpi->svc.layer_context[temporal_layer]; - RATE_CONTROL *const lrc = &lc->rc; - lrc->avg_frame_qindex[INTER_FRAME] = q_trans[oxcf->worst_allowed_q]; - lrc->last_q[INTER_FRAME] = q_trans[oxcf->worst_allowed_q]; - lrc->ni_av_qi = q_trans[oxcf->worst_allowed_q]; - lrc->total_actual_bits = 0; - lrc->total_target_vs_actual = 0; - lrc->ni_tot_qi = 0; - lrc->tot_q = 0.0; - lrc->avg_q = 0.0; - lrc->ni_frames = 0; - lrc->decimation_count = 0; - lrc->decimation_factor = 0; - lrc->rate_correction_factor = 1.0; - lrc->key_frame_rate_correction_factor = 1.0; - lc->target_bandwidth = oxcf->ts_target_bitrate[temporal_layer] * - 1000; - lrc->buffer_level = rescale((int)(oxcf->starting_buffer_level), - lc->target_bandwidth, 1000); - lrc->bits_off_target = lrc->buffer_level; - } -} - -// Update the layer context from a change_config() call. -static void update_layer_context_change_config(VP9_COMP *const cpi, - const int target_bandwidth) { - const VP9_CONFIG *const oxcf = &cpi->oxcf; - const RATE_CONTROL *const rc = &cpi->rc; - int temporal_layer = 0; - float bitrate_alloc = 1.0; - for (temporal_layer = 0; temporal_layer < cpi->svc.number_temporal_layers; - ++temporal_layer) { - LAYER_CONTEXT *const lc = &cpi->svc.layer_context[temporal_layer]; - RATE_CONTROL *const lrc = &lc->rc; - lc->target_bandwidth = oxcf->ts_target_bitrate[temporal_layer] * 1000; - bitrate_alloc = (float)lc->target_bandwidth / (float)target_bandwidth; - // Update buffer-related quantities. - lc->starting_buffer_level = - (int64_t)(oxcf->starting_buffer_level * bitrate_alloc); - lc->optimal_buffer_level = - (int64_t)(oxcf->optimal_buffer_level * bitrate_alloc); - lc->maximum_buffer_size = - (int64_t)(oxcf->maximum_buffer_size * bitrate_alloc); - lrc->bits_off_target = MIN(lrc->bits_off_target, lc->maximum_buffer_size); - lrc->buffer_level = MIN(lrc->buffer_level, lc->maximum_buffer_size); - // Update framerate-related quantities. - lc->framerate = oxcf->framerate / oxcf->ts_rate_decimator[temporal_layer]; - lrc->av_per_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate); - lrc->max_frame_bandwidth = rc->max_frame_bandwidth; - // Update qp-related quantities. - lrc->worst_quality = rc->worst_quality; - lrc->best_quality = rc->best_quality; - } -} - -// Prior to encoding the frame, update framerate-related quantities -// for the current layer. -static void update_layer_framerate(VP9_COMP *const cpi) { - int temporal_layer = cpi->svc.temporal_layer_id; - const VP9_CONFIG *const oxcf = &cpi->oxcf; - LAYER_CONTEXT *const lc = &cpi->svc.layer_context[temporal_layer]; - RATE_CONTROL *const lrc = &lc->rc; - lc->framerate = oxcf->framerate / oxcf->ts_rate_decimator[temporal_layer]; - lrc->av_per_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate); - lrc->max_frame_bandwidth = cpi->rc.max_frame_bandwidth; - // Update the average layer frame size (non-cumulative per-frame-bw). - if (temporal_layer == 0) { - lc->avg_frame_size = lrc->av_per_frame_bandwidth; - } else { - double prev_layer_framerate = oxcf->framerate / - oxcf->ts_rate_decimator[temporal_layer - 1]; - int prev_layer_target_bandwidth = - oxcf->ts_target_bitrate[temporal_layer - 1] * 1000; - lc->avg_frame_size = - (int)((lc->target_bandwidth - prev_layer_target_bandwidth) / - (lc->framerate - prev_layer_framerate)); - } -} - -// Prior to encoding the frame, set the layer context, for the current layer -// to be encoded, to the cpi struct. -static void restore_layer_context(VP9_COMP *const cpi) { - int temporal_layer = cpi->svc.temporal_layer_id; - LAYER_CONTEXT *lc = &cpi->svc.layer_context[temporal_layer]; - int frame_since_key = cpi->rc.frames_since_key; - int frame_to_key = cpi->rc.frames_to_key; - cpi->rc = lc->rc; - cpi->oxcf.target_bandwidth = lc->target_bandwidth; - cpi->oxcf.starting_buffer_level = lc->starting_buffer_level; - cpi->oxcf.optimal_buffer_level = lc->optimal_buffer_level; - cpi->oxcf.maximum_buffer_size = lc->maximum_buffer_size; - cpi->output_framerate = lc->framerate; - // Reset the frames_since_key and frames_to_key counters to their values - // before the layer restore. Keep these defined for the stream (not layer). - cpi->rc.frames_since_key = frame_since_key; - cpi->rc.frames_to_key = frame_to_key; -} - -// Save the layer context after encoding the frame. -static void save_layer_context(VP9_COMP *const cpi) { - int temporal_layer = cpi->svc.temporal_layer_id; - LAYER_CONTEXT *lc = &cpi->svc.layer_context[temporal_layer]; - lc->rc = cpi->rc; - lc->target_bandwidth = (int)cpi->oxcf.target_bandwidth; - lc->starting_buffer_level = cpi->oxcf.starting_buffer_level; - lc->optimal_buffer_level = cpi->oxcf.optimal_buffer_level; - lc->maximum_buffer_size = cpi->oxcf.maximum_buffer_size; - lc->framerate = cpi->output_framerate; -} - static void set_tile_limits(VP9_COMP *cpi) { VP9_COMMON *const cm = &cpi->common; @@ -1339,7 +1221,7 @@ static void init_config(struct VP9_COMP *cpi, VP9_CONFIG *oxcf) { if (cpi->svc.number_temporal_layers > 1 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - init_layer_context(cpi); + vp9_init_layer_context(cpi); } // change includes all joint functionality @@ -1468,21 +1350,24 @@ void vp9_change_config(struct VP9_COMP *cpi, VP9_CONFIG *oxcf) { // Convert target bandwidth from Kbit/s to Bit/s cpi->oxcf.target_bandwidth *= 1000; - cpi->oxcf.starting_buffer_level = rescale(cpi->oxcf.starting_buffer_level, - cpi->oxcf.target_bandwidth, 1000); + cpi->oxcf.starting_buffer_level = + vp9_rescale(cpi->oxcf.starting_buffer_level, + cpi->oxcf.target_bandwidth, 1000); // Set or reset optimal and maximum buffer levels. if (cpi->oxcf.optimal_buffer_level == 0) cpi->oxcf.optimal_buffer_level = cpi->oxcf.target_bandwidth / 8; else - cpi->oxcf.optimal_buffer_level = rescale(cpi->oxcf.optimal_buffer_level, - cpi->oxcf.target_bandwidth, 1000); + cpi->oxcf.optimal_buffer_level = + vp9_rescale(cpi->oxcf.optimal_buffer_level, + cpi->oxcf.target_bandwidth, 1000); if (cpi->oxcf.maximum_buffer_size == 0) cpi->oxcf.maximum_buffer_size = cpi->oxcf.target_bandwidth / 8; else - cpi->oxcf.maximum_buffer_size = rescale(cpi->oxcf.maximum_buffer_size, - cpi->oxcf.target_bandwidth, 1000); + cpi->oxcf.maximum_buffer_size = + vp9_rescale(cpi->oxcf.maximum_buffer_size, + cpi->oxcf.target_bandwidth, 1000); // Under a configuration change, where maximum_buffer_size may change, // keep buffer level clipped to the maximum allowed buffer size. cpi->rc.bits_off_target = MIN(cpi->rc.bits_off_target, @@ -1522,7 +1407,8 @@ void vp9_change_config(struct VP9_COMP *cpi, VP9_CONFIG *oxcf) { if (cpi->svc.number_temporal_layers > 1 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - update_layer_context_change_config(cpi, (int)cpi->oxcf.target_bandwidth); + vp9_update_layer_context_change_config(cpi, + (int)cpi->oxcf.target_bandwidth); } cpi->speed = abs(cpi->oxcf.cpu_used); @@ -3671,8 +3557,8 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, if (cpi->svc.number_temporal_layers > 1 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - update_layer_framerate(cpi); - restore_layer_context(cpi); + vp9_update_layer_framerate(cpi); + vp9_restore_layer_context(cpi); } // start with a 0 size frame @@ -3754,7 +3640,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, // Save layer specific state. if (cpi->svc.number_temporal_layers > 1 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - save_layer_context(cpi); + vp9_save_layer_context(cpi); } vpx_usec_timer_mark(&cmptimer); diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index 0d41f6c9b613369563ba9cc202e2eac81d9f6f56..87c0086deaa1864374fecdb72c03803b08ca4f19 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -30,6 +30,7 @@ #include "vp9/encoder/vp9_mcomp.h" #include "vp9/encoder/vp9_quantize.h" #include "vp9/encoder/vp9_ratectrl.h" +#include "vp9/encoder/vp9_svc_layercontext.h" #include "vp9/encoder/vp9_tokenize.h" #include "vp9/encoder/vp9_variance.h" @@ -432,16 +433,6 @@ typedef struct { BLOCK_SIZE max_intra_bsize; } SPEED_FEATURES; -typedef struct { - RATE_CONTROL rc; - int target_bandwidth; - int64_t starting_buffer_level; - int64_t optimal_buffer_level; - int64_t maximum_buffer_size; - double framerate; - int avg_frame_size; -} LAYER_CONTEXT; - typedef enum { NORMAL = 0, FOURFIVE = 1, @@ -822,15 +813,7 @@ typedef struct VP9_COMP { int use_svc; - struct svc { - int spatial_layer_id; - int temporal_layer_id; - int number_spatial_layers; - int number_temporal_layers; - // Layer context used for rate control in CBR mode, only defined for - // temporal layers for now. - LAYER_CONTEXT layer_context[VPX_TS_MAX_LAYERS]; - } svc; + SVC svc; #if CONFIG_MULTIPLE_ARF // ARF tracking variables. @@ -943,6 +926,10 @@ static int get_token_alloc(int mb_rows, int mb_cols) { return mb_rows * mb_cols * (48 * 16 + 4); } +extern const int q_trans[]; + +int64_t vp9_rescale(int64_t val, int64_t num, int denom); + static void set_ref_ptrs(VP9_COMMON *cm, MACROBLOCKD *xd, MV_REFERENCE_FRAME ref0, MV_REFERENCE_FRAME ref1) { xd->block_refs[0] = &cm->frame_refs[ref0 >= LAST_FRAME ? ref0 - LAST_FRAME diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h index a6f2c31c08b0cd7320ccfac44bda0d277da03469..ed6266fe281c1debaffa81c27f346cf97f515ef2 100644 --- a/vp9/encoder/vp9_ratectrl.h +++ b/vp9/encoder/vp9_ratectrl.h @@ -12,6 +12,10 @@ #ifndef VP9_ENCODER_VP9_RATECTRL_H_ #define VP9_ENCODER_VP9_RATECTRL_H_ +#include "vpx/vpx_integer.h" + +#include "vp9/common/vp9_blockd.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c new file mode 100644 index 0000000000000000000000000000000000000000..eba7bc68237f10a47e8c8cf26cec81963ea40474 --- /dev/null +++ b/vp9/encoder/vp9_svc_layercontext.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2014 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <math.h> + +#include "vp9/encoder/vp9_onyx_int.h" +#include "vp9/encoder/vp9_svc_layercontext.h" + +void vp9_init_layer_context(VP9_COMP *const cpi) { + const VP9_CONFIG *const oxcf = &cpi->oxcf; + int temporal_layer = 0; + cpi->svc.spatial_layer_id = 0; + cpi->svc.temporal_layer_id = 0; + for (temporal_layer = 0; temporal_layer < cpi->svc.number_temporal_layers; + ++temporal_layer) { + LAYER_CONTEXT *const lc = &cpi->svc.layer_context[temporal_layer]; + RATE_CONTROL *const lrc = &lc->rc; + lrc->avg_frame_qindex[INTER_FRAME] = q_trans[oxcf->worst_allowed_q]; + lrc->last_q[INTER_FRAME] = q_trans[oxcf->worst_allowed_q]; + lrc->ni_av_qi = q_trans[oxcf->worst_allowed_q]; + lrc->total_actual_bits = 0; + lrc->total_target_vs_actual = 0; + lrc->ni_tot_qi = 0; + lrc->tot_q = 0.0; + lrc->avg_q = 0.0; + lrc->ni_frames = 0; + lrc->decimation_count = 0; + lrc->decimation_factor = 0; + lrc->rate_correction_factor = 1.0; + lrc->key_frame_rate_correction_factor = 1.0; + lc->target_bandwidth = oxcf->ts_target_bitrate[temporal_layer] * + 1000; + lrc->buffer_level = + vp9_rescale((int)(oxcf->starting_buffer_level), + lc->target_bandwidth, 1000); + lrc->bits_off_target = lrc->buffer_level; + } +} + +// Update the layer context from a change_config() call. +void vp9_update_layer_context_change_config(VP9_COMP *const cpi, + const int target_bandwidth) { + const VP9_CONFIG *const oxcf = &cpi->oxcf; + const RATE_CONTROL *const rc = &cpi->rc; + int temporal_layer = 0; + float bitrate_alloc = 1.0; + for (temporal_layer = 0; temporal_layer < cpi->svc.number_temporal_layers; + ++temporal_layer) { + LAYER_CONTEXT *const lc = &cpi->svc.layer_context[temporal_layer]; + RATE_CONTROL *const lrc = &lc->rc; + lc->target_bandwidth = oxcf->ts_target_bitrate[temporal_layer] * 1000; + bitrate_alloc = (float)lc->target_bandwidth / (float)target_bandwidth; + // Update buffer-related quantities. + lc->starting_buffer_level = + (int64_t)(oxcf->starting_buffer_level * bitrate_alloc); + lc->optimal_buffer_level = + (int64_t)(oxcf->optimal_buffer_level * bitrate_alloc); + lc->maximum_buffer_size = + (int64_t)(oxcf->maximum_buffer_size * bitrate_alloc); + lrc->bits_off_target = MIN(lrc->bits_off_target, lc->maximum_buffer_size); + lrc->buffer_level = MIN(lrc->buffer_level, lc->maximum_buffer_size); + // Update framerate-related quantities. + lc->framerate = oxcf->framerate / oxcf->ts_rate_decimator[temporal_layer]; + lrc->av_per_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate); + lrc->max_frame_bandwidth = rc->max_frame_bandwidth; + // Update qp-related quantities. + lrc->worst_quality = rc->worst_quality; + lrc->best_quality = rc->best_quality; + } +} + +void vp9_update_layer_framerate(VP9_COMP *const cpi) { + int temporal_layer = cpi->svc.temporal_layer_id; + const VP9_CONFIG *const oxcf = &cpi->oxcf; + LAYER_CONTEXT *const lc = &cpi->svc.layer_context[temporal_layer]; + RATE_CONTROL *const lrc = &lc->rc; + lc->framerate = oxcf->framerate / oxcf->ts_rate_decimator[temporal_layer]; + lrc->av_per_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate); + lrc->max_frame_bandwidth = cpi->rc.max_frame_bandwidth; + // Update the average layer frame size (non-cumulative per-frame-bw). + if (temporal_layer == 0) { + lc->avg_frame_size = lrc->av_per_frame_bandwidth; + } else { + double prev_layer_framerate = oxcf->framerate / + oxcf->ts_rate_decimator[temporal_layer - 1]; + int prev_layer_target_bandwidth = + oxcf->ts_target_bitrate[temporal_layer - 1] * 1000; + lc->avg_frame_size = + (int)((lc->target_bandwidth - prev_layer_target_bandwidth) / + (lc->framerate - prev_layer_framerate)); + } +} + +void vp9_restore_layer_context(VP9_COMP *const cpi) { + int temporal_layer = cpi->svc.temporal_layer_id; + LAYER_CONTEXT *lc = &cpi->svc.layer_context[temporal_layer]; + int frame_since_key = cpi->rc.frames_since_key; + int frame_to_key = cpi->rc.frames_to_key; + cpi->rc = lc->rc; + cpi->oxcf.target_bandwidth = lc->target_bandwidth; + cpi->oxcf.starting_buffer_level = lc->starting_buffer_level; + cpi->oxcf.optimal_buffer_level = lc->optimal_buffer_level; + cpi->oxcf.maximum_buffer_size = lc->maximum_buffer_size; + cpi->output_framerate = lc->framerate; + // Reset the frames_since_key and frames_to_key counters to their values + // before the layer restore. Keep these defined for the stream (not layer). + cpi->rc.frames_since_key = frame_since_key; + cpi->rc.frames_to_key = frame_to_key; +} + +void vp9_save_layer_context(VP9_COMP *const cpi) { + int temporal_layer = cpi->svc.temporal_layer_id; + LAYER_CONTEXT *lc = &cpi->svc.layer_context[temporal_layer]; + lc->rc = cpi->rc; + lc->target_bandwidth = (int)cpi->oxcf.target_bandwidth; + lc->starting_buffer_level = cpi->oxcf.starting_buffer_level; + lc->optimal_buffer_level = cpi->oxcf.optimal_buffer_level; + lc->maximum_buffer_size = cpi->oxcf.maximum_buffer_size; + lc->framerate = cpi->output_framerate; +} diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h new file mode 100644 index 0000000000000000000000000000000000000000..c7a4c065c2e34afce218484c7acb7479996cfc49 --- /dev/null +++ b/vp9/encoder/vp9_svc_layercontext.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef VP9_ENCODER_VP9_SVC_LAYERCONTEXT_H_ +#define VP9_ENCODER_VP9_SVC_LAYERCONTEXT_H_ + +#include "vpx/vpx_encoder.h" + +#include "vp9/encoder/vp9_ratectrl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + RATE_CONTROL rc; + int target_bandwidth; + int64_t starting_buffer_level; + int64_t optimal_buffer_level; + int64_t maximum_buffer_size; + double framerate; + int avg_frame_size; +} LAYER_CONTEXT; + +typedef struct { + int spatial_layer_id; + int temporal_layer_id; + int number_spatial_layers; + int number_temporal_layers; + // Layer context used for rate control in CBR mode, only defined for + // temporal layers for now. + LAYER_CONTEXT layer_context[VPX_TS_MAX_LAYERS]; +} SVC; + +struct VP9_COMP; + +// Initialize layer context data from init_config(). +void vp9_init_layer_context(struct VP9_COMP *const cpi); + +// Update the layer context from a change_config() call. +void vp9_update_layer_context_change_config(struct VP9_COMP *const cpi, + const int target_bandwidth); + +// Prior to encoding the frame, update framerate-related quantities +// for the current layer. +void vp9_update_layer_framerate(struct VP9_COMP *const cpi); + +// Prior to encoding the frame, set the layer context, for the current layer +// to be encoded, to the cpi struct. +void vp9_restore_layer_context(struct VP9_COMP *const cpi); + +// Save the layer context after encoding the frame. +void vp9_save_layer_context(struct VP9_COMP *const cpi); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // VP9_ENCODER_VP9_SVC_LAYERCONTEXT_ diff --git a/vp9/vp9cx.mk b/vp9/vp9cx.mk index ff20f050d369902de01dbe223b1fb524233a3e90..ff29d885b56a8bd5fddf2273994dbdaa901cfbc2 100644 --- a/vp9/vp9cx.mk +++ b/vp9/vp9cx.mk @@ -44,6 +44,7 @@ VP9_CX_SRCS-yes += encoder/vp9_quantize.h VP9_CX_SRCS-yes += encoder/vp9_ratectrl.h VP9_CX_SRCS-yes += encoder/vp9_rdopt.h VP9_CX_SRCS-yes += encoder/vp9_pickmode.h +VP9_CX_SRCS-yes += encoder/vp9_svc_layercontext.h VP9_CX_SRCS-yes += encoder/vp9_tokenize.h VP9_CX_SRCS-yes += encoder/vp9_treewriter.h VP9_CX_SRCS-yes += encoder/vp9_variance.h @@ -60,6 +61,7 @@ VP9_CX_SRCS-yes += encoder/vp9_segmentation.c VP9_CX_SRCS-yes += encoder/vp9_segmentation.h VP9_CX_SRCS-yes += encoder/vp9_subexp.c VP9_CX_SRCS-yes += encoder/vp9_subexp.h +VP9_CX_SRCS-yes += encoder/vp9_svc_layercontext.c VP9_CX_SRCS-yes += encoder/vp9_resize.c VP9_CX_SRCS-yes += encoder/vp9_resize.h VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS) += encoder/vp9_ssim.c