Commit dcb3cff5 authored by Rupert Swarbrick's avatar Rupert Swarbrick Committed by Debargha Mukherjee

Don't send chroma data in monochrome mode

This is still a rather inefficient black+white encoder, since it carefully
computes some chroma data, but just doesn't write it. However, at least the
bitstream is now monochrome.

Change-Id: Ie8a89bf329e7b41441032fb0d9e9011385bc12ff
parent dfcbfbd4
...@@ -1682,7 +1682,7 @@ static float usec_to_fps(uint64_t usec, unsigned int frames) { ...@@ -1682,7 +1682,7 @@ static float usec_to_fps(uint64_t usec, unsigned int frames) {
} }
static void test_decode(struct stream_state *stream, static void test_decode(struct stream_state *stream,
enum TestDecodeFatality fatal) { enum TestDecodeFatality fatal, int is_mono) {
aom_image_t enc_img, dec_img; aom_image_t enc_img, dec_img;
if (stream->mismatch_seen) return; if (stream->mismatch_seen) return;
...@@ -1714,7 +1714,7 @@ static void test_decode(struct stream_state *stream, ...@@ -1714,7 +1714,7 @@ static void test_decode(struct stream_state *stream,
ctx_exit_on_error(&stream->encoder, "Failed to get encoder reference frame"); ctx_exit_on_error(&stream->encoder, "Failed to get encoder reference frame");
ctx_exit_on_error(&stream->decoder, "Failed to get decoder reference frame"); ctx_exit_on_error(&stream->decoder, "Failed to get decoder reference frame");
if (!aom_compare_img(&enc_img, &dec_img)) { if (!aom_compare_img(&enc_img, &dec_img, is_mono ? 1 : 3)) {
int y[4], u[4], v[4]; int y[4], u[4], v[4];
#if CONFIG_HIGHBITDEPTH #if CONFIG_HIGHBITDEPTH
if (enc_img.fmt & AOM_IMG_FMT_HIGHBITDEPTH) { if (enc_img.fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
...@@ -2132,7 +2132,8 @@ int main(int argc, const char **argv_) { ...@@ -2132,7 +2132,8 @@ int main(int argc, const char **argv_) {
if (got_data && global.test_decode != TEST_DECODE_OFF) { if (got_data && global.test_decode != TEST_DECODE_OFF) {
FOREACH_STREAM(stream, streams) { FOREACH_STREAM(stream, streams) {
test_decode(stream, global.test_decode); test_decode(stream, global.test_decode,
stream->config.cfg.monochrome);
} }
} }
} }
......
...@@ -483,10 +483,6 @@ typedef struct AV1Common { ...@@ -483,10 +483,6 @@ typedef struct AV1Common {
unsigned int single_tile_decoding; unsigned int single_tile_decoding;
#endif // CONFIG_EXT_TILE #endif // CONFIG_EXT_TILE
#if CONFIG_MONO_VIDEO
int monochrome;
#endif // CONFIG_MONO_VIDEO
#if CONFIG_DEPENDENT_HORZTILES #if CONFIG_DEPENDENT_HORZTILES
int dependent_horz_tiles; int dependent_horz_tiles;
int tile_group_start_row[MAX_TILE_ROWS][MAX_TILE_COLS]; int tile_group_start_row[MAX_TILE_ROWS][MAX_TILE_COLS];
...@@ -1129,6 +1125,15 @@ static INLINE int max_intra_block_height(const MACROBLOCKD *xd, ...@@ -1129,6 +1125,15 @@ static INLINE int max_intra_block_height(const MACROBLOCKD *xd,
} }
#endif // CONFIG_CFL #endif // CONFIG_CFL
static INLINE int av1_num_planes(const AV1_COMMON *cm) {
#if CONFIG_MONO_VIDEO
return cm->seq_params.monochrome ? 1 : MAX_MB_PLANE;
#else
(void)cm;
return MAX_MB_PLANE;
#endif
}
static INLINE void av1_zero_above_context(AV1_COMMON *const cm, static INLINE void av1_zero_above_context(AV1_COMMON *const cm,
int mi_col_start, int mi_col_end) { int mi_col_start, int mi_col_end) {
const int width = mi_col_end - mi_col_start; const int width = mi_col_end - mi_col_start;
......
...@@ -486,8 +486,7 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi, ...@@ -486,8 +486,7 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi,
#else #else
const int current_qindex = xd->current_qindex; const int current_qindex = xd->current_qindex;
#endif // CONFIG_EXT_DELTA_Q #endif // CONFIG_EXT_DELTA_Q
int j; for (int j = 0; j < av1_num_planes(cm); ++j) {
for (j = 0; j < MAX_MB_PLANE; ++j) {
const int dc_delta_q = const int dc_delta_q =
j == 0 ? cm->y_dc_delta_q j == 0 ? cm->y_dc_delta_q
: (j == 1 ? cm->u_dc_delta_q : cm->v_dc_delta_q); : (j == 1 ? cm->u_dc_delta_q : cm->v_dc_delta_q);
...@@ -505,14 +504,13 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi, ...@@ -505,14 +504,13 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi,
if (mbmi->skip) av1_reset_skip_context(xd, mi_row, mi_col, bsize); if (mbmi->skip) av1_reset_skip_context(xd, mi_row, mi_col, bsize);
if (!is_inter_block(mbmi)) { if (!is_inter_block(mbmi)) {
int plane; const int num_planes = av1_num_planes(cm);
for (int plane = 0; plane < AOMMIN(2, num_planes); ++plane) {
for (plane = 0; plane <= 1; ++plane) {
if (mbmi->palette_mode_info.palette_size[plane]) if (mbmi->palette_mode_info.palette_size[plane])
av1_decode_palette_tokens(xd, plane, r); av1_decode_palette_tokens(xd, plane, r);
} }
for (plane = 0; plane < MAX_MB_PLANE; ++plane) { for (int plane = 0; plane < num_planes; ++plane) {
const struct macroblockd_plane *const pd = &xd->plane[plane]; const struct macroblockd_plane *const pd = &xd->plane[plane];
const TX_SIZE tx_size = av1_get_tx_size(plane, xd); const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
const int stepr = tx_size_high_unit[tx_size]; const int stepr = tx_size_high_unit[tx_size];
...@@ -593,9 +591,7 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi, ...@@ -593,9 +591,7 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi,
// Reconstruction // Reconstruction
if (!mbmi->skip) { if (!mbmi->skip) {
int eobtotal = 0; int eobtotal = 0;
int plane; for (int plane = 0; plane < av1_num_planes(cm); ++plane) {
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
const struct macroblockd_plane *const pd = &xd->plane[plane]; const struct macroblockd_plane *const pd = &xd->plane[plane];
const BLOCK_SIZE plane_bsize = const BLOCK_SIZE plane_bsize =
AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd)); AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
...@@ -1008,7 +1004,7 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd, ...@@ -1008,7 +1004,7 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd,
} }
} }
#if CONFIG_LOOP_RESTORATION #if CONFIG_LOOP_RESTORATION
for (int plane = 0; plane < MAX_MB_PLANE; ++plane) { for (int plane = 0; plane < av1_num_planes(cm); ++plane) {
int rcol0, rcol1, rrow0, rrow1, tile_tl_idx; int rcol0, rcol1, rrow0, rrow1, tile_tl_idx;
if (av1_loop_restoration_corners_in_sb(cm, plane, mi_row, mi_col, bsize, if (av1_loop_restoration_corners_in_sb(cm, plane, mi_row, mi_col, bsize,
&rcol0, &rcol1, &rrow0, &rrow1, &rcol0, &rcol1, &rrow0, &rrow1,
...@@ -1131,7 +1127,8 @@ static void decode_restoration_mode(AV1_COMMON *cm, ...@@ -1131,7 +1127,8 @@ static void decode_restoration_mode(AV1_COMMON *cm,
#if CONFIG_INTRABC #if CONFIG_INTRABC
if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return; if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return;
#endif // CONFIG_INTRABC #endif // CONFIG_INTRABC
for (int p = 0; p < MAX_MB_PLANE; ++p) { int all_none = 1, chroma_none = 1;
for (int p = 0; p < av1_num_planes(cm); ++p) {
RestorationInfo *rsi = &cm->rst_info[p]; RestorationInfo *rsi = &cm->rst_info[p];
if (aom_rb_read_bit(rb)) { if (aom_rb_read_bit(rb)) {
rsi->frame_restoration_type = rsi->frame_restoration_type =
...@@ -1140,10 +1137,12 @@ static void decode_restoration_mode(AV1_COMMON *cm, ...@@ -1140,10 +1137,12 @@ static void decode_restoration_mode(AV1_COMMON *cm,
rsi->frame_restoration_type = rsi->frame_restoration_type =
aom_rb_read_bit(rb) ? RESTORE_SWITCHABLE : RESTORE_NONE; aom_rb_read_bit(rb) ? RESTORE_SWITCHABLE : RESTORE_NONE;
} }
if (rsi->frame_restoration_type != RESTORE_NONE) {
all_none = 0;
chroma_none &= p == 0;
}
} }
if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE || if (!all_none) {
cm->rst_info[1].frame_restoration_type != RESTORE_NONE ||
cm->rst_info[2].frame_restoration_type != RESTORE_NONE) {
const int qsize = RESTORATION_TILESIZE_MAX >> 2; const int qsize = RESTORATION_TILESIZE_MAX >> 2;
for (int p = 0; p < MAX_MB_PLANE; ++p) for (int p = 0; p < MAX_MB_PLANE; ++p)
cm->rst_info[p].restoration_unit_size = qsize; cm->rst_info[p].restoration_unit_size = qsize;
...@@ -1159,16 +1158,18 @@ static void decode_restoration_mode(AV1_COMMON *cm, ...@@ -1159,16 +1158,18 @@ static void decode_restoration_mode(AV1_COMMON *cm,
cm->rst_info[p].restoration_unit_size = size; cm->rst_info[p].restoration_unit_size = size;
} }
int s = AOMMIN(cm->subsampling_x, cm->subsampling_y); if (av1_num_planes(cm) > 1) {
if (s && (cm->rst_info[1].frame_restoration_type != RESTORE_NONE || int s = AOMMIN(cm->subsampling_x, cm->subsampling_y);
cm->rst_info[2].frame_restoration_type != RESTORE_NONE)) { if (s && !chroma_none) {
cm->rst_info[1].restoration_unit_size = cm->rst_info[1].restoration_unit_size =
cm->rst_info[0].restoration_unit_size >> (aom_rb_read_bit(rb) * s); cm->rst_info[0].restoration_unit_size >> (aom_rb_read_bit(rb) * s);
} else { } else {
cm->rst_info[1].restoration_unit_size = cm->rst_info[1].restoration_unit_size =
cm->rst_info[0].restoration_unit_size; cm->rst_info[0].restoration_unit_size;
}
cm->rst_info[2].restoration_unit_size =
cm->rst_info[1].restoration_unit_size;
} }
cm->rst_info[2].restoration_unit_size = cm->rst_info[1].restoration_unit_size;
} }
static void read_wiener_filter(int wiener_win, WienerInfo *wiener_info, static void read_wiener_filter(int wiener_win, WienerInfo *wiener_info,
......
...@@ -1212,7 +1212,12 @@ static void write_palette_mode_info(const AV1_COMMON *cm, const MACROBLOCKD *xd, ...@@ -1212,7 +1212,12 @@ static void write_palette_mode_info(const AV1_COMMON *cm, const MACROBLOCKD *xd,
} }
} }
if (mbmi->uv_mode == UV_DC_PRED) { const int uv_dc_pred =
#if CONFIG_MONO_VIDEO
!cm->seq_params.monochrome &&
#endif
mbmi->uv_mode == UV_DC_PRED;
if (uv_dc_pred) {
const int n = pmi->palette_size[1]; const int n = pmi->palette_size[1];
const int palette_uv_mode_ctx = (pmi->palette_size[0] > 0); const int palette_uv_mode_ctx = (pmi->palette_size[0] > 0);
#if CONFIG_NEW_MULTISYMBOL #if CONFIG_NEW_MULTISYMBOL
...@@ -2007,7 +2012,8 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile, ...@@ -2007,7 +2012,8 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile,
#endif // CONFIG_DEPENDENT_HORZTILES #endif // CONFIG_DEPENDENT_HORZTILES
cm->mi_rows, cm->mi_cols); cm->mi_rows, cm->mi_cols);
for (plane = 0; plane <= 1; ++plane) { const int num_planes = av1_num_planes(cm);
for (plane = 0; plane < AOMMIN(2, num_planes); ++plane) {
const uint8_t palette_size_plane = const uint8_t palette_size_plane =
mbmi->palette_mode_info.palette_size[plane]; mbmi->palette_mode_info.palette_size[plane];
if (palette_size_plane > 0) { if (palette_size_plane > 0) {
...@@ -2030,7 +2036,7 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile, ...@@ -2030,7 +2036,7 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile,
#if !CONFIG_LV_MAP #if !CONFIG_LV_MAP
assert(*tok < tok_end); assert(*tok < tok_end);
#endif #endif
for (plane = 0; plane < MAX_MB_PLANE; ++plane) { for (plane = 0; plane < num_planes; ++plane) {
if (!is_chroma_reference(mi_row, mi_col, mbmi->sb_type, if (!is_chroma_reference(mi_row, mi_col, mbmi->sb_type,
xd->plane[plane].subsampling_x, xd->plane[plane].subsampling_x,
xd->plane[plane].subsampling_y)) { xd->plane[plane].subsampling_y)) {
...@@ -2457,7 +2463,7 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile, ...@@ -2457,7 +2463,7 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile,
} }
} }
#if CONFIG_LOOP_RESTORATION #if CONFIG_LOOP_RESTORATION
for (int plane = 0; plane < MAX_MB_PLANE; ++plane) { for (int plane = 0; plane < av1_num_planes(cm); ++plane) {
int rcol0, rcol1, rrow0, rrow1, tile_tl_idx; int rcol0, rcol1, rrow0, rrow1, tile_tl_idx;
if (av1_loop_restoration_corners_in_sb(cm, plane, mi_row, mi_col, bsize, if (av1_loop_restoration_corners_in_sb(cm, plane, mi_row, mi_col, bsize,
&rcol0, &rcol1, &rrow0, &rrow1, &rcol0, &rcol1, &rrow0, &rrow1,
...@@ -2526,8 +2532,13 @@ static void encode_restoration_mode(AV1_COMMON *cm, ...@@ -2526,8 +2532,13 @@ static void encode_restoration_mode(AV1_COMMON *cm,
#if CONFIG_INTRABC #if CONFIG_INTRABC
if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return; if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return;
#endif // CONFIG_INTRABC #endif // CONFIG_INTRABC
for (int p = 0; p < MAX_MB_PLANE; ++p) { int all_none = 1, chroma_none = 1;
for (int p = 0; p < av1_num_planes(cm); ++p) {
RestorationInfo *rsi = &cm->rst_info[p]; RestorationInfo *rsi = &cm->rst_info[p];
if (rsi->frame_restoration_type != RESTORE_NONE) {
all_none = 0;
chroma_none &= p == 0;
}
switch (rsi->frame_restoration_type) { switch (rsi->frame_restoration_type) {
case RESTORE_NONE: case RESTORE_NONE:
aom_wb_write_bit(wb, 0); aom_wb_write_bit(wb, 0);
...@@ -2548,9 +2559,7 @@ static void encode_restoration_mode(AV1_COMMON *cm, ...@@ -2548,9 +2559,7 @@ static void encode_restoration_mode(AV1_COMMON *cm,
default: assert(0); default: assert(0);
} }
} }
if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE || if (!all_none) {
cm->rst_info[1].frame_restoration_type != RESTORE_NONE ||
cm->rst_info[2].frame_restoration_type != RESTORE_NONE) {
RestorationInfo *rsi = &cm->rst_info[0]; RestorationInfo *rsi = &cm->rst_info[0];
const int qsize = RESTORATION_TILESIZE_MAX >> 2; const int qsize = RESTORATION_TILESIZE_MAX >> 2;
const int hsize = RESTORATION_TILESIZE_MAX >> 1; const int hsize = RESTORATION_TILESIZE_MAX >> 1;
...@@ -2559,23 +2568,25 @@ static void encode_restoration_mode(AV1_COMMON *cm, ...@@ -2559,23 +2568,25 @@ static void encode_restoration_mode(AV1_COMMON *cm,
aom_wb_write_bit(wb, rsi->restoration_unit_size != hsize); aom_wb_write_bit(wb, rsi->restoration_unit_size != hsize);
} }
} }
int s = AOMMIN(cm->subsampling_x, cm->subsampling_y);
if (s && (cm->rst_info[1].frame_restoration_type != RESTORE_NONE || if (av1_num_planes(cm) > 1) {
cm->rst_info[2].frame_restoration_type != RESTORE_NONE)) { int s = AOMMIN(cm->subsampling_x, cm->subsampling_y);
aom_wb_write_bit(wb, if (s && !chroma_none) {
cm->rst_info[1].restoration_unit_size != aom_wb_write_bit(wb,
cm->rst_info[0].restoration_unit_size); cm->rst_info[1].restoration_unit_size !=
assert(cm->rst_info[1].restoration_unit_size == cm->rst_info[0].restoration_unit_size);
cm->rst_info[0].restoration_unit_size || assert(cm->rst_info[1].restoration_unit_size ==
cm->rst_info[1].restoration_unit_size == cm->rst_info[0].restoration_unit_size ||
(cm->rst_info[0].restoration_unit_size >> s)); cm->rst_info[1].restoration_unit_size ==
assert(cm->rst_info[2].restoration_unit_size == (cm->rst_info[0].restoration_unit_size >> s));
cm->rst_info[1].restoration_unit_size); assert(cm->rst_info[2].restoration_unit_size ==
} else if (!s) { cm->rst_info[1].restoration_unit_size);
assert(cm->rst_info[1].restoration_unit_size == } else if (!s) {
cm->rst_info[0].restoration_unit_size); assert(cm->rst_info[1].restoration_unit_size ==
assert(cm->rst_info[2].restoration_unit_size == cm->rst_info[0].restoration_unit_size);
cm->rst_info[1].restoration_unit_size); assert(cm->rst_info[2].restoration_unit_size ==
cm->rst_info[1].restoration_unit_size);
}
} }
} }
...@@ -3658,7 +3669,6 @@ void write_sequence_header(AV1_COMP *cpi, struct aom_write_bit_buffer *wb) { ...@@ -3658,7 +3669,6 @@ void write_sequence_header(AV1_COMP *cpi, struct aom_write_bit_buffer *wb) {
} }
#if CONFIG_MONO_VIDEO #if CONFIG_MONO_VIDEO
seq_params->monochrome = cm->monochrome;
aom_wb_write_bit(wb, seq_params->monochrome); aom_wb_write_bit(wb, seq_params->monochrome);
#endif // CONFIG_MONO_VIDEO #endif // CONFIG_MONO_VIDEO
} }
......
...@@ -3608,7 +3608,8 @@ void av1_init_tile_data(AV1_COMP *cpi) { ...@@ -3608,7 +3608,8 @@ void av1_init_tile_data(AV1_COMP *cpi) {
cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok; cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
pre_tok = cpi->tile_tok[tile_row][tile_col]; pre_tok = cpi->tile_tok[tile_row][tile_col];
tile_tok = allocated_tokens(*tile_info, cm->mib_size_log2 + MI_SIZE_LOG2); tile_tok = allocated_tokens(*tile_info, cm->mib_size_log2 + MI_SIZE_LOG2,
av1_num_planes(cm));
#if CONFIG_EXT_TILE #if CONFIG_EXT_TILE
tile_data->allow_update_cdf = !cm->large_scale_tile; tile_data->allow_update_cdf = !cm->large_scale_tile;
...@@ -3674,7 +3675,8 @@ void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row, ...@@ -3674,7 +3675,8 @@ void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
cpi->tok_count[tile_row][tile_col] = cpi->tok_count[tile_row][tile_col] =
(unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]); (unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]);
assert(cpi->tok_count[tile_row][tile_col] <= assert(cpi->tok_count[tile_row][tile_col] <=
allocated_tokens(*tile_info, cm->mib_size_log2 + MI_SIZE_LOG2)); allocated_tokens(*tile_info, cm->mib_size_log2 + MI_SIZE_LOG2,
av1_num_planes(cm)));
} }
static void encode_tiles(AV1_COMP *cpi) { static void encode_tiles(AV1_COMP *cpi) {
...@@ -4824,14 +4826,14 @@ static void encode_superblock(const AV1_COMP *const cpi, TileDataEnc *tile_data, ...@@ -4824,14 +4826,14 @@ static void encode_superblock(const AV1_COMP *const cpi, TileDataEnc *tile_data,
const int mi_height = mi_size_high[bsize]; const int mi_height = mi_size_high[bsize];
const int is_inter = is_inter_block(mbmi); const int is_inter = is_inter_block(mbmi);
const BLOCK_SIZE block_size = bsize; const BLOCK_SIZE block_size = bsize;
const int num_planes = av1_num_planes(cm);
if (!is_inter) { if (!is_inter) {
#if CONFIG_CFL #if CONFIG_CFL
xd->cfl->store_y = 1; xd->cfl->store_y = 1;
#endif // CONFIG_CFL #endif // CONFIG_CFL
int plane;
mbmi->skip = 1; mbmi->skip = 1;
for (plane = 0; plane < MAX_MB_PLANE; ++plane) { for (int plane = 0; plane < num_planes; ++plane) {
av1_encode_intra_block_plane((AV1_COMMON *)cm, x, block_size, plane, 1, av1_encode_intra_block_plane((AV1_COMMON *)cm, x, block_size, plane, 1,
mi_row, mi_col); mi_row, mi_col);
} }
...@@ -4850,7 +4852,7 @@ static void encode_superblock(const AV1_COMP *const cpi, TileDataEnc *tile_data, ...@@ -4850,7 +4852,7 @@ static void encode_superblock(const AV1_COMP *const cpi, TileDataEnc *tile_data,
} }
if (bsize >= BLOCK_8X8) { if (bsize >= BLOCK_8X8) {
for (plane = 0; plane <= 1; ++plane) { for (int plane = 0; plane < AOMMIN(2, num_planes); ++plane) {
if (mbmi->palette_mode_info.palette_size[plane] > 0) { if (mbmi->palette_mode_info.palette_size[plane] > 0) {
if (!dry_run) if (!dry_run)
av1_tokenize_color_map(x, plane, 0, t, bsize, mbmi->tx_size, av1_tokenize_color_map(x, plane, 0, t, bsize, mbmi->tx_size,
......
...@@ -845,8 +845,8 @@ static void alloc_compressor_data(AV1_COMP *cpi) { ...@@ -845,8 +845,8 @@ static void alloc_compressor_data(AV1_COMP *cpi) {
aom_free(cpi->tile_tok[0][0]); aom_free(cpi->tile_tok[0][0]);
{ {
unsigned int tokens = unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols,
get_token_alloc(cm->mb_rows, cm->mb_cols, MAX_SB_SIZE_LOG2); MAX_SB_SIZE_LOG2, av1_num_planes(cm));
CHECK_MEM_ERROR(cm, cpi->tile_tok[0][0], CHECK_MEM_ERROR(cm, cpi->tile_tok[0][0],
aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0]))); aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
} }
...@@ -5499,7 +5499,7 @@ static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size, ...@@ -5499,7 +5499,7 @@ static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
#endif // CONFIG_EXT_TILE #endif // CONFIG_EXT_TILE
#if CONFIG_MONO_VIDEO #if CONFIG_MONO_VIDEO
cm->monochrome = oxcf->monochrome; cm->seq_params.monochrome = oxcf->monochrome;
#endif // CONFIG_MONO_VIDEO #endif // CONFIG_MONO_VIDEO
#if CONFIG_XIPHRC #if CONFIG_XIPHRC
......
...@@ -719,7 +719,7 @@ static INLINE int enc_is_ref_frame_buf(AV1_COMP *cpi, RefCntBuffer *frame_buf) { ...@@ -719,7 +719,7 @@ static INLINE int enc_is_ref_frame_buf(AV1_COMP *cpi, RefCntBuffer *frame_buf) {
} }
static INLINE unsigned int get_token_alloc(int mb_rows, int mb_cols, static INLINE unsigned int get_token_alloc(int mb_rows, int mb_cols,
int sb_size_log2) { int sb_size_log2, int num_planes) {
// Calculate the maximum number of max superblocks in the image. // Calculate the maximum number of max superblocks in the image.
const int shift = sb_size_log2 - 4; const int shift = sb_size_log2 - 4;
const int sb_size = 1 << sb_size_log2; const int sb_size = 1 << sb_size_log2;
...@@ -727,10 +727,11 @@ static INLINE unsigned int get_token_alloc(int mb_rows, int mb_cols, ...@@ -727,10 +727,11 @@ static INLINE unsigned int get_token_alloc(int mb_rows, int mb_cols,
const int sb_rows = ALIGN_POWER_OF_TWO(mb_rows, shift) >> shift; const int sb_rows = ALIGN_POWER_OF_TWO(mb_rows, shift) >> shift;
const int sb_cols = ALIGN_POWER_OF_TWO(mb_cols, shift) >> shift; const int sb_cols = ALIGN_POWER_OF_TWO(mb_cols, shift) >> shift;
// For transform coefficients, assume 3 planes with no subsampling. We assume // For transform coefficients, assume planes with no subsampling. We assume
// up to 1 token per pixel, and then allow a head room of 1 EOSB token per // up to 1 token per pixel, and then allow a head room of 1 EOSB token per
// 4x4 block per plane, plus EOSB_TOKEN per plane. // 4x4 block per plane, plus EOSB_TOKEN per plane.
const int sb_coeff_toks = 3 * (sb_size_square + (sb_size_square / 16) + 1); const int sb_coeff_toks =
num_planes * (sb_size_square + (sb_size_square / 16) + 1);
// For palette coefficients, there can be at most one palette for each 8x8 // For palette coefficients, there can be at most one palette for each 8x8
// block. If w, h are the width and height of the block, the palette has at // block. If w, h are the width and height of the block, the palette has at
...@@ -743,11 +744,12 @@ static INLINE unsigned int get_token_alloc(int mb_rows, int mb_cols, ...@@ -743,11 +744,12 @@ static INLINE unsigned int get_token_alloc(int mb_rows, int mb_cols,
// Get the allocated token size for a tile. It does the same calculation as in // Get the allocated token size for a tile. It does the same calculation as in
// the frame token allocation. // the frame token allocation.
static INLINE unsigned int allocated_tokens(TileInfo tile, int sb_size_log2) { static INLINE unsigned int allocated_tokens(TileInfo tile, int sb_size_log2,
int num_planes) {
int tile_mb_rows = (tile.mi_row_end - tile.mi_row_start + 2) >> 2; int tile_mb_rows = (tile.mi_row_end - tile.mi_row_start + 2) >> 2;
int tile_mb_cols = (tile.mi_col_end - tile.mi_col_start + 2) >> 2; int tile_mb_cols = (tile.mi_col_end - tile.mi_col_start + 2) >> 2;
return get_token_alloc(tile_mb_rows, tile_mb_cols, sb_size_log2); return get_token_alloc(tile_mb_rows, tile_mb_cols, sb_size_log2, num_planes);
} }
#if CONFIG_TEMPMV_SIGNALING #if CONFIG_TEMPMV_SIGNALING
......
...@@ -647,7 +647,6 @@ void av1_tokenize_sb_vartx(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t, ...@@ -647,7 +647,6 @@ void av1_tokenize_sb_vartx(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
TOKENEXTRA *t_backup = *t; TOKENEXTRA *t_backup = *t;
#endif #endif
struct tokenize_b_args arg = { cpi, td, t, 0, allow_update_cdf }; struct tokenize_b_args arg = { cpi, td, t, 0, allow_update_cdf };
int plane;
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
if (mbmi->skip) { if (mbmi->skip) {
...@@ -663,7 +662,7 @@ void av1_tokenize_sb_vartx(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t, ...@@ -663,7 +662,7 @@ void av1_tokenize_sb_vartx(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
*t = t_backup; *t = t_backup;
#endif #endif
for (plane = 0; plane < MAX_MB_PLANE; ++plane) { for (int plane = 0; plane < av1_num_planes(cm); ++plane) {
if (!is_chroma_reference(mi_row, mi_col, bsize, if (!is_chroma_reference(mi_row, mi_col, bsize,
xd->plane[plane].subsampling_x, xd->plane[plane].subsampling_x,
xd->plane[plane].subsampling_y)) { xd->plane[plane].subsampling_y)) {
...@@ -735,10 +734,9 @@ void av1_tokenize_sb(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t, ...@@ -735,10 +734,9 @@ void av1_tokenize_sb(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
return; return;
} }
const int num_planes = av1_num_planes(&cpi->common);
if (!dry_run) { if (!dry_run) {
int plane; for (int plane = 0; plane < num_planes; ++plane) {
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
if (!is_chroma_reference(mi_row, mi_col, bsize, if (!is_chroma_reference(mi_row, mi_col, bsize,
xd->plane[plane].subsampling_x, xd->plane[plane].subsampling_x,
xd->plane[plane].subsampling_y)) { xd->plane[plane].subsampling_y)) {
...@@ -753,8 +751,7 @@ void av1_tokenize_sb(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t, ...@@ -753,8 +751,7 @@ void av1_tokenize_sb(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
(*t)++; (*t)++;
} }
} else if (dry_run == DRY_RUN_NORMAL) { } else if (dry_run == DRY_RUN_NORMAL) {
int plane; for (int plane = 0; plane < num_planes; ++plane) {
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
if (!is_chroma_reference(mi_row, mi_col, bsize, if (!is_chroma_reference(mi_row, mi_col, bsize,
xd->plane[plane].subsampling_x, xd->plane[plane].subsampling_x,
xd->plane[plane].subsampling_y)) xd->plane[plane].subsampling_y))
...@@ -763,8 +760,7 @@ void av1_tokenize_sb(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t, ...@@ -763,8 +760,7 @@ void av1_tokenize_sb(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
set_entropy_context_b, &arg); set_entropy_context_b, &arg);
} }
} else if (dry_run == DRY_RUN_COSTCOEFFS) { } else if (dry_run == DRY_RUN_COSTCOEFFS) {
int plane; for (int plane = 0; plane < num_planes; ++plane) {
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
if (!is_chroma_reference(mi_row, mi_col, bsize, if (!is_chroma_reference(mi_row, mi_col, bsize,
xd->plane[plane].subsampling_x, xd->plane[plane].subsampling_x,
xd->plane[plane].subsampling_y)) xd->plane[plane].subsampling_y))
......
...@@ -69,7 +69,8 @@ void usage_exit() { ...@@ -69,7 +69,8 @@ void usage_exit() {
} }
static void testing_decode(aom_codec_ctx_t *encoder, aom_codec_ctx_t *decoder, static void testing_decode(aom_codec_ctx_t *encoder, aom_codec_ctx_t *decoder,
unsigned int frame_out, int *mismatch_seen) { unsigned int frame_out, int *mismatch_seen,
int is_mono) {
aom_image_t enc_img, dec_img; aom_image_t enc_img, dec_img;
struct av1_ref_frame ref_enc, ref_dec; struct av1_ref_frame ref_enc, ref_dec;
...@@ -84,7 +85,7 @@ static void testing_decode(aom_codec_ctx_t *encoder, aom_codec_ctx_t *decoder, ...@@ -84,7 +85,7 @@ static void testing_decode(aom_codec_ctx_t *encoder, aom_codec_ctx_t *decoder,
die_codec(decoder, "Failed to get decoder reference frame"); die_codec(decoder, "Failed to get decoder reference frame");
dec_img = ref_dec.img; dec_img = ref_dec.img;
if (!aom_compare_img(&enc_img, &dec_img)) { if (!aom_compare_img(&enc_img, &dec_img, is_mono ? 1 : 3)) {
int y[4], u[4], v[4]; int y[4], u[4], v[4];
*mismatch_seen = 1; *mismatch_seen = 1;
...@@ -106,7 +107,8 @@ static void testing_decode(aom_codec_ctx_t *encoder, aom_codec_ctx_t *decoder, ...@@ -106,7 +107,8 @@ static void testing_decode(aom_codec_ctx_t *encoder, aom_codec_ctx_t *decoder,
static int encode_frame(aom_codec_ctx_t *ecodec, aom_image_t *img, static int encode_frame(aom_codec_ctx_t *ecodec, aom_image_t *img,
unsigned int frame_in, AvxVideoWriter *writer, unsigned int frame_in, AvxVideoWriter *writer,
int test_decode, aom_codec_ctx_t *dcodec, int test_decode, aom_codec_ctx_t *dcodec,
unsigned int *frame_out, int *mismatch_seen) { unsigned int *frame_out, int *mismatch_seen,
int is_mono) {
int got_pkts = 0; int got_pkts = 0;
aom_codec_iter_t iter = NULL; aom_codec_iter_t iter = NULL;
const aom_codec_cx_pkt_t *pkt = NULL; const aom_codec_cx_pkt_t *pkt = NULL;
...@@ -147,7 +149,7 @@ static int encode_frame(aom_codec_ctx_t *ecodec, aom_image_t *img, ...@@ -147,7 +149,7 @@ static int encode_frame(aom_codec_ctx_t *ecodec, aom_image_t *img,
// Mismatch checking // Mismatch checking
if (got_data && test_decode) { if (got_data && test_decode) {
testing_decode(ecodec, dcodec, *frame_out, mismatch_seen); testing_decode(ecodec, dcodec, *frame_out, mismatch_seen, is_mono);
} }
return got_pkts; return got_pkts;
...@@ -287,7 +289,7 @@ int main(int argc, char **argv) { ...@@ -287,7 +289,7 @@ int main(int argc, char **argv) {
} }
encode_frame(&ecodec, &raw, frame_in, writer, test_decode, &dcodec, encode_frame(&ecodec, &raw, frame_in, writer, test_decode, &dcodec,
&frame_out, &mismatch_seen); &frame_out, &mismatch_seen, cfg.monochrome);
frame_in++; frame_in++;
if (mismatch_seen) break; if (mismatch_seen) break;
} }
...@@ -295,7 +297,7 @@ int main(int argc, char **argv) { ...@@ -295,7 +297,7 @@ int main(int argc, char **argv) {
// Flush encoder. // Flush encoder.
if (!mismatch_seen) if (!mismatch_seen)
while (encode_frame(&ecodec, NULL, frame_in, writer, test_decode, &dcodec, while (encode_frame(&ecodec, NULL, frame_in, writer, test_decode, &dcodec,
&frame_out, &mismatch_seen)) { &frame_out, &mismatch_seen, cfg.monochrome)) {
} }
printf("\n"); printf("\n");
......
...@@ -102,12 +102,11 @@ void aom_find_mismatch(const aom_image_t *const img1, ...@@ -102,12 +102,11 @@ void aom_find_mismatch(const aom_image_t *const img1,
} }
int aom_compare_img(const aom_image_t *const img1, int aom_compare_img(const aom_image_t *const img1,
const aom_image_t *const img2) { const aom_image_t *const img2, int num_planes) {
uint32_t l_w = img1->d_w; uint32_t l_w = img1->d_w;
uint32_t c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift; uint32_t c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
const uint32_t c_h = const uint32_t c_h =
(img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift; (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
uint32_t i;
int match = 1; int match = 1;
match &= (img1->fmt == img2->fmt); match &= (img1->fmt == img2->fmt);
...@@ -120,20 +119,16 @@ int aom_compare_img(const aom_image_t *const img1, ...@@ -120,20 +119,16 @@ int aom_compare_img(const aom_image_t *const img1,
} }
#endif #endif
for (i = 0; i < img1->d_h; ++i) for (int plane = 0; plane < num_planes; ++plane) {
match &= (memcmp(img1->planes[AOM_PLANE_Y] + i * img1->stride[AOM_PLANE_Y], uint32_t height = plane ? c_h : img1->d_h;
img2->planes[AOM_PLANE_Y] + i * img2->stride[AOM_PLANE_Y],