Commit bafadaaf authored by Ronald S. Bultje's avatar Ronald S. Bultje Committed by Gerrit Code Review

Merge "vp10: per-segment lossless coding."

parents 92c4d814 60c58b52
...@@ -211,7 +211,7 @@ typedef struct macroblockd { ...@@ -211,7 +211,7 @@ typedef struct macroblockd {
int bd; int bd;
#endif #endif
int lossless; int lossless[MAX_SEGMENTS];
int corrupted; int corrupted;
struct vpx_internal_error_info *error_info; struct vpx_internal_error_info *error_info;
...@@ -240,8 +240,8 @@ static INLINE TX_TYPE get_tx_type(PLANE_TYPE plane_type, const MACROBLOCKD *xd, ...@@ -240,8 +240,8 @@ static INLINE TX_TYPE get_tx_type(PLANE_TYPE plane_type, const MACROBLOCKD *xd,
const MODE_INFO *const mi = xd->mi[0]; const MODE_INFO *const mi = xd->mi[0];
const MB_MODE_INFO *const mbmi = &mi->mbmi; 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[mbmi->segment_id] ||
mbmi->tx_size >= TX_32X32) is_inter_block(mbmi) || mbmi->tx_size >= TX_32X32)
return DCT_DCT; return DCT_DCT;
return intra_mode_to_tx_type_lookup[get_y_mode(mi, block_idx)]; return intra_mode_to_tx_type_lookup[get_y_mode(mi, block_idx)];
......
...@@ -213,6 +213,7 @@ static void inverse_transform_block_inter(MACROBLOCKD* xd, int plane, ...@@ -213,6 +213,7 @@ static void inverse_transform_block_inter(MACROBLOCKD* xd, int plane,
int eob, int block) { int eob, int block) {
struct macroblockd_plane *const pd = &xd->plane[plane]; struct macroblockd_plane *const pd = &xd->plane[plane];
TX_TYPE tx_type = get_tx_type(pd->plane_type, xd, block); TX_TYPE tx_type = get_tx_type(pd->plane_type, xd, block);
const int seg_id = xd->mi[0]->mbmi.segment_id;
if (eob > 0) { if (eob > 0) {
tran_low_t *const dqcoeff = pd->dqcoeff; tran_low_t *const dqcoeff = pd->dqcoeff;
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
...@@ -220,7 +221,7 @@ static void inverse_transform_block_inter(MACROBLOCKD* xd, int plane, ...@@ -220,7 +221,7 @@ static void inverse_transform_block_inter(MACROBLOCKD* xd, int plane,
switch (tx_size) { switch (tx_size) {
case TX_4X4: case TX_4X4:
vp10_highbd_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, xd->bd, vp10_highbd_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, xd->bd,
tx_type, xd->lossless); tx_type, xd->lossless[seg_id]);
break; break;
case TX_8X8: case TX_8X8:
vp10_highbd_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, xd->bd, vp10_highbd_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, xd->bd,
...@@ -243,7 +244,7 @@ static void inverse_transform_block_inter(MACROBLOCKD* xd, int plane, ...@@ -243,7 +244,7 @@ static void inverse_transform_block_inter(MACROBLOCKD* xd, int plane,
switch (tx_size) { switch (tx_size) {
case TX_4X4: case TX_4X4:
vp10_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, tx_type, vp10_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, tx_type,
xd->lossless); xd->lossless[seg_id]);
break; break;
case TX_8X8: case TX_8X8:
vp10_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, tx_type); vp10_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, tx_type);
...@@ -281,6 +282,7 @@ static void inverse_transform_block_intra(MACROBLOCKD* xd, int plane, ...@@ -281,6 +282,7 @@ static void inverse_transform_block_intra(MACROBLOCKD* xd, int plane,
uint8_t *dst, int stride, uint8_t *dst, int stride,
int eob) { int eob) {
struct macroblockd_plane *const pd = &xd->plane[plane]; struct macroblockd_plane *const pd = &xd->plane[plane];
const int seg_id = xd->mi[0]->mbmi.segment_id;
if (eob > 0) { if (eob > 0) {
tran_low_t *const dqcoeff = pd->dqcoeff; tran_low_t *const dqcoeff = pd->dqcoeff;
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
...@@ -288,7 +290,7 @@ static void inverse_transform_block_intra(MACROBLOCKD* xd, int plane, ...@@ -288,7 +290,7 @@ static void inverse_transform_block_intra(MACROBLOCKD* xd, int plane,
switch (tx_size) { switch (tx_size) {
case TX_4X4: case TX_4X4:
vp10_highbd_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, xd->bd, vp10_highbd_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, xd->bd,
tx_type, xd->lossless); tx_type, xd->lossless[seg_id]);
break; break;
case TX_8X8: case TX_8X8:
vp10_highbd_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, xd->bd, vp10_highbd_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, xd->bd,
...@@ -311,7 +313,7 @@ static void inverse_transform_block_intra(MACROBLOCKD* xd, int plane, ...@@ -311,7 +313,7 @@ static void inverse_transform_block_intra(MACROBLOCKD* xd, int plane,
switch (tx_size) { switch (tx_size) {
case TX_4X4: case TX_4X4:
vp10_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, tx_type, vp10_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, tx_type,
xd->lossless); xd->lossless[seg_id]);
break; break;
case TX_8X8: case TX_8X8:
vp10_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, tx_type); vp10_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, tx_type);
...@@ -1144,15 +1146,26 @@ static INLINE int read_delta_q(struct vpx_read_bit_buffer *rb) { ...@@ -1144,15 +1146,26 @@ static INLINE int read_delta_q(struct vpx_read_bit_buffer *rb) {
static void setup_quantization(VP10_COMMON *const cm, MACROBLOCKD *const xd, static void setup_quantization(VP10_COMMON *const cm, MACROBLOCKD *const xd,
struct vpx_read_bit_buffer *rb) { struct vpx_read_bit_buffer *rb) {
int i;
cm->base_qindex = vpx_rb_read_literal(rb, QINDEX_BITS); cm->base_qindex = vpx_rb_read_literal(rb, QINDEX_BITS);
cm->y_dc_delta_q = read_delta_q(rb); cm->y_dc_delta_q = read_delta_q(rb);
cm->uv_dc_delta_q = read_delta_q(rb); cm->uv_dc_delta_q = read_delta_q(rb);
cm->uv_ac_delta_q = read_delta_q(rb); cm->uv_ac_delta_q = read_delta_q(rb);
cm->dequant_bit_depth = cm->bit_depth; cm->dequant_bit_depth = cm->bit_depth;
xd->lossless = cm->base_qindex == 0 && for (i = 0; i < (cm->seg.enabled ? MAX_SEGMENTS : 1); ++i) {
cm->y_dc_delta_q == 0 && #if CONFIG_MISC_FIXES
cm->uv_dc_delta_q == 0 && const int qindex = vp10_get_qindex(&cm->seg, i, cm->base_qindex);
cm->uv_ac_delta_q == 0; #endif
xd->lossless[i] = cm->y_dc_delta_q == 0 &&
#if CONFIG_MISC_FIXES
qindex == 0 &&
#else
cm->base_qindex == 0 &&
#endif
cm->uv_dc_delta_q == 0 &&
cm->uv_ac_delta_q == 0;
}
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
xd->bd = (int)cm->bit_depth; xd->bd = (int)cm->bit_depth;
...@@ -2098,7 +2111,8 @@ static size_t read_uncompressed_header(VP10Decoder *pbi, ...@@ -2098,7 +2111,8 @@ static size_t read_uncompressed_header(VP10Decoder *pbi,
setup_segmentation(cm, rb); setup_segmentation(cm, rb);
setup_segmentation_dequant(cm); setup_segmentation_dequant(cm);
#if CONFIG_MISC_FIXES #if CONFIG_MISC_FIXES
cm->tx_mode = xd->lossless ? ONLY_4X4 : read_tx_mode(rb); cm->tx_mode = (!cm->seg.enabled && xd->lossless[0]) ? ONLY_4X4
: read_tx_mode(rb);
cm->reference_mode = read_frame_reference_mode(cm, rb); cm->reference_mode = read_frame_reference_mode(cm, rb);
#endif #endif
...@@ -2128,7 +2142,7 @@ static int read_compressed_header(VP10Decoder *pbi, const uint8_t *data, ...@@ -2128,7 +2142,7 @@ static int read_compressed_header(VP10Decoder *pbi, const uint8_t *data,
"Failed to allocate bool decoder 0"); "Failed to allocate bool decoder 0");
#if !CONFIG_MISC_FIXES #if !CONFIG_MISC_FIXES
cm->tx_mode = xd->lossless ? ONLY_4X4 : read_tx_mode(&r); cm->tx_mode = xd->lossless[0] ? ONLY_4X4 : read_tx_mode(&r);
#endif #endif
if (cm->tx_mode == TX_MODE_SELECT) if (cm->tx_mode == TX_MODE_SELECT)
read_tx_mode_probs(&fc->tx_probs, &r); read_tx_mode_probs(&fc->tx_probs, &r);
......
...@@ -1326,7 +1326,7 @@ static void write_uncompressed_header(VP10_COMP *cpi, ...@@ -1326,7 +1326,7 @@ static void write_uncompressed_header(VP10_COMP *cpi,
encode_quantization(cm, wb); encode_quantization(cm, wb);
encode_segmentation(cm, xd, wb); encode_segmentation(cm, xd, wb);
#if CONFIG_MISC_FIXES #if CONFIG_MISC_FIXES
if (xd->lossless) if (!cm->seg.enabled && xd->lossless[0])
cm->tx_mode = TX_4X4; cm->tx_mode = TX_4X4;
else else
write_txfm_mode(cm->tx_mode, wb); write_txfm_mode(cm->tx_mode, wb);
...@@ -1356,7 +1356,7 @@ static size_t write_compressed_header(VP10_COMP *cpi, uint8_t *data) { ...@@ -1356,7 +1356,7 @@ static size_t write_compressed_header(VP10_COMP *cpi, uint8_t *data) {
vpx_start_encode(&header_bc, data); vpx_start_encode(&header_bc, data);
#if !CONFIG_MISC_FIXES #if !CONFIG_MISC_FIXES
if (cpi->td.mb.e_mbd.lossless) if (cpi->td.mb.e_mbd.lossless[0])
cm->tx_mode = TX_4X4; cm->tx_mode = TX_4X4;
else else
update_txfm_probs(cm, &header_bc, counts); update_txfm_probs(cm, &header_bc, counts);
......
...@@ -2203,7 +2203,7 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td, ...@@ -2203,7 +2203,7 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td,
// terminated for current branch of the partition search tree. // terminated for current branch of the partition search tree.
// The dist & rate thresholds are set to 0 at speed 0 to disable the // The dist & rate thresholds are set to 0 at speed 0 to disable the
// early termination at that speed. // early termination at that speed.
if (!x->e_mbd.lossless && if (!x->e_mbd.lossless[xd->mi[0]->mbmi.segment_id] &&
(ctx->skippable && best_rdc.dist < dist_breakout_thr && (ctx->skippable && best_rdc.dist < dist_breakout_thr &&
best_rdc.rate < rate_breakout_thr)) { best_rdc.rate < rate_breakout_thr)) {
do_split = 0; do_split = 0;
...@@ -2588,7 +2588,7 @@ static MV_REFERENCE_FRAME get_frame_type(const VP10_COMP *cpi) { ...@@ -2588,7 +2588,7 @@ static MV_REFERENCE_FRAME get_frame_type(const VP10_COMP *cpi) {
} }
static TX_MODE select_tx_mode(const VP10_COMP *cpi, MACROBLOCKD *const xd) { static TX_MODE select_tx_mode(const VP10_COMP *cpi, MACROBLOCKD *const xd) {
if (xd->lossless) if (!cpi->common.seg.enabled && xd->lossless[0])
return ONLY_4X4; return ONLY_4X4;
if (cpi->sf.tx_size_search_method == USE_LARGESTALL) if (cpi->sf.tx_size_search_method == USE_LARGESTALL)
return ALLOW_32X32; return ALLOW_32X32;
...@@ -2695,6 +2695,7 @@ static void encode_frame_internal(VP10_COMP *cpi) { ...@@ -2695,6 +2695,7 @@ static void encode_frame_internal(VP10_COMP *cpi) {
VP10_COMMON *const cm = &cpi->common; VP10_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &x->e_mbd; MACROBLOCKD *const xd = &x->e_mbd;
RD_COUNTS *const rdc = &cpi->td.rd_counts; RD_COUNTS *const rdc = &cpi->td.rd_counts;
int i;
xd->mi = cm->mi_grid_visible; xd->mi = cm->mi_grid_visible;
xd->mi[0] = cm->mi; xd->mi[0] = cm->mi;
...@@ -2704,12 +2705,21 @@ static void encode_frame_internal(VP10_COMP *cpi) { ...@@ -2704,12 +2705,21 @@ static void encode_frame_internal(VP10_COMP *cpi) {
vp10_zero(rdc->comp_pred_diff); vp10_zero(rdc->comp_pred_diff);
vp10_zero(rdc->filter_diff); vp10_zero(rdc->filter_diff);
xd->lossless = cm->base_qindex == 0 && for (i = 0; i < (cm->seg.enabled ? MAX_SEGMENTS : 1); ++i) {
cm->y_dc_delta_q == 0 && #if CONFIG_MISC_FIXES
cm->uv_dc_delta_q == 0 && const int qindex = vp10_get_qindex(&cm->seg, i, cm->base_qindex);
cm->uv_ac_delta_q == 0; #endif
xd->lossless[i] = cm->y_dc_delta_q == 0 &&
#if CONFIG_MISC_FIXES
qindex == 0 &&
#else
cm->base_qindex == 0 &&
#endif
cm->uv_dc_delta_q == 0 &&
cm->uv_ac_delta_q == 0;
}
if (xd->lossless) if (!cm->seg.enabled && xd->lossless[0])
x->optimize = 0; x->optimize = 0;
cm->tx_mode = select_tx_mode(cpi, xd); cm->tx_mode = select_tx_mode(cpi, xd);
......
...@@ -367,7 +367,7 @@ void vp10_xform_quant_fp(MACROBLOCK *x, int plane, int block, ...@@ -367,7 +367,7 @@ void vp10_xform_quant_fp(MACROBLOCK *x, int plane, int block,
scan_order->scan, scan_order->iscan); scan_order->scan, scan_order->iscan);
break; break;
case TX_4X4: case TX_4X4:
if (xd->lossless) { if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
vp10_highbd_fwht4x4(src_diff, coeff, diff_stride); vp10_highbd_fwht4x4(src_diff, coeff, diff_stride);
} else { } else {
vpx_highbd_fdct4x4(src_diff, coeff, diff_stride); vpx_highbd_fdct4x4(src_diff, coeff, diff_stride);
...@@ -407,7 +407,7 @@ void vp10_xform_quant_fp(MACROBLOCK *x, int plane, int block, ...@@ -407,7 +407,7 @@ void vp10_xform_quant_fp(MACROBLOCK *x, int plane, int block,
scan_order->scan, scan_order->iscan); scan_order->scan, scan_order->iscan);
break; break;
case TX_4X4: case TX_4X4:
if (xd->lossless) { if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
vp10_fwht4x4(src_diff, coeff, diff_stride); vp10_fwht4x4(src_diff, coeff, diff_stride);
} else { } else {
vpx_fdct4x4(src_diff, coeff, diff_stride); vpx_fdct4x4(src_diff, coeff, diff_stride);
...@@ -461,7 +461,7 @@ void vp10_xform_quant_dc(MACROBLOCK *x, int plane, int block, ...@@ -461,7 +461,7 @@ void vp10_xform_quant_dc(MACROBLOCK *x, int plane, int block,
pd->dequant[0], eob); pd->dequant[0], eob);
break; break;
case TX_4X4: case TX_4X4:
if (xd->lossless) { if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
vp10_highbd_fwht4x4(src_diff, coeff, diff_stride); vp10_highbd_fwht4x4(src_diff, coeff, diff_stride);
} else { } else {
vpx_highbd_fdct4x4(src_diff, coeff, diff_stride); vpx_highbd_fdct4x4(src_diff, coeff, diff_stride);
...@@ -497,7 +497,7 @@ void vp10_xform_quant_dc(MACROBLOCK *x, int plane, int block, ...@@ -497,7 +497,7 @@ void vp10_xform_quant_dc(MACROBLOCK *x, int plane, int block,
pd->dequant[0], eob); pd->dequant[0], eob);
break; break;
case TX_4X4: case TX_4X4:
if (xd->lossless) { if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
vp10_fwht4x4(src_diff, coeff, diff_stride); vp10_fwht4x4(src_diff, coeff, diff_stride);
} else { } else {
vpx_fdct4x4(src_diff, coeff, diff_stride); vpx_fdct4x4(src_diff, coeff, diff_stride);
...@@ -702,7 +702,7 @@ void vp10_xform_quant(MACROBLOCK *x, int plane, int block, ...@@ -702,7 +702,7 @@ void vp10_xform_quant(MACROBLOCK *x, int plane, int block,
break; break;
case TX_4X4: case TX_4X4:
vp10_highbd_fwd_txfm_4x4(src_diff, coeff, diff_stride, tx_type, vp10_highbd_fwd_txfm_4x4(src_diff, coeff, diff_stride, tx_type,
xd->lossless); xd->lossless[xd->mi[0]->mbmi.segment_id]);
vpx_highbd_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round, vpx_highbd_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff, p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, eob, pd->dequant, eob,
...@@ -738,7 +738,8 @@ void vp10_xform_quant(MACROBLOCK *x, int plane, int block, ...@@ -738,7 +738,8 @@ void vp10_xform_quant(MACROBLOCK *x, int plane, int block,
scan_order->scan, scan_order->iscan); scan_order->scan, scan_order->iscan);
break; break;
case TX_4X4: case TX_4X4:
vp10_fwd_txfm_4x4(src_diff, coeff, diff_stride, tx_type, xd->lossless); vp10_fwd_txfm_4x4(src_diff, coeff, diff_stride, tx_type,
xd->lossless[xd->mi[0]->mbmi.segment_id]);
vpx_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round, vpx_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff, p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, eob, pd->dequant, eob,
...@@ -841,7 +842,7 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize, ...@@ -841,7 +842,7 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
// case. // case.
vp10_highbd_inv_txfm_add_4x4(dqcoeff, dst, pd->dst.stride, vp10_highbd_inv_txfm_add_4x4(dqcoeff, dst, pd->dst.stride,
p->eobs[block], xd->bd, tx_type, p->eobs[block], xd->bd, tx_type,
xd->lossless); xd->lossless[xd->mi[0]->mbmi.segment_id]);
break; break;
default: default:
assert(0 && "Invalid transform size"); assert(0 && "Invalid transform size");
...@@ -870,7 +871,7 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize, ...@@ -870,7 +871,7 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
// which is significant (not just an optimization) for the lossless // which is significant (not just an optimization) for the lossless
// case. // case.
vp10_inv_txfm_add_4x4(dqcoeff, dst, pd->dst.stride, p->eobs[block], vp10_inv_txfm_add_4x4(dqcoeff, dst, pd->dst.stride, p->eobs[block],
tx_type, xd->lossless); tx_type, xd->lossless[xd->mi[0]->mbmi.segment_id]);
break; break;
default: default:
assert(0 && "Invalid transform size"); assert(0 && "Invalid transform size");
...@@ -895,7 +896,7 @@ static void encode_block_pass1(int plane, int block, BLOCK_SIZE plane_bsize, ...@@ -895,7 +896,7 @@ static void encode_block_pass1(int plane, int block, BLOCK_SIZE plane_bsize,
if (p->eobs[block] > 0) { if (p->eobs[block] > 0) {
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
if (xd->lossless) { if (xd->lossless[0]) {
vp10_highbd_iwht4x4_add(dqcoeff, dst, pd->dst.stride, vp10_highbd_iwht4x4_add(dqcoeff, dst, pd->dst.stride,
p->eobs[block], xd->bd); p->eobs[block], xd->bd);
} else { } else {
...@@ -905,7 +906,7 @@ static void encode_block_pass1(int plane, int block, BLOCK_SIZE plane_bsize, ...@@ -905,7 +906,7 @@ static void encode_block_pass1(int plane, int block, BLOCK_SIZE plane_bsize,
return; return;
} }
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
if (xd->lossless) { if (xd->lossless[0]) {
vp10_iwht4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]); vp10_iwht4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
} else { } else {
vp10_idct4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]); vp10_idct4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
...@@ -1031,7 +1032,7 @@ void vp10_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, ...@@ -1031,7 +1032,7 @@ void vp10_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
vpx_highbd_subtract_block(4, 4, src_diff, diff_stride, vpx_highbd_subtract_block(4, 4, src_diff, diff_stride,
src, src_stride, dst, dst_stride, xd->bd); src, src_stride, dst, dst_stride, xd->bd);
vp10_highbd_fwd_txfm_4x4(src_diff, coeff, diff_stride, tx_type, vp10_highbd_fwd_txfm_4x4(src_diff, coeff, diff_stride, tx_type,
xd->lossless); xd->lossless[mbmi->segment_id]);
vpx_highbd_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round, vpx_highbd_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff, p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, eob, pd->dequant, eob,
...@@ -1043,7 +1044,7 @@ void vp10_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, ...@@ -1043,7 +1044,7 @@ void vp10_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
// eob<=1 which is significant (not just an optimization) for the // eob<=1 which is significant (not just an optimization) for the
// lossless case. // lossless case.
vp10_highbd_inv_txfm_add_4x4(dqcoeff, dst, dst_stride, *eob, xd->bd, vp10_highbd_inv_txfm_add_4x4(dqcoeff, dst, dst_stride, *eob, xd->bd,
tx_type, xd->lossless); tx_type, xd->lossless[mbmi->segment_id]);
break; break;
default: default:
assert(0); assert(0);
...@@ -1100,7 +1101,8 @@ void vp10_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, ...@@ -1100,7 +1101,8 @@ void vp10_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
if (!x->skip_recode) { if (!x->skip_recode) {
vpx_subtract_block(4, 4, src_diff, diff_stride, vpx_subtract_block(4, 4, src_diff, diff_stride,
src, src_stride, dst, dst_stride); src, src_stride, dst, dst_stride);
vp10_fwd_txfm_4x4(src_diff, coeff, diff_stride, tx_type, xd->lossless); vp10_fwd_txfm_4x4(src_diff, coeff, diff_stride, tx_type,
xd->lossless[mbmi->segment_id]);
vpx_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round, p->quant, vpx_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round, p->quant,
p->quant_shift, qcoeff, dqcoeff, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, eob, scan_order->scan, pd->dequant, eob, scan_order->scan,
...@@ -1112,7 +1114,7 @@ void vp10_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, ...@@ -1112,7 +1114,7 @@ void vp10_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
// which is significant (not just an optimization) for the lossless // which is significant (not just an optimization) for the lossless
// case. // case.
vp10_inv_txfm_add_4x4(dqcoeff, dst, dst_stride, *eob, tx_type, vp10_inv_txfm_add_4x4(dqcoeff, dst, dst_stride, *eob, tx_type,
xd->lossless); xd->lossless[mbmi->segment_id]);
} }
break; break;
default: default:
......
...@@ -2663,7 +2663,7 @@ void vp10_update_reference_frames(VP10_COMP *cpi) { ...@@ -2663,7 +2663,7 @@ void vp10_update_reference_frames(VP10_COMP *cpi) {
static void loopfilter_frame(VP10_COMP *cpi, VP10_COMMON *cm) { static void loopfilter_frame(VP10_COMP *cpi, VP10_COMMON *cm) {
MACROBLOCKD *xd = &cpi->td.mb.e_mbd; MACROBLOCKD *xd = &cpi->td.mb.e_mbd;
struct loopfilter *lf = &cm->lf; struct loopfilter *lf = &cm->lf;
if (xd->lossless) { if (is_lossless_requested(&cpi->oxcf)) {
lf->filter_level = 0; lf->filter_level = 0;
} else { } else {
struct vpx_usec_timer timer; struct vpx_usec_timer timer;
...@@ -4119,7 +4119,7 @@ int vp10_get_compressed_data(VP10_COMP *cpi, unsigned int *frame_flags, ...@@ -4119,7 +4119,7 @@ int vp10_get_compressed_data(VP10_COMP *cpi, unsigned int *frame_flags,
} }
if (oxcf->pass == 1) { if (oxcf->pass == 1) {
cpi->td.mb.e_mbd.lossless = is_lossless_requested(oxcf); cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(oxcf);
vp10_first_pass(cpi, source); vp10_first_pass(cpi, source);
} else if (oxcf->pass == 2) { } else if (oxcf->pass == 2) {
Pass2Encode(cpi, size, dest, frame_flags); Pass2Encode(cpi, size, dest, frame_flags);
......
...@@ -614,6 +614,7 @@ void vp10_first_pass(VP10_COMP *cpi, const struct lookahead_entry *source) { ...@@ -614,6 +614,7 @@ void vp10_first_pass(VP10_COMP *cpi, const struct lookahead_entry *source) {
cm->mi_rows, cm->mi_cols); cm->mi_rows, cm->mi_cols);
// Do intra 16x16 prediction. // Do intra 16x16 prediction.
xd->mi[0]->mbmi.segment_id = 0;
xd->mi[0]->mbmi.mode = DC_PRED; xd->mi[0]->mbmi.mode = DC_PRED;
xd->mi[0]->mbmi.tx_size = use_dc_pred ? xd->mi[0]->mbmi.tx_size = use_dc_pred ?
(bsize >= BLOCK_16X16 ? TX_16X16 : TX_8X8) : TX_4X4; (bsize >= BLOCK_16X16 ? TX_16X16 : TX_8X8) : TX_4X4;
......
...@@ -533,7 +533,7 @@ static void block_rd_txfm(int plane, int block, BLOCK_SIZE plane_bsize, ...@@ -533,7 +533,7 @@ static void block_rd_txfm(int plane, int block, BLOCK_SIZE plane_bsize,
rd = VPXMIN(rd1, rd2); rd = VPXMIN(rd1, rd2);
if (plane == 0) if (plane == 0)
x->zcoeff_blk[tx_size][block] = !x->plane[plane].eobs[block] || x->zcoeff_blk[tx_size][block] = !x->plane[plane].eobs[block] ||
(rd1 > rd2 && !xd->lossless); (rd1 > rd2 && !xd->lossless[mbmi->segment_id]);
args->this_rate += rate; args->this_rate += rate;
args->this_dist += dist; args->this_dist += dist;
...@@ -605,6 +605,21 @@ static void choose_largest_tx_size(VP10_COMP *cpi, MACROBLOCK *x, ...@@ -605,6 +605,21 @@ static void choose_largest_tx_size(VP10_COMP *cpi, MACROBLOCK *x,
mbmi->tx_size, cpi->sf.use_fast_coef_costing); mbmi->tx_size, cpi->sf.use_fast_coef_costing);
} }
static void choose_smallest_tx_size(VP10_COMP *cpi, MACROBLOCK *x,
int *rate, int64_t *distortion,
int *skip, int64_t *sse,
int64_t ref_best_rd,
BLOCK_SIZE bs) {
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
mbmi->tx_size = TX_4X4;
txfm_rd_in_plane(x, rate, distortion, skip,
sse, ref_best_rd, 0, bs,
mbmi->tx_size, cpi->sf.use_fast_coef_costing);
}
static void choose_tx_size_from_rd(VP10_COMP *cpi, MACROBLOCK *x, static void choose_tx_size_from_rd(VP10_COMP *cpi, MACROBLOCK *x,
int *rate, int *rate,
int64_t *distortion, int64_t *distortion,
...@@ -674,7 +689,8 @@ static void choose_tx_size_from_rd(VP10_COMP *cpi, MACROBLOCK *x, ...@@ -674,7 +689,8 @@ static void choose_tx_size_from_rd(VP10_COMP *cpi, MACROBLOCK *x,
rd[n][1] = RDCOST(x->rdmult, x->rddiv, r[n][1] + s0, d[n]); rd[n][1] = RDCOST(x->rdmult, x->rddiv, r[n][1] + s0, d[n]);
} }
if (is_inter_block(mbmi) && !xd->lossless && !s[n] && sse[n] != INT64_MAX) { if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] &&
!s[n] && sse[n] != INT64_MAX) {
rd[n][0] = VPXMIN(rd[n][0], RDCOST(x->rdmult, x->rddiv, s1, sse[n])); rd[n][0] = VPXMIN(rd[n][0], RDCOST(x->rdmult, x->rddiv, s1, sse[n]));
rd[n][1] = VPXMIN(rd[n][1], RDCOST(x->rdmult, x->rddiv, s1, sse[n])); rd[n][1] = VPXMIN(rd[n][1], RDCOST(x->rdmult, x->rddiv, s1, sse[n]));
} }
...@@ -709,7 +725,11 @@ static void super_block_yrd(VP10_COMP *cpi, MACROBLOCK *x, int *rate, ...@@ -709,7 +725,11 @@ static void super_block_yrd(VP10_COMP *cpi, MACROBLOCK *x, int *rate,
assert(bs == xd->mi[0]->mbmi.sb_type); assert(bs == xd->mi[0]->mbmi.sb_type);
if (cpi->sf.tx_size_search_method == USE_LARGESTALL || xd->lossless) { if (CONFIG_MISC_FIXES && xd->lossless[xd->mi[0]->mbmi.segment_id]) {
choose_smallest_tx_size(cpi, x, rate, distortion, skip, ret_sse,
ref_best_rd, bs);
} else if (cpi->sf.tx_size_search_method == USE_LARGESTALL ||
xd->lossless[xd->mi[0]->mbmi.segment_id]) {
choose_largest_tx_size(cpi, x, rate, distortion, skip, ret_sse, ref_best_rd, choose_largest_tx_size(cpi, x, rate, distortion, skip, ret_sse, ref_best_rd,
bs); bs);
} else { } else {
...@@ -963,7 +983,7 @@ static int64_t rd_pick_intra4x4block(VP10_COMP *cpi, MACROBLOCK *x, ...@@ -963,7 +983,7 @@ static int64_t rd_pick_intra4x4block(VP10_COMP *cpi, MACROBLOCK *x,
col + idx, row + idy, 0); col + idx, row + idy, 0);
vpx_highbd_subtract_block(4, 4, src_diff, 8, src, src_stride, vpx_highbd_subtract_block(4, 4, src_diff, 8, src, src_stride,
dst, dst_stride, xd->bd); dst, dst_stride, xd->bd);
if (xd->lossless) { if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block); TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block);
const scan_order *so = get_scan(TX_4X4, tx_type); const scan_order *so = get_scan(TX_4X4, tx_type);
vp10_highbd_fwd_txfm_4x4(src_diff, coeff, 8, DCT_DCT, 1); vp10_highbd_fwd_txfm_4x4(src_diff, coeff, 8, DCT_DCT, 1);
...@@ -1062,7 +1082,7 @@ static int64_t rd_pick_intra4x4block(VP10_COMP *cpi, MACROBLOCK *x, ...@@ -1062,7 +1082,7 @@ static int64_t rd_pick_intra4x4block(VP10_COMP *cpi, MACROBLOCK *x,
dst, dst_stride, col + idx, row + idy, 0); dst, dst_stride, col + idx, row + idy, 0);
vpx_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride); vpx_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride);
if (xd->lossless) { if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block); TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block);
const scan_order *so = get_scan(TX_4X4, tx_type); const scan_order *so = get_scan(TX_4X4, tx_type);
vp10_fwd_txfm_4x4(src_diff, coeff, 8, DCT_DCT, 1); vp10_fwd_txfm_4x4(src_diff, coeff, 8, DCT_DCT, 1);
...@@ -1497,12 +1517,13 @@ static int64_t encode_inter_mb_segment(VP10_COMP *cpi, ...@@ -1497,12 +1517,13 @@ static int64_t encode_inter_mb_segment(VP10_COMP *cpi,
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
fwd_txm4x4 = xd->lossless ? vp10_highbd_fwht4x4 : vpx_highbd_fdct4x4; fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_highbd_fwht4x4
: vpx_highbd_fdct4x4;
} else { } else {
fwd_txm4x4 = xd->lossless ? vp10_fwht4x4 : vpx_fdct4x4; fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_fwht4x4 : vpx_fdct4x4;
} }
#else #else
fwd_txm4x4 = xd->lossless ? vp10_fwht4x4 : vpx_fdct4x4; fwd_txm4x4 = xd->lossless[mi->mbmi.segment_id] ? vp10_fwht4x4 : vpx_fdct4x4;
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
...@@ -3460,7 +3481,7 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi, ...@@ -3460,7 +3481,7 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
// Cost the skip mb case // Cost the skip mb case
rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1); rate2 += vp10_cost_bit(vp10_get_skip_prob(cm, xd), 1);
} else if (ref_frame != INTRA_FRAME && !xd->lossless) { } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) < if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
RDCOST(x->rdmult, x->rddiv, 0, total_sse)) { RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
// Add in the cost of the no skip flag. // Add in the cost of the no skip flag.
...@@ -4215,7 +4236,7 @@ void vp10_rd_pick_inter_mode_sub8x8(VP10_COMP *cpi, ...@@ -4215,7 +4236,7 @@ void vp10_rd_pick_inter_mode_sub8x8(VP10_COMP *cpi,
// Skip is never coded at the segment level for sub8x8 blocks and instead // Skip is never coded at the segment level for sub8x8 blocks and instead
// always coded in the bitstream at the mode info level. // always coded in the bitstream at the mode info level.
if (ref_frame != INTRA_FRAME && !xd->lossless) { if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) < if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
RDCOST(x->rdmult, x->rddiv, 0, total_sse)) { RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
// Add in the cost of the no skip flag. // Add in the cost of the no skip flag.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment