summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild/make/rtcd.sh1
-rw-r--r--vp9/common/arm/neon/vp9_iht8x8_add_neon.asm2
-rw-r--r--vp9/common/vp9_blockd.c6
-rw-r--r--vp9/common/vp9_blockd.h18
-rw-r--r--vp9/common/vp9_entropy.h6
-rw-r--r--vp9/common/vp9_rtcd_defs.sh2
-rw-r--r--vp9/decoder/vp9_decodeframe.c6
-rw-r--r--vp9/encoder/vp9_bitstream.c97
-rw-r--r--vp9/encoder/vp9_bitstream.h6
-rw-r--r--vp9/encoder/vp9_encodeframe.c18
-rw-r--r--vp9/encoder/vp9_encodemb.c6
-rw-r--r--vp9/encoder/vp9_encodemv.c15
-rw-r--r--vp9/encoder/vp9_encodemv.h3
-rw-r--r--vp9/encoder/vp9_onyx_if.c2
-rw-r--r--vp9/encoder/vp9_onyx_int.h2
-rw-r--r--vp9/encoder/vp9_quantize.c52
-rw-r--r--vp9/encoder/vp9_quantize.h2
-rw-r--r--vp9/encoder/vp9_rdopt.c95
-rw-r--r--vp9/encoder/vp9_tokenize.c6
-rw-r--r--vpx/src/svc_encodeframe.c17
-rw-r--r--vpx/src/vpx_encoder.c42
21 files changed, 187 insertions, 217 deletions
diff --git a/build/make/rtcd.sh b/build/make/rtcd.sh
index ed037132a..93c9adcac 100755
--- a/build/make/rtcd.sh
+++ b/build/make/rtcd.sh
@@ -333,6 +333,7 @@ EOF
#
# Main Driver
#
+ALL_FUNCS=$(export LC_ALL=C; echo $ALL_FUNCS | tr ' ' '\n' | sort |tr '\n' ' ')
require c
case $arch in
x86)
diff --git a/vp9/common/arm/neon/vp9_iht8x8_add_neon.asm b/vp9/common/arm/neon/vp9_iht8x8_add_neon.asm
index 93d3af301..b41f5661b 100644
--- a/vp9/common/arm/neon/vp9_iht8x8_add_neon.asm
+++ b/vp9/common/arm/neon/vp9_iht8x8_add_neon.asm
@@ -576,6 +576,7 @@
vld1.s16 {q14,q15}, [r0]!
push {r0-r10}
+ vpush {d8-d15}
; transpose the input data
TRANSPOSE8X8
@@ -636,6 +637,7 @@ iadst_iadst
IADST8X8_1D
end_vp9_iht8x8_64_add_neon
+ vpop {d8-d15}
pop {r0-r10}
; ROUND_POWER_OF_TWO(temp_out[j], 5)
diff --git a/vp9/common/vp9_blockd.c b/vp9/common/vp9_blockd.c
index d918bedc6..e1d1318ac 100644
--- a/vp9/common/vp9_blockd.c
+++ b/vp9/common/vp9_blockd.c
@@ -16,8 +16,7 @@ MB_PREDICTION_MODE vp9_left_block_mode(const MODE_INFO *cur_mi,
if (!left_mi || is_inter_block(&left_mi->mbmi))
return DC_PRED;
- return left_mi->mbmi.sb_type < BLOCK_8X8 ? left_mi->bmi[b + 1].as_mode
- : left_mi->mbmi.mode;
+ return get_y_mode(left_mi, b + 1);
} else {
assert(b == 1 || b == 3);
return cur_mi->bmi[b - 1].as_mode;
@@ -30,8 +29,7 @@ MB_PREDICTION_MODE vp9_above_block_mode(const MODE_INFO *cur_mi,
if (!above_mi || is_inter_block(&above_mi->mbmi))
return DC_PRED;
- return above_mi->mbmi.sb_type < BLOCK_8X8 ? above_mi->bmi[b + 2].as_mode
- : above_mi->mbmi.mode;
+ return get_y_mode(above_mi, b + 2);
} else {
assert(b == 2 || b == 3);
return cur_mi->bmi[b - 2].as_mode;
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h
index 6086323f6..2a0ebfba0 100644
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -144,6 +144,11 @@ typedef struct {
b_mode_info bmi[4];
} MODE_INFO;
+static INLINE MB_PREDICTION_MODE get_y_mode(const MODE_INFO *mi, int block) {
+ return mi->mbmi.sb_type < BLOCK_8X8 ? mi->bmi[block].as_mode
+ : mi->mbmi.mode;
+}
+
static INLINE int is_inter_block(const MB_MODE_INFO *mbmi) {
return mbmi->ref_frame[0] > INTRA_FRAME;
}
@@ -255,13 +260,11 @@ extern const TX_TYPE mode2txfm_map[MB_MODE_COUNT];
static INLINE TX_TYPE get_tx_type_4x4(PLANE_TYPE plane_type,
const MACROBLOCKD *xd, int ib) {
const MODE_INFO *const mi = xd->mi_8x8[0];
- const MB_MODE_INFO *const mbmi = &mi->mbmi;
- if (plane_type != PLANE_TYPE_Y || xd->lossless || is_inter_block(mbmi))
+ if (plane_type != PLANE_TYPE_Y || xd->lossless || is_inter_block(&mi->mbmi))
return DCT_DCT;
- return mode2txfm_map[mbmi->sb_type < BLOCK_8X8 ? mi->bmi[ib].as_mode
- : mbmi->mode];
+ return mode2txfm_map[get_y_mode(mi, ib)];
}
static INLINE TX_TYPE get_tx_type_8x8(PLANE_TYPE plane_type,
@@ -328,13 +331,6 @@ void vp9_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd,
BLOCK_SIZE plane_bsize, TX_SIZE tx_size, int has_eob,
int aoff, int loff);
-
-static INLINE int get_tx_eob(const struct segmentation *seg, int segment_id,
- TX_SIZE tx_size) {
- const int eob_max = 16 << (tx_size << 1);
- return vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
-}
-
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/vp9/common/vp9_entropy.h b/vp9/common/vp9_entropy.h
index aab8b5388..bd5086aa1 100644
--- a/vp9/common/vp9_entropy.h
+++ b/vp9/common/vp9_entropy.h
@@ -177,13 +177,11 @@ static INLINE int get_entropy_context(TX_SIZE tx_size, const ENTROPY_CONTEXT *a,
static const INLINE scan_order *get_scan(const MACROBLOCKD *xd, TX_SIZE tx_size,
PLANE_TYPE type, int block_idx) {
const MODE_INFO *const mi = xd->mi_8x8[0];
- const MB_MODE_INFO *const mbmi = &mi->mbmi;
- if (is_inter_block(mbmi) || type != PLANE_TYPE_Y || xd->lossless) {
+ if (is_inter_block(&mi->mbmi) || type != PLANE_TYPE_Y || xd->lossless) {
return &vp9_default_scan_orders[tx_size];
} else {
- const MB_PREDICTION_MODE mode =
- mbmi->sb_type < BLOCK_8X8 ? mi->bmi[block_idx].as_mode : mbmi->mode;
+ const MB_PREDICTION_MODE mode = get_y_mode(mi, block_idx);
return &vp9_scan_orders[tx_size][mode2txfm_map[mode]];
}
}
diff --git a/vp9/common/vp9_rtcd_defs.sh b/vp9/common/vp9_rtcd_defs.sh
index 4031bda55..83ee69b7e 100644
--- a/vp9/common/vp9_rtcd_defs.sh
+++ b/vp9/common/vp9_rtcd_defs.sh
@@ -683,7 +683,7 @@ prototype unsigned int vp9_get_mb_ss "const int16_t *"
specialize vp9_get_mb_ss mmx sse2
# ENCODEMB INVOKE
-prototype int64_t vp9_block_error "int16_t *coeff, int16_t *dqcoeff, intptr_t block_size, int64_t *ssz"
+prototype int64_t vp9_block_error "const int16_t *coeff, const int16_t *dqcoeff, intptr_t block_size, int64_t *ssz"
specialize vp9_block_error $sse2_x86inc
prototype void vp9_subtract_block "int rows, int cols, int16_t *diff_ptr, ptrdiff_t diff_stride, const uint8_t *src_ptr, ptrdiff_t src_stride, const uint8_t *pred_ptr, ptrdiff_t pred_stride"
diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c
index e52b3f759..56b993d5f 100644
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -287,10 +287,8 @@ static void predict_and_reconstruct_intra_block(int plane, int block,
MACROBLOCKD *const xd = args->xd;
struct macroblockd_plane *const pd = &xd->plane[plane];
MODE_INFO *const mi = xd->mi_8x8[0];
- const MB_PREDICTION_MODE mode = (plane == 0)
- ? ((mi->mbmi.sb_type < BLOCK_8X8) ? mi->bmi[block].as_mode
- : mi->mbmi.mode)
- : mi->mbmi.uv_mode;
+ const MB_PREDICTION_MODE mode = (plane == 0) ? get_y_mode(mi, block)
+ : mi->mbmi.uv_mode;
int x, y;
uint8_t *dst;
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y);
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 34d1da7bd..14600e829 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -16,19 +16,19 @@
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem_ops.h"
+#include "vp9/common/vp9_entropy.h"
#include "vp9/common/vp9_entropymode.h"
#include "vp9/common/vp9_entropymv.h"
-#include "vp9/common/vp9_tile_common.h"
-#include "vp9/common/vp9_seg_common.h"
-#include "vp9/common/vp9_pred_common.h"
-#include "vp9/common/vp9_entropy.h"
#include "vp9/common/vp9_mvref_common.h"
-#include "vp9/common/vp9_systemdependent.h"
#include "vp9/common/vp9_pragmas.h"
+#include "vp9/common/vp9_pred_common.h"
+#include "vp9/common/vp9_seg_common.h"
+#include "vp9/common/vp9_systemdependent.h"
+#include "vp9/common/vp9_tile_common.h"
-#include "vp9/encoder/vp9_mcomp.h"
-#include "vp9/encoder/vp9_encodemv.h"
#include "vp9/encoder/vp9_bitstream.h"
+#include "vp9/encoder/vp9_encodemv.h"
+#include "vp9/encoder/vp9_mcomp.h"
#include "vp9/encoder/vp9_segmentation.h"
#include "vp9/encoder/vp9_subexp.h"
#include "vp9/encoder/vp9_tokenize.h"
@@ -62,8 +62,8 @@ static void write_inter_mode(vp9_writer *w, MB_PREDICTION_MODE mode,
&inter_mode_encodings[INTER_OFFSET(mode)]);
}
-void vp9_encode_unsigned_max(struct vp9_write_bit_buffer *wb,
- int data, int max) {
+static void encode_unsigned_max(struct vp9_write_bit_buffer *wb,
+ int data, int max) {
vp9_wb_write_literal(wb, data, get_unsigned_bits(max));
}
@@ -109,15 +109,14 @@ static int write_skip(const VP9_COMP *cpi, int segment_id, MODE_INFO *m,
}
}
-void vp9_update_skip_probs(VP9_COMMON *cm, vp9_writer *w) {
+static void update_skip_probs(VP9_COMMON *cm, vp9_writer *w) {
int k;
for (k = 0; k < SKIP_CONTEXTS; ++k)
vp9_cond_prob_diff_update(w, &cm->fc.skip_probs[k], cm->counts.skip[k]);
}
-static void update_switchable_interp_probs(VP9_COMP *cpi, vp9_writer *w) {
- VP9_COMMON *const cm = &cpi->common;
+static void update_switchable_interp_probs(VP9_COMMON *cm, vp9_writer *w) {
int j;
for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j)
prob_diff_update(vp9_switchable_interp_tree,
@@ -125,9 +124,8 @@ static void update_switchable_interp_probs(VP9_COMP *cpi, vp9_writer *w) {
cm->counts.switchable_interp[j], SWITCHABLE_FILTERS, w);
}
-static void pack_mb_tokens(vp9_writer* const w,
- TOKENEXTRA **tp,
- const TOKENEXTRA *const stop) {
+static void pack_mb_tokens(vp9_writer *w,
+ TOKENEXTRA **tp, const TOKENEXTRA *stop) {
TOKENEXTRA *p = *tp;
while (p < stop && p->token != EOSB_TOKEN) {
@@ -194,45 +192,40 @@ static void write_segment_id(vp9_writer *w, const struct segmentation *seg,
}
// This function encodes the reference frame
-static void encode_ref_frame(VP9_COMP *cpi, vp9_writer *bc) {
- VP9_COMMON *const cm = &cpi->common;
- MACROBLOCK *const x = &cpi->mb;
- MACROBLOCKD *const xd = &x->e_mbd;
- MB_MODE_INFO *mi = &xd->mi_8x8[0]->mbmi;
- const int segment_id = mi->segment_id;
- int seg_ref_active = vp9_segfeature_active(&cm->seg, segment_id,
- SEG_LVL_REF_FRAME);
+static void write_ref_frames(const VP9_COMP *cpi, vp9_writer *w) {
+ const VP9_COMMON *const cm = &cpi->common;
+ const MACROBLOCKD *const xd = &cpi->mb.e_mbd;
+ const MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
+ const int is_compound = has_second_ref(mbmi);
+ const int segment_id = mbmi->segment_id;
+
// If segment level coding of this signal is disabled...
// or the segment allows multiple reference frame options
- if (!seg_ref_active) {
+ if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
+ assert(!is_compound);
+ assert(mbmi->ref_frame[0] ==
+ vp9_get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME));
+ } else {
// does the feature use compound prediction or not
// (if not specified at the frame/segment level)
if (cm->reference_mode == REFERENCE_MODE_SELECT) {
- vp9_write(bc, mi->ref_frame[1] > INTRA_FRAME,
- vp9_get_reference_mode_prob(cm, xd));
+ vp9_write(w, is_compound, vp9_get_reference_mode_prob(cm, xd));
} else {
- assert((mi->ref_frame[1] <= INTRA_FRAME) ==
- (cm->reference_mode == SINGLE_REFERENCE));
+ assert(!is_compound == (cm->reference_mode == SINGLE_REFERENCE));
}
- if (mi->ref_frame[1] > INTRA_FRAME) {
- vp9_write(bc, mi->ref_frame[0] == GOLDEN_FRAME,
+ if (is_compound) {
+ vp9_write(w, mbmi->ref_frame[0] == GOLDEN_FRAME,
vp9_get_pred_prob_comp_ref_p(cm, xd));
} else {
- vp9_write(bc, mi->ref_frame[0] != LAST_FRAME,
- vp9_get_pred_prob_single_ref_p1(cm, xd));
- if (mi->ref_frame[0] != LAST_FRAME)
- vp9_write(bc, mi->ref_frame[0] != GOLDEN_FRAME,
- vp9_get_pred_prob_single_ref_p2(cm, xd));
+ const int bit0 = mbmi->ref_frame[0] != LAST_FRAME;
+ vp9_write(w, bit0, vp9_get_pred_prob_single_ref_p1(cm, xd));
+ if (bit0) {
+ const int bit1 = mbmi->ref_frame[0] != GOLDEN_FRAME;
+ vp9_write(w, bit1, vp9_get_pred_prob_single_ref_p2(cm, xd));
+ }
}
- } else {
- assert(mi->ref_frame[1] <= INTRA_FRAME);
- assert(vp9_get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME) ==
- mi->ref_frame[0]);
}
-
- // If using the prediction model we have nothing further to do because
- // the reference frame is fully coded by the segment.
}
static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc) {
@@ -241,7 +234,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc) {
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
const struct segmentation *const seg = &cm->seg;
- MB_MODE_INFO *const mi = &m->mbmi;
+ const MB_MODE_INFO *const mi = &m->mbmi;
const MV_REFERENCE_FRAME ref0 = mi->ref_frame[0];
const MV_REFERENCE_FRAME ref1 = mi->ref_frame[1];
const MB_PREDICTION_MODE mode = mi->mode;
@@ -298,7 +291,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc) {
write_intra_mode(bc, mi->uv_mode, cm->fc.uv_mode_prob[mode]);
} else {
vp9_prob *mv_ref_p;
- encode_ref_frame(cpi, bc);
+ write_ref_frames(cpi, bc);
mv_ref_p = cm->fc.inter_mode_probs[mi->mode_context[ref0]];
#ifdef ENTROPY_STATS
@@ -701,7 +694,7 @@ static void update_coef_probs_common(vp9_writer* const bc, VP9_COMP *cpi,
}
}
-static void update_coef_probs(VP9_COMP* cpi, vp9_writer* w) {
+static void update_coef_probs(VP9_COMP *cpi, vp9_writer* w) {
const TX_MODE tx_mode = cpi->common.tx_mode;
const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode];
TX_SIZE tx_size;
@@ -824,10 +817,10 @@ static void encode_segmentation(VP9_COMP *cpi,
const int data_max = vp9_seg_feature_data_max(j);
if (vp9_is_segfeature_signed(j)) {
- vp9_encode_unsigned_max(wb, abs(data), data_max);
+ encode_unsigned_max(wb, abs(data), data_max);
vp9_wb_write_bit(wb, data < 0);
} else {
- vp9_encode_unsigned_max(wb, data, data_max);
+ encode_unsigned_max(wb, data, data_max);
}
}
}
@@ -836,9 +829,7 @@ static void encode_segmentation(VP9_COMP *cpi,
}
-static void encode_txfm_probs(VP9_COMP *cpi, vp9_writer *w) {
- VP9_COMMON *const cm = &cpi->common;
-
+static void encode_txfm_probs(VP9_COMMON *cm, vp9_writer *w) {
// Mode
vp9_write_literal(w, MIN(cm->tx_mode, ALLOW_32X32), 2);
if (cm->tx_mode >= ALLOW_32X32)
@@ -1156,7 +1147,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
if (xd->lossless)
cm->tx_mode = ONLY_4X4;
else
- encode_txfm_probs(cpi, &header_bc);
+ encode_txfm_probs(cm, &header_bc);
update_coef_probs(cpi, &header_bc);
@@ -1164,7 +1155,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
active_section = 2;
#endif
- vp9_update_skip_probs(cm, &header_bc);
+ update_skip_probs(cm, &header_bc);
if (!frame_is_intra_only(cm)) {
int i;
@@ -1179,7 +1170,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
vp9_zero(cm->counts.inter_mode);
if (cm->interp_filter == SWITCHABLE)
- update_switchable_interp_probs(cpi, &header_bc);
+ update_switchable_interp_probs(cm, &header_bc);
for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
vp9_cond_prob_diff_update(&header_bc, &fc->intra_inter_prob[i],
diff --git a/vp9/encoder/vp9_bitstream.h b/vp9/encoder/vp9_bitstream.h
index 94bec8a43..ddfd0ed4f 100644
--- a/vp9/encoder/vp9_bitstream.h
+++ b/vp9/encoder/vp9_bitstream.h
@@ -16,7 +16,11 @@
extern "C" {
#endif
-void vp9_update_skip_probs(VP9_COMMON *cm, vp9_writer *bc);
+struct VP9_COMP;
+
+void vp9_entropy_mode_init();
+
+void vp9_pack_bitstream(struct VP9_COMP *cpi, uint8_t *dest, size_t *size);
#ifdef __cplusplus
} // extern "C"
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 57865138d..46072a2de 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -488,7 +488,7 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
if ((cpi->oxcf.aq_mode == VARIANCE_AQ) ||
(cpi->oxcf.aq_mode == COMPLEXITY_AQ)) {
- vp9_mb_init_quantizer(cpi, x);
+ vp9_init_plane_quantizers(cpi, x);
}
// FIXME(rbultje) I'm pretty sure this should go to the end of this block
@@ -539,10 +539,10 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
if (!frame_is_intra_only(cm)) {
if (is_inter_block(mbmi)) {
if (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV) {
- int_mv best_mv[2];
+ MV best_mv[2];
for (i = 0; i < 1 + has_second_ref(mbmi); ++i)
- best_mv[i].as_int = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_int;
- vp9_update_mv_count(cpi, x, best_mv);
+ best_mv[i] = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_mv;
+ vp9_update_mv_count(cm, xd, best_mv);
}
if (cm->interp_filter == SWITCHABLE) {
@@ -635,7 +635,7 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
: cm->last_frame_seg_map;
mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
}
- vp9_mb_init_quantizer(cpi, x);
+ vp9_init_plane_quantizers(cpi, x);
if (seg->enabled && cpi->seg0_cnt > 0 &&
!vp9_segfeature_active(seg, 0, SEG_LVL_REF_FRAME) &&
@@ -723,7 +723,7 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
}
rdmult_ratio = vp9_vaq_rdmult_ratio(energy);
- vp9_mb_init_quantizer(cpi, x);
+ vp9_init_plane_quantizers(cpi, x);
}
if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
@@ -1121,10 +1121,10 @@ static void update_state_rt(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
if (!frame_is_intra_only(cm)) {
if (is_inter_block(mbmi)) {
if (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV) {
- int_mv best_mv[2];
+ MV best_mv[2];
for (i = 0; i < 1 + has_second_ref(mbmi); ++i)
- best_mv[i].as_int = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_int;
- vp9_update_mv_count(cpi, x, best_mv);
+ best_mv[i] = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_mv;
+ vp9_update_mv_count(cm, xd, best_mv);
}
if (cm->interp_filter == SWITCHABLE) {
diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c
index 13eabe05d..513730e43 100644
--- a/vp9/encoder/vp9_encodemb.c
+++ b/vp9/encoder/vp9_encodemb.c
@@ -568,11 +568,7 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
case TX_4X4:
tx_type = get_tx_type_4x4(pd->plane_type, xd, block);
scan_order = &vp9_scan_orders[TX_4X4][tx_type];
- if (mbmi->sb_type < BLOCK_8X8 && plane == 0)
- mode = xd->mi_8x8[0]->bmi[block].as_mode;
- else
- mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
-
+ mode = plane == 0 ? get_y_mode(xd->mi_8x8[0], block) : mbmi->uv_mode;
vp9_predict_intra_block(xd, block, bwl, TX_4X4, mode,
x->skip_encode ? src : dst,
x->skip_encode ? src_stride : dst_stride,
diff --git a/vp9/encoder/vp9_encodemv.c b/vp9/encoder/vp9_encodemv.c
index be6abc2a1..507969951 100644
--- a/vp9/encoder/vp9_encodemv.c
+++ b/vp9/encoder/vp9_encodemv.c
@@ -231,21 +231,22 @@ void vp9_build_nmv_cost_table(int *mvjoint, int *mvcost[2],
build_nmv_component_cost_table(mvcost[1], &ctx->comps[1], usehp);
}
-static void inc_mvs(int_mv mv[2], int_mv ref[2], int is_compound,
+static void inc_mvs(const int_mv mv[2], const MV ref[2], int is_compound,
nmv_context_counts *counts) {
int i;
for (i = 0; i < 1 + is_compound; ++i) {
- const MV diff = { mv[i].as_mv.row - ref[i].as_mv.row,
- mv[i].as_mv.col - ref[i].as_mv.col };
+ const MV diff = { mv[i].as_mv.row - ref[i].row,
+ mv[i].as_mv.col - ref[i].col };
vp9_inc_mv(&diff, counts);
}
}
-void vp9_update_mv_count(VP9_COMP *cpi, MACROBLOCK *x, int_mv best_ref_mv[2]) {
- MODE_INFO *mi = x->e_mbd.mi_8x8[0];
- MB_MODE_INFO *const mbmi = &mi->mbmi;
+void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd,
+ const MV best_ref_mv[2]) {
+ const MODE_INFO *mi = xd->mi_8x8[0];
+ const MB_MODE_INFO *const mbmi = &mi->mbmi;
const int is_compound = has_second_ref(mbmi);
- nmv_context_counts *counts = &cpi->common.counts.mv;
+ nmv_context_counts *counts = &cm->counts.mv;
if (mbmi->sb_type < BLOCK_8X8) {
const int num_4x4_w = num_4x4_blocks_wide_lookup[mbmi->sb_type];
diff --git a/vp9/encoder/vp9_encodemv.h b/vp9/encoder/vp9_encodemv.h
index 7f997ff37..f16b2c17c 100644
--- a/vp9/encoder/vp9_encodemv.h
+++ b/vp9/encoder/vp9_encodemv.h
@@ -28,7 +28,8 @@ void vp9_encode_mv(VP9_COMP *cpi, vp9_writer* w, const MV* mv, const MV* ref,
void vp9_build_nmv_cost_table(int *mvjoint, int *mvcost[2],
const nmv_context* mvctx, int usehp);
-void vp9_update_mv_count(VP9_COMP *cpi, MACROBLOCK *x, int_mv best_ref_mv[2]);
+void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd,
+ const MV best_ref_mv[2]);
#ifdef __cplusplus
} // extern "C"
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 95ebb0c6d..3921ea8eb 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -27,6 +27,7 @@
#include "vp9/common/vp9_systemdependent.h"
#include "vp9/common/vp9_tile_common.h"
+#include "vp9/encoder/vp9_bitstream.h"
#include "vp9/encoder/vp9_encodemv.h"
#include "vp9/encoder/vp9_firstpass.h"
#include "vp9/encoder/vp9_mbgraph.h"
@@ -39,7 +40,6 @@
#include "vp9/encoder/vp9_vaq.h"
#include "vp9/encoder/vp9_resize.h"
-void vp9_entropy_mode_init();
void vp9_coef_tree_initialize();
#define DEFAULT_INTERP_FILTER SWITCHABLE
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index fd2356591..c4b018ad7 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -714,8 +714,6 @@ static YV12_BUFFER_CONFIG *get_ref_frame_buffer(VP9_COMP *cpi,
void vp9_encode_frame(VP9_COMP *cpi);
-void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, size_t *size);
-
void vp9_set_speed_features(VP9_COMP *cpi);
int vp9_calc_ss_err(const YV12_BUFFER_CONFIG *source,
diff --git a/vp9/encoder/vp9_quantize.c b/vp9/encoder/vp9_quantize.c
index 372c36221..f68aba43f 100644
--- a/vp9/encoder/vp9_quantize.c
+++ b/vp9/encoder/vp9_quantize.c
@@ -9,13 +9,14 @@
*/
#include <math.h>
+
#include "vpx_mem/vpx_mem.h"
#include "vp9/encoder/vp9_onyx_int.h"
-#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_quantize.h"
-#include "vp9/common/vp9_quant_common.h"
+#include "vp9/encoder/vp9_rdopt.h"
+#include "vp9/common/vp9_quant_common.h"
#include "vp9/common/vp9_seg_common.h"
void vp9_quantize_b_c(const int16_t *coeff_ptr, intptr_t count,
@@ -151,44 +152,40 @@ static void invert_quant(int16_t *quant, int16_t *shift, int d) {
}
void vp9_init_quantizer(VP9_COMP *cpi) {
- int i, q;
VP9_COMMON *const cm = &cpi->common;
+ int i, q, quant;
for (q = 0; q < QINDEX_RANGE; q++) {
const int qzbin_factor = q == 0 ? 64 : (vp9_dc_quant(q, 0) < 148 ? 84 : 80);
const int qrounding_factor = q == 0 ? 64 : 48;
- // y
for (i = 0; i < 2; ++i) {
- const int quant = i == 0 ? vp9_dc_quant(q, cm->y_dc_delta_q)
- : vp9_ac_quant(q, 0);
+ // y
+ quant = i == 0 ? vp9_dc_quant(q, cm->y_dc_delta_q)
+ : vp9_ac_quant(q, 0);
invert_quant(&cpi->y_quant[q][i], &cpi->y_quant_shift[q][i], quant);
cpi->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7);
cpi->y_round[q][i] = (qrounding_factor * quant) >> 7;
cm->y_dequant[q][i] = quant;
- }
- // uv
- for (i = 0; i < 2; ++i) {
- const int quant = i == 0 ? vp9_dc_quant(q, cm->uv_dc_delta_q)
- : vp9_ac_quant(q, cm->uv_ac_delta_q);
+ // uv
+ quant = i == 0 ? vp9_dc_quant(q, cm->uv_dc_delta_q)
+ : vp9_ac_quant(q, cm->uv_ac_delta_q);
invert_quant(&cpi->uv_quant[q][i], &cpi->uv_quant_shift[q][i], quant);
cpi->uv_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7);
cpi->uv_round[q][i] = (qrounding_factor * quant) >> 7;
cm->uv_dequant[q][i] = quant;
- }
#if CONFIG_ALPHA
- // alpha
- for (i = 0; i < 2; ++i) {
- const int quant = i == 0 ? vp9_dc_quant(q, cm->a_dc_delta_q)
- : vp9_ac_quant(q, cm->a_ac_delta_q);
+ // alpha
+ quant = i == 0 ? vp9_dc_quant(q, cm->a_dc_delta_q)
+ : vp9_ac_quant(q, cm->a_ac_delta_q);
invert_quant(&cpi->a_quant[q][i], &cpi->a_quant_shift[q][i], quant);
cpi->a_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7);
cpi->a_round[q][i] = (qrounding_factor * quant) >> 7;
cm->a_dequant[q][i] = quant;
- }
#endif
+ }
for (i = 2; i < 8; i++) {
cpi->y_quant[q][i] = cpi->y_quant[q][1];
@@ -214,7 +211,7 @@ void vp9_init_quantizer(VP9_COMP *cpi) {
}
}
-void vp9_mb_init_quantizer(VP9_COMP *cpi, MACROBLOCK *x) {
+void vp9_init_plane_quantizers(VP9_COMP *cpi, MACROBLOCK *x) {
const VP9_COMMON *const cm = &cpi->common;
MACROBLOCKD *xd = &x->e_mbd;
const int segment_id = xd->mi_8x8[0]->mbmi.segment_id;
@@ -246,7 +243,7 @@ void vp9_mb_init_quantizer(VP9_COMP *cpi, MACROBLOCK *x) {
x->plane[3].quant_shift = cpi->a_quant_shift[qindex];
x->plane[3].zbin = cpi->a_zbin[qindex];
x->plane[3].round = cpi->a_round[qindex];
- x->plane[3].zbin_extra = (int16_t)zbin_extra;
+ x->plane[3].zbin_extra = (int16_t)((cm->a_dequant[qindex][1] * zbin) >> 7);
xd->plane[3].dequant = cm->a_dequant[qindex];
#endif
@@ -272,26 +269,17 @@ void vp9_update_zbin_extra(VP9_COMP *cpi, MACROBLOCK *x) {
}
void vp9_frame_init_quantizer(VP9_COMP *cpi) {
- // Clear Zbin mode boost for default case
cpi->zbin_mode_boost = 0;
-
- // MB level quantizer setup
- vp9_mb_init_quantizer(cpi, &cpi->mb);
+ vp9_init_plane_quantizers(cpi, &cpi->mb);
}
void vp9_set_quantizer(struct VP9_COMP *cpi, int q) {
- VP9_COMMON *cm = &cpi->common;
+ VP9_COMMON *const cm = &cpi->common;
+ // quantizer has to be reinitialized with vp9_init_quantizer() if any
+ // delta_q changes.
cm->base_qindex = q;
-
- // if any of the delta_q values are changing update flag will
- // have to be set.
cm->y_dc_delta_q = 0;
cm->uv_dc_delta_q = 0;
cm->uv_ac_delta_q = 0;
-
- // quantizer has to be reinitialized if any delta_q changes.
- // As there are not any here for now this is inactive code.
- // if(update)
- // vp9_init_quantizer(cpi);
}
diff --git a/vp9/encoder/vp9_quantize.h b/vp9/encoder/vp9_quantize.h
index 680cf4aec..f356b125c 100644
--- a/vp9/encoder/vp9_quantize.h
+++ b/vp9/encoder/vp9_quantize.h
@@ -28,7 +28,7 @@ void vp9_frame_init_quantizer(struct VP9_COMP *cpi);
void vp9_update_zbin_extra(struct VP9_COMP *cpi, MACROBLOCK *x);
-void vp9_mb_init_quantizer(struct VP9_COMP *cpi, MACROBLOCK *x);
+void vp9_init_plane_quantizers(struct VP9_COMP *cpi, MACROBLOCK *x);
void vp9_init_quantizer(struct VP9_COMP *cpi);
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index f7577e174..b57b94806 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -36,6 +36,7 @@
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_mvref_common.h"
#include "vp9/common/vp9_common.h"
+#include "vp9/common/vp9_idct.h"
/* Factor to weigh the rate for switchable interp filters */
#define SWITCHABLE_INTERP_RATE_FACTOR 1
@@ -272,18 +273,12 @@ static void set_block_thresholds(VP9_COMP *cpi) {
void vp9_initialize_rd_consts(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
MACROBLOCK *x = &cpi->mb;
- int qindex, i;
+ int i;
vp9_clear_system_state();
- // Further tests required to see if optimum is different
- // for key frames, golden frames and arf frames.
- // if (cpi->common.refresh_golden_frame ||
- // cpi->common.refresh_alt_ref_frame)
- qindex = clamp(cm->base_qindex + cm->y_dc_delta_q, 0, MAXQ);
-
cpi->RDDIV = RDDIV_BITS; // in bits (to multiply D by 128)
- cpi->RDMULT = vp9_compute_rd_mult(cpi, qindex);
+ cpi->RDMULT = vp9_compute_rd_mult(cpi, cm->base_qindex + cm->y_dc_delta_q);
x->errorperbit = cpi->RDMULT / RD_MULT_EPB_RATIO;
x->errorperbit += (x->errorperbit == 0);
@@ -525,15 +520,15 @@ static void model_rd_for_sb_y_tx(VP9_COMP *cpi, BLOCK_SIZE bsize,
*out_dist_sum = dist_sum << 4;
}
-int64_t vp9_block_error_c(int16_t *coeff, int16_t *dqcoeff,
+int64_t vp9_block_error_c(const int16_t *coeff, const int16_t *dqcoeff,
intptr_t block_size, int64_t *ssz) {
int i;
int64_t error = 0, sqcoeff = 0;
for (i = 0; i < block_size; i++) {
- int this_diff = coeff[i] - dqcoeff[i];
- error += (unsigned)this_diff * this_diff;
- sqcoeff += (unsigned) coeff[i] * coeff[i];
+ const int diff = coeff[i] - dqcoeff[i];
+ error += diff * diff;
+ sqcoeff += coeff[i] * coeff[i];
}
*ssz = sqcoeff;
@@ -1037,10 +1032,9 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
int64_t *bestdistortion,
BLOCK_SIZE bsize, int64_t rd_thresh) {
MB_PREDICTION_MODE mode;
- MACROBLOCKD *xd = &x->e_mbd;
+ MACROBLOCKD *const xd = &x->e_mbd;
int64_t best_rd = rd_thresh;
- int rate = 0;
- int64_t distortion;
+
struct macroblock_plane *p = &x->plane[0];
struct macroblockd_plane *pd = &xd->plane[0];
const int src_stride = p->src.stride;
@@ -1049,8 +1043,6 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
src_stride)];
uint8_t *dst_init = &pd->dst.buf[raster_block_offset(BLOCK_8X8, ib,
dst_stride)];
- int16_t *src_diff, *coeff;
-
ENTROPY_CONTEXT ta[2], tempa[2];
ENTROPY_CONTEXT tl[2], templ[2];
@@ -1068,6 +1060,8 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
int64_t this_rd;
int ratey = 0;
+ int64_t distortion = 0;
+ int rate = bmode_costs[mode];
if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
continue;
@@ -1079,55 +1073,50 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
continue;
}
- rate = bmode_costs[mode];
- distortion = 0;
-
vpx_memcpy(tempa, ta, sizeof(ta));
vpx_memcpy(templ, tl, sizeof(tl));
for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
- int64_t ssz;
- const scan_order *so;
- const uint8_t *src = src_init + idx * 4 + idy * 4 * src_stride;
- uint8_t *dst = dst_init + idx * 4 + idy * 4 * dst_stride;
const int block = ib + idy * 2 + idx;
- TX_TYPE tx_type;
+ const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
+ uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
+ int16_t *const src_diff = raster_block_offset_int16(BLOCK_8X8, block,
+ p->src_diff);
+ int16_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
xd->mi_8x8[0]->bmi[block].as_mode = mode;
- src_diff = raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
- coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
vp9_predict_intra_block(xd, block, 1,
TX_4X4, mode,
x->skip_encode ? src : dst,
x->skip_encode ? src_stride : dst_stride,
dst, dst_stride, idx, idy, 0);
- vp9_subtract_block(4, 4, src_diff, 8,
- src, src_stride,
- dst, dst_stride);
-
- tx_type = get_tx_type_4x4(PLANE_TYPE_Y, xd, block);
- so = &vp9_scan_orders[TX_4X4][tx_type];
-
- if (tx_type != DCT_DCT)
+ vp9_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride);
+
+ if (xd->lossless) {
+ const scan_order *so = &vp9_default_scan_orders[TX_4X4];
+ vp9_fwht4x4(src_diff, coeff, 8);
+ vp9_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
+ ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy, TX_4X4,
+ so->scan, so->neighbors);
+ if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
+ goto next;
+ vp9_iwht4x4_add(BLOCK_OFFSET(pd->dqcoeff, block), dst, dst_stride,
+ p->eobs[block]);
+ } else {
+ int64_t unused;
+ const TX_TYPE tx_type = get_tx_type_4x4(PLANE_TYPE_Y, xd, block);
+ const scan_order *so = &vp9_scan_orders[TX_4X4][tx_type];
vp9_fht4x4(src_diff, coeff, 8, tx_type);
- else
- x->fwd_txm4x4(src_diff, coeff, 8);
-
- vp9_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
-
- ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy, TX_4X4,
- so->scan, so->neighbors);
- distortion += vp9_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, block),
- 16, &ssz) >> 2;
- if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
- goto next;
-
- if (tx_type != DCT_DCT)
- vp9_iht4x4_16_add(BLOCK_OFFSET(pd->dqcoeff, block),
- dst, pd->dst.stride, tx_type);
- else
- xd->itxm_add(BLOCK_OFFSET(pd->dqcoeff, block), dst, pd->dst.stride,
- 16);
+ vp9_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
+ ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy, TX_4X4,
+ so->scan, so->neighbors);
+ distortion += vp9_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, block),
+ 16, &unused) >> 2;
+ if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
+ goto next;
+ vp9_iht4x4_add(tx_type, BLOCK_OFFSET(pd->dqcoeff, block),
+ dst, dst_stride, p->eobs[block]);
+ }
}
}
diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c
index 7ae110707..e8179f302 100644
--- a/vp9/encoder/vp9_tokenize.c
+++ b/vp9/encoder/vp9_tokenize.c
@@ -199,6 +199,12 @@ static INLINE void add_token_no_extra(TOKENEXTRA **t,
++counts[token];
}
+static INLINE int get_tx_eob(const struct segmentation *seg, int segment_id,
+ TX_SIZE tx_size) {
+ const int eob_max = 16 << (tx_size << 1);
+ return vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
+}
+
static void tokenize_b(int plane, int block, BLOCK_SIZE plane_bsize,
TX_SIZE tx_size, void *arg) {
struct tokenize_b_args* const args = arg;
diff --git a/vpx/src/svc_encodeframe.c b/vpx/src/svc_encodeframe.c
index 5537fb508..c7837244f 100644
--- a/vpx/src/svc_encodeframe.c
+++ b/vpx/src/svc_encodeframe.c
@@ -548,15 +548,20 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
for (i = 0; i < si->layers; ++i) {
int pos = i + VPX_SS_MAX_LAYERS - svc_ctx->spatial_layers;
- alloc_ratio[i] = si->scaling_factor_num[pos] * 1.0 /
- si->scaling_factor_den[pos];
- alloc_ratio[i] *= alloc_ratio[i];
- total += alloc_ratio[i];
+ if (pos < VPX_SS_MAX_LAYERS && si->scaling_factor_den[pos] > 0) {
+ alloc_ratio[i] = (float)(si->scaling_factor_num[pos] * 1.0 /
+ si->scaling_factor_den[pos]);
+
+ alloc_ratio[i] *= alloc_ratio[i];
+ total += alloc_ratio[i];
+ }
}
for (i = 0; i < si->layers; ++i) {
- enc_cfg->ss_target_bitrate[i] = enc_cfg->rc_target_bitrate *
- alloc_ratio[i] / total;
+ if (total > 0) {
+ enc_cfg->ss_target_bitrate[i] = (unsigned int)
+ (enc_cfg->rc_target_bitrate * alloc_ratio[i] / total);
+ }
}
}
diff --git a/vpx/src/vpx_encoder.c b/vpx/src/vpx_encoder.c
index 23742c8e8..e69d96efb 100644
--- a/vpx/src/vpx_encoder.c
+++ b/vpx/src/vpx_encoder.c
@@ -255,8 +255,8 @@ vpx_codec_err_t vpx_codec_encode(vpx_codec_ctx_t *ctx,
}
-const vpx_codec_cx_pkt_t *vpx_codec_get_cx_data(vpx_codec_ctx_t *ctx,
- vpx_codec_iter_t *iter) {
+const vpx_codec_cx_pkt_t *vpx_codec_get_cx_data(vpx_codec_ctx_t *ctx,
+ vpx_codec_iter_t *iter) {
const vpx_codec_cx_pkt_t *pkt = NULL;
if (ctx) {
@@ -271,32 +271,30 @@ const vpx_codec_cx_pkt_t *vpx_codec_get_cx_data(vpx_codec_ctx_t *ctx,
}
if (pkt && pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
- /* If the application has specified a destination area for the
- * compressed data, and the codec has not placed the data there,
- * and it fits, copy it.
- */
- char *dst_buf = ctx->priv->enc.cx_data_dst_buf.buf;
-
- if (dst_buf
- && pkt->data.raw.buf != dst_buf
- && pkt->data.raw.sz
- + ctx->priv->enc.cx_data_pad_before
- + ctx->priv->enc.cx_data_pad_after
- <= ctx->priv->enc.cx_data_dst_buf.sz) {
- vpx_codec_cx_pkt_t *modified_pkt = &ctx->priv->enc.cx_data_pkt;
-
- memcpy(dst_buf + ctx->priv->enc.cx_data_pad_before,
- pkt->data.raw.buf, pkt->data.raw.sz);
+ // If the application has specified a destination area for the
+ // compressed data, and the codec has not placed the data there,
+ // and it fits, copy it.
+ vpx_codec_priv_t *const priv = ctx->priv;
+ char *const dst_buf = (char *)priv->enc.cx_data_dst_buf.buf;
+
+ if (dst_buf &&
+ pkt->data.raw.buf != dst_buf &&
+ pkt->data.raw.sz + priv->enc.cx_data_pad_before +
+ priv->enc.cx_data_pad_after <= priv->enc.cx_data_dst_buf.sz) {
+ vpx_codec_cx_pkt_t *modified_pkt = &priv->enc.cx_data_pkt;
+
+ memcpy(dst_buf + priv->enc.cx_data_pad_before, pkt->data.raw.buf,
+ pkt->data.raw.sz);
*modified_pkt = *pkt;
modified_pkt->data.raw.buf = dst_buf;
- modified_pkt->data.raw.sz += ctx->priv->enc.cx_data_pad_before
- + ctx->priv->enc.cx_data_pad_after;
+ modified_pkt->data.raw.sz += priv->enc.cx_data_pad_before +
+ priv->enc.cx_data_pad_after;
pkt = modified_pkt;
}
if (dst_buf == pkt->data.raw.buf) {
- ctx->priv->enc.cx_data_dst_buf.buf = dst_buf + pkt->data.raw.sz;
- ctx->priv->enc.cx_data_dst_buf.sz -= pkt->data.raw.sz;
+ priv->enc.cx_data_dst_buf.buf = dst_buf + pkt->data.raw.sz;
+ priv->enc.cx_data_dst_buf.sz -= pkt->data.raw.sz;
}
}