<< " The datarate for the file is greater than target by too much, "
"for layer: " << j;
// Expect some frame drops in this test: for this 200 frames test,
- // expect at least 10% and not more than 50% drops.
+ // expect at least 10% and not more than 60% drops.
ASSERT_GE(num_drops_, 20);
- ASSERT_LE(num_drops_, 100);
+ ASSERT_LE(num_drops_, 120);
}
}
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large,
::testing::Values(::libvpx_test::kOnePassGood,
::libvpx_test::kRealTime),
- ::testing::Range(2, 5));
-// TODO(marpan): Speed 5 to 7 fails on one of these tests, for
-// real-time mode. So for now test up to speed 4, and start at 2
-// (since speed 0 and 1 are slow). Enable more speeds when issue is fixed.
+ ::testing::Range(2, 7));
} // namespace
int post_proc_flag;
int deblocking_level;
int noise_level;
+#if CONFIG_POSTPROC_VISUALIZER
int display_ref_frame_flag;
int display_mb_modes_flag;
int display_b_modes_flag;
int display_mv_flag;
+#endif // CONFIG_POSTPROC_VISUALIZER
} vp9_ppflags_t;
#ifdef __cplusplus
}
}
-VP9D_COMP *vp9_create_decompressor(const VP9D_CONFIG *oxcf) {
- VP9D_COMP *const pbi = vpx_memalign(32, sizeof(VP9D_COMP));
+VP9D_COMP *vp9_decoder_create(const VP9D_CONFIG *oxcf) {
+ VP9D_COMP *const pbi = vpx_memalign(32, sizeof(*pbi));
VP9_COMMON *const cm = pbi ? &pbi->common : NULL;
if (!cm)
vp9_zero(*pbi);
- // Initialize the references to not point to any frame buffers.
- memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map));
-
if (setjmp(cm->error.jmp)) {
cm->error.setjmp = 0;
- vp9_remove_decompressor(pbi);
+ vp9_decoder_remove(pbi);
return NULL;
}
vp9_rtcd();
+ // Initialize the references to not point to any frame buffers.
+ vpx_memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map));
+
+ cm->current_video_frame = 0;
pbi->oxcf = *oxcf;
pbi->ready_for_new_data = 1;
- cm->current_video_frame = 0;
+ pbi->decoded_key_frame = 0;
// vp9_init_dequantizer() is first called here. Add check in
// frame_init_dequantizer() to avoid unnecessary calling of
vp9_loop_filter_init(cm);
cm->error.setjmp = 0;
- pbi->decoded_key_frame = 0;
vp9_worker_init(&pbi->lf_worker);
return pbi;
}
-void vp9_remove_decompressor(VP9D_COMP *pbi) {
+void vp9_decoder_remove(VP9D_COMP *pbi) {
VP9_COMMON *const cm = &pbi->common;
int i;
#if CONFIG_VP9_POSTPROC
ret = vp9_post_proc_frame(&pbi->common, sd, flags);
#else
-
- if (pbi->common.frame_to_show) {
*sd = *pbi->common.frame_to_show;
sd->y_width = pbi->common.width;
sd->y_height = pbi->common.height;
sd->uv_width = sd->y_width >> pbi->common.subsampling_x;
sd->uv_height = sd->y_height >> pbi->common.subsampling_y;
-
ret = 0;
- } else {
- ret = -1;
- }
-
#endif /*!CONFIG_POSTPROC*/
vp9_clear_system_state();
return ret;
int index, YV12_BUFFER_CONFIG **fb);
-struct VP9Decompressor *vp9_create_decompressor(const VP9D_CONFIG *oxcf);
+struct VP9Decompressor *vp9_decoder_create(const VP9D_CONFIG *oxcf);
-void vp9_remove_decompressor(struct VP9Decompressor *pbi);
+void vp9_decoder_remove(struct VP9Decompressor *pbi);
#ifdef __cplusplus
} // extern "C"
const int entropy_nodes_update = UNCONSTRAINED_NODES;
int i, j, k, l, t;
switch (cpi->sf.use_fast_coef_updates) {
- case 0: {
+ case TWO_LOOP: {
/* dry run to see if there is any udpate at all needed */
int savings = 0;
int update[2] = {0, 0};
return;
}
- case 1:
- case 2: {
+ case ONE_LOOP:
+ case ONE_LOOP_REDUCED: {
const int prev_coef_contexts_to_update =
- cpi->sf.use_fast_coef_updates == 2 ? COEFF_CONTEXTS >> 1
- : COEFF_CONTEXTS;
+ cpi->sf.use_fast_coef_updates == ONE_LOOP_REDUCED ?
+ COEFF_CONTEXTS >> 1 : COEFF_CONTEXTS;
const int coef_band_to_update =
- cpi->sf.use_fast_coef_updates == 2 ? COEF_BANDS >> 1
- : COEF_BANDS;
+ cpi->sf.use_fast_coef_updates == ONE_LOOP_REDUCED ?
+ COEF_BANDS >> 1 : COEF_BANDS;
int updates = 0;
int noupdates_before_first = 0;
for (i = 0; i < PLANE_TYPES; ++i) {
}
vp9_init_plane_quantizers(cpi, x);
- if (seg->enabled && cpi->seg0_cnt > 0 &&
- !vp9_segfeature_active(seg, 0, SEG_LVL_REF_FRAME) &&
- vp9_segfeature_active(seg, 1, SEG_LVL_REF_FRAME)) {
- cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt;
- } else {
- const int y = mb_row & ~3;
- const int x = mb_col & ~3;
- const int p16 = ((mb_row & 1) << 1) + (mb_col & 1);
- const int p32 = ((mb_row & 2) << 2) + ((mb_col & 2) << 1);
- const int tile_progress = tile->mi_col_start * cm->mb_rows >> 1;
- const int mb_cols = (tile->mi_col_end - tile->mi_col_start) >> 1;
-
- cpi->seg0_progress = ((y * mb_cols + x * 4 + p32 + p16 + tile_progress)
- << 16) / cm->MBs;
- }
-
x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id];
} else {
mbmi->segment_id = 0;
const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols);
x->act_zbin_adj = 0;
- cpi->seg0_idx = 0;
// Copy data over into macro block data structures.
vp9_setup_src_planes(x, cpi->Source, 0, 0);
extern void vp9_new_framerate(VP9_COMP *cpi, double framerate);
void vp9_init_second_pass(VP9_COMP *cpi) {
+ SVC *const svc = &cpi->svc;
FIRSTPASS_STATS this_frame;
const FIRSTPASS_STATS *start_pos;
struct twopass_rc *twopass = &cpi->twopass;
const VP9_CONFIG *const oxcf = &cpi->oxcf;
- const int is_spatial_svc = (cpi->svc.number_spatial_layers > 1) &&
- (cpi->svc.number_temporal_layers == 1);
+ const int is_spatial_svc = (svc->number_spatial_layers > 1) &&
+ (svc->number_temporal_layers == 1);
double frame_rate;
if (is_spatial_svc) {
- twopass = &cpi->svc.layer_context[cpi->svc.spatial_layer_id].twopass;
+ twopass = &svc->layer_context[svc->spatial_layer_id].twopass;
}
zero_stats(&twopass->total_stats);
vp9_update_spatial_layer_framerate(cpi, frame_rate);
twopass->bits_left =
(int64_t)(twopass->total_stats.duration *
- cpi->svc.layer_context[cpi->svc.spatial_layer_id].target_bandwidth /
+ svc->layer_context[svc->spatial_layer_id].target_bandwidth /
10000000.0);
} else {
vp9_new_framerate(cpi, frame_rate);
else
cpi->static_mb_pct = 0;
- cpi->seg0_cnt = ncnt[0];
vp9_enable_segmentation(&cm->seg);
} else {
cpi->static_mb_pct = 0;
int *mvjcost, int *mvcost[2],
const MV *center_mv) {
const MACROBLOCKD *const xd = &x->e_mbd;
- MV neighbors[4] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}};
- int i, j;
-
- const int what_stride = x->plane[0].src.stride;
- const int in_what_stride = xd->plane[0].pre[0].stride;
- const uint8_t *what = x->plane[0].src.buf;
- const uint8_t *best_address = xd->plane[0].pre[0].buf +
- (ref_mv->row * xd->plane[0].pre[0].stride) +
- ref_mv->col;
-
+ const MV neighbors[4] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}};
+ const struct buf_2d *const what = &x->plane[0].src;
+ const struct buf_2d *const in_what = &xd->plane[0].pre[0];
const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
-
const int *mvjsadcost = x->nmvjointsadcost;
int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]};
-
- unsigned int bestsad = fn_ptr->sdf(what, what_stride, best_address,
- in_what_stride, 0x7fffffff) +
+ const uint8_t *best_address = get_buf_from_mv(in_what, ref_mv);
+ unsigned int best_sad = fn_ptr->sdf(what->buf, what->stride, best_address,
+ in_what->stride, 0x7fffffff) +
mvsad_err_cost(ref_mv, &fcenter_mv, mvjsadcost, mvsadcost, error_per_bit);
+ int i, j;
for (i = 0; i < search_range; i++) {
int best_site = -1;
- int all_in = ((ref_mv->row - 1) > x->mv_row_min) &
- ((ref_mv->row + 1) < x->mv_row_max) &
- ((ref_mv->col - 1) > x->mv_col_min) &
- ((ref_mv->col + 1) < x->mv_col_max);
+ const int all_in = ((ref_mv->row - 1) > x->mv_row_min) &
+ ((ref_mv->row + 1) < x->mv_row_max) &
+ ((ref_mv->col - 1) > x->mv_col_min) &
+ ((ref_mv->col + 1) < x->mv_col_max);
if (all_in) {
- unsigned int sad_array[4];
- uint8_t const *block_offset[4] = {
- best_address - in_what_stride,
+ unsigned int sads[4];
+ const uint8_t *const positions[4] = {
+ best_address - in_what->stride,
best_address - 1,
best_address + 1,
- best_address + in_what_stride
+ best_address + in_what->stride
};
- fn_ptr->sdx4df(what, what_stride, block_offset, in_what_stride,
- sad_array);
+ fn_ptr->sdx4df(what->buf, what->stride, positions, in_what->stride, sads);
- for (j = 0; j < 4; j++) {
- if (sad_array[j] < bestsad) {
- const MV this_mv = {ref_mv->row + neighbors[j].row,
- ref_mv->col + neighbors[j].col};
- sad_array[j] += mvsad_err_cost(&this_mv, &fcenter_mv,
+ for (j = 0; j < 4; ++j) {
+ if (sads[j] < best_sad) {
+ const MV mv = {ref_mv->row + neighbors[j].row,
+ ref_mv->col + neighbors[j].col};
+ sads[j] += mvsad_err_cost(&mv, &fcenter_mv,
mvjsadcost, mvsadcost, error_per_bit);
- if (sad_array[j] < bestsad) {
- bestsad = sad_array[j];
+ if (sads[j] < best_sad) {
+ best_sad = sads[j];
best_site = j;
}
}
}
} else {
- for (j = 0; j < 4; j++) {
- const MV this_mv = {ref_mv->row + neighbors[j].row,
- ref_mv->col + neighbors[j].col};
-
- if (is_mv_in(x, &this_mv)) {
- const uint8_t *check_here = neighbors[j].row * in_what_stride +
- neighbors[j].col + best_address;
- unsigned int thissad = fn_ptr->sdf(what, what_stride,
- check_here, in_what_stride,
- bestsad);
-
- if (thissad < bestsad) {
- thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
- mvjsadcost, mvsadcost, error_per_bit);
+ for (j = 0; j < 4; ++j) {
+ const MV mv = {ref_mv->row + neighbors[j].row,
+ ref_mv->col + neighbors[j].col};
+
+ if (is_mv_in(x, &mv)) {
+ unsigned int sad = fn_ptr->sdf(what->buf, what->stride,
+ get_buf_from_mv(in_what, &mv),
+ in_what->stride, best_sad);
+ if (sad < best_sad) {
+ sad += mvsad_err_cost(&mv, &fcenter_mv,
+ mvjsadcost, mvsadcost, error_per_bit);
- if (thissad < bestsad) {
- bestsad = thissad;
+ if (sad < best_sad) {
+ best_sad = sad;
best_site = j;
}
}
} else {
ref_mv->row += neighbors[best_site].row;
ref_mv->col += neighbors[best_site].col;
- best_address += (neighbors[best_site].row) * in_what_stride +
- neighbors[best_site].col;
+ best_address = get_buf_from_mv(in_what, ref_mv);
}
}
- return bestsad;
+ return best_sad;
}
// This function is called when we do joint motion search in comp_inter_inter
}
}
+static void save_coding_context(VP9_COMP *cpi) {
+ CODING_CONTEXT *const cc = &cpi->coding_context;
+ VP9_COMMON *cm = &cpi->common;
+
+ // Stores a snapshot of key state variables which can subsequently be
+ // restored with a call to vp9_restore_coding_context. These functions are
+ // intended for use in a re-code loop in vp9_compress_frame where the
+ // quantizer value is adjusted between loop iterations.
+ vp9_copy(cc->nmvjointcost, cpi->mb.nmvjointcost);
+ vp9_copy(cc->nmvcosts, cpi->mb.nmvcosts);
+ vp9_copy(cc->nmvcosts_hp, cpi->mb.nmvcosts_hp);
+
+ vp9_copy(cc->segment_pred_probs, cm->seg.pred_probs);
+
+ vpx_memcpy(cpi->coding_context.last_frame_seg_map_copy,
+ cm->last_frame_seg_map, (cm->mi_rows * cm->mi_cols));
+
+ vp9_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas);
+ vp9_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas);
+
+ cc->fc = cm->fc;
+}
+
+static void restore_coding_context(VP9_COMP *cpi) {
+ CODING_CONTEXT *const cc = &cpi->coding_context;
+ VP9_COMMON *cm = &cpi->common;
+
+ // Restore key state variables to the snapshot state stored in the
+ // previous call to vp9_save_coding_context.
+ vp9_copy(cpi->mb.nmvjointcost, cc->nmvjointcost);
+ vp9_copy(cpi->mb.nmvcosts, cc->nmvcosts);
+ vp9_copy(cpi->mb.nmvcosts_hp, cc->nmvcosts_hp);
+
+ vp9_copy(cm->seg.pred_probs, cc->segment_pred_probs);
+
+ vpx_memcpy(cm->last_frame_seg_map,
+ cpi->coding_context.last_frame_seg_map_copy,
+ (cm->mi_rows * cm->mi_cols));
+
+ vp9_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas);
+ vp9_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas);
+
+ cm->fc = cc->fc;
+}
+
// Computes a q delta (in "q index" terms) to get from a starting q value
// to a target q value
int vp9_compute_qdelta(const VP9_COMP *cpi, double qstart, double qtarget) {
rc->total_actual_bits = 0;
rc->total_target_vs_actual = 0;
+
+ rc->baseline_gf_interval = DEFAULT_GF_INTERVAL;
+ rc->frames_since_key = 8; // Sensible default for first frame.
+ rc->this_key_frame_forced = 0;
+ rc->next_key_frame_forced = 0;
+ rc->source_alt_ref_pending = 0;
+ rc->source_alt_ref_active = 0;
+
+ rc->frames_till_gf_update_due = 0;
+
+ rc->ni_av_qi = oxcf->worst_allowed_q;
+ rc->ni_tot_qi = 0;
+ rc->ni_frames = 0;
+
+ rc->tot_q = 0.0;
+ rc->avg_q = vp9_convert_qindex_to_q(oxcf->worst_allowed_q);
+
+ rc->rate_correction_factor = 1.0;
+ rc->key_frame_rate_correction_factor = 1.0;
+ rc->gf_rate_correction_factor = 1.0;
}
static void init_config(struct VP9_COMP *cpi, VP9_CONFIG *oxcf) {
int i, j;
VP9_COMP *const cpi = vpx_memalign(32, sizeof(VP9_COMP));
VP9_COMMON *const cm = cpi != NULL ? &cpi->common : NULL;
- RATE_CONTROL *const rc = cpi != NULL ? &cpi->rc : NULL;
if (!cm)
return NULL;
// Set reference frame sign bias for ALTREF frame to 1 (for now)
cm->ref_frame_sign_bias[ALTREF_FRAME] = 1;
- rc->baseline_gf_interval = DEFAULT_GF_INTERVAL;
-
cpi->gold_is_last = 0;
cpi->alt_is_last = 0;
cpi->gold_is_alt = 0;
/*Initialize the feed-forward activity masking.*/
cpi->activity_avg = 90 << 12;
cpi->key_frame_frequency = cpi->oxcf.key_freq;
-
- rc->frames_since_key = 8; // Sensible default for first frame.
- rc->this_key_frame_forced = 0;
- rc->next_key_frame_forced = 0;
-
- rc->source_alt_ref_pending = 0;
- rc->source_alt_ref_active = 0;
cpi->refresh_alt_ref_frame = 0;
#if CONFIG_MULTIPLE_ARF
cpi->first_time_stamp_ever = INT64_MAX;
- rc->frames_till_gf_update_due = 0;
-
- rc->ni_av_qi = cpi->oxcf.worst_allowed_q;
- rc->ni_tot_qi = 0;
- rc->ni_frames = 0;
- rc->tot_q = 0.0;
- rc->avg_q = vp9_convert_qindex_to_q(cpi->oxcf.worst_allowed_q);
-
- rc->rate_correction_factor = 1.0;
- rc->key_frame_rate_correction_factor = 1.0;
- rc->gf_rate_correction_factor = 1.0;
-
cal_nmvjointsadcost(cpi->mb.nmvjointsadcost);
cpi->mb.nmvcost[0] = &cpi->mb.nmvcosts[0][MV_MAX];
cpi->mb.nmvcost[1] = &cpi->mb.nmvcosts[1][MV_MAX];
// accurate estimate of output frame size to determine if we need
// to recode.
if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF) {
- vp9_save_coding_context(cpi);
+ save_coding_context(cpi);
cpi->dummy_packing = 1;
if (!cpi->sf.use_nonrd_pick_mode)
vp9_pack_bitstream(cpi, dest, size);
rc->projected_frame_size = (int)(*size) << 3;
- vp9_restore_coding_context(cpi);
+ restore_coding_context(cpi);
if (frame_over_shoot_limit == 0)
frame_over_shoot_limit = 1;
MBGRAPH_FRAME_STATS mbgraph_stats[MAX_LAG_BUFFERS];
int mbgraph_n_frames; // number of frames filled in the above
int static_mb_pct; // % forced skip mbs by segmentation
- int seg0_progress, seg0_idx, seg0_cnt;
// for real time encoding
int speed;
static void full_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
const TileInfo *const tile,
BLOCK_SIZE bsize, int mi_row, int mi_col,
- int_mv *tmp_mv) {
+ int_mv *tmp_mv, int *rate_mv) {
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
for (i = 0; i < MAX_MB_PLANE; i++)
xd->plane[i].pre[0] = backup_yv12[i];
}
+
+ // calculate the bit cost on motion vector
+ mvp_full.row = tmp_mv->as_mv.row * 8;
+ mvp_full.col = tmp_mv->as_mv.col * 8;
+ *rate_mv = vp9_mv_bit_cost(&mvp_full, &ref_mv,
+ x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
}
static void sub_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
const TileInfo *const tile,
BLOCK_SIZE bsize, int mi_row, int mi_col,
- MV *tmp_mv, int *rate_mv) {
+ MV *tmp_mv) {
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
x->nmvjointcost, x->mvcost,
&dis, &x->pred_sse[ref]);
- // calculate the bit cost on motion vector
- *rate_mv = vp9_mv_bit_cost(tmp_mv, &ref_mv,
- x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
-
if (scaled_ref_frame) {
int i;
for (i = 0; i < MAX_MB_PLANE; i++)
continue;
if (this_mode == NEWMV) {
+ int rate_mode = 0;
if (this_rd < (int64_t)(1 << num_pels_log2_lookup[bsize]))
continue;
full_pixel_motion_search(cpi, x, tile, bsize, mi_row, mi_col,
- &frame_mv[NEWMV][ref_frame]);
+ &frame_mv[NEWMV][ref_frame], &rate_mv);
if (frame_mv[NEWMV][ref_frame].as_int == INVALID_MV)
continue;
+ rate_mode = x->inter_mode_cost[mbmi->mode_context[ref_frame]]
+ [INTER_OFFSET(this_mode)];
+ if (RDCOST(x->rdmult, x->rddiv, rate_mv + rate_mode, 0) > best_rd)
+ continue;
+
sub_pixel_motion_search(cpi, x, tile, bsize, mi_row, mi_col,
- &frame_mv[NEWMV][ref_frame].as_mv, &rate_mv);
+ &frame_mv[NEWMV][ref_frame].as_mv);
}
if (this_mode != NEARESTMV)
return (int)(0.5 + (enumerator * correction_factor / q));
}
-void vp9_save_coding_context(VP9_COMP *cpi) {
- CODING_CONTEXT *const cc = &cpi->coding_context;
- VP9_COMMON *cm = &cpi->common;
-
- // Stores a snapshot of key state variables which can subsequently be
- // restored with a call to vp9_restore_coding_context. These functions are
- // intended for use in a re-code loop in vp9_compress_frame where the
- // quantizer value is adjusted between loop iterations.
- vp9_copy(cc->nmvjointcost, cpi->mb.nmvjointcost);
- vp9_copy(cc->nmvcosts, cpi->mb.nmvcosts);
- vp9_copy(cc->nmvcosts_hp, cpi->mb.nmvcosts_hp);
-
- vp9_copy(cc->segment_pred_probs, cm->seg.pred_probs);
-
- vpx_memcpy(cpi->coding_context.last_frame_seg_map_copy,
- cm->last_frame_seg_map, (cm->mi_rows * cm->mi_cols));
-
- vp9_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas);
- vp9_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas);
-
- cc->fc = cm->fc;
-}
-
-void vp9_restore_coding_context(VP9_COMP *cpi) {
- CODING_CONTEXT *const cc = &cpi->coding_context;
- VP9_COMMON *cm = &cpi->common;
-
- // Restore key state variables to the snapshot state stored in the
- // previous call to vp9_save_coding_context.
- vp9_copy(cpi->mb.nmvjointcost, cc->nmvjointcost);
- vp9_copy(cpi->mb.nmvcosts, cc->nmvcosts);
- vp9_copy(cpi->mb.nmvcosts_hp, cc->nmvcosts_hp);
-
- vp9_copy(cm->seg.pred_probs, cc->segment_pred_probs);
-
- vpx_memcpy(cm->last_frame_seg_map,
- cpi->coding_context.last_frame_seg_map_copy,
- (cm->mi_rows * cm->mi_cols));
-
- vp9_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas);
- vp9_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas);
-
- cm->fc = cc->fc;
-}
-
static int estimate_bits_at_q(int frame_kind, int q, int mbs,
double correction_factor) {
const int bpm = (int)(vp9_rc_bits_per_mb(frame_kind, q, correction_factor));
struct VP9_COMP;
-void vp9_save_coding_context(struct VP9_COMP *cpi);
-void vp9_restore_coding_context(struct VP9_COMP *cpi);
-
double vp9_convert_qindex_to_q(int qindex);
void vp9_rc_init_minq_luts();
(1 << THR_ALTR) | \
(1 << THR_GOLD))
-static void set_good_speed_feature(VP9_COMP *cpi,
- VP9_COMMON *cm,
- SPEED_FEATURES *sf,
- int speed) {
- int i;
+static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm,
+ SPEED_FEATURES *sf, int speed) {
sf->adaptive_rd_thresh = 1;
- sf->recode_loop = ((speed < 1) ? ALLOW_RECODE : ALLOW_RECODE_KFMAXBW);
+ sf->recode_loop = (speed < 1) ? ALLOW_RECODE : ALLOW_RECODE_KFMAXBW;
sf->allow_skip_recode = 1;
if (speed >= 1) {
sf->use_square_partition_only = !frame_is_intra_only(cm);
sf->less_rectangular_check = 1;
- sf->tx_size_search_method = vp9_frame_is_boosted(cpi)
- ? USE_FULL_RD : USE_LARGESTALL;
+ sf->tx_size_search_method = vp9_frame_is_boosted(cpi) ? USE_FULL_RD
+ : USE_LARGESTALL;
if (MIN(cm->width, cm->height) >= 720)
- sf->disable_split_mask = cm->show_frame ?
- DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
+ sf->disable_split_mask = cm->show_frame ? DISABLE_ALL_SPLIT
+ : DISABLE_ALL_INTER_SPLIT;
else
sf->disable_split_mask = DISABLE_COMPOUND_SPLIT;
sf->use_rd_breakout = 1;
sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
}
- // Additions or changes from speed 1 for speed >= 2.
+
if (speed >= 2) {
- sf->tx_size_search_method = vp9_frame_is_boosted(cpi)
- ? USE_FULL_RD : USE_LARGESTALL;
+ sf->tx_size_search_method = vp9_frame_is_boosted(cpi) ? USE_FULL_RD
+ : USE_LARGESTALL;
if (MIN(cm->width, cm->height) >= 720)
- sf->disable_split_mask = cm->show_frame ?
- DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
+ sf->disable_split_mask = cm->show_frame ? DISABLE_ALL_SPLIT
+ : DISABLE_ALL_INTER_SPLIT;
else
sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY;
sf->adaptive_pred_interp_filter = 2;
-
sf->reference_masking = 1;
sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
FLAG_SKIP_INTRA_BESTINTER |
FLAG_SKIP_INTRA_LOWVAR;
sf->disable_filter_search_var_thresh = 100;
sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
-
sf->auto_min_max_partition_size = RELAXED_NEIGHBORING_MIN_MAX;
sf->use_lastframe_partitioning = LAST_FRAME_PARTITION_LOW_MOTION;
sf->adjust_partitioning_from_last_frame = 1;
sf->last_partitioning_redo_frequency = 3;
}
- // Additions or changes for speed 3 and above
+
if (speed >= 3) {
if (MIN(cm->width, cm->height) >= 720)
sf->disable_split_mask = DISABLE_ALL_SPLIT;
sf->disable_split_mask = DISABLE_ALL_INTER_SPLIT;
sf->recode_loop = ALLOW_RECODE_KFMAXBW;
-
sf->adaptive_rd_thresh = 3;
sf->mode_skip_start = 6;
- sf->use_fast_coef_updates = 2;
+ sf->use_fast_coef_updates = ONE_LOOP_REDUCED;
sf->use_fast_coef_costing = 1;
}
- // Additions or changes for speed 3 and above
+
if (speed >= 4) {
sf->use_square_partition_only = 1;
sf->tx_size_search_method = USE_LARGESTALL;
sf->disable_split_mask = DISABLE_ALL_SPLIT;
-
sf->adaptive_rd_thresh = 4;
-
- // Add a couple more skip flags
sf->mode_search_skip_flags |= FLAG_SKIP_COMP_REFMISMATCH |
FLAG_EARLY_TERMINATE;
-
sf->disable_filter_search_var_thresh = 200;
-
sf->use_lastframe_partitioning = LAST_FRAME_PARTITION_ALL;
sf->use_lp32x32fdct = 1;
}
+
if (speed >= 5) {
+ int i;
+
sf->partition_search_type = FIXED_PARTITION;
sf->optimize_coefficients = 0;
sf->search_method = HEX;
sf->disable_filter_search_var_thresh = 500;
- for (i = 0; i < TX_SIZES; i++) {
+ for (i = 0; i < TX_SIZES; ++i) {
sf->intra_y_mode_mask[i] = INTRA_DC_ONLY;
sf->intra_uv_mode_mask[i] = INTRA_DC_ONLY;
}
}
}
-static void set_rt_speed_feature(VP9_COMMON *cm,
- SPEED_FEATURES *sf,
+static void set_rt_speed_feature(VP9_COMMON *cm, SPEED_FEATURES *sf,
int speed) {
sf->static_segmentation = 0;
sf->adaptive_rd_thresh = 1;
if (speed == 1) {
sf->use_square_partition_only = !frame_is_intra_only(cm);
sf->less_rectangular_check = 1;
- sf->tx_size_search_method =
- frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL;
+ sf->tx_size_search_method = frame_is_intra_only(cm) ? USE_FULL_RD
+ : USE_LARGESTALL;
if (MIN(cm->width, cm->height) >= 720)
- sf->disable_split_mask = cm->show_frame ?
- DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
+ sf->disable_split_mask = cm->show_frame ? DISABLE_ALL_SPLIT
+ : DISABLE_ALL_INTER_SPLIT;
else
sf->disable_split_mask = DISABLE_COMPOUND_SPLIT;
sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
sf->encode_breakout_thresh = 8;
}
+
if (speed >= 2) {
sf->use_square_partition_only = !frame_is_intra_only(cm);
sf->less_rectangular_check = 1;
- sf->tx_size_search_method =
- frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL;
-
+ sf->tx_size_search_method = frame_is_intra_only(cm) ? USE_FULL_RD
+ : USE_LARGESTALL;
if (MIN(cm->width, cm->height) >= 720)
sf->disable_split_mask = cm->show_frame ?
DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
else
sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY;
- sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH
- | FLAG_SKIP_INTRA_BESTINTER | FLAG_SKIP_COMP_BESTINTRA
- | FLAG_SKIP_INTRA_LOWVAR;
-
+ sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
+ FLAG_SKIP_INTRA_BESTINTER |
+ FLAG_SKIP_COMP_BESTINTRA |
+ FLAG_SKIP_INTRA_LOWVAR;
sf->use_rd_breakout = 1;
sf->adaptive_motion_search = 1;
sf->adaptive_pred_interp_filter = 2;
sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
sf->encode_breakout_thresh = 200;
}
+
if (speed >= 3) {
sf->use_square_partition_only = 1;
sf->disable_filter_search_var_thresh = 100;
sf->use_uv_intra_rd_estimate = 1;
sf->skip_encode_sb = 1;
sf->subpel_iters_per_step = 1;
- sf->use_fast_coef_updates = 2;
+ sf->use_fast_coef_updates = ONE_LOOP_REDUCED;
sf->adaptive_rd_thresh = 4;
sf->mode_skip_start = 6;
sf->allow_skip_recode = 0;
sf->lpf_pick = LPF_PICK_FROM_Q;
sf->encode_breakout_thresh = 700;
}
+
if (speed >= 4) {
int i;
sf->last_partitioning_redo_frequency = 4;
sf->max_intra_bsize = BLOCK_32X32;
sf->allow_skip_recode = 1;
}
+
if (speed >= 5) {
sf->max_partition_size = BLOCK_32X32;
sf->min_partition_size = BLOCK_8X8;
sf->search_method = FAST_DIAMOND;
sf->allow_skip_recode = 0;
}
+
if (speed >= 6) {
sf->partition_search_type = VAR_BASED_FIXED_PARTITION;
sf->use_nonrd_pick_mode = 1;
sf->search_method = FAST_DIAMOND;
}
+
if (speed >= 7) {
int i;
for (i = 0; i < BLOCK_SIZES; ++i)
- sf->disable_inter_mode_mask[i] = 14; // only search NEARESTMV (0)
+ sf->disable_inter_mode_mask[i] = ~(1 << INTER_OFFSET(NEARESTMV));
}
}
void vp9_set_speed_features(VP9_COMP *cpi) {
SPEED_FEATURES *const sf = &cpi->sf;
VP9_COMMON *const cm = &cpi->common;
+ const VP9_CONFIG *const oxcf = &cpi->oxcf;
const int speed = cpi->speed < 0 ? -cpi->speed : cpi->speed;
int i;
sf->subpel_search_method = SUBPEL_TREE;
sf->subpel_iters_per_step = 2;
sf->subpel_force_stop = 0;
- sf->optimize_coefficients = !cpi->oxcf.lossless;
+ sf->optimize_coefficients = !oxcf->lossless;
sf->reduce_first_step_size = 0;
sf->auto_mv_step_size = 0;
sf->max_step_search_steps = MAX_MVSEARCH_STEPS;
sf->use_uv_intra_rd_estimate = 0;
sf->allow_skip_recode = 0;
sf->lpf_pick = LPF_PICK_FROM_FULL_IMAGE;
- sf->use_fast_coef_updates = 0;
+ sf->use_fast_coef_updates = TWO_LOOP;
sf->use_fast_coef_costing = 0;
sf->mode_skip_start = MAX_MODES; // Mode index at which mode skip mask set
sf->use_nonrd_pick_mode = 0;
// Recode loop tolerence %.
sf->recode_tolerance = 25;
- switch (cpi->oxcf.mode) {
+ switch (oxcf->mode) {
case MODE_BESTQUALITY:
case MODE_SECONDPASS_BEST: // This is the best quality mode.
cpi->diamond_search_sad = vp9_full_range_search;
// Slow quant, dct and trellis not worthwhile for first pass
// so make sure they are always turned off.
- if (cpi->pass == 1) {
+ if (cpi->pass == 1)
sf->optimize_coefficients = 0;
- }
// No recode for 1 pass.
if (cpi->pass == 0) {
sf->optimize_coefficients = 0;
}
- if (cpi->sf.subpel_search_method == SUBPEL_TREE) {
+ if (sf->subpel_search_method == SUBPEL_TREE) {
cpi->find_fractional_mv_step = vp9_find_best_sub_pixel_tree;
cpi->find_fractional_mv_step_comp = vp9_find_best_sub_pixel_comp_tree;
}
- cpi->mb.optimize = cpi->sf.optimize_coefficients == 1 && cpi->pass != 1;
+ cpi->mb.optimize = sf->optimize_coefficients == 1 && cpi->pass != 1;
- if (cpi->encode_breakout && cpi->oxcf.mode == MODE_REALTIME &&
+ if (cpi->encode_breakout && oxcf->mode == MODE_REALTIME &&
sf->encode_breakout_thresh > cpi->encode_breakout)
cpi->encode_breakout = sf->encode_breakout_thresh;
VAR_BASED_PARTITION
} PARTITION_SEARCH_TYPE;
+typedef enum {
+ // Does a dry run to see if any of the contexts need to be updated or not,
+ // before the final run.
+ TWO_LOOP = 0,
+
+ // No dry run conducted.
+ ONE_LOOP = 1,
+
+ // No dry run, also only half the coef contexts and bands are updated.
+ // The rest are not updated at all.
+ ONE_LOOP_REDUCED = 2
+} FAST_COEFF_UPDATE;
+
typedef struct {
// Frame level coding parameter update
int frame_parameter_update;
// This feature limits the number of coefficients updates we actually do
// by only looking at counts from 1/2 the bands.
- int use_fast_coef_updates; // 0: 2-loop, 1: 1-loop, 2: 1-loop reduced
+ FAST_COEFF_UPDATE use_fast_coef_updates;
// This flag controls the use of non-RD mode decision.
int use_nonrd_pick_mode;
#include "vp9/encoder/vp9_svc_layercontext.h"
void vp9_init_layer_context(VP9_COMP *const cpi) {
+ SVC *const svc = &cpi->svc;
const VP9_CONFIG *const oxcf = &cpi->oxcf;
int layer;
int layer_end;
- cpi->svc.spatial_layer_id = 0;
- cpi->svc.temporal_layer_id = 0;
+ svc->spatial_layer_id = 0;
+ svc->temporal_layer_id = 0;
- if (cpi->svc.number_temporal_layers > 1) {
- layer_end = cpi->svc.number_temporal_layers;
+ if (svc->number_temporal_layers > 1) {
+ layer_end = svc->number_temporal_layers;
} else {
- layer_end = cpi->svc.number_spatial_layers;
+ layer_end = svc->number_spatial_layers;
}
for (layer = 0; layer < layer_end; ++layer) {
- LAYER_CONTEXT *const lc = &cpi->svc.layer_context[layer];
+ LAYER_CONTEXT *const lc = &svc->layer_context[layer];
RATE_CONTROL *const lrc = &lc->rc;
lc->current_video_frame_in_layer = 0;
lrc->avg_frame_qindex[INTER_FRAME] = q_trans[oxcf->worst_allowed_q];
lrc->rate_correction_factor = 1.0;
lrc->key_frame_rate_correction_factor = 1.0;
- if (cpi->svc.number_temporal_layers > 1) {
+ if (svc->number_temporal_layers > 1) {
lc->target_bandwidth = oxcf->ts_target_bitrate[layer] * 1000;
lrc->last_q[INTER_FRAME] = q_trans[oxcf->worst_allowed_q];
} else {
// Update the layer context from a change_config() call.
void vp9_update_layer_context_change_config(VP9_COMP *const cpi,
const int target_bandwidth) {
+ SVC *const svc = &cpi->svc;
const VP9_CONFIG *const oxcf = &cpi->oxcf;
const RATE_CONTROL *const rc = &cpi->rc;
int layer;
int layer_end;
float bitrate_alloc = 1.0;
- if (cpi->svc.number_temporal_layers > 1) {
- layer_end = cpi->svc.number_temporal_layers;
+ if (svc->number_temporal_layers > 1) {
+ layer_end = svc->number_temporal_layers;
} else {
- layer_end = cpi->svc.number_spatial_layers;
+ layer_end = svc->number_spatial_layers;
}
for (layer = 0; layer < layer_end; ++layer) {
- LAYER_CONTEXT *const lc = &cpi->svc.layer_context[layer];
+ LAYER_CONTEXT *const lc = &svc->layer_context[layer];
RATE_CONTROL *const lrc = &lc->rc;
- if (cpi->svc.number_temporal_layers > 1) {
+ if (svc->number_temporal_layers > 1) {
lc->target_bandwidth = oxcf->ts_target_bitrate[layer] * 1000;
} else {
lc->target_bandwidth = oxcf->ss_target_bitrate[layer] * 1000;
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.
- if (cpi->svc.number_temporal_layers > 1) {
+ if (svc->number_temporal_layers > 1) {
lc->framerate = oxcf->framerate / oxcf->ts_rate_decimator[layer];
} else {
lc->framerate = oxcf->framerate;
}
void vp9_update_temporal_layer_framerate(VP9_COMP *const cpi) {
- const int layer = cpi->svc.temporal_layer_id;
+ SVC *const svc = &cpi->svc;
const VP9_CONFIG *const oxcf = &cpi->oxcf;
- LAYER_CONTEXT *const lc = get_layer_context(&cpi->svc);
+ LAYER_CONTEXT *const lc = get_layer_context(svc);
RATE_CONTROL *const lrc = &lc->rc;
+ const int layer = svc->temporal_layer_id;
lc->framerate = oxcf->framerate / oxcf->ts_rate_decimator[layer];
lrc->av_per_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
}
void vp9_init_second_pass_spatial_svc(VP9_COMP *cpi) {
+ SVC *const svc = &cpi->svc;
int i;
- for (i = 0; i < cpi->svc.number_spatial_layers; ++i) {
- struct twopass_rc *const twopass = &cpi->svc.layer_context[i].twopass;
- cpi->svc.spatial_layer_id = i;
+ for (i = 0; i < svc->number_spatial_layers; ++i) {
+ struct twopass_rc *const twopass = &svc->layer_context[i].twopass;
+
+ svc->spatial_layer_id = i;
vp9_init_second_pass(cpi);
twopass->total_stats.spatial_layer_id = i;
twopass->total_left_stats.spatial_layer_id = i;
}
- cpi->svc.spatial_layer_id = 0;
+ svc->spatial_layer_id = 0;
}
}
-static vpx_codec_err_t set_vp9e_config(VP9_CONFIG *oxcf,
- const vpx_codec_enc_cfg_t *cfg,
- const struct vp9_extracfg *extra_cfg) {
+static vpx_codec_err_t set_encoder_config(VP9_CONFIG *oxcf,
+ const vpx_codec_enc_cfg_t *cfg, const struct vp9_extracfg *extra_cfg) {
oxcf->version = cfg->g_profile;
oxcf->width = cfg->g_w;
oxcf->height = cfg->g_h;
return VPX_CODEC_OK;
}
-static vpx_codec_err_t vp9e_set_config(vpx_codec_alg_priv_t *ctx,
- const vpx_codec_enc_cfg_t *cfg) {
+static vpx_codec_err_t encoder_set_config(vpx_codec_alg_priv_t *ctx,
+ const vpx_codec_enc_cfg_t *cfg) {
vpx_codec_err_t res;
if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h)
if (res == VPX_CODEC_OK) {
ctx->cfg = *cfg;
- set_vp9e_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
+ set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
vp9_change_config(ctx->cpi, &ctx->oxcf);
}
int vp9_reverse_trans(int q);
-static vpx_codec_err_t get_param(vpx_codec_alg_priv_t *ctx, int ctrl_id,
+static vpx_codec_err_t ctrl_get_param(vpx_codec_alg_priv_t *ctx, int ctrl_id,
va_list args) {
void *arg = va_arg(args, void *);
}
-static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx, int ctrl_id,
- va_list args) {
+static vpx_codec_err_t ctrl_set_param(vpx_codec_alg_priv_t *ctx, int ctrl_id,
+ va_list args) {
vpx_codec_err_t res = VPX_CODEC_OK;
struct vp9_extracfg extra_cfg = ctx->extra_cfg;
if (res == VPX_CODEC_OK) {
ctx->extra_cfg = extra_cfg;
- set_vp9e_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
+ set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
vp9_change_config(ctx->cpi, &ctx->oxcf);
}
#undef MAP
}
-
-static vpx_codec_err_t vp9e_common_init(vpx_codec_ctx_t *ctx) {
+static vpx_codec_err_t encoder_common_init(vpx_codec_ctx_t *ctx) {
vpx_codec_err_t res = VPX_CODEC_OK;
if (ctx->priv == NULL) {
if (res == VPX_CODEC_OK) {
VP9_COMP *cpi;
- set_vp9e_config(&ctx->priv->alg_priv->oxcf,
+ set_encoder_config(&ctx->priv->alg_priv->oxcf,
&ctx->priv->alg_priv->cfg,
&ctx->priv->alg_priv->extra_cfg);
cpi = vp9_create_compressor(&ctx->priv->alg_priv->oxcf);
}
-static vpx_codec_err_t vp9e_init(vpx_codec_ctx_t *ctx,
- vpx_codec_priv_enc_mr_cfg_t *data) {
- return vp9e_common_init(ctx);
+static vpx_codec_err_t encoder_init(vpx_codec_ctx_t *ctx,
+ vpx_codec_priv_enc_mr_cfg_t *data) {
+ return encoder_common_init(ctx);
}
-static vpx_codec_err_t vp9e_destroy(vpx_codec_alg_priv_t *ctx) {
+static vpx_codec_err_t encoder_destroy(vpx_codec_alg_priv_t *ctx) {
free(ctx->cx_data);
vp9_remove_compressor(ctx->cpi);
free(ctx);
return index_sz;
}
-static vpx_codec_err_t vp9e_encode(vpx_codec_alg_priv_t *ctx,
- const vpx_image_t *img,
- vpx_codec_pts_t pts,
- unsigned long duration,
- vpx_enc_frame_flags_t flags,
- unsigned long deadline) {
+static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx,
+ const vpx_image_t *img,
+ vpx_codec_pts_t pts,
+ unsigned long duration,
+ vpx_enc_frame_flags_t flags,
+ unsigned long deadline) {
vpx_codec_err_t res = VPX_CODEC_OK;
if (img)
}
-static const vpx_codec_cx_pkt_t *vp9e_get_cxdata(vpx_codec_alg_priv_t *ctx,
- vpx_codec_iter_t *iter) {
+static const vpx_codec_cx_pkt_t *encoder_get_cxdata(vpx_codec_alg_priv_t *ctx,
+ vpx_codec_iter_t *iter) {
return vpx_codec_pkt_list_get(&ctx->pkt_list.head, iter);
}
-static vpx_codec_err_t vp9e_set_reference(vpx_codec_alg_priv_t *ctx,
- int ctr_id,
- va_list args) {
+static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
vpx_ref_frame_t *const frame = va_arg(args, vpx_ref_frame_t *);
if (frame != NULL) {
}
}
-static vpx_codec_err_t vp9e_copy_reference(vpx_codec_alg_priv_t *ctx,
- int ctr_id,
- va_list args) {
+static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
vpx_ref_frame_t *const frame = va_arg(args, vpx_ref_frame_t *);
if (frame != NULL) {
}
}
-static vpx_codec_err_t get_reference(vpx_codec_alg_priv_t *ctx,
- int ctr_id,
- va_list args) {
+static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
vp9_ref_frame_t *frame = va_arg(args, vp9_ref_frame_t *);
if (frame != NULL) {
}
}
-static vpx_codec_err_t vp9e_set_previewpp(vpx_codec_alg_priv_t *ctx,
- int ctr_id,
- va_list args) {
+static vpx_codec_err_t ctrl_set_previewpp(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
#if CONFIG_VP9_POSTPROC
vp8_postproc_cfg_t *config = va_arg(args, vp8_postproc_cfg_t *);
(void)ctr_id;
}
-static vpx_image_t *vp9e_get_preview(vpx_codec_alg_priv_t *ctx) {
+static vpx_image_t *encoder_get_preview(vpx_codec_alg_priv_t *ctx) {
YV12_BUFFER_CONFIG sd;
vp9_ppflags_t flags = {0};
}
}
-static vpx_codec_err_t vp9e_update_entropy(vpx_codec_alg_priv_t *ctx,
- int ctr_id,
- va_list args) {
+static vpx_codec_err_t ctrl_update_entropy(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
const int update = va_arg(args, int);
vp9_update_entropy(ctx->cpi, update);
return VPX_CODEC_OK;
}
-static vpx_codec_err_t vp9e_update_reference(vpx_codec_alg_priv_t *ctx,
- int ctr_id,
- va_list args) {
+static vpx_codec_err_t ctrl_update_reference(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
const int ref_frame_flags = va_arg(args, int);
vp9_update_reference(ctx->cpi, ref_frame_flags);
return VPX_CODEC_OK;
}
-static vpx_codec_err_t vp9e_use_reference(vpx_codec_alg_priv_t *ctx,
- int ctr_id,
- va_list args) {
+static vpx_codec_err_t ctrl_use_reference(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
const int reference_flag = va_arg(args, int);
vp9_use_as_reference(ctx->cpi, reference_flag);
return VPX_CODEC_OK;
}
-static vpx_codec_err_t vp9e_set_roi_map(vpx_codec_alg_priv_t *ctx,
- int ctr_id,
- va_list args) {
+static vpx_codec_err_t ctrl_set_roi_map(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
// TODO(yaowu): Need to re-implement and test for VP9.
return VPX_CODEC_INVALID_PARAM;
}
-static vpx_codec_err_t vp9e_set_activemap(vpx_codec_alg_priv_t *ctx,
- int ctr_id,
- va_list args) {
+static vpx_codec_err_t ctrl_set_active_map(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
vpx_active_map_t *const map = va_arg(args, vpx_active_map_t *);
if (map) {
}
}
-static vpx_codec_err_t vp9e_set_scalemode(vpx_codec_alg_priv_t *ctx,
- int ctr_id, va_list args) {
+static vpx_codec_err_t ctrl_set_scale_mode(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
vpx_scaling_mode_t *const mode = va_arg(args, vpx_scaling_mode_t *);
if (mode) {
}
}
-static vpx_codec_err_t vp9e_set_svc(vpx_codec_alg_priv_t *ctx, int ctr_id,
+static vpx_codec_err_t ctrl_set_svc(vpx_codec_alg_priv_t *ctx, int ctr_id,
va_list args) {
int data = va_arg(args, int);
const vpx_codec_enc_cfg_t *cfg = &ctx->cfg;
return VPX_CODEC_OK;
}
-static vpx_codec_err_t vp9e_set_svc_layer_id(vpx_codec_alg_priv_t *ctx,
+static vpx_codec_err_t ctrl_set_svc_layer_id(vpx_codec_alg_priv_t *ctx,
int ctr_id,
va_list args) {
vpx_svc_layer_id_t *const data = va_arg(args, vpx_svc_layer_id_t *);
return VPX_CODEC_OK;
}
-static vpx_codec_err_t vp9e_set_svc_parameters(vpx_codec_alg_priv_t *ctx,
+static vpx_codec_err_t ctrl_set_svc_parameters(vpx_codec_alg_priv_t *ctx,
int ctr_id, va_list args) {
VP9_COMP *const cpi = ctx->cpi;
vpx_svc_parameters_t *const params = va_arg(args, vpx_svc_parameters_t *);
ctx->cfg.rc_max_quantizer = params->max_quantizer;
ctx->cfg.rc_min_quantizer = params->min_quantizer;
- set_vp9e_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
+ set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
vp9_change_config(ctx->cpi, &ctx->oxcf);
return VPX_CODEC_OK;
}
-static vpx_codec_ctrl_fn_map_t vp9e_ctf_maps[] = {
- {VP8_SET_REFERENCE, vp9e_set_reference},
- {VP8_COPY_REFERENCE, vp9e_copy_reference},
- {VP8_SET_POSTPROC, vp9e_set_previewpp},
- {VP8E_UPD_ENTROPY, vp9e_update_entropy},
- {VP8E_UPD_REFERENCE, vp9e_update_reference},
- {VP8E_USE_REFERENCE, vp9e_use_reference},
- {VP8E_SET_ROI_MAP, vp9e_set_roi_map},
- {VP8E_SET_ACTIVEMAP, vp9e_set_activemap},
- {VP8E_SET_SCALEMODE, vp9e_set_scalemode},
- {VP8E_SET_CPUUSED, set_param},
- {VP8E_SET_NOISE_SENSITIVITY, set_param},
- {VP8E_SET_ENABLEAUTOALTREF, set_param},
- {VP8E_SET_SHARPNESS, set_param},
- {VP8E_SET_STATIC_THRESHOLD, set_param},
- {VP9E_SET_TILE_COLUMNS, set_param},
- {VP9E_SET_TILE_ROWS, set_param},
- {VP8E_GET_LAST_QUANTIZER, get_param},
- {VP8E_GET_LAST_QUANTIZER_64, get_param},
- {VP8E_SET_ARNR_MAXFRAMES, set_param},
- {VP8E_SET_ARNR_STRENGTH, set_param},
- {VP8E_SET_ARNR_TYPE, set_param},
- {VP8E_SET_TUNING, set_param},
- {VP8E_SET_CQ_LEVEL, set_param},
- {VP8E_SET_MAX_INTRA_BITRATE_PCT, set_param},
- {VP9E_SET_LOSSLESS, set_param},
- {VP9E_SET_FRAME_PARALLEL_DECODING, set_param},
- {VP9E_SET_AQ_MODE, set_param},
- {VP9E_SET_FRAME_PERIODIC_BOOST, set_param},
- {VP9_GET_REFERENCE, get_reference},
- {VP9E_SET_SVC, vp9e_set_svc},
- {VP9E_SET_SVC_PARAMETERS, vp9e_set_svc_parameters},
- {VP9E_SET_SVC_LAYER_ID, vp9e_set_svc_layer_id},
+static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
+ {VP8_COPY_REFERENCE, ctrl_copy_reference},
+ {VP8E_UPD_ENTROPY, ctrl_update_entropy},
+ {VP8E_UPD_REFERENCE, ctrl_update_reference},
+ {VP8E_USE_REFERENCE, ctrl_use_reference},
+
+ // Setters
+ {VP8_SET_REFERENCE, ctrl_set_reference},
+ {VP8_SET_POSTPROC, ctrl_set_previewpp},
+ {VP8E_SET_ROI_MAP, ctrl_set_roi_map},
+ {VP8E_SET_ACTIVEMAP, ctrl_set_active_map},
+ {VP8E_SET_SCALEMODE, ctrl_set_scale_mode},
+ {VP8E_SET_CPUUSED, ctrl_set_param},
+ {VP8E_SET_NOISE_SENSITIVITY, ctrl_set_param},
+ {VP8E_SET_ENABLEAUTOALTREF, ctrl_set_param},
+ {VP8E_SET_SHARPNESS, ctrl_set_param},
+ {VP8E_SET_STATIC_THRESHOLD, ctrl_set_param},
+ {VP9E_SET_TILE_COLUMNS, ctrl_set_param},
+ {VP9E_SET_TILE_ROWS, ctrl_set_param},
+ {VP8E_SET_ARNR_MAXFRAMES, ctrl_set_param},
+ {VP8E_SET_ARNR_STRENGTH, ctrl_set_param},
+ {VP8E_SET_ARNR_TYPE, ctrl_set_param},
+ {VP8E_SET_TUNING, ctrl_set_param},
+ {VP8E_SET_CQ_LEVEL, ctrl_set_param},
+ {VP8E_SET_MAX_INTRA_BITRATE_PCT, ctrl_set_param},
+ {VP9E_SET_LOSSLESS, ctrl_set_param},
+ {VP9E_SET_FRAME_PARALLEL_DECODING, ctrl_set_param},
+ {VP9E_SET_AQ_MODE, ctrl_set_param},
+ {VP9E_SET_FRAME_PERIODIC_BOOST, ctrl_set_param},
+ {VP9E_SET_SVC, ctrl_set_svc},
+ {VP9E_SET_SVC_PARAMETERS, ctrl_set_svc_parameters},
+ {VP9E_SET_SVC_LAYER_ID, ctrl_set_svc_layer_id},
+
+ // Getters
+ {VP8E_GET_LAST_QUANTIZER, ctrl_get_param},
+ {VP8E_GET_LAST_QUANTIZER_64, ctrl_get_param},
+ {VP9_GET_REFERENCE, ctrl_get_reference},
+
{ -1, NULL},
};
-static vpx_codec_enc_cfg_map_t vp9e_usage_cfg_map[] = {
+static vpx_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
{
0,
{ // NOLINT
- 0, /* g_usage */
- 0, /* g_threads */
- 0, /* g_profile */
+ 0, // g_usage
+ 0, // g_threads
+ 0, // g_profile
- 320, /* g_width */
- 240, /* g_height */
- {1, 30}, /* g_timebase */
+ 320, // g_width
+ 240, // g_height
+ {1, 30}, // g_timebase
- 0, /* g_error_resilient */
+ 0, // g_error_resilient
- VPX_RC_ONE_PASS, /* g_pass */
+ VPX_RC_ONE_PASS, // g_pass
- 25, /* g_lag_in_frames */
+ 25, // g_lag_in_frames
- 0, /* rc_dropframe_thresh */
- 0, /* rc_resize_allowed */
- 60, /* rc_resize_down_thresold */
- 30, /* rc_resize_up_thresold */
+ 0, // rc_dropframe_thresh
+ 0, // rc_resize_allowed
+ 60, // rc_resize_down_thresold
+ 30, // rc_resize_up_thresold
- VPX_VBR, /* rc_end_usage */
+ VPX_VBR, // rc_end_usage
#if VPX_ENCODER_ABI_VERSION > (1 + VPX_CODEC_ABI_VERSION)
- {0}, /* rc_twopass_stats_in */
+ {0}, // rc_twopass_stats_in
#endif
- 256, /* rc_target_bandwidth */
- 0, /* rc_min_quantizer */
- 63, /* rc_max_quantizer */
- 100, /* rc_undershoot_pct */
- 100, /* rc_overshoot_pct */
-
- 6000, /* rc_max_buffer_size */
- 4000, /* rc_buffer_initial_size; */
- 5000, /* rc_buffer_optimal_size; */
-
- 50, /* rc_two_pass_vbrbias */
- 0, /* rc_two_pass_vbrmin_section */
- 2000, /* rc_two_pass_vbrmax_section */
-
- /* keyframing settings (kf) */
- VPX_KF_AUTO, /* g_kfmode*/
- 0, /* kf_min_dist */
- 9999, /* kf_max_dist */
-
- VPX_SS_DEFAULT_LAYERS, /* ss_number_layers */
- {0}, /* ss_target_bitrate */
- 1, /* ts_number_layers */
- {0}, /* ts_target_bitrate */
- {0}, /* ts_rate_decimator */
- 0, /* ts_periodicity */
- {0}, /* ts_layer_id */
+ 256, // rc_target_bandwidth
+ 0, // rc_min_quantizer
+ 63, // rc_max_quantizer
+ 100, // rc_undershoot_pct
+ 100, // rc_overshoot_pct
+
+ 6000, // rc_max_buffer_size
+ 4000, // rc_buffer_initial_size
+ 5000, // rc_buffer_optimal_size
+
+ 50, // rc_two_pass_vbrbias
+ 0, // rc_two_pass_vbrmin_section
+ 2000, // rc_two_pass_vbrmax_section
+
+ // keyframing settings (kf)
+ VPX_KF_AUTO, // g_kfmode
+ 0, // kf_min_dist
+ 9999, // kf_max_dist
+
+ VPX_SS_DEFAULT_LAYERS, // ss_number_layers
+ {0}, // ss_target_bitrate
+ 1, // ts_number_layers
+ {0}, // ts_target_bitrate
+ {0}, // ts_rate_decimator
+ 0, // ts_periodicity
+ {0}, // ts_layer_id
#if VPX_ENCODER_ABI_VERSION == (1 + VPX_CODEC_ABI_VERSION)
- "vp8.fpf" /* first pass filename */
+ "vp8.fpf" // first pass filename
#endif
}
},
{ -1, {NOT_IMPLEMENTED}}
};
-
#ifndef VERSION_STRING
#define VERSION_STRING
#endif
CODEC_INTERFACE(vpx_codec_vp9_cx) = {
"WebM Project VP9 Encoder" VERSION_STRING,
VPX_CODEC_INTERNAL_ABI_VERSION,
- VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR,
- /* vpx_codec_caps_t caps; */
- vp9e_init, /* vpx_codec_init_fn_t init; */
- vp9e_destroy, /* vpx_codec_destroy_fn_t destroy; */
- vp9e_ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */
- NOT_IMPLEMENTED, /* vpx_codec_get_mmap_fn_t get_mmap; */
- NOT_IMPLEMENTED, /* vpx_codec_set_mmap_fn_t set_mmap; */
+ VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR, // vpx_codec_caps_t
+ encoder_init, // vpx_codec_init_fn_t
+ encoder_destroy, // vpx_codec_destroy_fn_t
+ encoder_ctrl_maps, // vpx_codec_ctrl_fn_map_t
+ NOT_IMPLEMENTED, // vpx_codec_get_mmap_fn_t
+ NOT_IMPLEMENTED, // vpx_codec_set_mmap_fn_t
{ // NOLINT
- NOT_IMPLEMENTED, /* vpx_codec_peek_si_fn_t peek_si; */
- NOT_IMPLEMENTED, /* vpx_codec_get_si_fn_t get_si; */
- NOT_IMPLEMENTED, /* vpx_codec_decode_fn_t decode; */
- NOT_IMPLEMENTED, /* vpx_codec_frame_get_fn_t frame_get; */
+ NOT_IMPLEMENTED, // vpx_codec_peek_si_fn_t
+ NOT_IMPLEMENTED, // vpx_codec_get_si_fn_t
+ NOT_IMPLEMENTED, // vpx_codec_decode_fn_t
+ NOT_IMPLEMENTED, // vpx_codec_frame_get_fn_t
},
{ // NOLINT
- vp9e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t peek_si; */
- vp9e_encode, /* vpx_codec_encode_fn_t encode; */
- vp9e_get_cxdata, /* vpx_codec_get_cx_data_fn_t frame_get; */
- vp9e_set_config,
- NOT_IMPLEMENTED,
- vp9e_get_preview,
- } /* encoder functions */
+ encoder_usage_cfg_map, // vpx_codec_enc_cfg_map_t
+ encoder_encode, // vpx_codec_encode_fn_t
+ encoder_get_cxdata, // vpx_codec_get_cx_data_fn_t
+ encoder_set_config, // vpx_codec_enc_config_set_fn_t
+ NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t
+ encoder_get_preview, // vpx_codec_get_preview_frame_fn_t
+ NOT_IMPLEMENTED , // vpx_codec_enc_mr_get_mem_loc_fn_t
+ }
};
* be found in the AUTHORS file in the root of the source tree.
*/
-
#include <stdlib.h>
#include <string.h>
-#include "vpx/vpx_decoder.h"
-#include "vpx/vp8dx.h"
-#include "vpx/internal/vpx_codec_internal.h"
+
#include "./vpx_version.h"
+
+#include "vpx/internal/vpx_codec_internal.h"
+#include "vpx/vp8dx.h"
+#include "vpx/vpx_decoder.h"
+
#include "vp9/common/vp9_frame_buffers.h"
+
#include "vp9/decoder/vp9_decoder.h"
#include "vp9/decoder/vp9_read_bit_buffer.h"
+
#include "vp9/vp9_iface_common.h"
#define VP9_CAP_POSTPROC (CONFIG_VP9_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0)
-typedef vpx_codec_stream_info_t vp9_stream_info_t;
+
+typedef vpx_codec_stream_info_t vp9_stream_info_t;
struct vpx_codec_alg_priv {
vpx_codec_priv_t base;
vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb;
};
-static vpx_codec_err_t vp9_init(vpx_codec_ctx_t *ctx,
- vpx_codec_priv_enc_mr_cfg_t *data) {
+static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx,
+ vpx_codec_priv_enc_mr_cfg_t *data) {
// This function only allocates space for the vpx_codec_alg_priv_t
// structure. More memory may be required at the time the stream
// information becomes known.
if (!ctx->priv) {
- void *base = vpx_memalign(32, sizeof(vpx_codec_alg_priv_t));
- if (base == NULL)
+ vpx_codec_alg_priv_t *alg_priv = vpx_memalign(32, sizeof(*alg_priv));
+ if (alg_priv == NULL)
return VPX_CODEC_MEM_ERROR;
- memset(base, 0, sizeof(vpx_codec_alg_priv_t));
- ctx->priv = (vpx_codec_priv_t *)base;
+ vp9_zero(*alg_priv);
+
+ ctx->priv = (vpx_codec_priv_t *)alg_priv;
ctx->priv->sz = sizeof(*ctx->priv);
ctx->priv->iface = ctx->iface;
- ctx->priv->alg_priv = (vpx_codec_alg_priv_t *)base;
+ ctx->priv->alg_priv = alg_priv;
ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si);
ctx->priv->init_flags = ctx->init_flags;
return VPX_CODEC_OK;
}
-static vpx_codec_err_t vp9_destroy(vpx_codec_alg_priv_t *ctx) {
- if (ctx->pbi)
- vp9_remove_decompressor(ctx->pbi);
+static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) {
+ if (ctx->pbi) {
+ vp9_decoder_remove(ctx->pbi);
+ ctx->pbi = NULL;
+ }
return VPX_CODEC_OK;
}
-static vpx_codec_err_t vp9_peek_si(const uint8_t *data, unsigned int data_sz,
- vpx_codec_stream_info_t *si) {
- if (data_sz <= 8) return VPX_CODEC_UNSUP_BITSTREAM;
- if (data + data_sz <= data) return VPX_CODEC_INVALID_PARAM;
+static vpx_codec_err_t decoder_peek_si(const uint8_t *data,
+ unsigned int data_sz,
+ vpx_codec_stream_info_t *si) {
+ if (data_sz <= 8)
+ return VPX_CODEC_UNSUP_BITSTREAM;
+
+ if (data + data_sz <= data)
+ return VPX_CODEC_INVALID_PARAM;
si->is_kf = 0;
si->w = si->h = 0;
return VPX_CODEC_OK;
}
-static vpx_codec_err_t vp9_get_si(vpx_codec_alg_priv_t *ctx,
- vpx_codec_stream_info_t *si) {
+static vpx_codec_err_t decoder_get_si(vpx_codec_alg_priv_t *ctx,
+ vpx_codec_stream_info_t *si) {
const size_t sz = (si->sz >= sizeof(vp9_stream_info_t))
? sizeof(vp9_stream_info_t)
: sizeof(vpx_codec_stream_info_t);
return VPX_CODEC_OK;
}
-
static vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t *ctx,
const struct vpx_internal_error_info *error) {
if (error->error_code)
return error->error_code;
}
+static void init_buffer_callbacks(vpx_codec_alg_priv_t *ctx) {
+ VP9_COMMON *const cm = &ctx->pbi->common;
+
+ cm->new_fb_idx = -1;
+
+ if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) {
+ cm->get_fb_cb = ctx->get_ext_fb_cb;
+ cm->release_fb_cb = ctx->release_ext_fb_cb;
+ cm->cb_priv = ctx->ext_priv;
+ } else {
+ cm->get_fb_cb = vp9_get_frame_buffer;
+ cm->release_fb_cb = vp9_release_frame_buffer;
+
+ if (vp9_alloc_internal_frame_buffers(&cm->int_frame_buffers))
+ vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
+ "Failed to initialize internal frame buffers");
+
+ cm->cb_priv = &cm->int_frame_buffers;
+ }
+}
+
+static void set_default_ppflags(vp8_postproc_cfg_t *cfg) {
+ cfg->post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK;
+ cfg->deblocking_level = 4;
+ cfg->noise_level = 0;
+}
+
+static void set_ppflags(const vpx_codec_alg_priv_t *ctx,
+ vp9_ppflags_t *flags) {
+ flags->post_proc_flag =
+#if CONFIG_POSTPROC_VISUALIZER
+ (ctx->dbg_color_ref_frame_flag ? VP9D_DEBUG_CLR_FRM_REF_BLKS : 0) |
+ (ctx->dbg_color_mb_modes_flag ? VP9D_DEBUG_CLR_BLK_MODES : 0) |
+ (ctx->dbg_color_b_modes_flag ? VP9D_DEBUG_CLR_BLK_MODES : 0) |
+ (ctx->dbg_display_mv_flag ? VP9D_DEBUG_DRAW_MV : 0) |
+#endif
+ ctx->postproc_cfg.post_proc_flag;
+
+ flags->deblocking_level = ctx->postproc_cfg.deblocking_level;
+ flags->noise_level = ctx->postproc_cfg.noise_level;
+#if CONFIG_POSTPROC_VISUALIZER
+ flags->display_ref_frame_flag = ctx->dbg_color_ref_frame_flag;
+ flags->display_mb_modes_flag = ctx->dbg_color_mb_modes_flag;
+ flags->display_b_modes_flag = ctx->dbg_color_b_modes_flag;
+ flags->display_mv_flag = ctx->dbg_display_mv_flag;
+#endif
+}
+
+static void init_decoder(vpx_codec_alg_priv_t *ctx) {
+ VP9D_CONFIG oxcf;
+ oxcf.width = ctx->si.w;
+ oxcf.height = ctx->si.h;
+ oxcf.version = 9;
+ oxcf.max_threads = ctx->cfg.threads;
+ oxcf.inv_tile_order = ctx->invert_tile_order;
+
+ ctx->pbi = vp9_decoder_create(&oxcf);
+ if (ctx->pbi == NULL)
+ return;
+
+ vp9_initialize_dec();
+
+ // If postprocessing was enabled by the application and a
+ // configuration has not been provided, default it.
+ if (!ctx->postproc_cfg_set &&
+ (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC))
+ set_default_ppflags(&ctx->postproc_cfg);
+
+ init_buffer_callbacks(ctx);
+}
+
static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
const uint8_t **data, unsigned int data_sz,
void *user_priv, int64_t deadline) {
- vpx_codec_err_t res = VPX_CODEC_OK;
+ YV12_BUFFER_CONFIG sd = { 0 };
+ int64_t time_stamp = 0, time_end_stamp = 0;
+ vp9_ppflags_t flags = {0};
+ VP9_COMMON *cm = NULL;
ctx->img_avail = 0;
// Determine the stream parameters. Note that we rely on peek_si to
// validate that we have a buffer that does not wrap around the top
// of the heap.
- if (!ctx->si.h)
- res = ctx->base.iface->dec.peek_si(*data, data_sz, &ctx->si);
-
- /* Initialize the decoder instance on the first frame*/
- if (!res && !ctx->decoder_init) {
- VP9D_CONFIG oxcf;
- struct VP9Decompressor *optr;
-
- vp9_initialize_dec();
-
- oxcf.width = ctx->si.w;
- oxcf.height = ctx->si.h;
- oxcf.version = 9;
- oxcf.max_threads = ctx->cfg.threads;
- oxcf.inv_tile_order = ctx->invert_tile_order;
- optr = vp9_create_decompressor(&oxcf);
-
- // If postprocessing was enabled by the application and a
- // configuration has not been provided, default it.
- if (!ctx->postproc_cfg_set &&
- (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) {
- ctx->postproc_cfg.post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK;
- ctx->postproc_cfg.deblocking_level = 4;
- ctx->postproc_cfg.noise_level = 0;
- }
-
- if (!optr) {
- res = VPX_CODEC_ERROR;
- } else {
- VP9D_COMP *const pbi = (VP9D_COMP*)optr;
- VP9_COMMON *const cm = &pbi->common;
-
- // Set index to not initialized.
- cm->new_fb_idx = -1;
-
- if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) {
- cm->get_fb_cb = ctx->get_ext_fb_cb;
- cm->release_fb_cb = ctx->release_ext_fb_cb;
- cm->cb_priv = ctx->ext_priv;
- } else {
- cm->get_fb_cb = vp9_get_frame_buffer;
- cm->release_fb_cb = vp9_release_frame_buffer;
-
- if (vp9_alloc_internal_frame_buffers(&cm->int_frame_buffers))
- vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
- "Failed to initialize internal frame buffers");
- cm->cb_priv = &cm->int_frame_buffers;
- }
+ if (!ctx->si.h) {
+ const vpx_codec_err_t res =
+ ctx->base.iface->dec.peek_si(*data, data_sz, &ctx->si);
+ if (res != VPX_CODEC_OK)
+ return res;
+ }
- ctx->pbi = optr;
- }
+ // Initialize the decoder instance on the first frame
+ if (!ctx->decoder_init) {
+ init_decoder(ctx);
+ if (ctx->pbi == NULL)
+ return VPX_CODEC_ERROR;
ctx->decoder_init = 1;
}
- if (!res && ctx->pbi) {
- VP9D_COMP *const pbi = ctx->pbi;
- VP9_COMMON *const cm = &pbi->common;
- YV12_BUFFER_CONFIG sd;
- int64_t time_stamp = 0, time_end_stamp = 0;
- vp9_ppflags_t flags = {0};
-
- if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) {
- flags.post_proc_flag =
-#if CONFIG_POSTPROC_VISUALIZER
- (ctx->dbg_color_ref_frame_flag ? VP9D_DEBUG_CLR_FRM_REF_BLKS : 0) |
- (ctx->dbg_color_mb_modes_flag ? VP9D_DEBUG_CLR_BLK_MODES : 0) |
- (ctx->dbg_color_b_modes_flag ? VP9D_DEBUG_CLR_BLK_MODES : 0) |
- (ctx->dbg_display_mv_flag ? VP9D_DEBUG_DRAW_MV : 0) |
-#endif
- ctx->postproc_cfg.post_proc_flag;
+ cm = &ctx->pbi->common;
- flags.deblocking_level = ctx->postproc_cfg.deblocking_level;
- flags.noise_level = ctx->postproc_cfg.noise_level;
-#if CONFIG_POSTPROC_VISUALIZER
- flags.display_ref_frame_flag = ctx->dbg_color_ref_frame_flag;
- flags.display_mb_modes_flag = ctx->dbg_color_mb_modes_flag;
- flags.display_b_modes_flag = ctx->dbg_color_b_modes_flag;
- flags.display_mv_flag = ctx->dbg_display_mv_flag;
-#endif
- }
+ if (vp9_receive_compressed_data(ctx->pbi, data_sz, data, deadline))
+ return update_error_state(ctx, &cm->error);
- if (vp9_receive_compressed_data(pbi, data_sz, data, deadline))
- res = update_error_state(ctx, &cm->error);
+ if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)
+ set_ppflags(ctx, &flags);
- if (!res && 0 == vp9_get_raw_frame(pbi, &sd, &time_stamp,
- &time_end_stamp, &flags)) {
- yuvconfig2image(&ctx->img, &sd, user_priv);
+ if (vp9_get_raw_frame(ctx->pbi, &sd, &time_stamp, &time_end_stamp, &flags))
+ return update_error_state(ctx, &cm->error);
- ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
- ctx->img_avail = 1;
- }
- }
+ yuvconfig2image(&ctx->img, &sd, user_priv);
+ ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
+ ctx->img_avail = 1;
- return res;
+ return VPX_CODEC_OK;
}
static void parse_superframe_index(const uint8_t *data, size_t data_sz,
if (data_sz >= index_sz && data[data_sz - index_sz] == marker) {
// found a valid superframe index
uint32_t i, j;
- const uint8_t *x = data + data_sz - index_sz + 1;
+ const uint8_t *x = &data[data_sz - index_sz + 1];
for (i = 0; i < frames; i++) {
uint32_t this_sz = 0;
}
}
-static vpx_codec_err_t vp9_decode(vpx_codec_alg_priv_t *ctx,
- const uint8_t *data,
- unsigned int data_sz,
- void *user_priv,
- long deadline) {
+static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx,
+ const uint8_t *data, unsigned int data_sz,
+ void *user_priv, long deadline) {
const uint8_t *data_start = data;
const uint8_t *data_end = data + data_sz;
vpx_codec_err_t res = VPX_CODEC_OK;
uint32_t sizes[8];
int frames_this_pts, frame_count = 0;
- if (data == NULL || data_sz == 0) return VPX_CODEC_INVALID_PARAM;
+ if (data == NULL || data_sz == 0)
+ return VPX_CODEC_INVALID_PARAM;
parse_superframe_index(data, data_sz, sizes, &frames_this_pts);
assert(data_start >= data);
assert(data_start <= data_end);
- /* Early exit if there was a decode error */
+ // Early exit if there was a decode error
if (res)
break;
- /* Account for suboptimal termination by the encoder. */
+ // Account for suboptimal termination by the encoder.
while (data_start < data_end && *data_start == 0)
data_start++;
data_sz = (unsigned int)(data_end - data_start);
} while (data_start < data_end);
+
return res;
}
-static vpx_image_t *vp9_get_frame(vpx_codec_alg_priv_t *ctx,
- vpx_codec_iter_t *iter) {
+static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx,
+ vpx_codec_iter_t *iter) {
vpx_image_t *img = NULL;
if (ctx->img_avail) {
- /* iter acts as a flip flop, so an image is only returned on the first
- * call to get_frame.
- */
+ // iter acts as a flip flop, so an image is only returned on the first
+ // call to get_frame.
if (!(*iter)) {
img = &ctx->img;
*iter = img;
return img;
}
-static vpx_codec_err_t vp9_set_fb_fn(
+static vpx_codec_err_t decoder_set_fb_fn(
vpx_codec_alg_priv_t *ctx,
vpx_get_frame_buffer_cb_fn_t cb_get,
vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
return VPX_CODEC_ERROR;
}
-static vpx_codec_err_t set_reference(vpx_codec_alg_priv_t *ctx, int ctr_id,
- va_list args) {
+static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
vpx_ref_frame_t *const data = va_arg(args, vpx_ref_frame_t *);
if (data) {
}
}
-static vpx_codec_err_t copy_reference(vpx_codec_alg_priv_t *ctx, int ctr_id,
- va_list args) {
+static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
if (data) {
}
}
-static vpx_codec_err_t get_reference(vpx_codec_alg_priv_t *ctx, int ctr_id,
- va_list args) {
+static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *);
if (data) {
}
}
-static vpx_codec_err_t set_postproc(vpx_codec_alg_priv_t *ctx, int ctr_id,
- va_list args) {
+static vpx_codec_err_t ctrl_set_postproc(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
#if CONFIG_VP9_POSTPROC
vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *);
#endif
}
-static vpx_codec_err_t set_dbg_options(vpx_codec_alg_priv_t *ctx, int ctrl_id,
- va_list args) {
+static vpx_codec_err_t ctrl_set_dbg_options(vpx_codec_alg_priv_t *ctx,
+ int ctrl_id, va_list args) {
#if CONFIG_POSTPROC_VISUALIZER && CONFIG_POSTPROC
int data = va_arg(args, int);
#endif
}
-static vpx_codec_err_t get_last_ref_updates(vpx_codec_alg_priv_t *ctx,
- int ctrl_id, va_list args) {
+static vpx_codec_err_t ctrl_get_last_ref_updates(vpx_codec_alg_priv_t *ctx,
+ int ctrl_id, va_list args) {
int *const update_info = va_arg(args, int *);
if (update_info) {
}
-static vpx_codec_err_t get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
- int ctrl_id, va_list args) {
+static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
+ int ctrl_id, va_list args) {
int *corrupted = va_arg(args, int *);
if (corrupted) {
}
}
-static vpx_codec_err_t get_display_size(vpx_codec_alg_priv_t *ctx,
- int ctrl_id, va_list args) {
+static vpx_codec_err_t ctrl_get_display_size(vpx_codec_alg_priv_t *ctx,
+ int ctrl_id, va_list args) {
int *const display_size = va_arg(args, int *);
if (display_size) {
}
}
-static vpx_codec_err_t set_invert_tile_order(vpx_codec_alg_priv_t *ctx,
- int ctr_id,
- va_list args) {
+static vpx_codec_err_t ctrl_set_invert_tile_order(vpx_codec_alg_priv_t *ctx,
+ int ctr_id, va_list args) {
ctx->invert_tile_order = va_arg(args, int);
return VPX_CODEC_OK;
}
-static vpx_codec_ctrl_fn_map_t ctf_maps[] = {
- {VP8_SET_REFERENCE, set_reference},
- {VP8_COPY_REFERENCE, copy_reference},
- {VP8_SET_POSTPROC, set_postproc},
- {VP8_SET_DBG_COLOR_REF_FRAME, set_dbg_options},
- {VP8_SET_DBG_COLOR_MB_MODES, set_dbg_options},
- {VP8_SET_DBG_COLOR_B_MODES, set_dbg_options},
- {VP8_SET_DBG_DISPLAY_MV, set_dbg_options},
- {VP8D_GET_LAST_REF_UPDATES, get_last_ref_updates},
- {VP8D_GET_FRAME_CORRUPTED, get_frame_corrupted},
- {VP9_GET_REFERENCE, get_reference},
- {VP9D_GET_DISPLAY_SIZE, get_display_size},
- {VP9_INVERT_TILE_DECODE_ORDER, set_invert_tile_order},
+static vpx_codec_ctrl_fn_map_t decoder_ctrl_maps[] = {
+ {VP8_COPY_REFERENCE, ctrl_copy_reference},
+
+ // Setters
+ {VP8_SET_REFERENCE, ctrl_set_reference},
+ {VP8_SET_POSTPROC, ctrl_set_postproc},
+ {VP8_SET_DBG_COLOR_REF_FRAME, ctrl_set_dbg_options},
+ {VP8_SET_DBG_COLOR_MB_MODES, ctrl_set_dbg_options},
+ {VP8_SET_DBG_COLOR_B_MODES, ctrl_set_dbg_options},
+ {VP8_SET_DBG_DISPLAY_MV, ctrl_set_dbg_options},
+ {VP9_INVERT_TILE_DECODE_ORDER, ctrl_set_invert_tile_order},
+
+ // Getters
+ {VP8D_GET_LAST_REF_UPDATES, ctrl_get_last_ref_updates},
+ {VP8D_GET_FRAME_CORRUPTED, ctrl_get_frame_corrupted},
+ {VP9_GET_REFERENCE, ctrl_get_reference},
+ {VP9D_GET_DISPLAY_SIZE, ctrl_get_display_size},
+
{ -1, NULL},
};
-
#ifndef VERSION_STRING
#define VERSION_STRING
#endif
"WebM Project VP9 Decoder" VERSION_STRING,
VPX_CODEC_INTERNAL_ABI_VERSION,
VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC |
- VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER,
- /* vpx_codec_caps_t caps; */
- vp9_init, /* vpx_codec_init_fn_t init; */
- vp9_destroy, /* vpx_codec_destroy_fn_t destroy; */
- ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */
- NOT_IMPLEMENTED, /* vpx_codec_get_mmap_fn_t get_mmap; */
- NOT_IMPLEMENTED, /* vpx_codec_set_mmap_fn_t set_mmap; */
+ VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER, // vpx_codec_caps_t
+ decoder_init, // vpx_codec_init_fn_t
+ decoder_destroy, // vpx_codec_destroy_fn_t
+ decoder_ctrl_maps, // vpx_codec_ctrl_fn_map_t
+ NOT_IMPLEMENTED, // vpx_codec_get_mmap_fn_t
+ NOT_IMPLEMENTED, // vpx_codec_set_mmap_fn_t
{ // NOLINT
- vp9_peek_si, /* vpx_codec_peek_si_fn_t peek_si; */
- vp9_get_si, /* vpx_codec_get_si_fn_t get_si; */
- vp9_decode, /* vpx_codec_decode_fn_t decode; */
- vp9_get_frame, /* vpx_codec_frame_get_fn_t frame_get; */
- vp9_set_fb_fn, /* vpx_codec_set_fb_fn_t set_fb_fn; */
+ decoder_peek_si, // vpx_codec_peek_si_fn_t
+ decoder_get_si, // vpx_codec_get_si_fn_t
+ decoder_decode, // vpx_codec_decode_fn_t
+ decoder_get_frame, // vpx_codec_frame_get_fn_t
+ decoder_set_fb_fn, // vpx_codec_set_fb_fn_t
},
{ // NOLINT
- /* encoder functions */
NOT_IMPLEMENTED,
NOT_IMPLEMENTED,
NOT_IMPLEMENTED,