Compare commits
29 Commits
main
...
sandbox/ji
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ac50b75e50 | ||
![]() |
81c389e790 | ||
![]() |
0a42a1efd4 | ||
![]() |
2aa2ef4094 | ||
![]() |
85c220b2c4 | ||
![]() |
7cbea06386 | ||
![]() |
a4fd58a761 | ||
![]() |
e272e5b8fb | ||
![]() |
5180368403 | ||
![]() |
63c0d8df9f | ||
![]() |
9ce132ac37 | ||
![]() |
9692042493 | ||
![]() |
87a0d5436b | ||
![]() |
948c6d882e | ||
![]() |
79d6b8fc85 | ||
![]() |
b54dd00f53 | ||
![]() |
3239e22a42 | ||
![]() |
a96f2ca319 | ||
![]() |
0207dcde4a | ||
![]() |
33f05e90fe | ||
![]() |
0451c6b6dd | ||
![]() |
d4b8dd76c4 | ||
![]() |
cd4aca5959 | ||
![]() |
64f3820f80 | ||
![]() |
6fc13b5cc2 | ||
![]() |
df2042dc1e | ||
![]() |
a15cf9a5b7 | ||
![]() |
bf99a00340 | ||
![]() |
5f6fe83ac5 |
@ -21,13 +21,13 @@
|
||||
|
||||
namespace {
|
||||
|
||||
const int kLegacyByteAlignment = 0;
|
||||
const int kLegacyYPlaneByteAlignment = 32;
|
||||
const int kNumPlanesToCheck = 3;
|
||||
const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
|
||||
const char kVP9Md5File[] = "vp90-2-02-size-lf-1920x1080.webm.md5";
|
||||
//const int kLegacyByteAlignment = 0;
|
||||
//const int kLegacyYPlaneByteAlignment = 32;
|
||||
//const int kNumPlanesToCheck = 3;
|
||||
//const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
|
||||
//const char kVP9Md5File[] = "vp90-2-02-size-lf-1920x1080.webm.md5";
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
#if CONFIG_WEBM_IO && 0
|
||||
|
||||
struct ByteAlignmentTestParam {
|
||||
int byte_alignment;
|
||||
|
@ -398,7 +398,7 @@ TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
|
||||
delete video;
|
||||
}
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
#if CONFIG_WEBM_IO && 0
|
||||
TEST_F(ExternalFrameBufferTest, MinFrameBuffers) {
|
||||
// Minimum number of external frame buffers for VP9 is
|
||||
// #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS.
|
||||
@ -481,8 +481,8 @@ TEST_F(ExternalFrameBufferTest, SetAfterDecode) {
|
||||
}
|
||||
#endif // CONFIG_WEBM_IO
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(ExternalFrameBufferMD5Test,
|
||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||
libvpx_test::kVP9TestVectors +
|
||||
libvpx_test::kNumVP9TestVectors));
|
||||
//VP9_INSTANTIATE_TEST_CASE(ExternalFrameBufferMD5Test,
|
||||
// ::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||
// libvpx_test::kVP9TestVectors +
|
||||
// libvpx_test::kNumVP9TestVectors));
|
||||
} // namespace
|
||||
|
@ -110,23 +110,23 @@ TEST_P(InvalidFileTest, ReturnCode) {
|
||||
RunTest();
|
||||
}
|
||||
|
||||
const DecodeParam kVP9InvalidFileTests[] = {
|
||||
{1, "invalid-vp90-02-v2.webm"},
|
||||
{1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf"},
|
||||
{1, "invalid-vp90-03-v3.webm"},
|
||||
{1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf"},
|
||||
{1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf"},
|
||||
{1, "invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf"},
|
||||
{1, "invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf"},
|
||||
{1, "invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf"},
|
||||
{1, "invalid-vp91-2-mixedrefcsp-444to420.ivf"},
|
||||
{1, "invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf"},
|
||||
{1, "invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf"},
|
||||
{1, "invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf"},
|
||||
};
|
||||
//const DecodeParam kVP9InvalidFileTests[] = {
|
||||
// {1, "invalid-vp90-02-v2.webm"},
|
||||
// {1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf"},
|
||||
// {1, "invalid-vp90-03-v3.webm"},
|
||||
// {1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf"},
|
||||
// {1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf"},
|
||||
// {1, "invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf"},
|
||||
// {1, "invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf"},
|
||||
// {1, "invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf"},
|
||||
// {1, "invalid-vp91-2-mixedrefcsp-444to420.ivf"},
|
||||
// {1, "invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf"},
|
||||
// {1, "invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf"},
|
||||
// {1, "invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf"},
|
||||
//};
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(InvalidFileTest,
|
||||
::testing::ValuesIn(kVP9InvalidFileTests));
|
||||
//VP9_INSTANTIATE_TEST_CASE(InvalidFileTest,
|
||||
// ::testing::ValuesIn(kVP9InvalidFileTests));
|
||||
|
||||
// This class will include test vectors that are expected to fail
|
||||
// peek. However they are still expected to have no fatal failures.
|
||||
@ -142,26 +142,26 @@ TEST_P(InvalidFileInvalidPeekTest, ReturnCode) {
|
||||
RunTest();
|
||||
}
|
||||
|
||||
const DecodeParam kVP9InvalidFileInvalidPeekTests[] = {
|
||||
{1, "invalid-vp90-01-v2.webm"},
|
||||
};
|
||||
//const DecodeParam kVP9InvalidFileInvalidPeekTests[] = {
|
||||
// {1, "invalid-vp90-01-v2.webm"},
|
||||
//};
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
|
||||
::testing::ValuesIn(kVP9InvalidFileInvalidPeekTests));
|
||||
//VP9_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
|
||||
// ::testing::ValuesIn(kVP9InvalidFileInvalidPeekTests));
|
||||
|
||||
const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
|
||||
{4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm"},
|
||||
{4, "invalid-"
|
||||
"vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf"},
|
||||
{4, "invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf"},
|
||||
{2, "invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf"},
|
||||
{4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf"},
|
||||
};
|
||||
//const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
|
||||
// {4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm"},
|
||||
// {4, "invalid-"
|
||||
// "vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf"},
|
||||
// {4, "invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf"},
|
||||
// {2, "invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf"},
|
||||
// {4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf"},
|
||||
//};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP9MultiThreaded, InvalidFileTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory*>(&libvpx_test::kVP9)),
|
||||
::testing::ValuesIn(kMultiThreadedVP9InvalidFileTests)));
|
||||
//INSTANTIATE_TEST_CASE_P(
|
||||
// VP9MultiThreaded, InvalidFileTest,
|
||||
// ::testing::Combine(
|
||||
// ::testing::Values(
|
||||
// static_cast<const libvpx_test::CodecFactory*>(&libvpx_test::kVP9)),
|
||||
// ::testing::ValuesIn(kMultiThreadedVP9InvalidFileTests)));
|
||||
} // namespace
|
||||
|
@ -145,28 +145,28 @@ VP8_INSTANTIATE_TEST_CASE(
|
||||
libvpx_test::kNumVP8TestVectors)));
|
||||
|
||||
// Test VP9 decode in serial mode with single thread.
|
||||
VP9_INSTANTIATE_TEST_CASE(
|
||||
TestVectorTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(0), // Serial Mode.
|
||||
::testing::Values(1), // Single thread.
|
||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||
libvpx_test::kVP9TestVectors +
|
||||
libvpx_test::kNumVP9TestVectors)));
|
||||
//VP9_INSTANTIATE_TEST_CASE(
|
||||
// TestVectorTest,
|
||||
// ::testing::Combine(
|
||||
// ::testing::Values(0), // Serial Mode.
|
||||
// ::testing::Values(1), // Single thread.
|
||||
// ::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||
// libvpx_test::kVP9TestVectors +
|
||||
// libvpx_test::kNumVP9TestVectors)));
|
||||
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
// Test VP9 decode in frame parallel mode with different number of threads.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP9MultiThreadedFrameParallel, TestVectorTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
||||
::testing::Combine(
|
||||
::testing::Values(1), // Frame Parallel mode.
|
||||
::testing::Range(2, 9), // With 2 ~ 8 threads.
|
||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||
libvpx_test::kVP9TestVectors +
|
||||
libvpx_test::kNumVP9TestVectors))));
|
||||
#endif
|
||||
//#if CONFIG_VP9_DECODER
|
||||
//// Test VP9 decode in frame parallel mode with different number of threads.
|
||||
//INSTANTIATE_TEST_CASE_P(
|
||||
// VP9MultiThreadedFrameParallel, TestVectorTest,
|
||||
// ::testing::Combine(
|
||||
// ::testing::Values(
|
||||
// static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
||||
// ::testing::Combine(
|
||||
// ::testing::Values(1), // Frame Parallel mode.
|
||||
// ::testing::Range(2, 9), // With 2 ~ 8 threads.
|
||||
// ::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||
// libvpx_test::kVP9TestVectors +
|
||||
// libvpx_test::kNumVP9TestVectors))));
|
||||
//#endif
|
||||
} // namespace
|
||||
|
@ -30,7 +30,7 @@ namespace {
|
||||
using std::string;
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
#if CONFIG_WEBM_IO && 0
|
||||
|
||||
void CheckUserPrivateData(void *user_priv, int *target) {
|
||||
// actual pointer value should be the same as expected.
|
||||
|
@ -43,29 +43,29 @@ void test_decrypt_cb(void *decrypt_state, const uint8_t *input,
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
TEST(TestDecrypt, DecryptWorksVp9) {
|
||||
libvpx_test::IVFVideoSource video("vp90-2-05-resize.ivf");
|
||||
video.Init();
|
||||
|
||||
vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t();
|
||||
VP9Decoder decoder(dec_cfg, 0);
|
||||
|
||||
video.Begin();
|
||||
|
||||
// no decryption
|
||||
vpx_codec_err_t res = decoder.DecodeFrame(video.cxdata(), video.frame_size());
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
|
||||
|
||||
// decrypt frame
|
||||
video.Next();
|
||||
|
||||
std::vector<uint8_t> encrypted(video.frame_size());
|
||||
encrypt_buffer(video.cxdata(), &encrypted[0], video.frame_size(), 0);
|
||||
vpx_decrypt_init di = { test_decrypt_cb, &encrypted[0] };
|
||||
decoder.Control(VPXD_SET_DECRYPTOR, &di);
|
||||
|
||||
res = decoder.DecodeFrame(&encrypted[0], encrypted.size());
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
|
||||
}
|
||||
//TEST(TestDecrypt, DecryptWorksVp9) {
|
||||
// libvpx_test::IVFVideoSource video("vp90-2-05-resize.ivf");
|
||||
// video.Init();
|
||||
//
|
||||
// vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t();
|
||||
// VP9Decoder decoder(dec_cfg, 0);
|
||||
//
|
||||
// video.Begin();
|
||||
//
|
||||
// // no decryption
|
||||
// vpx_codec_err_t res = decoder.DecodeFrame(video.cxdata(), video.frame_size());
|
||||
// ASSERT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
|
||||
//
|
||||
// // decrypt frame
|
||||
// video.Next();
|
||||
//
|
||||
// std::vector<uint8_t> encrypted(video.frame_size());
|
||||
// encrypt_buffer(video.cxdata(), &encrypted[0], video.frame_size(), 0);
|
||||
// vpx_decrypt_init di = { test_decrypt_cb, &encrypted[0] };
|
||||
// decoder.Control(VPXD_SET_DECRYPTOR, &di);
|
||||
//
|
||||
// res = decoder.DecodeFrame(&encrypted[0], encrypted.size());
|
||||
// ASSERT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
|
||||
//}
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
@ -27,7 +27,7 @@ namespace {
|
||||
|
||||
using std::string;
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
#if CONFIG_WEBM_IO && 0
|
||||
|
||||
struct FileList {
|
||||
const char *name;
|
||||
|
@ -152,7 +152,7 @@ TEST(VP9WorkerThreadTest, TestInterfaceAPI) {
|
||||
// -----------------------------------------------------------------------------
|
||||
// Multi-threaded decode tests
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
#if CONFIG_WEBM_IO && 0
|
||||
struct FileList {
|
||||
const char *name;
|
||||
const char *expected_md5;
|
||||
|
@ -114,6 +114,8 @@ void vp9_free_context_buffers(VP9_COMMON *cm) {
|
||||
cm->above_context = NULL;
|
||||
vpx_free(cm->above_seg_context);
|
||||
cm->above_seg_context = NULL;
|
||||
vpx_free(cm->above_txfm_context);
|
||||
cm->above_txfm_context = NULL;
|
||||
}
|
||||
|
||||
int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) {
|
||||
@ -137,6 +139,10 @@ int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) {
|
||||
mi_cols_aligned_to_sb(cm->mi_cols), sizeof(*cm->above_seg_context));
|
||||
if (!cm->above_seg_context) goto fail;
|
||||
|
||||
cm->above_txfm_context = (TXFM_CONTEXT *)vpx_calloc(
|
||||
mi_cols_aligned_to_sb(cm->mi_cols), sizeof(*cm->above_txfm_context));
|
||||
if (!cm->above_txfm_context) goto fail;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
@ -29,6 +29,7 @@ extern "C" {
|
||||
#define BLOCK_SIZE_GROUPS 4
|
||||
#define SKIP_CONTEXTS 3
|
||||
#define INTER_MODE_CONTEXTS 7
|
||||
#define TXFM_PARTITION_CONTEXTS 12
|
||||
|
||||
/* Segment Feature Masks */
|
||||
#define MAX_MV_REF_CANDIDATES 2
|
||||
@ -46,6 +47,7 @@ typedef enum {
|
||||
#define MAX_MB_PLANE 3
|
||||
|
||||
typedef char ENTROPY_CONTEXT;
|
||||
typedef TX_SIZE TXFM_CONTEXT;
|
||||
|
||||
static INLINE int combine_entropy_contexts(ENTROPY_CONTEXT a,
|
||||
ENTROPY_CONTEXT b) {
|
||||
@ -113,6 +115,8 @@ typedef struct {
|
||||
BLOCK_SIZE sb_type;
|
||||
PREDICTION_MODE mode;
|
||||
TX_SIZE tx_size;
|
||||
TX_SIZE inter_tx_size[64]; // Assume maximum of 64x64 block size.
|
||||
TX_SIZE max_tx_size; // Maximum tx size allowed in current block.
|
||||
int8_t skip;
|
||||
int8_t segment_id;
|
||||
int8_t seg_id_predicted; // valid only when temporal_update is enabled
|
||||
@ -126,7 +130,6 @@ typedef struct {
|
||||
int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
|
||||
uint8_t mode_context[MAX_REF_FRAMES];
|
||||
INTERP_FILTER interp_filter;
|
||||
|
||||
} MB_MODE_INFO;
|
||||
|
||||
typedef struct MODE_INFO {
|
||||
@ -218,6 +221,10 @@ typedef struct macroblockd {
|
||||
PARTITION_CONTEXT *above_seg_context;
|
||||
PARTITION_CONTEXT left_seg_context[8];
|
||||
|
||||
TXFM_CONTEXT *above_txfm_context;
|
||||
TXFM_CONTEXT *left_txfm_context;
|
||||
TXFM_CONTEXT left_txfm_context_buffer[8];
|
||||
|
||||
/* mc buffer */
|
||||
DECLARE_ALIGNED(16, uint8_t, mc_buf[80 * 2 * 80 * 2]);
|
||||
|
||||
@ -265,13 +272,21 @@ static INLINE TX_TYPE get_tx_type_4x4(PLANE_TYPE plane_type,
|
||||
|
||||
void vp9_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y);
|
||||
|
||||
static INLINE TX_SIZE get_uv_tx_size_impl(TX_SIZE y_tx_size, BLOCK_SIZE bsize,
|
||||
static TX_SIZE get_uv_tx_size_impl(TX_SIZE y_tx_size, BLOCK_SIZE bsize,
|
||||
int xss, int yss) {
|
||||
if (bsize < BLOCK_8X8) {
|
||||
return TX_4X4;
|
||||
} else {
|
||||
const BLOCK_SIZE plane_bsize = ss_size_lookup[bsize][xss][yss];
|
||||
return MIN(y_tx_size, max_txsize_lookup[plane_bsize]);
|
||||
TX_SIZE uv_tx_size = TX_4X4;
|
||||
if (y_tx_size == TX_32X32)
|
||||
uv_tx_size = TX_16X16;
|
||||
else if (y_tx_size == TX_16X16)
|
||||
uv_tx_size = TX_8X8;
|
||||
else if (y_tx_size == TX_8X8)
|
||||
uv_tx_size = TX_4X4;
|
||||
|
||||
return MIN(uv_tx_size, max_txsize_lookup[plane_bsize]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -300,7 +315,7 @@ void vp9_foreach_transformed_block(
|
||||
const MACROBLOCKD* const xd, BLOCK_SIZE bsize,
|
||||
foreach_transformed_block_visitor visit, void *arg);
|
||||
|
||||
static INLINE void txfrm_block_to_raster_xy(BLOCK_SIZE plane_bsize,
|
||||
static void txfrm_block_to_raster_xy(BLOCK_SIZE plane_bsize,
|
||||
TX_SIZE tx_size, int block,
|
||||
int *x, int *y) {
|
||||
const int bwl = b_width_log2_lookup[plane_bsize];
|
||||
|
@ -13,118 +13,12 @@
|
||||
#include "vp9/common/vp9_onyxc_int.h"
|
||||
#include "vp9/common/vp9_seg_common.h"
|
||||
|
||||
const vp9_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1] = {
|
||||
{ // above = dc
|
||||
{ 137, 30, 42, 148, 151, 207, 70, 52, 91 }, // left = dc
|
||||
{ 92, 45, 102, 136, 116, 180, 74, 90, 100 }, // left = v
|
||||
{ 73, 32, 19, 187, 222, 215, 46, 34, 100 }, // left = h
|
||||
{ 91, 30, 32, 116, 121, 186, 93, 86, 94 }, // left = d45
|
||||
{ 72, 35, 36, 149, 68, 206, 68, 63, 105 }, // left = d135
|
||||
{ 73, 31, 28, 138, 57, 124, 55, 122, 151 }, // left = d117
|
||||
{ 67, 23, 21, 140, 126, 197, 40, 37, 171 }, // left = d153
|
||||
{ 86, 27, 28, 128, 154, 212, 45, 43, 53 }, // left = d207
|
||||
{ 74, 32, 27, 107, 86, 160, 63, 134, 102 }, // left = d63
|
||||
{ 59, 67, 44, 140, 161, 202, 78, 67, 119 } // left = tm
|
||||
}, { // above = v
|
||||
{ 63, 36, 126, 146, 123, 158, 60, 90, 96 }, // left = dc
|
||||
{ 43, 46, 168, 134, 107, 128, 69, 142, 92 }, // left = v
|
||||
{ 44, 29, 68, 159, 201, 177, 50, 57, 77 }, // left = h
|
||||
{ 58, 38, 76, 114, 97, 172, 78, 133, 92 }, // left = d45
|
||||
{ 46, 41, 76, 140, 63, 184, 69, 112, 57 }, // left = d135
|
||||
{ 38, 32, 85, 140, 46, 112, 54, 151, 133 }, // left = d117
|
||||
{ 39, 27, 61, 131, 110, 175, 44, 75, 136 }, // left = d153
|
||||
{ 52, 30, 74, 113, 130, 175, 51, 64, 58 }, // left = d207
|
||||
{ 47, 35, 80, 100, 74, 143, 64, 163, 74 }, // left = d63
|
||||
{ 36, 61, 116, 114, 128, 162, 80, 125, 82 } // left = tm
|
||||
}, { // above = h
|
||||
{ 82, 26, 26, 171, 208, 204, 44, 32, 105 }, // left = dc
|
||||
{ 55, 44, 68, 166, 179, 192, 57, 57, 108 }, // left = v
|
||||
{ 42, 26, 11, 199, 241, 228, 23, 15, 85 }, // left = h
|
||||
{ 68, 42, 19, 131, 160, 199, 55, 52, 83 }, // left = d45
|
||||
{ 58, 50, 25, 139, 115, 232, 39, 52, 118 }, // left = d135
|
||||
{ 50, 35, 33, 153, 104, 162, 64, 59, 131 }, // left = d117
|
||||
{ 44, 24, 16, 150, 177, 202, 33, 19, 156 }, // left = d153
|
||||
{ 55, 27, 12, 153, 203, 218, 26, 27, 49 }, // left = d207
|
||||
{ 53, 49, 21, 110, 116, 168, 59, 80, 76 }, // left = d63
|
||||
{ 38, 72, 19, 168, 203, 212, 50, 50, 107 } // left = tm
|
||||
}, { // above = d45
|
||||
{ 103, 26, 36, 129, 132, 201, 83, 80, 93 }, // left = dc
|
||||
{ 59, 38, 83, 112, 103, 162, 98, 136, 90 }, // left = v
|
||||
{ 62, 30, 23, 158, 200, 207, 59, 57, 50 }, // left = h
|
||||
{ 67, 30, 29, 84, 86, 191, 102, 91, 59 }, // left = d45
|
||||
{ 60, 32, 33, 112, 71, 220, 64, 89, 104 }, // left = d135
|
||||
{ 53, 26, 34, 130, 56, 149, 84, 120, 103 }, // left = d117
|
||||
{ 53, 21, 23, 133, 109, 210, 56, 77, 172 }, // left = d153
|
||||
{ 77, 19, 29, 112, 142, 228, 55, 66, 36 }, // left = d207
|
||||
{ 61, 29, 29, 93, 97, 165, 83, 175, 162 }, // left = d63
|
||||
{ 47, 47, 43, 114, 137, 181, 100, 99, 95 } // left = tm
|
||||
}, { // above = d135
|
||||
{ 69, 23, 29, 128, 83, 199, 46, 44, 101 }, // left = dc
|
||||
{ 53, 40, 55, 139, 69, 183, 61, 80, 110 }, // left = v
|
||||
{ 40, 29, 19, 161, 180, 207, 43, 24, 91 }, // left = h
|
||||
{ 60, 34, 19, 105, 61, 198, 53, 64, 89 }, // left = d45
|
||||
{ 52, 31, 22, 158, 40, 209, 58, 62, 89 }, // left = d135
|
||||
{ 44, 31, 29, 147, 46, 158, 56, 102, 198 }, // left = d117
|
||||
{ 35, 19, 12, 135, 87, 209, 41, 45, 167 }, // left = d153
|
||||
{ 55, 25, 21, 118, 95, 215, 38, 39, 66 }, // left = d207
|
||||
{ 51, 38, 25, 113, 58, 164, 70, 93, 97 }, // left = d63
|
||||
{ 47, 54, 34, 146, 108, 203, 72, 103, 151 } // left = tm
|
||||
}, { // above = d117
|
||||
{ 64, 19, 37, 156, 66, 138, 49, 95, 133 }, // left = dc
|
||||
{ 46, 27, 80, 150, 55, 124, 55, 121, 135 }, // left = v
|
||||
{ 36, 23, 27, 165, 149, 166, 54, 64, 118 }, // left = h
|
||||
{ 53, 21, 36, 131, 63, 163, 60, 109, 81 }, // left = d45
|
||||
{ 40, 26, 35, 154, 40, 185, 51, 97, 123 }, // left = d135
|
||||
{ 35, 19, 34, 179, 19, 97, 48, 129, 124 }, // left = d117
|
||||
{ 36, 20, 26, 136, 62, 164, 33, 77, 154 }, // left = d153
|
||||
{ 45, 18, 32, 130, 90, 157, 40, 79, 91 }, // left = d207
|
||||
{ 45, 26, 28, 129, 45, 129, 49, 147, 123 }, // left = d63
|
||||
{ 38, 44, 51, 136, 74, 162, 57, 97, 121 } // left = tm
|
||||
}, { // above = d153
|
||||
{ 75, 17, 22, 136, 138, 185, 32, 34, 166 }, // left = dc
|
||||
{ 56, 39, 58, 133, 117, 173, 48, 53, 187 }, // left = v
|
||||
{ 35, 21, 12, 161, 212, 207, 20, 23, 145 }, // left = h
|
||||
{ 56, 29, 19, 117, 109, 181, 55, 68, 112 }, // left = d45
|
||||
{ 47, 29, 17, 153, 64, 220, 59, 51, 114 }, // left = d135
|
||||
{ 46, 16, 24, 136, 76, 147, 41, 64, 172 }, // left = d117
|
||||
{ 34, 17, 11, 108, 152, 187, 13, 15, 209 }, // left = d153
|
||||
{ 51, 24, 14, 115, 133, 209, 32, 26, 104 }, // left = d207
|
||||
{ 55, 30, 18, 122, 79, 179, 44, 88, 116 }, // left = d63
|
||||
{ 37, 49, 25, 129, 168, 164, 41, 54, 148 } // left = tm
|
||||
}, { // above = d207
|
||||
{ 82, 22, 32, 127, 143, 213, 39, 41, 70 }, // left = dc
|
||||
{ 62, 44, 61, 123, 105, 189, 48, 57, 64 }, // left = v
|
||||
{ 47, 25, 17, 175, 222, 220, 24, 30, 86 }, // left = h
|
||||
{ 68, 36, 17, 106, 102, 206, 59, 74, 74 }, // left = d45
|
||||
{ 57, 39, 23, 151, 68, 216, 55, 63, 58 }, // left = d135
|
||||
{ 49, 30, 35, 141, 70, 168, 82, 40, 115 }, // left = d117
|
||||
{ 51, 25, 15, 136, 129, 202, 38, 35, 139 }, // left = d153
|
||||
{ 68, 26, 16, 111, 141, 215, 29, 28, 28 }, // left = d207
|
||||
{ 59, 39, 19, 114, 75, 180, 77, 104, 42 }, // left = d63
|
||||
{ 40, 61, 26, 126, 152, 206, 61, 59, 93 } // left = tm
|
||||
}, { // above = d63
|
||||
{ 78, 23, 39, 111, 117, 170, 74, 124, 94 }, // left = dc
|
||||
{ 48, 34, 86, 101, 92, 146, 78, 179, 134 }, // left = v
|
||||
{ 47, 22, 24, 138, 187, 178, 68, 69, 59 }, // left = h
|
||||
{ 56, 25, 33, 105, 112, 187, 95, 177, 129 }, // left = d45
|
||||
{ 48, 31, 27, 114, 63, 183, 82, 116, 56 }, // left = d135
|
||||
{ 43, 28, 37, 121, 63, 123, 61, 192, 169 }, // left = d117
|
||||
{ 42, 17, 24, 109, 97, 177, 56, 76, 122 }, // left = d153
|
||||
{ 58, 18, 28, 105, 139, 182, 70, 92, 63 }, // left = d207
|
||||
{ 46, 23, 32, 74, 86, 150, 67, 183, 88 }, // left = d63
|
||||
{ 36, 38, 48, 92, 122, 165, 88, 137, 91 } // left = tm
|
||||
}, { // above = tm
|
||||
{ 65, 70, 60, 155, 159, 199, 61, 60, 81 }, // left = dc
|
||||
{ 44, 78, 115, 132, 119, 173, 71, 112, 93 }, // left = v
|
||||
{ 39, 38, 21, 184, 227, 206, 42, 32, 64 }, // left = h
|
||||
{ 58, 47, 36, 124, 137, 193, 80, 82, 78 }, // left = d45
|
||||
{ 49, 50, 35, 144, 95, 205, 63, 78, 59 }, // left = d135
|
||||
{ 41, 53, 52, 148, 71, 142, 65, 128, 51 }, // left = d117
|
||||
{ 40, 36, 28, 143, 143, 202, 40, 55, 137 }, // left = d153
|
||||
{ 52, 34, 29, 129, 183, 227, 42, 35, 43 }, // left = d207
|
||||
{ 42, 44, 44, 104, 105, 164, 64, 130, 80 }, // left = d63
|
||||
{ 43, 81, 53, 140, 169, 204, 68, 84, 72 } // left = tm
|
||||
}
|
||||
const vp9_prob vp9_intra_mode_prob[INTRA_MODES] = {
|
||||
227, 223, 219, 213, 204, 191, 170, 127
|
||||
};
|
||||
|
||||
const vp9_prob vp9_intra_predictor_prob[3] = {
|
||||
170, 192, 170
|
||||
};
|
||||
|
||||
const vp9_prob vp9_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1] = {
|
||||
@ -302,6 +196,10 @@ void tx_counts_to_branch_counts_8x8(const unsigned int *tx_count_8x8p,
|
||||
ct_8x8p[0][1] = tx_count_8x8p[TX_8X8];
|
||||
}
|
||||
|
||||
static const vp9_prob default_txfm_partition_probs[TXFM_PARTITION_CONTEXTS] = {
|
||||
141, 139, 175, 87, 196, 165, 177, 75, 220, 179, 205, 197
|
||||
};
|
||||
|
||||
static const vp9_prob default_skip_probs[SKIP_CONTEXTS] = {
|
||||
192, 128, 64
|
||||
};
|
||||
@ -324,6 +222,8 @@ void vp9_init_mode_probs(FRAME_CONTEXT *fc) {
|
||||
vp9_copy(fc->comp_ref_prob, default_comp_ref_p);
|
||||
vp9_copy(fc->single_ref_prob, default_single_ref_p);
|
||||
fc->tx_probs = default_tx_probs;
|
||||
vp9_copy(fc->txfm_partition_prob, default_txfm_partition_probs);
|
||||
vp9_copy(fc->intra_predictor_prob, vp9_intra_predictor_prob);
|
||||
vp9_copy(fc->skip_probs, default_skip_probs);
|
||||
vp9_copy(fc->inter_mode_probs, default_inter_mode_probs);
|
||||
}
|
||||
@ -402,6 +302,11 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < TXFM_PARTITION_CONTEXTS; ++i)
|
||||
fc->txfm_partition_prob[i] =
|
||||
mode_mv_merge_probs(pre_fc->txfm_partition_prob[i],
|
||||
counts->txfm_partition[i]);
|
||||
|
||||
for (i = 0; i < SKIP_CONTEXTS; ++i)
|
||||
fc->skip_probs[i] = mode_mv_merge_probs(
|
||||
pre_fc->skip_probs[i], counts->skip[i]);
|
||||
|
@ -49,6 +49,8 @@ typedef struct frame_contexts {
|
||||
vp9_prob single_ref_prob[REF_CONTEXTS][2];
|
||||
vp9_prob comp_ref_prob[REF_CONTEXTS];
|
||||
struct tx_probs tx_probs;
|
||||
vp9_prob txfm_partition_prob[TXFM_PARTITION_CONTEXTS];
|
||||
vp9_prob intra_predictor_prob[3];
|
||||
vp9_prob skip_probs[SKIP_CONTEXTS];
|
||||
nmv_context nmvc;
|
||||
int initialized;
|
||||
@ -70,12 +72,13 @@ typedef struct FRAME_COUNTS {
|
||||
unsigned int comp_ref[REF_CONTEXTS][2];
|
||||
struct tx_counts tx;
|
||||
unsigned int skip[SKIP_CONTEXTS][2];
|
||||
unsigned int txfm_partition[TXFM_PARTITION_CONTEXTS][2];
|
||||
unsigned int intra_predictor[2][2];
|
||||
nmv_context_counts mv;
|
||||
} FRAME_COUNTS;
|
||||
|
||||
extern const vp9_prob vp9_intra_mode_prob[INTRA_MODES];
|
||||
extern const vp9_prob vp9_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1];
|
||||
extern const vp9_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES]
|
||||
[INTRA_MODES - 1];
|
||||
extern const vp9_prob vp9_kf_partition_probs[PARTITION_CONTEXTS]
|
||||
[PARTITION_TYPES - 1];
|
||||
extern const vp9_tree_index vp9_intra_mode_tree[TREE_SIZE(INTRA_MODES)];
|
||||
@ -97,15 +100,6 @@ void tx_counts_to_branch_counts_16x16(const unsigned int *tx_count_16x16p,
|
||||
void tx_counts_to_branch_counts_8x8(const unsigned int *tx_count_8x8p,
|
||||
unsigned int (*ct_8x8p)[2]);
|
||||
|
||||
static INLINE const vp9_prob *get_y_mode_probs(const MODE_INFO *mi,
|
||||
const MODE_INFO *above_mi,
|
||||
const MODE_INFO *left_mi,
|
||||
int block) {
|
||||
const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi, block);
|
||||
const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi, block);
|
||||
return vp9_kf_y_mode_prob[above][left];
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -1176,27 +1176,37 @@ void vp9_filter_block_plane_non420(VP9_COMMON *cm,
|
||||
// Determine the vertical edges that need filtering
|
||||
for (c = 0; c < MI_BLOCK_SIZE && mi_col + c < cm->mi_cols; c += col_step) {
|
||||
const MODE_INFO *mi = mi_8x8[c].src_mi;
|
||||
const BLOCK_SIZE sb_type = mi[0].mbmi.sb_type;
|
||||
const int skip_this = mi[0].mbmi.skip && is_inter_block(&mi[0].mbmi);
|
||||
const MB_MODE_INFO *mbmi = &mi[0].mbmi;
|
||||
const BLOCK_SIZE sb_type = mbmi->sb_type;
|
||||
const int skip_this = mbmi->skip && is_inter_block(mbmi);
|
||||
const int blk_row = r & (num_8x8_blocks_high_lookup[sb_type] - 1);
|
||||
const int blk_col = c & (num_8x8_blocks_wide_lookup[sb_type] - 1);
|
||||
// left edge of current unit is block/partition edge -> no skip
|
||||
const int block_edge_left = (num_4x4_blocks_wide_lookup[sb_type] > 1) ?
|
||||
!(c & (num_8x8_blocks_wide_lookup[sb_type] - 1)) : 1;
|
||||
!blk_col : 1;
|
||||
const int skip_this_c = skip_this && !block_edge_left;
|
||||
// top edge of current unit is block/partition edge -> no skip
|
||||
const int block_edge_above = (num_4x4_blocks_high_lookup[sb_type] > 1) ?
|
||||
!(r & (num_8x8_blocks_high_lookup[sb_type] - 1)) : 1;
|
||||
!blk_row : 1;
|
||||
const int skip_this_r = skip_this && !block_edge_above;
|
||||
const TX_SIZE tx_size = (plane->plane_type == PLANE_TYPE_UV)
|
||||
? get_uv_tx_size(&mi[0].mbmi, plane)
|
||||
: mi[0].mbmi.tx_size;
|
||||
|
||||
TX_SIZE tx_size = (plane->plane_type == PLANE_TYPE_UV) ?
|
||||
get_uv_tx_size_impl(mbmi->tx_size, mbmi->sb_type, ss_x, ss_y)
|
||||
: mbmi->tx_size;
|
||||
const int skip_border_4x4_c = ss_x && mi_col + c == cm->mi_cols - 1;
|
||||
const int skip_border_4x4_r = ss_y && mi_row + r == cm->mi_rows - 1;
|
||||
|
||||
// Filter level can vary per MI
|
||||
if (!(lfl[(r << 3) + (c >> ss_x)] =
|
||||
get_filter_level(&cm->lf_info, &mi[0].mbmi)))
|
||||
get_filter_level(&cm->lf_info, mbmi)))
|
||||
continue;
|
||||
|
||||
if (is_inter_block(mbmi) && !mbmi->skip)
|
||||
tx_size = (plane->plane_type == PLANE_TYPE_UV) ?
|
||||
get_uv_tx_size_impl(mbmi->inter_tx_size[blk_row * 8 + blk_col],
|
||||
mbmi->sb_type, ss_x, ss_y)
|
||||
: mbmi->inter_tx_size[blk_row * 8 + blk_col];
|
||||
|
||||
// Build masks based on the transform size of each block
|
||||
if (tx_size == TX_32X32) {
|
||||
if (!skip_this_c && ((c >> ss_x) & 3) == 0) {
|
||||
@ -1531,19 +1541,8 @@ void vp9_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer,
|
||||
struct macroblockd_plane planes[MAX_MB_PLANE],
|
||||
int start, int stop, int y_only) {
|
||||
const int num_planes = y_only ? 1 : MAX_MB_PLANE;
|
||||
enum lf_path path;
|
||||
LOOP_FILTER_MASK lfm;
|
||||
int mi_row, mi_col;
|
||||
|
||||
if (y_only)
|
||||
path = LF_PATH_444;
|
||||
else if (planes[1].subsampling_y == 1 && planes[1].subsampling_x == 1)
|
||||
path = LF_PATH_420;
|
||||
else if (planes[1].subsampling_y == 0 && planes[1].subsampling_x == 0)
|
||||
path = LF_PATH_444;
|
||||
else
|
||||
path = LF_PATH_SLOW;
|
||||
|
||||
for (mi_row = start; mi_row < stop; mi_row += MI_BLOCK_SIZE) {
|
||||
MODE_INFO *mi = cm->mi + mi_row * cm->mi_stride;
|
||||
|
||||
@ -1552,25 +1551,9 @@ void vp9_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer,
|
||||
|
||||
vp9_setup_dst_planes(planes, frame_buffer, mi_row, mi_col);
|
||||
|
||||
// TODO(JBB): Make setup_mask work for non 420.
|
||||
vp9_setup_mask(cm, mi_row, mi_col, mi + mi_col, cm->mi_stride,
|
||||
&lfm);
|
||||
|
||||
vp9_filter_block_plane_ss00(cm, &planes[0], mi_row, &lfm);
|
||||
for (plane = 1; plane < num_planes; ++plane) {
|
||||
switch (path) {
|
||||
case LF_PATH_420:
|
||||
vp9_filter_block_plane_ss11(cm, &planes[plane], mi_row, &lfm);
|
||||
break;
|
||||
case LF_PATH_444:
|
||||
vp9_filter_block_plane_ss00(cm, &planes[plane], mi_row, &lfm);
|
||||
break;
|
||||
case LF_PATH_SLOW:
|
||||
vp9_filter_block_plane_non420(cm, &planes[plane], mi + mi_col,
|
||||
mi_row, mi_col);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (plane = 0; plane < num_planes; ++plane)
|
||||
vp9_filter_block_plane_non420(cm, &planes[plane], mi + mi_col,
|
||||
mi_row, mi_col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -266,8 +266,9 @@ typedef struct VP9Common {
|
||||
// External BufferPool passed from outside.
|
||||
BufferPool *buffer_pool;
|
||||
|
||||
PARTITION_CONTEXT *above_seg_context;
|
||||
ENTROPY_CONTEXT *above_context;
|
||||
PARTITION_CONTEXT *above_seg_context;
|
||||
TXFM_CONTEXT *above_txfm_context;
|
||||
} VP9_COMMON;
|
||||
|
||||
// TODO(hkuang): Don't need to lock the whole pool after implementing atomic
|
||||
@ -328,6 +329,7 @@ static INLINE void init_macroblockd(VP9_COMMON *cm, MACROBLOCKD *xd) {
|
||||
}
|
||||
|
||||
xd->above_seg_context = cm->above_seg_context;
|
||||
xd->above_txfm_context = cm->above_txfm_context;
|
||||
xd->mi_stride = cm->mi_stride;
|
||||
xd->error_info = &cm->error;
|
||||
}
|
||||
@ -427,6 +429,30 @@ static INLINE int partition_plane_context(const MACROBLOCKD *xd,
|
||||
return (left * 2 + above) + bsl * PARTITION_PLOFFSET;
|
||||
}
|
||||
|
||||
static void txfm_partition_update(TXFM_CONTEXT *above_ctx,
|
||||
TXFM_CONTEXT *left_ctx,
|
||||
TX_SIZE tx_size) {
|
||||
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
||||
int bs = num_8x8_blocks_high_lookup[bsize];
|
||||
int i;
|
||||
for (i = 0; i < bs; ++i) {
|
||||
above_ctx[i] = tx_size;
|
||||
left_ctx[i] = tx_size;
|
||||
}
|
||||
}
|
||||
|
||||
static int max_tx_size_offset[TX_SIZES] = {0, 0, 2, 6};
|
||||
|
||||
static int txfm_partition_context(const TXFM_CONTEXT *above_ctx,
|
||||
const TXFM_CONTEXT *left_ctx,
|
||||
TX_SIZE max_tx_size,
|
||||
TX_SIZE tx_size) {
|
||||
int above = *above_ctx < tx_size;
|
||||
int left = *left_ctx < tx_size;
|
||||
return max_tx_size_offset[max_tx_size] +
|
||||
2 * (max_tx_size - tx_size) + (above || left);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -138,7 +138,6 @@ void thread_loop_filter_rows(const YV12_BUFFER_CONFIG *const frame_buffer,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sync_write(lf_sync, r, c, sb_cols);
|
||||
}
|
||||
}
|
||||
@ -400,6 +399,10 @@ void vp9_accumulate_frame_counts(VP9_COMMON *cm, FRAME_COUNTS *counts,
|
||||
for (i = 0; i < TX_SIZES; i++)
|
||||
cm->counts.tx.tx_totals[i] += counts->tx.tx_totals[i];
|
||||
|
||||
for (i = 0; i < TXFM_PARTITION_CONTEXTS; ++i)
|
||||
for (j = 0; j < 2; ++j)
|
||||
cm->counts.txfm_partition[i][j] += counts->txfm_partition[i][j];
|
||||
|
||||
for (i = 0; i < SKIP_CONTEXTS; i++)
|
||||
for (j = 0; j < 2; j++)
|
||||
cm->counts.skip[i][j] += counts->skip[i][j];
|
||||
|
@ -338,6 +338,59 @@ struct inter_args {
|
||||
const int16_t *const uv_dequant;
|
||||
};
|
||||
|
||||
static void decode_reconstruct_tx(int blk_row, int blk_col,
|
||||
int plane, int block,
|
||||
TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
|
||||
void *arg) {
|
||||
struct inter_args *args = (struct inter_args *)arg;
|
||||
VP9_COMMON *const cm = args->cm;
|
||||
MACROBLOCKD *const xd = args->xd;
|
||||
MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
|
||||
(blk_col >> (1 - pd->subsampling_x));
|
||||
TX_SIZE plane_tx_size = plane ?
|
||||
get_uv_tx_size_impl(mbmi->inter_tx_size[tx_idx], plane_bsize, 0, 0) :
|
||||
mbmi->inter_tx_size[tx_idx];
|
||||
|
||||
int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
|
||||
int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
|
||||
|
||||
if (xd->mb_to_bottom_edge < 0)
|
||||
max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
|
||||
if (xd->mb_to_right_edge < 0)
|
||||
max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
|
||||
|
||||
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
|
||||
return;
|
||||
|
||||
if (tx_size == plane_tx_size) {
|
||||
const int16_t *const dequant = (plane == 0) ? args->y_dequant
|
||||
: args->uv_dequant;
|
||||
int eob;
|
||||
eob = vp9_decode_block_tokens(cm, xd, args->counts, plane, block,
|
||||
plane_bsize, blk_col, blk_row,
|
||||
tx_size, args->r, dequant);
|
||||
inverse_transform_block(xd, plane, block, tx_size,
|
||||
&pd->dst.buf[4 * blk_row * pd->dst.stride +
|
||||
4 * blk_col],
|
||||
pd->dst.stride, eob);
|
||||
*args->eobtotal += eob;
|
||||
} else {
|
||||
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
||||
int bh = num_4x4_blocks_high_lookup[bsize];
|
||||
int step = 1 << (2 *(tx_size - 1));
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
int offsetr = (i >> 1) * bh / 2;
|
||||
int offsetc = (i & 0x01) * bh / 2;
|
||||
decode_reconstruct_tx(blk_row + offsetr, blk_col + offsetc,
|
||||
plane, block + i * step, tx_size - 1,
|
||||
plane_bsize, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void reconstruct_inter_block(int plane, int block,
|
||||
BLOCK_SIZE plane_bsize,
|
||||
TX_SIZE tx_size, void *arg) {
|
||||
@ -370,6 +423,7 @@ static MB_MODE_INFO *set_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd,
|
||||
xd->mi = cm->mi + offset;
|
||||
xd->mi[0].src_mi = &xd->mi[0]; // Point to self.
|
||||
xd->mi[0].mbmi.sb_type = bsize;
|
||||
xd->mi[0].mbmi.max_tx_size = max_txsize_lookup[bsize];
|
||||
|
||||
for (y = 0; y < y_mis; ++y)
|
||||
for (x = !y; x < x_mis; ++x) {
|
||||
@ -425,12 +479,32 @@ static void decode_block(VP9Decoder *const pbi, MACROBLOCKD *const xd,
|
||||
int eobtotal = 0;
|
||||
struct inter_args arg = {cm, xd, r, counts, &eobtotal, y_dequant,
|
||||
uv_dequant};
|
||||
vp9_foreach_transformed_block(xd, bsize, reconstruct_inter_block, &arg);
|
||||
int plane;
|
||||
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
|
||||
const struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
|
||||
const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
|
||||
const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
|
||||
BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
|
||||
int bh = num_4x4_blocks_wide_lookup[txb_size];
|
||||
int idx, idy;
|
||||
int block = 0;
|
||||
int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
|
||||
|
||||
for (idy = 0; idy < mi_height; idy += bh) {
|
||||
for (idx = 0; idx < mi_width; idx += bh) {
|
||||
decode_reconstruct_tx(idy, idx, plane, block,
|
||||
max_txsize_lookup[plane_bsize],
|
||||
plane_bsize, &arg);
|
||||
block += step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!less8x8 && eobtotal == 0)
|
||||
mbmi->skip = 1; // skip loopfilter
|
||||
}
|
||||
}
|
||||
|
||||
xd->corrupted |= vp9_reader_has_error(r);
|
||||
}
|
||||
|
||||
@ -943,9 +1017,10 @@ static const uint8_t *decode_tiles(VP9Decoder *pbi,
|
||||
// are allocated as part of the same buffer.
|
||||
vpx_memset(cm->above_context, 0,
|
||||
sizeof(*cm->above_context) * MAX_MB_PLANE * 2 * aligned_cols);
|
||||
|
||||
vpx_memset(cm->above_seg_context, 0,
|
||||
sizeof(*cm->above_seg_context) * aligned_cols);
|
||||
vpx_memset(cm->above_txfm_context, 0,
|
||||
sizeof(*cm->above_txfm_context) * aligned_cols);
|
||||
|
||||
get_tile_buffers(pbi, data, data_end, tile_cols, tile_rows, tile_buffers);
|
||||
|
||||
@ -988,6 +1063,7 @@ static const uint8_t *decode_tiles(VP9Decoder *pbi,
|
||||
vp9_tile_set_col(&tile, tile_data->cm, col);
|
||||
vp9_zero(tile_data->xd.left_context);
|
||||
vp9_zero(tile_data->xd.left_seg_context);
|
||||
vp9_zero(tile_data->xd.left_txfm_context_buffer);
|
||||
for (mi_col = tile.mi_col_start; mi_col < tile.mi_col_end;
|
||||
mi_col += MI_BLOCK_SIZE) {
|
||||
decode_partition(pbi, &tile_data->xd, &cm->counts, &tile, mi_row,
|
||||
@ -1061,6 +1137,7 @@ static int tile_worker_hook(TileWorkerData *const tile_data,
|
||||
mi_row += MI_BLOCK_SIZE) {
|
||||
vp9_zero(tile_data->xd.left_context);
|
||||
vp9_zero(tile_data->xd.left_seg_context);
|
||||
vp9_zero(tile_data->xd.left_txfm_context_buffer);
|
||||
for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
|
||||
mi_col += MI_BLOCK_SIZE) {
|
||||
decode_partition(tile_data->pbi, &tile_data->xd, &tile_data->counts,
|
||||
@ -1146,6 +1223,8 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi,
|
||||
sizeof(*cm->above_context) * MAX_MB_PLANE * 2 * aligned_mi_cols);
|
||||
vpx_memset(cm->above_seg_context, 0,
|
||||
sizeof(*cm->above_seg_context) * aligned_mi_cols);
|
||||
vpx_memset(cm->above_txfm_context, 0,
|
||||
sizeof(*cm->above_txfm_context) * aligned_mi_cols);
|
||||
|
||||
// Load tile data into tile_buffers
|
||||
get_tile_buffers(pbi, data, data_end, tile_cols, tile_rows, tile_buffers);
|
||||
@ -1516,6 +1595,12 @@ static int read_compressed_header(VP9Decoder *pbi, const uint8_t *data,
|
||||
read_tx_mode_probs(&fc->tx_probs, &r);
|
||||
read_coef_probs(fc, cm->tx_mode, &r);
|
||||
|
||||
for (k = 0; k < TXFM_PARTITION_CONTEXTS; ++k)
|
||||
vp9_diff_update_prob(&r, &fc->txfm_partition_prob[k]);
|
||||
|
||||
for (k = 0; k < 3; ++k)
|
||||
vp9_diff_update_prob(&r, &fc->intra_predictor_prob[k]);
|
||||
|
||||
for (k = 0; k < SKIP_CONTEXTS; ++k)
|
||||
vp9_diff_update_prob(&r, &fc->skip_probs[k]);
|
||||
|
||||
|
@ -23,6 +23,51 @@
|
||||
#include "vp9/decoder/vp9_decodeframe.h"
|
||||
#include "vp9/decoder/vp9_reader.h"
|
||||
|
||||
static PREDICTION_MODE read_intra_mode_exp(const VP9_COMMON *cm,
|
||||
vp9_reader *r, const MODE_INFO *mi,
|
||||
const MODE_INFO *above_mi,
|
||||
const MODE_INFO *left_mi,
|
||||
int block) {
|
||||
const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi, block);
|
||||
const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi, block);
|
||||
PREDICTION_MODE i;
|
||||
int count = 0;
|
||||
|
||||
if (above == left) {
|
||||
if (vp9_read(r, cm->fc->intra_predictor_prob[0]))
|
||||
return above;
|
||||
for (i = DC_PRED; i < INTRA_MODES - 1; ++i) {
|
||||
if (i == above)
|
||||
continue;
|
||||
if (vp9_read(r, vp9_intra_mode_prob[count]))
|
||||
return i;
|
||||
++count;
|
||||
if (count == INTRA_MODES - 2)
|
||||
return (i + 1) == above ? (i + 2) : (i + 1);
|
||||
}
|
||||
return (INTRA_MODES - 1);
|
||||
} else {
|
||||
if (vp9_read(r, cm->fc->intra_predictor_prob[1]))
|
||||
return above;
|
||||
if (vp9_read(r, cm->fc->intra_predictor_prob[2]))
|
||||
return left;
|
||||
|
||||
for (i = DC_PRED; i < INTRA_MODES - 1; ++i) {
|
||||
if (i == above || i == left)
|
||||
continue;
|
||||
if (vp9_read(r, vp9_intra_mode_prob[count + 1]))
|
||||
return i;
|
||||
++count;
|
||||
if (count == INTRA_MODES - 3)
|
||||
break;
|
||||
}
|
||||
for (++i; i <= INTRA_MODES - 1; ++i)
|
||||
if (i != above && i != left)
|
||||
return i;
|
||||
return (INTRA_MODES - 1);
|
||||
}
|
||||
}
|
||||
|
||||
static PREDICTION_MODE read_intra_mode(vp9_reader *r, const vp9_prob *p) {
|
||||
return (PREDICTION_MODE)vp9_read_tree(r, vp9_intra_mode_tree, p);
|
||||
}
|
||||
@ -60,6 +105,62 @@ static int read_segment_id(vp9_reader *r, const struct segmentation *seg) {
|
||||
return vp9_read_tree(r, vp9_segment_tree, seg->tree_probs);
|
||||
}
|
||||
|
||||
static void read_tx_size_inter(VP9_COMMON *cm, MACROBLOCKD *xd,
|
||||
FRAME_COUNTS *counts, TX_SIZE tx_size,
|
||||
int blk_row, int blk_col, vp9_reader *r) {
|
||||
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
int is_split = 0;
|
||||
int tx_idx = (blk_row / 2) * 8 + (blk_col / 2);
|
||||
int max_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
|
||||
int max_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
|
||||
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
||||
int bh = num_4x4_blocks_high_lookup[bsize];
|
||||
int i, j;
|
||||
int ctx = txfm_partition_context(xd->above_txfm_context + (blk_col / 2),
|
||||
xd->left_txfm_context + (blk_row / 2),
|
||||
mbmi->max_tx_size,
|
||||
tx_size);
|
||||
if (xd->mb_to_bottom_edge < 0)
|
||||
max_blocks_high += xd->mb_to_bottom_edge >> 5;
|
||||
if (xd->mb_to_right_edge < 0)
|
||||
max_blocks_wide += xd->mb_to_right_edge >> 5;
|
||||
|
||||
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
|
||||
return;
|
||||
|
||||
is_split = vp9_read(r, cm->fc->txfm_partition_prob[ctx]);
|
||||
|
||||
if (!is_split) {
|
||||
mbmi->inter_tx_size[tx_idx] = tx_size;
|
||||
for (j = 0; j < bh / 2; ++j)
|
||||
for (i = 0; i < bh / 2; ++i)
|
||||
mbmi->inter_tx_size[tx_idx + j * 8 + i] = tx_size;
|
||||
mbmi->tx_size = tx_size;
|
||||
++counts->txfm_partition[ctx][0];
|
||||
txfm_partition_update(xd->above_txfm_context + (blk_col / 2),
|
||||
xd->left_txfm_context + (blk_row / 2), tx_size);
|
||||
} else {
|
||||
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
||||
int bh = num_4x4_blocks_high_lookup[bsize];
|
||||
int i;
|
||||
++counts->txfm_partition[ctx][1];
|
||||
if (tx_size == TX_8X8) {
|
||||
mbmi->inter_tx_size[tx_idx] = TX_4X4;
|
||||
mbmi->tx_size = TX_4X4;
|
||||
txfm_partition_update(xd->above_txfm_context + (blk_col / 2),
|
||||
xd->left_txfm_context + (blk_row / 2), TX_4X4);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
int offsetr = (i >> 1) * bh / 2;
|
||||
int offsetc = (i & 0x01) * bh / 2;
|
||||
read_tx_size_inter(cm, xd, counts, tx_size - 1,
|
||||
blk_row + offsetr, blk_col + offsetc, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static TX_SIZE read_selected_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd,
|
||||
FRAME_COUNTS *counts,
|
||||
TX_SIZE max_tx_size, vp9_reader *r) {
|
||||
@ -208,24 +309,24 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
|
||||
case BLOCK_4X4:
|
||||
for (i = 0; i < 4; ++i)
|
||||
mi->bmi[i].as_mode =
|
||||
read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, i));
|
||||
read_intra_mode_exp(cm, r, mi, above_mi, left_mi, i);
|
||||
mbmi->mode = mi->bmi[3].as_mode;
|
||||
break;
|
||||
case BLOCK_4X8:
|
||||
mi->bmi[0].as_mode = mi->bmi[2].as_mode =
|
||||
read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0));
|
||||
read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 0);
|
||||
mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode =
|
||||
read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 1));
|
||||
read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 1);
|
||||
break;
|
||||
case BLOCK_8X4:
|
||||
mi->bmi[0].as_mode = mi->bmi[1].as_mode =
|
||||
read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0));
|
||||
read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 0);
|
||||
mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode =
|
||||
read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 2));
|
||||
read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 2);
|
||||
break;
|
||||
default:
|
||||
mbmi->mode = read_intra_mode(r,
|
||||
get_y_mode_probs(mi, above_mi, left_mi, 0));
|
||||
mbmi->mode =
|
||||
read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 0);
|
||||
}
|
||||
|
||||
mbmi->uv_mode = read_intra_mode(r, vp9_kf_uv_mode_prob[mbmi->mode]);
|
||||
@ -569,13 +670,63 @@ static void read_inter_frame_mode_info(VP9Decoder *const pbi,
|
||||
MODE_INFO *const mi = xd->mi[0].src_mi;
|
||||
MB_MODE_INFO *const mbmi = &mi->mbmi;
|
||||
int inter_block;
|
||||
BLOCK_SIZE bsize = mbmi->sb_type;
|
||||
|
||||
mbmi->mv[0].as_int = 0;
|
||||
mbmi->mv[1].as_int = 0;
|
||||
mbmi->segment_id = read_inter_segment_id(cm, xd, mi_row, mi_col, r);
|
||||
mbmi->skip = read_skip(cm, xd, counts, mbmi->segment_id, r);
|
||||
inter_block = read_is_inter_block(cm, xd, counts, mbmi->segment_id, r);
|
||||
mbmi->tx_size = read_tx_size(cm, xd, counts, !mbmi->skip || !inter_block, r);
|
||||
xd->above_txfm_context = cm->above_txfm_context + mi_col;
|
||||
xd->left_txfm_context = xd->left_txfm_context_buffer + (mi_row & 0x07);
|
||||
|
||||
if (mbmi->sb_type >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT &&
|
||||
!mbmi->skip && inter_block) {
|
||||
BLOCK_SIZE txb_size = txsize_to_bsize[mbmi->max_tx_size];
|
||||
int bh = num_4x4_blocks_wide_lookup[txb_size];
|
||||
int width = num_4x4_blocks_wide_lookup[bsize];
|
||||
int height = num_4x4_blocks_high_lookup[bsize];
|
||||
int idx, idy;
|
||||
for (idy = 0; idy < height; idy += bh)
|
||||
for (idx = 0; idx < width; idx += bh)
|
||||
read_tx_size_inter(cm, xd, counts, mbmi->max_tx_size,
|
||||
idy, idx, r);
|
||||
} else {
|
||||
int i;
|
||||
mbmi->tx_size = read_tx_size(cm, xd, counts,
|
||||
!mbmi->skip || !inter_block, r);
|
||||
for (i = 0; i < 64; ++i)
|
||||
mbmi->inter_tx_size[i] = mbmi->tx_size;
|
||||
}
|
||||
|
||||
if (mbmi->sb_type < BLOCK_8X8)
|
||||
txfm_partition_update(xd->above_txfm_context, xd->left_txfm_context,
|
||||
TX_4X4);
|
||||
|
||||
if (inter_block) {
|
||||
if (bsize >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT && mbmi->skip) {
|
||||
BLOCK_SIZE txb_size = txsize_to_bsize[mbmi->max_tx_size];
|
||||
int bh = num_4x4_blocks_wide_lookup[txb_size];
|
||||
int width = num_4x4_blocks_wide_lookup[bsize];
|
||||
int height = num_4x4_blocks_high_lookup[bsize];
|
||||
int idx, idy;
|
||||
for (idy = 0; idy < height; idy += bh)
|
||||
for (idx = 0; idx < width; idx += bh)
|
||||
txfm_partition_update(xd->above_txfm_context + (idx / 2),
|
||||
xd->left_txfm_context + (idy / 2),
|
||||
mbmi->max_tx_size);
|
||||
}
|
||||
} else {
|
||||
BLOCK_SIZE txb_size = txsize_to_bsize[mbmi->max_tx_size];
|
||||
int bh = num_4x4_blocks_wide_lookup[txb_size];
|
||||
int width = num_4x4_blocks_wide_lookup[bsize];
|
||||
int height = num_4x4_blocks_high_lookup[bsize];
|
||||
int idx, idy;
|
||||
for (idy = 0; idy < height; idy += bh)
|
||||
for (idx = 0; idx < width; idx += bh)
|
||||
txfm_partition_update(xd->above_txfm_context + (idx / 2),
|
||||
xd->left_txfm_context + (idy / 2), mbmi->tx_size);
|
||||
}
|
||||
|
||||
if (inter_block)
|
||||
read_inter_block_mode_info(pbi, xd, counts, tile, mi, mi_row, mi_col, r);
|
||||
|
@ -44,6 +44,53 @@ static const struct vp9_token partition_encodings[PARTITION_TYPES] =
|
||||
static const struct vp9_token inter_mode_encodings[INTER_MODES] =
|
||||
{{2, 2}, {6, 3}, {0, 1}, {7, 3}};
|
||||
|
||||
static void write_intra_mode_exp(const VP9_COMMON *cm,
|
||||
vp9_writer *w, const MODE_INFO *mi,
|
||||
const MODE_INFO *above_mi,
|
||||
const MODE_INFO *left_mi, int block,
|
||||
PREDICTION_MODE mode) {
|
||||
const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi, block);
|
||||
const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi, block);
|
||||
PREDICTION_MODE i;
|
||||
int count = 0;
|
||||
|
||||
if (above == left) {
|
||||
vp9_write(w, mode == above, cm->fc->intra_predictor_prob[0]);
|
||||
if (mode == above)
|
||||
return;
|
||||
|
||||
for (i = DC_PRED; i < INTRA_MODES - 1; ++i) {
|
||||
if (i == above)
|
||||
continue;
|
||||
vp9_write(w, i == mode, vp9_intra_mode_prob[count]);
|
||||
++count;
|
||||
if (i == mode)
|
||||
return;
|
||||
if (count == INTRA_MODES - 2)
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// above and left reference modes differ
|
||||
vp9_write(w, mode == above, cm->fc->intra_predictor_prob[1]);
|
||||
if (mode == above)
|
||||
return;
|
||||
vp9_write(w, mode == left, cm->fc->intra_predictor_prob[2]);
|
||||
if (mode == left)
|
||||
return;
|
||||
|
||||
for (i = DC_PRED; i < INTRA_MODES - 1; ++i) {
|
||||
if (i == above || i == left)
|
||||
continue;
|
||||
vp9_write(w, i == mode, vp9_intra_mode_prob[count + 1]);
|
||||
++count;
|
||||
if (i == mode)
|
||||
return;
|
||||
if (count == INTRA_MODES - 3)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void write_intra_mode(vp9_writer *w, PREDICTION_MODE mode,
|
||||
const vp9_prob *probs) {
|
||||
vp9_write_token(w, vp9_intra_mode_tree, probs, &intra_mode_encodings[mode]);
|
||||
@ -76,6 +123,52 @@ static void prob_diff_update(const vp9_tree_index *tree,
|
||||
vp9_cond_prob_diff_update(w, &probs[i], branch_ct[i]);
|
||||
}
|
||||
|
||||
static void write_tx_size_inter(const VP9_COMMON *cm, MACROBLOCKD *xd,
|
||||
TX_SIZE tx_size, int blk_row, int blk_col,
|
||||
vp9_writer *w) {
|
||||
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
int tx_idx = (blk_row / 2) * 8 + (blk_col / 2);
|
||||
int max_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
|
||||
int max_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
|
||||
int ctx = txfm_partition_context(xd->above_txfm_context + (blk_col / 2),
|
||||
xd->left_txfm_context + (blk_row / 2),
|
||||
mbmi->max_tx_size,
|
||||
tx_size);
|
||||
if (xd->mb_to_bottom_edge < 0)
|
||||
max_blocks_high += xd->mb_to_bottom_edge >> 5;
|
||||
if (xd->mb_to_right_edge < 0)
|
||||
max_blocks_wide += xd->mb_to_right_edge >> 5;
|
||||
|
||||
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
|
||||
return;
|
||||
|
||||
// TODO(jingning): this assumes support of the possible 64x64 transform.
|
||||
if (tx_size == mbmi->inter_tx_size[tx_idx]) {
|
||||
vp9_write(w, 0, cm->fc->txfm_partition_prob[ctx]);
|
||||
txfm_partition_update(xd->above_txfm_context + (blk_col / 2),
|
||||
xd->left_txfm_context + (blk_row / 2), tx_size);
|
||||
} else { // further split
|
||||
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
||||
int bh = num_4x4_blocks_high_lookup[bsize];
|
||||
int i;
|
||||
|
||||
vp9_write(w, 1, cm->fc->txfm_partition_prob[ctx]);
|
||||
|
||||
if (tx_size == TX_8X8) {
|
||||
txfm_partition_update(xd->above_txfm_context + (blk_col / 2),
|
||||
xd->left_txfm_context + (blk_row / 2), TX_4X4);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
int offsetr = (i >> 1) * bh / 2;
|
||||
int offsetc = (i & 0x01) * bh / 2;
|
||||
write_tx_size_inter(cm, xd, tx_size - 1,
|
||||
blk_row + offsetr, blk_col + offsetc, w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void write_selected_tx_size(const VP9_COMMON *cm,
|
||||
const MACROBLOCKD *xd, vp9_writer *w) {
|
||||
TX_SIZE tx_size = xd->mi[0].src_mi->mbmi.tx_size;
|
||||
@ -91,6 +184,22 @@ static void write_selected_tx_size(const VP9_COMMON *cm,
|
||||
}
|
||||
}
|
||||
|
||||
static void update_txfm_partition_probs(VP9_COMMON *cm, vp9_writer *w,
|
||||
FRAME_COUNTS *counts) {
|
||||
int k;
|
||||
for (k = 0; k < TXFM_PARTITION_CONTEXTS; ++k)
|
||||
vp9_cond_prob_diff_update(w, &cm->fc->txfm_partition_prob[k],
|
||||
counts->txfm_partition[k]);
|
||||
}
|
||||
|
||||
static void update_intra_predictor_probs(VP9_COMMON *cm, vp9_writer *w,
|
||||
FRAME_COUNTS *counts) {
|
||||
int k;
|
||||
for (k = 0; k < 3; ++k)
|
||||
vp9_cond_prob_diff_update(w, &cm->fc->intra_predictor_prob[k],
|
||||
counts->intra_predictor[k]);
|
||||
}
|
||||
|
||||
static int write_skip(const VP9_COMMON *cm, const MACROBLOCKD *xd,
|
||||
int segment_id, const MODE_INFO *mi, vp9_writer *w) {
|
||||
if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
|
||||
@ -238,8 +347,8 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
|
||||
vp9_writer *w) {
|
||||
VP9_COMMON *const cm = &cpi->common;
|
||||
const nmv_context *nmvc = &cm->fc->nmvc;
|
||||
const MACROBLOCK *const x = &cpi->td.mb;
|
||||
const MACROBLOCKD *const xd = &x->e_mbd;
|
||||
MACROBLOCK *x = &cpi->td.mb;
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
const struct segmentation *const seg = &cm->seg;
|
||||
const MB_MODE_INFO *const mbmi = &mi->mbmi;
|
||||
const PREDICTION_MODE mode = mbmi->mode;
|
||||
@ -269,7 +378,47 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
|
||||
|
||||
if (bsize >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT &&
|
||||
!(is_inter && skip)) {
|
||||
write_selected_tx_size(cm, xd, w);
|
||||
if (!is_inter) {
|
||||
write_selected_tx_size(cm, xd, w);
|
||||
} else {
|
||||
BLOCK_SIZE txb_size = txsize_to_bsize[mbmi->max_tx_size];
|
||||
int bh = num_4x4_blocks_wide_lookup[txb_size];
|
||||
int width = num_4x4_blocks_wide_lookup[bsize];
|
||||
int height = num_4x4_blocks_high_lookup[bsize];
|
||||
int idx, idy;
|
||||
for (idy = 0; idy < height; idy += bh)
|
||||
for (idx = 0; idx < width; idx += bh)
|
||||
write_tx_size_inter(cm, xd, mbmi->max_tx_size, idy, idx, w);
|
||||
}
|
||||
}
|
||||
|
||||
if (bsize < BLOCK_8X8)
|
||||
txfm_partition_update(xd->above_txfm_context,
|
||||
xd->left_txfm_context, TX_4X4);
|
||||
|
||||
if (is_inter) {
|
||||
if (bsize >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT && skip) {
|
||||
BLOCK_SIZE txb_size = txsize_to_bsize[mbmi->max_tx_size];
|
||||
int bh = num_4x4_blocks_wide_lookup[txb_size];
|
||||
int width = num_4x4_blocks_wide_lookup[bsize];
|
||||
int height = num_4x4_blocks_high_lookup[bsize];
|
||||
int idx, idy;
|
||||
for (idy = 0; idy < height; idy += bh)
|
||||
for (idx = 0; idx < width; idx += bh)
|
||||
txfm_partition_update(xd->above_txfm_context + (idx / 2),
|
||||
xd->left_txfm_context + (idy / 2),
|
||||
mbmi->max_tx_size);
|
||||
}
|
||||
} else {
|
||||
BLOCK_SIZE txb_size = txsize_to_bsize[mbmi->max_tx_size];
|
||||
int bh = num_4x4_blocks_wide_lookup[txb_size];
|
||||
int width = num_4x4_blocks_wide_lookup[bsize];
|
||||
int height = num_4x4_blocks_high_lookup[bsize];
|
||||
int idx, idy;
|
||||
for (idy = 0; idy < height; idy += bh)
|
||||
for (idx = 0; idx < width; idx += bh)
|
||||
txfm_partition_update(xd->above_txfm_context + (idx / 2),
|
||||
xd->left_txfm_context + (idy / 2), mbmi->tx_size);
|
||||
}
|
||||
|
||||
if (!is_inter) {
|
||||
@ -355,7 +504,7 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, const MACROBLOCKD *xd,
|
||||
write_selected_tx_size(cm, xd, w);
|
||||
|
||||
if (bsize >= BLOCK_8X8) {
|
||||
write_intra_mode(w, mbmi->mode, get_y_mode_probs(mi, above_mi, left_mi, 0));
|
||||
write_intra_mode_exp(cm, w, mi, above_mi, left_mi, 0, mbmi->mode);
|
||||
} else {
|
||||
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
|
||||
const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
|
||||
@ -364,8 +513,8 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, const MACROBLOCKD *xd,
|
||||
for (idy = 0; idy < 2; idy += num_4x4_h) {
|
||||
for (idx = 0; idx < 2; idx += num_4x4_w) {
|
||||
const int block = idy * 2 + idx;
|
||||
write_intra_mode(w, mi->bmi[block].as_mode,
|
||||
get_y_mode_probs(mi, above_mi, left_mi, block));
|
||||
write_intra_mode_exp(cm, w, mi, above_mi, left_mi, block,
|
||||
mi->bmi[block].as_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -391,6 +540,8 @@ static void write_modes_b(VP9_COMP *cpi, const TileInfo *const tile,
|
||||
if (frame_is_intra_only(cm)) {
|
||||
write_mb_modes_kf(cm, xd, xd->mi, w);
|
||||
} else {
|
||||
xd->above_txfm_context = cm->above_txfm_context + mi_col;
|
||||
xd->left_txfm_context = xd->left_txfm_context_buffer + (mi_row & 0x07);
|
||||
pack_inter_mode_mvs(cpi, m, w);
|
||||
}
|
||||
|
||||
@ -487,6 +638,7 @@ static void write_modes(VP9_COMP *cpi,
|
||||
for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end;
|
||||
mi_row += MI_BLOCK_SIZE) {
|
||||
vp9_zero(xd->left_seg_context);
|
||||
vp9_zero(xd->left_txfm_context_buffer);
|
||||
for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
|
||||
mi_col += MI_BLOCK_SIZE)
|
||||
write_modes_sb(cpi, tile, w, tok, tok_end, mi_row, mi_col,
|
||||
@ -930,6 +1082,8 @@ static size_t encode_tiles(VP9_COMP *cpi, uint8_t *data_ptr) {
|
||||
|
||||
vpx_memset(cm->above_seg_context, 0, sizeof(*cm->above_seg_context) *
|
||||
mi_cols_aligned_to_sb(cm->mi_cols));
|
||||
vpx_memset(cm->above_txfm_context, 0, sizeof(*cm->above_txfm_context) *
|
||||
mi_cols_aligned_to_sb(cm->mi_cols));
|
||||
|
||||
for (tile_row = 0; tile_row < tile_rows; tile_row++) {
|
||||
for (tile_col = 0; tile_col < tile_cols; tile_col++) {
|
||||
@ -1158,6 +1312,8 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
|
||||
encode_txfm_probs(cm, &header_bc, counts);
|
||||
|
||||
update_coef_probs(cpi, &header_bc);
|
||||
update_txfm_partition_probs(cm, &header_bc, counts);
|
||||
update_intra_predictor_probs(cm, &header_bc, counts);
|
||||
update_skip_probs(cm, &header_bc, counts);
|
||||
|
||||
if (!frame_is_intra_only(cm)) {
|
||||
|
@ -95,6 +95,7 @@ struct macroblock {
|
||||
|
||||
uint8_t zcoeff_blk[TX_SIZES][256];
|
||||
int skip;
|
||||
uint8_t blk_skip[MAX_MB_PLANE][256];
|
||||
|
||||
int encode_breakout;
|
||||
|
||||
|
@ -28,6 +28,8 @@ static void alloc_mode_context(VP9_COMMON *cm, int num_4x4_blk,
|
||||
CHECK_MEM_ERROR(cm, ctx->zcoeff_blk,
|
||||
vpx_calloc(num_4x4_blk, sizeof(uint8_t)));
|
||||
for (i = 0; i < MAX_MB_PLANE; ++i) {
|
||||
CHECK_MEM_ERROR(cm, ctx->blk_skip[i],
|
||||
vpx_calloc(num_4x4_blk, sizeof(uint8_t)));
|
||||
for (k = 0; k < 3; ++k) {
|
||||
CHECK_MEM_ERROR(cm, ctx->coeff[i][k],
|
||||
vpx_memalign(16, num_pix * sizeof(*ctx->coeff[i][k])));
|
||||
@ -50,6 +52,8 @@ static void free_mode_context(PICK_MODE_CONTEXT *ctx) {
|
||||
vpx_free(ctx->zcoeff_blk);
|
||||
ctx->zcoeff_blk = 0;
|
||||
for (i = 0; i < MAX_MB_PLANE; ++i) {
|
||||
vpx_free(ctx->blk_skip[i]);
|
||||
ctx->blk_skip[i] = 0;
|
||||
for (k = 0; k < 3; ++k) {
|
||||
vpx_free(ctx->coeff[i][k]);
|
||||
ctx->coeff[i][k] = 0;
|
||||
|
@ -21,6 +21,7 @@ struct ThreadData;
|
||||
typedef struct {
|
||||
MODE_INFO mic;
|
||||
uint8_t *zcoeff_blk;
|
||||
uint8_t *blk_skip[MAX_MB_PLANE];
|
||||
tran_low_t *coeff[MAX_MB_PLANE][3];
|
||||
tran_low_t *qcoeff[MAX_MB_PLANE][3];
|
||||
tran_low_t *dqcoeff[MAX_MB_PLANE][3];
|
||||
|
@ -893,6 +893,10 @@ static void update_state(VP9_COMP *cpi, ThreadData *td,
|
||||
vpx_memcpy(x->zcoeff_blk[mbmi->tx_size], ctx->zcoeff_blk,
|
||||
sizeof(uint8_t) * ctx->num_4x4_blk);
|
||||
|
||||
for (i = 0; i < MAX_MB_PLANE; ++i)
|
||||
vpx_memcpy(x->blk_skip[i], ctx->blk_skip[i],
|
||||
sizeof(uint8_t) * ctx->num_4x4_blk);
|
||||
|
||||
if (!output_enabled)
|
||||
return;
|
||||
|
||||
@ -983,6 +987,7 @@ static void set_mode_info_seg_skip(MACROBLOCK *x, TX_MODE tx_mode,
|
||||
mbmi->mode = ZEROMV;
|
||||
mbmi->tx_size = MIN(max_txsize_lookup[bsize],
|
||||
tx_mode_to_biggest_tx_size[tx_mode]);
|
||||
mbmi->max_tx_size = max_txsize_lookup[bsize];
|
||||
mbmi->skip = 1;
|
||||
mbmi->uv_mode = DC_PRED;
|
||||
mbmi->ref_frame[0] = LAST_FRAME;
|
||||
@ -1031,6 +1036,7 @@ static void rd_pick_sb_modes(VP9_COMP *cpi,
|
||||
set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
|
||||
mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
mbmi->sb_type = bsize;
|
||||
mbmi->max_tx_size = max_txsize_lookup[bsize];
|
||||
|
||||
for (i = 0; i < MAX_MB_PLANE; ++i) {
|
||||
p[i].coeff = ctx->coeff_pbuf[i][0];
|
||||
@ -1187,6 +1193,7 @@ static void restore_context(MACROBLOCK *const x, int mi_row, int mi_col,
|
||||
ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
|
||||
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
|
||||
PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
|
||||
TXFM_CONTEXT ta[8], TXFM_CONTEXT tl[8],
|
||||
BLOCK_SIZE bsize) {
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
int p;
|
||||
@ -1211,12 +1218,17 @@ static void restore_context(MACROBLOCK *const x, int mi_row, int mi_col,
|
||||
sizeof(*xd->above_seg_context) * mi_width);
|
||||
vpx_memcpy(xd->left_seg_context + (mi_row & MI_MASK), sl,
|
||||
sizeof(xd->left_seg_context[0]) * mi_height);
|
||||
vpx_memcpy(xd->above_txfm_context, ta,
|
||||
sizeof(*xd->above_txfm_context) * mi_width);
|
||||
vpx_memcpy(xd->left_txfm_context, tl,
|
||||
sizeof(*xd->left_txfm_context) * mi_height);
|
||||
}
|
||||
|
||||
static void save_context(MACROBLOCK *const x, int mi_row, int mi_col,
|
||||
ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
|
||||
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
|
||||
PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
|
||||
TXFM_CONTEXT ta[8], TXFM_CONTEXT tl[8],
|
||||
BLOCK_SIZE bsize) {
|
||||
const MACROBLOCKD *const xd = &x->e_mbd;
|
||||
int p;
|
||||
@ -1243,6 +1255,10 @@ static void save_context(MACROBLOCK *const x, int mi_row, int mi_col,
|
||||
sizeof(*xd->above_seg_context) * mi_width);
|
||||
vpx_memcpy(sl, xd->left_seg_context + (mi_row & MI_MASK),
|
||||
sizeof(xd->left_seg_context[0]) * mi_height);
|
||||
vpx_memcpy(ta, xd->above_txfm_context,
|
||||
sizeof(*xd->above_txfm_context) * mi_width);
|
||||
vpx_memcpy(tl, xd->left_txfm_context,
|
||||
sizeof(*xd->left_txfm_context) * mi_height);
|
||||
}
|
||||
|
||||
static void encode_b(VP9_COMP *cpi, const TileInfo *const tile,
|
||||
@ -1400,6 +1416,7 @@ static void set_fixed_partitioning(VP9_COMP *cpi, const TileInfo *const tile,
|
||||
int index = block_row * mis + block_col;
|
||||
mi_8x8[index].src_mi = mi_upper_left + index;
|
||||
mi_8x8[index].src_mi->mbmi.sb_type = bsize;
|
||||
mi_8x8[index].src_mi->mbmi.max_tx_size = max_txsize_lookup[bsize];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1465,6 +1482,7 @@ static void set_source_var_based_partition(VP9_COMP *cpi,
|
||||
index = b_mi_row * mis + b_mi_col;
|
||||
mi_8x8[index].src_mi = mi_upper_left + index;
|
||||
mi_8x8[index].src_mi->mbmi.sb_type = BLOCK_16X16;
|
||||
mi_8x8[index].src_mi->mbmi.max_tx_size = max_txsize_lookup[BLOCK_16X16];
|
||||
|
||||
// TODO(yunqingwang): If d16[j].var is very large, use 8x8 partition
|
||||
// size to further improve quality.
|
||||
@ -1487,6 +1505,7 @@ static void set_source_var_based_partition(VP9_COMP *cpi,
|
||||
index = coord_lookup[i*4].row * mis + coord_lookup[i*4].col;
|
||||
mi_8x8[index].src_mi = mi_upper_left + index;
|
||||
mi_8x8[index].src_mi->mbmi.sb_type = BLOCK_32X32;
|
||||
mi_8x8[index].src_mi->mbmi.max_tx_size = max_txsize_lookup[BLOCK_32X32];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1499,6 +1518,7 @@ static void set_source_var_based_partition(VP9_COMP *cpi,
|
||||
if (is_larger_better) {
|
||||
mi_8x8[0].src_mi = mi_upper_left;
|
||||
mi_8x8[0].src_mi->mbmi.sb_type = BLOCK_64X64;
|
||||
mi_8x8[0].src_mi->mbmi.max_tx_size = max_txsize_lookup[BLOCK_64X64];
|
||||
}
|
||||
}
|
||||
} else { // partial in-image SB64
|
||||
@ -1693,6 +1713,7 @@ static void rd_use_partition(VP9_COMP *cpi,
|
||||
BLOCK_SIZE subsize;
|
||||
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
|
||||
PARTITION_CONTEXT sl[8], sa[8];
|
||||
TXFM_CONTEXT tl[8], ta[8];
|
||||
RD_COST last_part_rdc, none_rdc, chosen_rdc;
|
||||
BLOCK_SIZE sub_subsize = BLOCK_4X4;
|
||||
int splits_below = 0;
|
||||
@ -1714,7 +1735,9 @@ static void rd_use_partition(VP9_COMP *cpi,
|
||||
subsize = get_subsize(bsize, partition);
|
||||
|
||||
pc_tree->partitioning = partition;
|
||||
save_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
xd->above_txfm_context = cm->above_txfm_context + mi_col;
|
||||
xd->left_txfm_context = xd->left_txfm_context_buffer + (mi_row & 0x07);
|
||||
save_context(x, mi_row, mi_col, a, l, sa, sl, ta, tl, bsize);
|
||||
|
||||
if (bsize == BLOCK_16X16 && cpi->oxcf.aq_mode) {
|
||||
set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
|
||||
@ -1754,7 +1777,7 @@ static void rd_use_partition(VP9_COMP *cpi,
|
||||
none_rdc.dist);
|
||||
}
|
||||
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, ta, tl, bsize);
|
||||
mi_8x8[0].src_mi->mbmi.sb_type = bs_type;
|
||||
pc_tree->partitioning = partition;
|
||||
}
|
||||
@ -1865,7 +1888,7 @@ static void rd_use_partition(VP9_COMP *cpi,
|
||||
BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
|
||||
chosen_rdc.rate = 0;
|
||||
chosen_rdc.dist = 0;
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, ta, tl, bsize);
|
||||
pc_tree->partitioning = PARTITION_SPLIT;
|
||||
|
||||
// Split partition.
|
||||
@ -1875,17 +1898,18 @@ static void rd_use_partition(VP9_COMP *cpi,
|
||||
RD_COST tmp_rdc;
|
||||
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
|
||||
PARTITION_CONTEXT sl[8], sa[8];
|
||||
TXFM_CONTEXT tl[8], ta[8];
|
||||
|
||||
if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
|
||||
continue;
|
||||
|
||||
save_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
save_context(x, mi_row, mi_col, a, l, sa, sl, ta, tl, bsize);
|
||||
pc_tree->split[i]->partitioning = PARTITION_NONE;
|
||||
rd_pick_sb_modes(cpi, tile_data, x,
|
||||
mi_row + y_idx, mi_col + x_idx, &tmp_rdc,
|
||||
split_subsize, &pc_tree->split[i]->none, INT64_MAX);
|
||||
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, ta, tl, bsize);
|
||||
|
||||
if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
|
||||
vp9_rd_cost_reset(&chosen_rdc);
|
||||
@ -1925,7 +1949,9 @@ static void rd_use_partition(VP9_COMP *cpi,
|
||||
chosen_rdc = none_rdc;
|
||||
}
|
||||
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
xd->above_txfm_context = cm->above_txfm_context + mi_col;
|
||||
xd->left_txfm_context = xd->left_txfm_context_buffer + (mi_row & 0x07);
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, ta, tl, bsize);
|
||||
|
||||
// We must have chosen a partitioning and encoding or we'll fail later on.
|
||||
// No other opportunities for success.
|
||||
@ -2279,6 +2305,7 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
|
||||
const int mi_step = num_8x8_blocks_wide_lookup[bsize] / 2;
|
||||
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
|
||||
PARTITION_CONTEXT sl[8], sa[8];
|
||||
TXFM_CONTEXT tl[8], ta[8];
|
||||
TOKENEXTRA *tp_orig = *tp;
|
||||
PICK_MODE_CONTEXT *ctx = &pc_tree->none;
|
||||
int i, pl;
|
||||
@ -2344,7 +2371,9 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
|
||||
partition_vert_allowed &= force_vert_split;
|
||||
}
|
||||
|
||||
save_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
xd->above_txfm_context = cm->above_txfm_context + mi_col;
|
||||
xd->left_txfm_context = xd->left_txfm_context_buffer + (mi_row & 0x07);
|
||||
save_context(x, mi_row, mi_col, a, l, sa, sl, ta, tl, bsize);
|
||||
|
||||
#if CONFIG_FP_MB_STATS
|
||||
if (cpi->use_fp_mb_stats) {
|
||||
@ -2490,7 +2519,7 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
|
||||
#endif
|
||||
}
|
||||
}
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, ta, tl, bsize);
|
||||
}
|
||||
|
||||
// store estimated motion vector
|
||||
@ -2555,7 +2584,9 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
|
||||
if (cpi->sf.less_rectangular_check)
|
||||
do_rect &= !partition_none_allowed;
|
||||
}
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
xd->above_txfm_context = cm->above_txfm_context + mi_col;
|
||||
xd->left_txfm_context = xd->left_txfm_context_buffer + (mi_row & 0x07);
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, ta, tl, bsize);
|
||||
}
|
||||
|
||||
// PARTITION_HORZ
|
||||
@ -2582,6 +2613,10 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
|
||||
partition_none_allowed)
|
||||
pc_tree->horizontal[1].pred_interp_filter =
|
||||
ctx->mic.mbmi.interp_filter;
|
||||
|
||||
xd->above_txfm_context = cm->above_txfm_context + mi_col;
|
||||
xd->left_txfm_context = xd->left_txfm_context_buffer +
|
||||
((mi_row + mi_step) & 0x07);
|
||||
rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col,
|
||||
&this_rdc, subsize, &pc_tree->horizontal[1],
|
||||
best_rdc.rdcost - sum_rdc.rdcost);
|
||||
@ -2603,7 +2638,9 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
|
||||
pc_tree->partitioning = PARTITION_HORZ;
|
||||
}
|
||||
}
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
xd->above_txfm_context = cm->above_txfm_context + mi_col;
|
||||
xd->left_txfm_context = xd->left_txfm_context_buffer + (mi_row & 0x07);
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, ta, tl, bsize);
|
||||
}
|
||||
// PARTITION_VERT
|
||||
if (partition_vert_allowed && do_rect) {
|
||||
@ -2629,6 +2666,8 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
|
||||
partition_none_allowed)
|
||||
pc_tree->vertical[1].pred_interp_filter =
|
||||
ctx->mic.mbmi.interp_filter;
|
||||
xd->above_txfm_context = cm->above_txfm_context + mi_col + mi_step;
|
||||
xd->left_txfm_context = xd->left_txfm_context_buffer + (mi_row & 0x07);
|
||||
rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step,
|
||||
&this_rdc, subsize,
|
||||
&pc_tree->vertical[1], best_rdc.rdcost - sum_rdc.rdcost);
|
||||
@ -2651,7 +2690,9 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
|
||||
pc_tree->partitioning = PARTITION_VERT;
|
||||
}
|
||||
}
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
xd->above_txfm_context = cm->above_txfm_context + mi_col;
|
||||
xd->left_txfm_context = xd->left_txfm_context_buffer + (mi_row & 0x07);
|
||||
restore_context(x, mi_row, mi_col, a, l, sa, sl, ta, tl, bsize);
|
||||
}
|
||||
|
||||
// TODO(jbb): This code added so that we avoid static analysis
|
||||
@ -2693,6 +2734,8 @@ static void encode_rd_sb_row(VP9_COMP *cpi,
|
||||
// Initialize the left context for the new SB row
|
||||
vpx_memset(&xd->left_context, 0, sizeof(xd->left_context));
|
||||
vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
|
||||
vpx_memset(xd->left_txfm_context_buffer, 0,
|
||||
sizeof(xd->left_txfm_context_buffer));
|
||||
|
||||
// Code each SB in the row
|
||||
for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
|
||||
@ -2781,6 +2824,8 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
|
||||
2 * aligned_mi_cols * MAX_MB_PLANE);
|
||||
vpx_memset(xd->above_seg_context, 0,
|
||||
sizeof(*xd->above_seg_context) * aligned_mi_cols);
|
||||
vpx_memset(cm->above_txfm_context, 0,
|
||||
sizeof(*xd->above_txfm_context) * aligned_mi_cols);
|
||||
}
|
||||
|
||||
static int check_dual_ref_flags(VP9_COMP *cpi) {
|
||||
@ -2821,6 +2866,9 @@ static MV_REFERENCE_FRAME get_frame_type(const VP9_COMP *cpi) {
|
||||
static TX_MODE select_tx_mode(const VP9_COMP *cpi, MACROBLOCKD *const xd) {
|
||||
if (xd->lossless)
|
||||
return ONLY_4X4;
|
||||
|
||||
return TX_MODE_SELECT;
|
||||
|
||||
if (cpi->common.frame_type == KEY_FRAME &&
|
||||
cpi->sf.use_nonrd_pick_mode &&
|
||||
cpi->sf.partition_search_type == VAR_BASED_PARTITION)
|
||||
@ -2854,6 +2902,7 @@ static void nonrd_pick_sb_modes(VP9_COMP *cpi,
|
||||
set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
|
||||
mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
mbmi->sb_type = bsize;
|
||||
mbmi->max_tx_size = max_txsize_lookup[bsize];
|
||||
|
||||
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled)
|
||||
if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
|
||||
@ -3762,6 +3811,7 @@ static void encode_frame_internal(VP9_COMP *cpi) {
|
||||
vp9_zero(rdc->filter_diff);
|
||||
vp9_zero(rdc->tx_select_diff);
|
||||
vp9_zero(rd_opt->tx_select_threshes);
|
||||
vp9_zero(x->blk_skip);
|
||||
|
||||
xd->lossless = cm->base_qindex == 0 &&
|
||||
cm->y_dc_delta_q == 0 &&
|
||||
@ -3962,40 +4012,40 @@ void vp9_encode_frame(VP9_COMP *cpi) {
|
||||
}
|
||||
}
|
||||
|
||||
if (cm->tx_mode == TX_MODE_SELECT) {
|
||||
int count4x4 = 0;
|
||||
int count8x8_lp = 0, count8x8_8x8p = 0;
|
||||
int count16x16_16x16p = 0, count16x16_lp = 0;
|
||||
int count32x32 = 0;
|
||||
|
||||
for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
|
||||
count4x4 += counts->tx.p32x32[i][TX_4X4];
|
||||
count4x4 += counts->tx.p16x16[i][TX_4X4];
|
||||
count4x4 += counts->tx.p8x8[i][TX_4X4];
|
||||
|
||||
count8x8_lp += counts->tx.p32x32[i][TX_8X8];
|
||||
count8x8_lp += counts->tx.p16x16[i][TX_8X8];
|
||||
count8x8_8x8p += counts->tx.p8x8[i][TX_8X8];
|
||||
|
||||
count16x16_16x16p += counts->tx.p16x16[i][TX_16X16];
|
||||
count16x16_lp += counts->tx.p32x32[i][TX_16X16];
|
||||
count32x32 += counts->tx.p32x32[i][TX_32X32];
|
||||
}
|
||||
if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
|
||||
count32x32 == 0) {
|
||||
cm->tx_mode = ALLOW_8X8;
|
||||
reset_skip_tx_size(cm, TX_8X8);
|
||||
} else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
|
||||
count8x8_lp == 0 && count16x16_lp == 0 && count32x32 == 0) {
|
||||
cm->tx_mode = ONLY_4X4;
|
||||
reset_skip_tx_size(cm, TX_4X4);
|
||||
} else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
|
||||
cm->tx_mode = ALLOW_32X32;
|
||||
} else if (count32x32 == 0 && count8x8_lp == 0 && count4x4 == 0) {
|
||||
cm->tx_mode = ALLOW_16X16;
|
||||
reset_skip_tx_size(cm, TX_16X16);
|
||||
}
|
||||
}
|
||||
// if (cm->tx_mode == TX_MODE_SELECT) {
|
||||
// int count4x4 = 0;
|
||||
// int count8x8_lp = 0, count8x8_8x8p = 0;
|
||||
// int count16x16_16x16p = 0, count16x16_lp = 0;
|
||||
// int count32x32 = 0;
|
||||
//
|
||||
// for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
|
||||
// count4x4 += counts->tx.p32x32[i][TX_4X4];
|
||||
// count4x4 += counts->tx.p16x16[i][TX_4X4];
|
||||
// count4x4 += counts->tx.p8x8[i][TX_4X4];
|
||||
//
|
||||
// count8x8_lp += counts->tx.p32x32[i][TX_8X8];
|
||||
// count8x8_lp += counts->tx.p16x16[i][TX_8X8];
|
||||
// count8x8_8x8p += counts->tx.p8x8[i][TX_8X8];
|
||||
//
|
||||
// count16x16_16x16p += counts->tx.p16x16[i][TX_16X16];
|
||||
// count16x16_lp += counts->tx.p32x32[i][TX_16X16];
|
||||
// count32x32 += counts->tx.p32x32[i][TX_32X32];
|
||||
// }
|
||||
// if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
|
||||
// count32x32 == 0) {
|
||||
// cm->tx_mode = ALLOW_8X8;
|
||||
// reset_skip_tx_size(cm, TX_8X8);
|
||||
// } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
|
||||
// count8x8_lp == 0 && count16x16_lp == 0 && count32x32 == 0) {
|
||||
// cm->tx_mode = ONLY_4X4;
|
||||
// reset_skip_tx_size(cm, TX_4X4);
|
||||
// } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
|
||||
// cm->tx_mode = ALLOW_32X32;
|
||||
// } else if (count32x32 == 0 && count8x8_lp == 0 && count4x4 == 0) {
|
||||
// cm->tx_mode = ALLOW_16X16;
|
||||
// reset_skip_tx_size(cm, TX_16X16);
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
cm->reference_mode = SINGLE_REFERENCE;
|
||||
encode_frame_internal(cpi);
|
||||
@ -4021,6 +4071,57 @@ static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi) {
|
||||
++counts->uv_mode[y_mode][uv_mode];
|
||||
}
|
||||
|
||||
static void update_txfm_count(MACROBLOCKD *xd, FRAME_COUNTS *counts,
|
||||
TX_SIZE tx_size, int blk_row, int blk_col,
|
||||
int dry_run) {
|
||||
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
int tx_idx = (blk_row / 2) * 8 + (blk_col / 2);
|
||||
int max_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
|
||||
int max_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
|
||||
int ctx = txfm_partition_context(xd->above_txfm_context + (blk_col / 2),
|
||||
xd->left_txfm_context + (blk_row / 2),
|
||||
mbmi->max_tx_size,
|
||||
tx_size);
|
||||
TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_idx];
|
||||
|
||||
if (xd->mb_to_bottom_edge < 0)
|
||||
max_blocks_high += xd->mb_to_bottom_edge >> 5;
|
||||
if (xd->mb_to_right_edge < 0)
|
||||
max_blocks_wide += xd->mb_to_right_edge >> 5;
|
||||
|
||||
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
|
||||
return;
|
||||
|
||||
if (tx_size == plane_tx_size) {
|
||||
if (!dry_run)
|
||||
++counts->txfm_partition[ctx][0];
|
||||
mbmi->tx_size = tx_size;
|
||||
txfm_partition_update(xd->above_txfm_context + (blk_col / 2),
|
||||
xd->left_txfm_context + (blk_row / 2), tx_size);
|
||||
} else {
|
||||
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
||||
int bh = num_4x4_blocks_high_lookup[bsize];
|
||||
int i;
|
||||
if (!dry_run)
|
||||
++counts->txfm_partition[ctx][1];
|
||||
|
||||
if (tx_size == TX_8X8) {
|
||||
mbmi->inter_tx_size[tx_idx] = TX_4X4;
|
||||
mbmi->tx_size = TX_4X4;
|
||||
txfm_partition_update(xd->above_txfm_context + (blk_col / 2),
|
||||
xd->left_txfm_context + (blk_row / 2), TX_4X4);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
int offsetr = (i >> 1) * bh / 2;
|
||||
int offsetc = (i & 0x01) * bh / 2;
|
||||
update_txfm_count(xd, counts, tx_size - 1,
|
||||
blk_row + offsetr, blk_col + offsetc, dry_run);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void encode_superblock(VP9_COMP *cpi, ThreadData *td,
|
||||
TOKENEXTRA **t, int output_enabled,
|
||||
int mi_row, int mi_col, BLOCK_SIZE bsize,
|
||||
@ -4080,15 +4181,20 @@ static void encode_superblock(VP9_COMP *cpi, ThreadData *td,
|
||||
vp9_build_inter_predictors_sbuv(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8));
|
||||
|
||||
vp9_encode_sb(x, MAX(bsize, BLOCK_8X8));
|
||||
vp9_tokenize_sb(cpi, td, t, !output_enabled, MAX(bsize, BLOCK_8X8));
|
||||
|
||||
vp9_tokenize_sb_inter(cpi, td, t, !output_enabled, MAX(bsize, BLOCK_8X8));
|
||||
}
|
||||
|
||||
xd->above_txfm_context = cm->above_txfm_context + mi_col;
|
||||
xd->left_txfm_context = xd->left_txfm_context_buffer + (mi_row & 0x07);
|
||||
|
||||
if (output_enabled) {
|
||||
if (cm->tx_mode == TX_MODE_SELECT &&
|
||||
mbmi->sb_type >= BLOCK_8X8 &&
|
||||
!(is_inter_block(mbmi) && (mbmi->skip || seg_skip))) {
|
||||
++get_tx_counts(max_txsize_lookup[bsize], vp9_get_tx_size_context(xd),
|
||||
&td->counts->tx)[mbmi->tx_size];
|
||||
if (!is_inter_block(mbmi))
|
||||
++get_tx_counts(max_txsize_lookup[bsize], vp9_get_tx_size_context(xd),
|
||||
&td->counts->tx)[mbmi->tx_size];
|
||||
} else {
|
||||
int x, y;
|
||||
TX_SIZE tx_size;
|
||||
@ -4105,7 +4211,80 @@ static void encode_superblock(VP9_COMP *cpi, ThreadData *td,
|
||||
if (mi_col + x < cm->mi_cols && mi_row + y < cm->mi_rows)
|
||||
mi_8x8[mis * y + x].src_mi->mbmi.tx_size = tx_size;
|
||||
}
|
||||
|
||||
if (!is_inter_block(mbmi)) {
|
||||
// TODO(jingning): refactor this code for speed improvement.
|
||||
const MODE_INFO *above_mi = xd->mi[-cm->mi_stride].src_mi;
|
||||
const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1].src_mi : NULL;
|
||||
if (bsize >= BLOCK_8X8) {
|
||||
int idx, idy;
|
||||
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
|
||||
const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
|
||||
for (idy = 0; idy < 2; idy += num_4x4_h) {
|
||||
for (idx = 0; idx < 2; idx += num_4x4_w) {
|
||||
const int block = idy * 2 + idx;
|
||||
const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi,
|
||||
block);
|
||||
const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi,
|
||||
block);
|
||||
if (above == left) {
|
||||
++td->counts->intra_predictor[0][mi->bmi[block].as_mode == above];
|
||||
} else {
|
||||
++td->counts->intra_predictor[1][mi->bmi[block].as_mode == above];
|
||||
if (mbmi->mode != above)
|
||||
++td->counts->intra_predictor[1]
|
||||
[mi->bmi[block].as_mode == left];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi, 0);
|
||||
const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi, 0);
|
||||
if (above == left) {
|
||||
++td->counts->intra_predictor[0][mbmi->mode == above];
|
||||
} else {
|
||||
++td->counts->intra_predictor[1][mbmi->mode == above];
|
||||
if (mbmi->mode != above)
|
||||
++td->counts->intra_predictor[1][mbmi->mode == left];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++td->counts->tx.tx_totals[mbmi->tx_size];
|
||||
++td->counts->tx.tx_totals[get_uv_tx_size(mbmi, &xd->plane[1])];
|
||||
}
|
||||
|
||||
if (is_inter_block(mbmi)) {
|
||||
if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8) {
|
||||
BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[bsize]];
|
||||
int bh = num_4x4_blocks_wide_lookup[txb_size];
|
||||
int width = num_4x4_blocks_wide_lookup[bsize];
|
||||
int height = num_4x4_blocks_high_lookup[bsize];
|
||||
int idx, idy;
|
||||
for (idy = 0; idy < height; idy += bh)
|
||||
for (idx = 0; idx < width; idx += bh)
|
||||
if (mbmi->skip || seg_skip)
|
||||
txfm_partition_update(xd->above_txfm_context + (idx / 2),
|
||||
xd->left_txfm_context + (idy / 2),
|
||||
max_txsize_lookup[bsize]);
|
||||
else
|
||||
update_txfm_count(xd, td->counts, max_txsize_lookup[mbmi->sb_type],
|
||||
idy, idx, !output_enabled);
|
||||
}
|
||||
} else {
|
||||
TX_SIZE max_tx_size = max_txsize_lookup[bsize];
|
||||
BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
|
||||
int bh = num_4x4_blocks_wide_lookup[txb_size];
|
||||
int width = num_4x4_blocks_wide_lookup[bsize];
|
||||
int height = num_4x4_blocks_high_lookup[bsize];
|
||||
int idx, idy;
|
||||
for (idy = 0; idy < height; idy += bh)
|
||||
for (idx = 0; idx < width; idx += bh)
|
||||
txfm_partition_update(xd->above_txfm_context + (idx / 2),
|
||||
xd->left_txfm_context + (idy / 2), mbmi->tx_size);
|
||||
}
|
||||
|
||||
if (mbmi->sb_type < BLOCK_8X8)
|
||||
txfm_partition_update(xd->above_txfm_context,
|
||||
xd->left_txfm_context, TX_4X4);
|
||||
}
|
||||
|
@ -530,6 +530,94 @@ void vp9_xform_quant_dc(MACROBLOCK *x, int plane, int block,
|
||||
}
|
||||
}
|
||||
|
||||
void vp9_xform_quant_inter(MACROBLOCK *x, int plane, int block,
|
||||
int blk_row, int blk_col,
|
||||
BLOCK_SIZE plane_bsize, TX_SIZE tx_size) {
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
const struct macroblock_plane *const p = &x->plane[plane];
|
||||
const struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
const scan_order *const scan_order = &vp9_default_scan_orders[tx_size];
|
||||
tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
|
||||
tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
|
||||
tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
|
||||
uint16_t *const eob = &p->eobs[block];
|
||||
const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
|
||||
const int16_t *src_diff;
|
||||
src_diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
switch (tx_size) {
|
||||
case TX_32X32:
|
||||
highbd_fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride);
|
||||
vp9_highbd_quantize_b_32x32(coeff, 1024, x->skip_block, p->zbin,
|
||||
p->round, p->quant, p->quant_shift, qcoeff,
|
||||
dqcoeff, pd->dequant, eob,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
break;
|
||||
case TX_16X16:
|
||||
vp9_highbd_fdct16x16(src_diff, coeff, diff_stride);
|
||||
vp9_highbd_quantize_b(coeff, 256, x->skip_block, p->zbin, p->round,
|
||||
p->quant, p->quant_shift, qcoeff, dqcoeff,
|
||||
pd->dequant, eob,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
break;
|
||||
case TX_8X8:
|
||||
vp9_highbd_fdct8x8(src_diff, coeff, diff_stride);
|
||||
vp9_highbd_quantize_b(coeff, 64, x->skip_block, p->zbin, p->round,
|
||||
p->quant, p->quant_shift, qcoeff, dqcoeff,
|
||||
pd->dequant, eob,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
break;
|
||||
case TX_4X4:
|
||||
x->fwd_txm4x4(src_diff, coeff, diff_stride);
|
||||
vp9_highbd_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round,
|
||||
p->quant, p->quant_shift, qcoeff, dqcoeff,
|
||||
pd->dequant, eob,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
switch (tx_size) {
|
||||
case TX_32X32:
|
||||
fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride);
|
||||
vp9_quantize_b_32x32(coeff, 1024, x->skip_block, p->zbin, p->round,
|
||||
p->quant, p->quant_shift, qcoeff, dqcoeff,
|
||||
pd->dequant, eob, scan_order->scan,
|
||||
scan_order->iscan);
|
||||
break;
|
||||
case TX_16X16:
|
||||
vp9_fdct16x16(src_diff, coeff, diff_stride);
|
||||
vp9_quantize_b(coeff, 256, x->skip_block, p->zbin, p->round,
|
||||
p->quant, p->quant_shift, qcoeff, dqcoeff,
|
||||
pd->dequant, eob,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
break;
|
||||
case TX_8X8:
|
||||
vp9_fdct8x8(src_diff, coeff, diff_stride);
|
||||
vp9_quantize_b(coeff, 64, x->skip_block, p->zbin, p->round,
|
||||
p->quant, p->quant_shift, qcoeff, dqcoeff,
|
||||
pd->dequant, eob,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
break;
|
||||
case TX_4X4:
|
||||
x->fwd_txm4x4(src_diff, coeff, diff_stride);
|
||||
vp9_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round,
|
||||
p->quant, p->quant_shift, qcoeff, dqcoeff,
|
||||
pd->dequant, eob,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void vp9_xform_quant(MACROBLOCK *x, int plane, int block,
|
||||
BLOCK_SIZE plane_bsize, TX_SIZE tx_size) {
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
@ -619,8 +707,9 @@ void vp9_xform_quant(MACROBLOCK *x, int plane, int block,
|
||||
}
|
||||
}
|
||||
|
||||
static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
|
||||
TX_SIZE tx_size, void *arg) {
|
||||
static void encode_block_b(int blk_row, int blk_col, int plane,
|
||||
int block, BLOCK_SIZE plane_bsize,
|
||||
TX_SIZE tx_size, void *arg) {
|
||||
struct encode_b_args *const args = arg;
|
||||
MACROBLOCK *const x = args->x;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
@ -628,61 +717,60 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
|
||||
struct macroblock_plane *const p = &x->plane[plane];
|
||||
struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
|
||||
int i, j;
|
||||
uint8_t *dst;
|
||||
ENTROPY_CONTEXT *a, *l;
|
||||
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
|
||||
dst = &pd->dst.buf[4 * j * pd->dst.stride + 4 * i];
|
||||
a = &ctx->ta[plane][i];
|
||||
l = &ctx->tl[plane][j];
|
||||
const int block_stride = num_4x4_blocks_wide_lookup[plane_bsize];
|
||||
int i;
|
||||
dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
|
||||
a = &ctx->ta[plane][blk_col];
|
||||
l = &ctx->tl[plane][blk_row];
|
||||
|
||||
// TODO(jingning): per transformed block zero forcing only enabled for
|
||||
// luma component. will integrate chroma components as well.
|
||||
if (x->zcoeff_blk[tx_size][block] && plane == 0) {
|
||||
// if (x->zcoeff_blk[tx_size][block] && plane == 0) {
|
||||
// p->eobs[block] = 0;
|
||||
// *a = *l = 0;
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (x->blk_skip[plane][blk_row * block_stride + blk_col] == 0)
|
||||
vp9_xform_quant_inter(x, plane, block, blk_row, blk_col,
|
||||
plane_bsize, tx_size);
|
||||
else
|
||||
p->eobs[block] = 0;
|
||||
*a = *l = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!x->skip_recode) {
|
||||
if (x->quant_fp) {
|
||||
// Encoding process for rtc mode
|
||||
if (x->skip_txfm[0] == 1 && plane == 0) {
|
||||
// skip forward transform
|
||||
p->eobs[block] = 0;
|
||||
*a = *l = 0;
|
||||
return;
|
||||
} else {
|
||||
vp9_xform_quant_fp(x, plane, block, plane_bsize, tx_size);
|
||||
}
|
||||
} else {
|
||||
if (max_txsize_lookup[plane_bsize] == tx_size) {
|
||||
int txfm_blk_index = (plane << 2) + (block >> (tx_size << 1));
|
||||
if (x->skip_txfm[txfm_blk_index] == 0) {
|
||||
// full forward transform and quantization
|
||||
vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
|
||||
} else if (x->skip_txfm[txfm_blk_index]== 2) {
|
||||
// fast path forward transform and quantization
|
||||
vp9_xform_quant_dc(x, plane, block, plane_bsize, tx_size);
|
||||
} else {
|
||||
// skip forward transform
|
||||
p->eobs[block] = 0;
|
||||
*a = *l = 0;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
|
||||
}
|
||||
if (x->optimize) {
|
||||
int context;
|
||||
switch (tx_size) {
|
||||
case TX_4X4:
|
||||
break;
|
||||
case TX_8X8:
|
||||
a[0] = !!*(const uint16_t *)&a[0];
|
||||
l[0] = !!*(const uint16_t *)&l[0];
|
||||
break;
|
||||
case TX_16X16:
|
||||
a[0] = !!*(const uint32_t *)&a[0];
|
||||
l[0] = !!*(const uint32_t *)&l[0];
|
||||
break;
|
||||
case TX_32X32:
|
||||
a[0] = !!*(const uint64_t *)&a[0];
|
||||
l[0] = !!*(const uint64_t *)&l[0];
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Invalid transform size.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (x->optimize && (!x->skip_recode || !x->skip_optimize)) {
|
||||
const int ctx = combine_entropy_contexts(*a, *l);
|
||||
*a = *l = optimize_b(x, plane, block, tx_size, ctx) > 0;
|
||||
context = combine_entropy_contexts(*a, *l);
|
||||
*a = *l = optimize_b(x, plane, block, tx_size, context) > 0;
|
||||
} else {
|
||||
*a = *l = p->eobs[block] > 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < (1 << tx_size); ++i) {
|
||||
a[i] = a[0];
|
||||
l[i] = l[0];
|
||||
}
|
||||
|
||||
if (p->eobs[block])
|
||||
*(args->skip) = 0;
|
||||
|
||||
@ -739,6 +827,46 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
|
||||
}
|
||||
}
|
||||
|
||||
static void encode_block_inter(int blk_row, int blk_col,
|
||||
int plane, int block, BLOCK_SIZE plane_bsize,
|
||||
TX_SIZE tx_size, void *arg) {
|
||||
struct encode_b_args *const args = arg;
|
||||
MACROBLOCK *const x = args->x;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
|
||||
(blk_col >> (1 - pd->subsampling_x));
|
||||
TX_SIZE plane_tx_size = plane ?
|
||||
get_uv_tx_size_impl(mbmi->inter_tx_size[tx_idx], plane_bsize, 0, 0) :
|
||||
mbmi->inter_tx_size[tx_idx];
|
||||
int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
|
||||
int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
|
||||
if (xd->mb_to_bottom_edge < 0)
|
||||
max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
|
||||
if (xd->mb_to_right_edge < 0)
|
||||
max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
|
||||
|
||||
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
|
||||
return;
|
||||
|
||||
if (tx_size == plane_tx_size) {
|
||||
encode_block_b(blk_row, blk_col, plane, block, plane_bsize, tx_size, arg);
|
||||
} else {
|
||||
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
||||
int bh = num_4x4_blocks_high_lookup[bsize];
|
||||
int step = 1 << (2 *(tx_size - 1));
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
int offsetr = (i >> 1) * bh / 2;
|
||||
int offsetc = (i & 0x01) * bh / 2;
|
||||
encode_block_inter(blk_row + offsetr, blk_col + offsetc,
|
||||
plane, block + i * step, plane_bsize,
|
||||
tx_size - 1, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void encode_block_pass1(int plane, int block, BLOCK_SIZE plane_bsize,
|
||||
TX_SIZE tx_size, void *arg) {
|
||||
MACROBLOCK *const x = (MACROBLOCK *)arg;
|
||||
@ -783,18 +911,27 @@ void vp9_encode_sb(MACROBLOCK *x, BLOCK_SIZE bsize) {
|
||||
return;
|
||||
|
||||
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
|
||||
if (!x->skip_recode)
|
||||
vp9_subtract_plane(x, bsize, plane);
|
||||
const struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
|
||||
const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
|
||||
const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
|
||||
BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
|
||||
int bh = num_4x4_blocks_wide_lookup[txb_size];
|
||||
int idx, idy;
|
||||
int block = 0;
|
||||
int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
|
||||
|
||||
if (x->optimize && (!x->skip_recode || !x->skip_optimize)) {
|
||||
const struct macroblockd_plane* const pd = &xd->plane[plane];
|
||||
const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
|
||||
vp9_get_entropy_contexts(bsize, tx_size, pd,
|
||||
ctx.ta[plane], ctx.tl[plane]);
|
||||
vp9_subtract_plane(x, bsize, plane);
|
||||
|
||||
vp9_get_entropy_contexts(bsize, TX_4X4, pd, ctx.ta[plane], ctx.tl[plane]);
|
||||
|
||||
for (idy = 0; idy < mi_height; idy += bh) {
|
||||
for (idx = 0; idx < mi_width; idx += bh) {
|
||||
encode_block_inter(idy, idx, plane, block, plane_bsize,
|
||||
max_txsize_lookup[plane_bsize], &arg);
|
||||
block += step;
|
||||
}
|
||||
}
|
||||
|
||||
vp9_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
|
||||
&arg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -820,6 +957,7 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
|
||||
const int src_stride = p->src.stride;
|
||||
const int dst_stride = pd->dst.stride;
|
||||
int i, j;
|
||||
|
||||
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
|
||||
dst = &pd->dst.buf[4 * (j * dst_stride + i)];
|
||||
src = &p->src.buf[4 * (j * src_stride + i)];
|
||||
|
@ -29,6 +29,9 @@ void vp9_xform_quant_fp(MACROBLOCK *x, int plane, int block,
|
||||
BLOCK_SIZE plane_bsize, TX_SIZE tx_size);
|
||||
void vp9_xform_quant_dc(MACROBLOCK *x, int plane, int block,
|
||||
BLOCK_SIZE plane_bsize, TX_SIZE tx_size);
|
||||
void vp9_xform_quant_inter(MACROBLOCK *x, int plane, int block,
|
||||
int blk_row, int blk_col,
|
||||
BLOCK_SIZE plane_bsize, TX_SIZE tx_size);
|
||||
void vp9_xform_quant(MACROBLOCK *x, int plane, int block,
|
||||
BLOCK_SIZE plane_bsize, TX_SIZE tx_size);
|
||||
|
||||
|
@ -3453,6 +3453,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
||||
MAX_MODES * sizeof(*cpi->mode_chosen_counts));
|
||||
#endif
|
||||
|
||||
cpi->dummy_writing = 1;
|
||||
if (cpi->sf.recode_loop == DISALLOW_RECODE) {
|
||||
encode_without_recode_loop(cpi);
|
||||
} else {
|
||||
@ -3498,6 +3499,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
||||
// Pick the loop filter level for the frame.
|
||||
loopfilter_frame(cpi, cm);
|
||||
|
||||
cpi->dummy_writing = 0;
|
||||
// build the bitstream
|
||||
vp9_pack_bitstream(cpi, dest, size);
|
||||
|
||||
|
@ -417,6 +417,7 @@ typedef struct VP9_COMP {
|
||||
|
||||
int b_calculate_ssimg;
|
||||
#endif
|
||||
int dummy_writing;
|
||||
int b_calculate_psnr;
|
||||
|
||||
int droppable;
|
||||
|
@ -940,12 +940,11 @@ void vp9_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *rd_cost,
|
||||
MIN(max_txsize_lookup[bsize],
|
||||
tx_mode_to_biggest_tx_size[cpi->common.tx_mode]);
|
||||
MODE_INFO *const mic = xd->mi[0].src_mi;
|
||||
int *bmode_costs;
|
||||
int bmode_costs;
|
||||
const MODE_INFO *above_mi = xd->mi[-xd->mi_stride].src_mi;
|
||||
const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1].src_mi : NULL;
|
||||
const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
|
||||
const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
|
||||
bmode_costs = cpi->y_mode_costs[A][L];
|
||||
|
||||
(void) ctx;
|
||||
vp9_rd_cost_reset(&best_rdc);
|
||||
@ -963,11 +962,17 @@ void vp9_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *rd_cost,
|
||||
args.rate = 0;
|
||||
args.dist = 0;
|
||||
mbmi->tx_size = intra_tx_size;
|
||||
|
||||
if (A == L)
|
||||
bmode_costs = (this_mode == A) ? 406 : 961;
|
||||
else // (A != L)
|
||||
bmode_costs = (this_mode == A) || (this_mode == L) ? 512 : 1024;
|
||||
|
||||
vp9_foreach_transformed_block_in_plane(xd, bsize, 0,
|
||||
estimate_block_intra, &args);
|
||||
this_rdc.rate = args.rate;
|
||||
this_rdc.dist = args.dist;
|
||||
this_rdc.rate += bmode_costs[this_mode];
|
||||
this_rdc.rate += bmode_costs;
|
||||
this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
|
||||
this_rdc.rate, this_rdc.dist);
|
||||
|
||||
@ -1521,6 +1526,12 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
mbmi->ref_frame[0] = best_ref_frame;
|
||||
x->skip_txfm[0] = best_mode_skip_txfm;
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 64; ++i)
|
||||
mbmi->inter_tx_size[i] = mbmi->tx_size;
|
||||
}
|
||||
|
||||
if (reuse_inter_pred && best_pred != NULL) {
|
||||
if (best_pred->data != orig_dst.buf && is_inter_mode(mbmi->mode)) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
|
@ -66,12 +66,7 @@ static const uint8_t rd_thresh_block_size_factor[BLOCK_SIZES] = {
|
||||
|
||||
static void fill_mode_costs(VP9_COMP *cpi) {
|
||||
const FRAME_CONTEXT *const fc = cpi->common.fc;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < INTRA_MODES; ++i)
|
||||
for (j = 0; j < INTRA_MODES; ++j)
|
||||
vp9_cost_tokens(cpi->y_mode_costs[i][j], vp9_kf_y_mode_prob[i][j],
|
||||
vp9_intra_mode_tree);
|
||||
int i;
|
||||
|
||||
vp9_cost_tokens(cpi->mbmode_cost, fc->y_mode_prob[1], vp9_intra_mode_tree);
|
||||
vp9_cost_tokens(cpi->intra_uv_mode_cost[KEY_FRAME],
|
||||
|
@ -61,6 +61,7 @@ typedef struct {
|
||||
} REF_DEFINITION;
|
||||
|
||||
struct rdcost_block_args {
|
||||
const VP9_COMP *cpi;
|
||||
MACROBLOCK *x;
|
||||
ENTROPY_CONTEXT t_above[16];
|
||||
ENTROPY_CONTEXT t_left[16];
|
||||
@ -365,10 +366,6 @@ static int cost_coeffs(MACROBLOCK *x,
|
||||
const int16_t *cat6_high_cost = vp9_get_high_cost_table(8);
|
||||
#endif
|
||||
|
||||
// Check for consistency of tx_size with mode info
|
||||
assert(type == PLANE_TYPE_Y ? mbmi->tx_size == tx_size
|
||||
: get_uv_tx_size(mbmi, pd) == tx_size);
|
||||
|
||||
if (eob == 0) {
|
||||
// single eob token
|
||||
cost = token_costs[0][0][pt][EOB_TOKEN];
|
||||
@ -490,15 +487,35 @@ static void block_rd_txfm(int plane, int block, BLOCK_SIZE plane_bsize,
|
||||
|
||||
if (!is_inter_block(mbmi)) {
|
||||
struct encode_b_args arg = {x, NULL, &mbmi->skip};
|
||||
vp9_encode_block_intra(plane, block, plane_bsize, tx_size, &arg);
|
||||
int i, j;
|
||||
uint8_t *dst, *src;
|
||||
int src_stride, dst_stride;
|
||||
unsigned int tmp_sse;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
(void) i, j, dst, src, src_stride, dst_stride, tmp_sse;
|
||||
vp9_encode_block_intra(plane, block, plane_bsize, tx_size, &arg);
|
||||
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
dist_block(plane, block, tx_size, args, xd->bd);
|
||||
} else {
|
||||
dist_block(plane, block, tx_size, args, 8);
|
||||
}
|
||||
#else
|
||||
dist_block(plane, block, tx_size, args);
|
||||
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
|
||||
src_stride = x->plane[plane].src.stride;
|
||||
dst_stride = xd->plane[plane].dst.stride;
|
||||
src = &x->plane[plane].src.buf[4 * (j * src_stride + i)];
|
||||
dst = &xd->plane[plane].dst.buf[4 * (j * dst_stride + i)];
|
||||
|
||||
args->cpi->fn_ptr[txsize_to_bsize[tx_size]].vf(src, src_stride,
|
||||
dst, dst_stride, &tmp_sse);
|
||||
args->sse = (int64_t)tmp_sse * 16;
|
||||
|
||||
vp9_encode_block_intra(plane, block, plane_bsize, tx_size, &arg);
|
||||
|
||||
args->cpi->fn_ptr[txsize_to_bsize[tx_size]].vf(src, src_stride,
|
||||
dst, dst_stride, &tmp_sse);
|
||||
args->dist = (int64_t)tmp_sse * 16;
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
} else if (max_txsize_lookup[plane_bsize] == tx_size) {
|
||||
if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] == 0) {
|
||||
@ -573,7 +590,7 @@ static void block_rd_txfm(int plane, int block, BLOCK_SIZE plane_bsize,
|
||||
}
|
||||
}
|
||||
|
||||
static void txfm_rd_in_plane(MACROBLOCK *x,
|
||||
static void txfm_rd_in_plane(const VP9_COMP *cpi, MACROBLOCK *x,
|
||||
int *rate, int64_t *distortion,
|
||||
int *skippable, int64_t *sse,
|
||||
int64_t ref_best_rd, int plane,
|
||||
@ -583,6 +600,7 @@ static void txfm_rd_in_plane(MACROBLOCK *x,
|
||||
const struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
struct rdcost_block_args args;
|
||||
vp9_zero(args);
|
||||
args.cpi = cpi;
|
||||
args.x = x;
|
||||
args.best_rd = ref_best_rd;
|
||||
args.use_fast_coef_costing = use_fast_coef_casting;
|
||||
@ -622,7 +640,7 @@ static void choose_largest_tx_size(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
|
||||
mbmi->tx_size = MIN(max_tx_size, largest_tx_size);
|
||||
|
||||
txfm_rd_in_plane(x, rate, distortion, skip,
|
||||
txfm_rd_in_plane(cpi, x, rate, distortion, skip,
|
||||
sse, ref_best_rd, 0, bs,
|
||||
mbmi->tx_size, cpi->sf.use_fast_coef_costing);
|
||||
}
|
||||
@ -658,7 +676,7 @@ static void choose_tx_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
s1 = vp9_cost_bit(skip_prob, 1);
|
||||
|
||||
for (n = max_tx_size; n >= 0; n--) {
|
||||
txfm_rd_in_plane(x, &r[n][0], &d[n], &s[n],
|
||||
txfm_rd_in_plane(cpi, x, &r[n][0], &d[n], &s[n],
|
||||
&sse[n], ref_best_rd, 0, bs, n,
|
||||
cpi->sf.use_fast_coef_costing);
|
||||
r[n][1] = r[n][0];
|
||||
@ -694,7 +712,6 @@ static void choose_tx_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
mbmi->tx_size = cm->tx_mode == TX_MODE_SELECT ?
|
||||
best_tx : MIN(max_tx_size, max_mode_tx_size);
|
||||
|
||||
|
||||
*distortion = d[mbmi->tx_size];
|
||||
*rate = r[mbmi->tx_size][cm->tx_mode == TX_MODE_SELECT];
|
||||
*skip = s[mbmi->tx_size];
|
||||
@ -760,8 +777,8 @@ static int conditional_skipintra(PREDICTION_MODE mode,
|
||||
|
||||
static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
|
||||
PREDICTION_MODE *best_mode,
|
||||
const int *bmode_costs,
|
||||
ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
|
||||
PREDICTION_MODE A, PREDICTION_MODE L,
|
||||
int *bestrate, int *bestratey,
|
||||
int64_t *bestdistortion,
|
||||
BLOCK_SIZE bsize, int64_t rd_thresh) {
|
||||
@ -800,7 +817,12 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
|
||||
int64_t this_rd;
|
||||
int ratey = 0;
|
||||
int64_t distortion = 0;
|
||||
int rate = bmode_costs[mode];
|
||||
int rate;
|
||||
|
||||
if (A == L)
|
||||
rate = (mode == A) ? 256 : 1064;
|
||||
else // (A != L)
|
||||
rate = (mode == A) || (mode == L) ? 404 : 1169;
|
||||
|
||||
if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
|
||||
continue;
|
||||
@ -901,7 +923,12 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
|
||||
int64_t this_rd;
|
||||
int ratey = 0;
|
||||
int64_t distortion = 0;
|
||||
int rate = bmode_costs[mode];
|
||||
int rate;
|
||||
|
||||
if (A == L)
|
||||
rate = (mode == A) ? 406 : 961;
|
||||
else // (A != L)
|
||||
rate = (mode == A) || (mode == L) ? 512 : 1024;
|
||||
|
||||
if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
|
||||
continue;
|
||||
@ -1009,7 +1036,8 @@ static int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP *cpi, MACROBLOCK *mb,
|
||||
int tot_rate_y = 0;
|
||||
int64_t total_rd = 0;
|
||||
ENTROPY_CONTEXT t_above[4], t_left[4];
|
||||
const int *bmode_costs = cpi->mbmode_cost;
|
||||
PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
|
||||
PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
|
||||
|
||||
vpx_memcpy(t_above, xd->plane[0].above_context, sizeof(t_above));
|
||||
vpx_memcpy(t_left, xd->plane[0].left_context, sizeof(t_left));
|
||||
@ -1022,14 +1050,13 @@ static int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP *cpi, MACROBLOCK *mb,
|
||||
int64_t d = INT64_MAX, this_rd = INT64_MAX;
|
||||
i = idy * 2 + idx;
|
||||
if (cpi->common.frame_type == KEY_FRAME) {
|
||||
const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, i);
|
||||
const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, i);
|
||||
|
||||
bmode_costs = cpi->y_mode_costs[A][L];
|
||||
A = vp9_above_block_mode(mic, above_mi, i);
|
||||
L = vp9_left_block_mode(mic, left_mi, i);
|
||||
}
|
||||
|
||||
this_rd = rd_pick_intra4x4block(cpi, mb, i, &best_mode, bmode_costs,
|
||||
t_above + idx, t_left + idy, &r, &ry, &d,
|
||||
this_rd = rd_pick_intra4x4block(cpi, mb, i, &best_mode,
|
||||
t_above + idx, t_left + idy,
|
||||
A, L, &r, &ry, &d,
|
||||
bsize, best_rd - total_rd);
|
||||
if (this_rd >= best_rd - total_rd)
|
||||
return INT64_MAX;
|
||||
@ -1073,12 +1100,11 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
int64_t this_distortion, this_rd;
|
||||
TX_SIZE best_tx = TX_4X4;
|
||||
int i;
|
||||
int *bmode_costs;
|
||||
int bmode_costs;
|
||||
const MODE_INFO *above_mi = xd->above_mi;
|
||||
const MODE_INFO *left_mi = xd->left_mi;
|
||||
const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
|
||||
const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
|
||||
bmode_costs = cpi->y_mode_costs[A][L];
|
||||
|
||||
if (cpi->sf.tx_size_search_method == USE_FULL_RD)
|
||||
for (i = 0; i < TX_MODES; i++)
|
||||
@ -1089,6 +1115,11 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
for (mode = DC_PRED; mode <= TM_PRED; mode++) {
|
||||
int64_t local_tx_cache[TX_MODES];
|
||||
|
||||
if (A == L)
|
||||
bmode_costs = (mode == A) ? 406 : 961;
|
||||
else // (A != L)
|
||||
bmode_costs = (mode == A) || (mode == L) ? 512 : 1024;
|
||||
|
||||
if (cpi->sf.use_nonrd_pick_mode) {
|
||||
// These speed features are turned on in hybrid non-RD and RD mode
|
||||
// for key frame coding in the context of real-time setting.
|
||||
@ -1106,7 +1137,7 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
if (this_rate_tokenonly == INT_MAX)
|
||||
continue;
|
||||
|
||||
this_rate = this_rate_tokenonly + bmode_costs[mode];
|
||||
this_rate = this_rate_tokenonly + bmode_costs;
|
||||
this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
|
||||
|
||||
if (this_rd < best_rd) {
|
||||
@ -1136,8 +1167,496 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
return best_rd;
|
||||
}
|
||||
|
||||
static void tx_block_rd_b(VP9_COMP const *cpi, MACROBLOCK *x, TX_SIZE tx_size,
|
||||
int blk_row, int blk_col, int plane, int block,
|
||||
int plane_bsize, ENTROPY_CONTEXT *above_ctx,
|
||||
ENTROPY_CONTEXT *left_ctx, int *zero_blk_rate,
|
||||
int *rate, int64_t *dist, int64_t *bsse, int *skip) {
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
const struct macroblock_plane *const p = &x->plane[plane];
|
||||
unsigned int tmp_sse = 0;
|
||||
tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
|
||||
ENTROPY_CONTEXT *ta = above_ctx + blk_col;
|
||||
ENTROPY_CONTEXT *tl = left_ctx + blk_row;
|
||||
scan_order const *sc = get_scan(xd, tx_size, pd->plane_type, 0);
|
||||
int i, pt;
|
||||
BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
|
||||
int bh = 4 * num_4x4_blocks_wide_lookup[txm_bsize];
|
||||
int src_stride = p->src.stride;
|
||||
uint8_t *src = &p->src.buf[4 * blk_row * src_stride + 4 * blk_col];
|
||||
uint8_t *dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
|
||||
DECLARE_ALIGNED_ARRAY(16, uint8_t, rec_buffer, 32 * 32);
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
int64_t this_sse;
|
||||
const int ss_txfrm_size = tx_size << 1;
|
||||
int shift = tx_size == TX_32X32 ? 0 : 2;
|
||||
tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
|
||||
|
||||
(void)this_dist, tmp_sse, txm_bsize, bh, src_stride, src, dst, rec_buffer;
|
||||
vp9_xform_quant_inter(x, plane, block, blk_row, blk_col,
|
||||
plane_bsize, tx_size);
|
||||
*dist += vp9_highbd_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
|
||||
&this_sse, xd->bd) >> shift;
|
||||
*bsse += this_sse >> shift;
|
||||
#else
|
||||
// TODO(jingning) refactor the data structure to save repeated computation.
|
||||
int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
|
||||
int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
|
||||
|
||||
if (xd->mb_to_bottom_edge < 0)
|
||||
max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
|
||||
if (xd->mb_to_right_edge < 0)
|
||||
max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
|
||||
|
||||
vp9_convolve_copy(dst, pd->dst.stride, rec_buffer, 32,
|
||||
NULL, 0, NULL, 0, bh, bh);
|
||||
|
||||
if ((bh >> 2) + blk_col > max_blocks_wide ||
|
||||
(bh >> 2) + blk_row > max_blocks_high) {
|
||||
int idx, idy;
|
||||
unsigned int this_sse;
|
||||
int blocks_height = MIN(bh >> 2, max_blocks_high - blk_row);
|
||||
int blocks_width = MIN(bh >> 2, max_blocks_wide - blk_col);
|
||||
for (idy = 0; idy < blocks_height; idy += 2) {
|
||||
for (idx = 0; idx < blocks_width; idx += 2) {
|
||||
cpi->fn_ptr[BLOCK_8X8].vf(src + 4 * idy * src_stride + 4 * idx,
|
||||
src_stride,
|
||||
rec_buffer + 4 * idy * 32 + 4 * idx,
|
||||
32, &this_sse);
|
||||
tmp_sse += this_sse;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cpi->fn_ptr[txm_bsize].vf(src, src_stride,
|
||||
rec_buffer, 32, &tmp_sse);
|
||||
}
|
||||
*bsse = (int64_t)tmp_sse * 16;
|
||||
|
||||
vp9_xform_quant_inter(x, plane, block, blk_row, blk_col,
|
||||
plane_bsize, tx_size);
|
||||
|
||||
if (p->eobs[block] > 0) {
|
||||
switch (tx_size) {
|
||||
case TX_32X32:
|
||||
vp9_idct32x32_add(dqcoeff, rec_buffer, 32, p->eobs[block]);
|
||||
break;
|
||||
case TX_16X16:
|
||||
vp9_idct16x16_add(dqcoeff, rec_buffer, 32, p->eobs[block]);
|
||||
break;
|
||||
case TX_8X8:
|
||||
vp9_idct8x8_add(dqcoeff, rec_buffer, 32, p->eobs[block]);
|
||||
break;
|
||||
case TX_4X4:
|
||||
// this is like vp9_short_idct4x4 but has a special case around eob<=1
|
||||
// which is significant (not just an optimization) for the lossless
|
||||
// case.
|
||||
x->itxm_add(dqcoeff, rec_buffer, 32, p->eobs[block]);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Invalid transform size");
|
||||
break;
|
||||
}
|
||||
|
||||
if ((bh >> 2) + blk_col > max_blocks_wide ||
|
||||
(bh >> 2) + blk_row > max_blocks_high) {
|
||||
int idx, idy;
|
||||
unsigned int this_sse;
|
||||
int blocks_height = MIN(bh >> 2, max_blocks_high - blk_row);
|
||||
int blocks_width = MIN(bh >> 2, max_blocks_wide - blk_col);
|
||||
tmp_sse = 0;
|
||||
for (idy = 0; idy < blocks_height; idy += 2) {
|
||||
for (idx = 0; idx < blocks_width; idx += 2) {
|
||||
cpi->fn_ptr[BLOCK_8X8].vf(src + 4 * idy * src_stride + 4 * idx,
|
||||
src_stride,
|
||||
rec_buffer + 4 * idy * 32 + 4 * idx,
|
||||
32, &this_sse);
|
||||
tmp_sse += this_sse;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cpi->fn_ptr[txm_bsize].vf(src, src_stride,
|
||||
rec_buffer, 32, &tmp_sse);
|
||||
}
|
||||
}
|
||||
*dist = (int64_t)tmp_sse * 16;
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
switch (tx_size) {
|
||||
case TX_4X4:
|
||||
break;
|
||||
case TX_8X8:
|
||||
ta[0] = !!*(const uint16_t *)&ta[0];
|
||||
tl[0] = !!*(const uint16_t *)&tl[0];
|
||||
break;
|
||||
case TX_16X16:
|
||||
ta[0] = !!*(const uint32_t *)&ta[0];
|
||||
tl[0] = !!*(const uint32_t *)&tl[0];
|
||||
break;
|
||||
case TX_32X32:
|
||||
ta[0] = !!*(const uint64_t *)&ta[0];
|
||||
tl[0] = !!*(const uint64_t *)&tl[0];
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Invalid transform size.");
|
||||
break;
|
||||
}
|
||||
pt = (ta[0] != 0) + (tl[0] != 0);
|
||||
*zero_blk_rate =
|
||||
x->token_costs[tx_size][pd->plane_type][1][0][0][pt][EOB_TOKEN];
|
||||
*rate = cost_coeffs(x, plane, block, ta, tl, tx_size,
|
||||
sc->scan, sc->neighbors, 0);
|
||||
|
||||
for (i = 0; i < (1 << tx_size); ++i) {
|
||||
ta[i] = ta[0];
|
||||
tl[i] = tl[0];
|
||||
}
|
||||
*skip = (p->eobs[block] == 0);
|
||||
}
|
||||
|
||||
static void select_tx_block(const VP9_COMP *cpi, MACROBLOCK *x,
|
||||
int blk_row, int blk_col, int plane, int block,
|
||||
TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
|
||||
BLOCK_SIZE txb_bsize,
|
||||
ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
|
||||
TXFM_CONTEXT *txa, TXFM_CONTEXT *txl,
|
||||
int *rate, int64_t *dist,
|
||||
int64_t *bsse, int *skip) {
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
|
||||
(blk_col >> (1 - pd->subsampling_x));
|
||||
int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
|
||||
int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
|
||||
int block_stride = max_blocks_wide;
|
||||
int mi_width = num_8x8_blocks_wide_lookup[txb_bsize];
|
||||
int mi_height = num_8x8_blocks_high_lookup[txb_bsize];
|
||||
int64_t this_rd = INT64_MAX;
|
||||
ENTROPY_CONTEXT ctxa[16], ctxl[16];
|
||||
ENTROPY_CONTEXT *pta = ta + (blk_col >> pd->subsampling_x);
|
||||
ENTROPY_CONTEXT *ptl = tl + (blk_row >> pd->subsampling_y);
|
||||
TXFM_CONTEXT stxa[8], stxl[8];
|
||||
int ctx = txfm_partition_context(txa + (blk_col / 2),
|
||||
txl + (blk_row / 2),
|
||||
mbmi->max_tx_size,
|
||||
tx_size);
|
||||
int zero_blk_rate;
|
||||
|
||||
vpx_memcpy(ctxa, ta, sizeof(ENTROPY_CONTEXT) * max_blocks_wide);
|
||||
vpx_memcpy(ctxl, tl, sizeof(ENTROPY_CONTEXT) * max_blocks_high);
|
||||
|
||||
// Store the above and left transform block partition context.
|
||||
vpx_memcpy(stxa + (blk_col / 2), txa + (blk_col / 2),
|
||||
sizeof(TXFM_CONTEXT) * mi_width);
|
||||
vpx_memcpy(stxl + (blk_row / 2), txl + (blk_row / 2),
|
||||
sizeof(TXFM_CONTEXT) * mi_height);
|
||||
|
||||
if (xd->mb_to_bottom_edge < 0)
|
||||
max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
|
||||
if (xd->mb_to_right_edge < 0)
|
||||
max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
|
||||
|
||||
*rate = 0;
|
||||
*dist = 0;
|
||||
*bsse = 0;
|
||||
*skip = 1;
|
||||
|
||||
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
|
||||
return;
|
||||
|
||||
mbmi->inter_tx_size[tx_idx] = tx_size;
|
||||
mbmi->tx_size = tx_size;
|
||||
|
||||
if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
|
||||
tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
|
||||
plane_bsize, ta, tl, &zero_blk_rate, rate, dist, bsse, skip);
|
||||
txfm_partition_update(txa + (blk_col / 2), txl + (blk_row / 2), tx_size);
|
||||
|
||||
if (*skip == 1) {
|
||||
x->blk_skip[plane][blk_row * block_stride + blk_col] = 1;
|
||||
} else {
|
||||
if (RDCOST(x->rdmult, x->rddiv, *rate, *dist) >=
|
||||
RDCOST(x->rdmult, x->rddiv, zero_blk_rate, *bsse)) {
|
||||
int i;
|
||||
*rate = zero_blk_rate;
|
||||
*dist = *bsse;
|
||||
*skip = 1;
|
||||
x->blk_skip[plane][blk_row * block_stride + blk_col] = 1;
|
||||
for (i = 0; i < (1 << tx_size); ++i) {
|
||||
pta[i] = 0;
|
||||
ptl[i] = 0;
|
||||
}
|
||||
} else {
|
||||
x->blk_skip[plane][blk_row * block_stride + blk_col] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_size >= TX_8X8)
|
||||
*rate += vp9_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
|
||||
this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *dist);
|
||||
}
|
||||
|
||||
if (tx_size > TX_4X4) {
|
||||
int bh = num_4x4_blocks_high_lookup[txb_bsize];
|
||||
int sub_step = 1 << (2 * (tx_size - 1));
|
||||
int i;
|
||||
int this_rate, sum_rate;
|
||||
int64_t this_dist, sum_dist = 0;
|
||||
int64_t this_bsse, sum_bsse = 0;
|
||||
int this_skip, all_skip = 1;
|
||||
int64_t sum_rd;
|
||||
|
||||
sum_rate = vp9_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
|
||||
for (i = 0; i < 4; ++i) {
|
||||
int offsetr = (i >> 1) * bh / 2;
|
||||
int offsetc = (i & 0x01) * bh / 2;
|
||||
select_tx_block(cpi, x, blk_row + offsetr, blk_col + offsetc,
|
||||
plane, block + i * sub_step, tx_size - 1,
|
||||
plane_bsize, txsize_to_bsize[tx_size - 1],
|
||||
ctxa, ctxl, stxa, stxl, &this_rate, &this_dist,
|
||||
&this_bsse, &this_skip);
|
||||
sum_rate += this_rate;
|
||||
sum_dist += this_dist;
|
||||
sum_bsse += this_bsse;
|
||||
all_skip &= this_skip;
|
||||
}
|
||||
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
||||
|
||||
if (this_rd < sum_rd) {
|
||||
int idx, idy;
|
||||
for (idy = blk_row; idy < blk_row + bh; idy += 2)
|
||||
for (idx = blk_col; idx < blk_col + bh; idx += 2)
|
||||
mbmi->inter_tx_size[(idy / 2) * 8 + (idx / 2)] = tx_size;
|
||||
mbmi->tx_size = tx_size;
|
||||
x->blk_skip[plane][blk_row * block_stride + blk_col] = *skip;
|
||||
} else {
|
||||
*rate = sum_rate;
|
||||
*dist = sum_dist;
|
||||
*bsse = sum_bsse;
|
||||
*skip = all_skip;
|
||||
vpx_memcpy(pta, ctxa + (blk_col >> pd->subsampling_x),
|
||||
sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide_lookup[txb_bsize]);
|
||||
vpx_memcpy(ptl, ctxl + (blk_row >> pd->subsampling_y),
|
||||
sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high_lookup[txb_bsize]);
|
||||
vpx_memcpy(txa + (blk_col / 2), stxa + (blk_col / 2),
|
||||
sizeof(TXFM_CONTEXT) * mi_width);
|
||||
vpx_memcpy(txl + (blk_row / 2), stxl + (blk_row / 2),
|
||||
sizeof(TXFM_CONTEXT) * mi_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void inter_block_yrd(const VP9_COMP *cpi, MACROBLOCK *x,
|
||||
int *rate, int64_t *distortion, int *skippable,
|
||||
int64_t *sse, BLOCK_SIZE bsize,
|
||||
int64_t ref_best_rd) {
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
int is_cost_valid = 1;
|
||||
int64_t this_rd;
|
||||
vp9_prob skip_prob = vp9_get_skip_prob(&cpi->common, xd);
|
||||
int s0 = vp9_cost_bit(skip_prob, 0);
|
||||
int s1 = vp9_cost_bit(skip_prob, 1);
|
||||
|
||||
if (ref_best_rd < 0)
|
||||
is_cost_valid = 0;
|
||||
|
||||
*rate = 0;
|
||||
*distortion = 0;
|
||||
*sse = 0;
|
||||
*skippable = 1;
|
||||
|
||||
if (is_cost_valid) {
|
||||
const struct macroblockd_plane *const pd = &xd->plane[0];
|
||||
const int mi_width = num_4x4_blocks_wide_lookup[bsize];
|
||||
const int mi_height = num_4x4_blocks_high_lookup[bsize];
|
||||
TX_SIZE max_tx_size = xd->mi[0].mbmi.max_tx_size;
|
||||
BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
|
||||
int bh = num_4x4_blocks_wide_lookup[txb_size];
|
||||
int idx, idy;
|
||||
int block = 0;
|
||||
int step = 1 << (max_tx_size * 2);
|
||||
ENTROPY_CONTEXT ctxa[16], ctxl[16];
|
||||
TXFM_CONTEXT txa[8], txl[8];
|
||||
|
||||
int pnrate = 0, pnskip = 1;
|
||||
int64_t pndist = 0, pnsse = 0;
|
||||
|
||||
vp9_get_entropy_contexts(bsize, TX_4X4, pd, ctxa, ctxl);
|
||||
|
||||
vpx_memcpy(txa, xd->above_txfm_context,
|
||||
sizeof(TXFM_CONTEXT) * num_8x8_blocks_wide_lookup[bsize]);
|
||||
vpx_memcpy(txl, xd->left_txfm_context,
|
||||
sizeof(TXFM_CONTEXT) * num_8x8_blocks_high_lookup[bsize]);
|
||||
|
||||
for (idy = 0; idy < mi_height; idy += bh) {
|
||||
for (idx = 0; idx < mi_width; idx += bh) {
|
||||
select_tx_block(cpi, x, idy, idx, 0, block,
|
||||
max_tx_size, bsize, txb_size,
|
||||
ctxa, ctxl, txa, txl,
|
||||
&pnrate, &pndist, &pnsse, &pnskip);
|
||||
*rate += pnrate;
|
||||
*distortion += pndist;
|
||||
*sse += pnsse;
|
||||
*skippable &= pnskip;
|
||||
|
||||
block += step;
|
||||
}
|
||||
}
|
||||
|
||||
this_rd = MIN(RDCOST(x->rdmult, x->rddiv, *rate + s0, *distortion),
|
||||
RDCOST(x->rdmult, x->rddiv, s1, *sse));
|
||||
if (this_rd > ref_best_rd)
|
||||
is_cost_valid = 0;
|
||||
}
|
||||
|
||||
if (!is_cost_valid) {
|
||||
// reset cost value
|
||||
*rate = INT_MAX;
|
||||
*distortion = INT64_MAX;
|
||||
*sse = INT64_MAX;
|
||||
*skippable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void tx_block_rd(const VP9_COMP *cpi, MACROBLOCK *x,
|
||||
int blk_row, int blk_col, int plane, int block,
|
||||
TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
|
||||
ENTROPY_CONTEXT *above_ctx, ENTROPY_CONTEXT *left_ctx,
|
||||
int *rate, int64_t *dist, int64_t *bsse, int *skip) {
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
|
||||
(blk_col >> (1 - pd->subsampling_x));
|
||||
TX_SIZE plane_tx_size = plane ?
|
||||
get_uv_tx_size_impl(mbmi->inter_tx_size[tx_idx], plane_bsize, 0, 0) :
|
||||
mbmi->inter_tx_size[tx_idx];
|
||||
int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
|
||||
int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
|
||||
int zero_blk_rate;
|
||||
int this_rate, this_skip;
|
||||
int64_t this_dist, this_bsse;
|
||||
|
||||
if (xd->mb_to_bottom_edge < 0)
|
||||
max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
|
||||
if (xd->mb_to_right_edge < 0)
|
||||
max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
|
||||
|
||||
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
|
||||
return;
|
||||
|
||||
if (tx_size == plane_tx_size) {
|
||||
tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
|
||||
plane_bsize, above_ctx, left_ctx,
|
||||
&zero_blk_rate, &this_rate,
|
||||
&this_dist, &this_bsse, &this_skip);
|
||||
*rate += this_rate;
|
||||
*dist += this_dist;
|
||||
*bsse += this_bsse;
|
||||
*skip &= this_skip;
|
||||
} else {
|
||||
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
||||
int bh = num_4x4_blocks_high_lookup[bsize];
|
||||
int step = 1 << (2 *(tx_size - 1));
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
int offsetr = (i >> 1) * bh / 2;
|
||||
int offsetc = (i & 0x01) * bh / 2;
|
||||
tx_block_rd(cpi, x, blk_row + offsetr, blk_col + offsetc, plane,
|
||||
block + i * step, tx_size - 1, plane_bsize,
|
||||
above_ctx, left_ctx, rate, dist, bsse, skip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return value 0: early termination triggered, no valid rd cost available;
|
||||
// 1: rd cost values are valid.
|
||||
static int inter_block_uvrd(const VP9_COMP *cpi, MACROBLOCK *x,
|
||||
int *rate, int64_t *distortion, int *skippable,
|
||||
int64_t *sse, BLOCK_SIZE bsize,
|
||||
int64_t ref_best_rd) {
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
int plane;
|
||||
int is_cost_valid = 1;
|
||||
int64_t this_rd;
|
||||
|
||||
if (ref_best_rd < 0) {
|
||||
is_cost_valid = 0;
|
||||
// reset cost value
|
||||
*rate = INT_MAX;
|
||||
*distortion = INT64_MAX;
|
||||
*sse = INT64_MAX;
|
||||
*skippable = 0;
|
||||
return is_cost_valid;
|
||||
}
|
||||
|
||||
if (is_inter_block(mbmi) && is_cost_valid) {
|
||||
int plane;
|
||||
for (plane = 1; plane < MAX_MB_PLANE; ++plane)
|
||||
vp9_subtract_plane(x, bsize, plane);
|
||||
}
|
||||
|
||||
*rate = 0;
|
||||
*distortion = 0;
|
||||
*sse = 0;
|
||||
*skippable = 1;
|
||||
|
||||
for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
|
||||
const struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
|
||||
const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
|
||||
const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
|
||||
BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
|
||||
int bh = num_4x4_blocks_wide_lookup[txb_size];
|
||||
int idx, idy;
|
||||
int block = 0;
|
||||
int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
|
||||
int pnrate = 0, pnskip = 1;
|
||||
int64_t pndist = 0, pnsse = 0;
|
||||
ENTROPY_CONTEXT ta[16], tl[16];
|
||||
|
||||
vp9_get_entropy_contexts(bsize, TX_4X4, pd, ta, tl);
|
||||
|
||||
for (idy = 0; idy < mi_height; idy += bh) {
|
||||
for (idx = 0; idx < mi_width; idx += bh) {
|
||||
tx_block_rd(cpi, x, idy, idx, plane, block,
|
||||
max_txsize_lookup[plane_bsize], plane_bsize, ta, tl,
|
||||
&pnrate, &pndist, &pnsse, &pnskip);
|
||||
block += step;
|
||||
}
|
||||
}
|
||||
|
||||
if (pnrate == INT_MAX) {
|
||||
is_cost_valid = 0;
|
||||
break;
|
||||
}
|
||||
*rate += pnrate;
|
||||
*distortion += pndist;
|
||||
*sse += pnsse;
|
||||
*skippable &= pnskip;
|
||||
|
||||
this_rd = MIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
|
||||
RDCOST(x->rdmult, x->rddiv, 0, *sse));
|
||||
if (this_rd > ref_best_rd) {
|
||||
is_cost_valid = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_cost_valid) {
|
||||
// reset cost value
|
||||
*rate = INT_MAX;
|
||||
*distortion = INT64_MAX;
|
||||
*sse = INT64_MAX;
|
||||
*skippable = 0;
|
||||
}
|
||||
|
||||
return is_cost_valid;
|
||||
}
|
||||
|
||||
static int super_block_uvrd(const VP9_COMP *cpi, MACROBLOCK *x,
|
||||
int *rate, int64_t *distortion, int *skippable,
|
||||
int64_t *sse, BLOCK_SIZE bsize,
|
||||
@ -1165,7 +1684,7 @@ static int super_block_uvrd(const VP9_COMP *cpi, MACROBLOCK *x,
|
||||
*skippable = 1;
|
||||
|
||||
for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
|
||||
txfm_rd_in_plane(x, &pnrate, &pndist, &pnskip, &pnsse,
|
||||
txfm_rd_in_plane(cpi, x, &pnrate, &pndist, &pnskip, &pnsse,
|
||||
ref_best_rd, plane, bsize, uv_tx_size,
|
||||
cpi->sf.use_fast_coef_costing);
|
||||
if (pnrate == INT_MAX) {
|
||||
@ -2446,6 +2965,8 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
int64_t skip_sse_sb = INT64_MAX;
|
||||
int64_t distortion_y = 0, distortion_uv = 0;
|
||||
|
||||
(void)txfm_cache;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf16);
|
||||
@ -2725,8 +3246,17 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
|
||||
// Y cost and distortion
|
||||
vp9_subtract_plane(x, bsize, 0);
|
||||
super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
|
||||
bsize, txfm_cache, ref_best_rd);
|
||||
|
||||
if (cm->tx_mode == TX_MODE_SELECT) {
|
||||
inter_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
|
||||
bsize, ref_best_rd);
|
||||
} else {
|
||||
super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
|
||||
bsize, txfm_cache, ref_best_rd);
|
||||
// sudo load
|
||||
for (i = 0; i < 64; ++i)
|
||||
mbmi->inter_tx_size[i] = mbmi->tx_size;
|
||||
}
|
||||
|
||||
if (*rate_y == INT_MAX) {
|
||||
*rate2 = INT_MAX;
|
||||
@ -2741,7 +3271,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
|
||||
rdcosty = MIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse));
|
||||
|
||||
if (!super_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
|
||||
if (!inter_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
|
||||
&sseuv, bsize, ref_best_rd - rdcosty)) {
|
||||
*rate2 = INT_MAX;
|
||||
*distortion = INT64_MAX;
|
||||
@ -3266,6 +3796,13 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi,
|
||||
if (ref_frame == INTRA_FRAME) {
|
||||
TX_SIZE uv_tx;
|
||||
struct macroblockd_plane *const pd = &xd->plane[1];
|
||||
MODE_INFO *const mic = xd->mi[0].src_mi;
|
||||
const MODE_INFO *above_mi = xd->above_mi;
|
||||
const MODE_INFO *left_mi = xd->left_mi;
|
||||
|
||||
const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
|
||||
const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
|
||||
int intra_mode_cost;
|
||||
vpx_memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
|
||||
super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
|
||||
NULL, bsize, tx_cache, best_rd);
|
||||
@ -3280,18 +3817,22 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi,
|
||||
&dist_uv[uv_tx], &skip_uv[uv_tx], &mode_uv[uv_tx]);
|
||||
}
|
||||
|
||||
if (A == L)
|
||||
intra_mode_cost = (this_mode == A) ? 256 : 1064;
|
||||
else // (A != L)
|
||||
intra_mode_cost = (this_mode == A) || (this_mode == L) ? 404 : 1169;
|
||||
|
||||
rate_uv = rate_uv_tokenonly[uv_tx];
|
||||
distortion_uv = dist_uv[uv_tx];
|
||||
skippable = skippable && skip_uv[uv_tx];
|
||||
mbmi->uv_mode = mode_uv[uv_tx];
|
||||
|
||||
rate2 = rate_y + cpi->mbmode_cost[mbmi->mode] + rate_uv_intra[uv_tx];
|
||||
rate2 = rate_y + intra_mode_cost + rate_uv_intra[uv_tx];
|
||||
if (this_mode != DC_PRED && this_mode != TM_PRED)
|
||||
rate2 += intra_cost_penalty;
|
||||
distortion2 = distortion_y + distortion_uv;
|
||||
} else {
|
||||
this_rd = handle_inter_mode(cpi, x, bsize,
|
||||
tx_cache,
|
||||
this_rd = handle_inter_mode(cpi, x, bsize, tx_cache,
|
||||
&rate2, &distortion2, &skippable,
|
||||
&rate_y, &rate_uv,
|
||||
&disable_skip, frame_mv,
|
||||
@ -3393,6 +3934,10 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi,
|
||||
vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
|
||||
sizeof(uint8_t) * ctx->num_4x4_blk);
|
||||
|
||||
for (i = 0; i < MAX_MB_PLANE; ++i)
|
||||
vpx_memcpy(ctx->blk_skip[i], x->blk_skip[i],
|
||||
sizeof(uint8_t) * ctx->num_4x4_blk);
|
||||
|
||||
// TODO(debargha): enhance this test with a better distortion prediction
|
||||
// based on qp, activity mask and history
|
||||
if ((mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
|
||||
@ -3754,6 +4299,12 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi,
|
||||
vpx_memset(x->zcoeff_blk[TX_4X4], 0, 4);
|
||||
vp9_zero(best_mbmode);
|
||||
|
||||
for (i = 0; i < MAX_MB_PLANE; ++i) {
|
||||
int j;
|
||||
for (j = 0; j < 4; ++j)
|
||||
x->blk_skip[i][j] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
|
||||
filter_cache[i] = INT64_MAX;
|
||||
|
||||
@ -3899,6 +4450,10 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi,
|
||||
x->skip = 0;
|
||||
set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
|
||||
|
||||
// sudo load
|
||||
for (i = 0; i < 64; ++i)
|
||||
mbmi->inter_tx_size[i] = mbmi->tx_size;
|
||||
|
||||
// Select prediction reference frames.
|
||||
for (i = 0; i < MAX_MB_PLANE; i++) {
|
||||
xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
|
||||
@ -4159,6 +4714,10 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi,
|
||||
vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[TX_4X4],
|
||||
sizeof(uint8_t) * ctx->num_4x4_blk);
|
||||
|
||||
for (i = 0; i < MAX_MB_PLANE; ++i)
|
||||
vpx_memcpy(ctx->blk_skip[i], x->blk_skip[i],
|
||||
sizeof(uint8_t) * ctx->num_4x4_blk);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
best_bmodes[i] = xd->mi[0].src_mi->bmi[i];
|
||||
|
||||
|
@ -580,7 +580,6 @@ static void temporal_filter_iterate_c(VP9_COMP *cpi,
|
||||
mb_y_offset += 16 * (f->y_stride - mb_cols);
|
||||
mb_uv_offset += mb_uv_height * f->uv_stride - mb_uv_width * mb_cols;
|
||||
}
|
||||
|
||||
// Restore input state
|
||||
for (i = 0; i < MAX_MB_PLANE; i++)
|
||||
mbd->plane[i].pre[0].buf = input_buffer[i];
|
||||
|
@ -442,6 +442,20 @@ struct tokenize_b_args {
|
||||
TOKENEXTRA **tp;
|
||||
};
|
||||
|
||||
static void set_entropy_context_b_inter(int plane, int block,
|
||||
BLOCK_SIZE plane_bsize,
|
||||
int blk_row, int blk_col,
|
||||
TX_SIZE tx_size, void *arg) {
|
||||
struct tokenize_b_args* const args = arg;
|
||||
ThreadData *const td = args->td;
|
||||
MACROBLOCK *const x = &td->mb;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
struct macroblock_plane *p = &x->plane[plane];
|
||||
struct macroblockd_plane *pd = &xd->plane[plane];
|
||||
vp9_set_contexts(xd, pd, plane_bsize, tx_size, p->eobs[block] > 0,
|
||||
blk_col, blk_row);
|
||||
}
|
||||
|
||||
static void set_entropy_context_b(int plane, int block, BLOCK_SIZE plane_bsize,
|
||||
TX_SIZE tx_size, void *arg) {
|
||||
struct tokenize_b_args* const args = arg;
|
||||
@ -486,6 +500,85 @@ static INLINE int get_tx_eob(const struct segmentation *seg, int segment_id,
|
||||
return vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
|
||||
}
|
||||
|
||||
static void tokenize_b_inter(int plane, int block, BLOCK_SIZE plane_bsize,
|
||||
int blk_row, int blk_col,
|
||||
TX_SIZE tx_size, void *arg) {
|
||||
struct tokenize_b_args* const args = arg;
|
||||
VP9_COMP *cpi = args->cpi;
|
||||
ThreadData *const td = args->td;
|
||||
MACROBLOCK *const x = &td->mb;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
TOKENEXTRA **tp = args->tp;
|
||||
uint8_t token_cache[32 * 32];
|
||||
struct macroblock_plane *p = &x->plane[plane];
|
||||
struct macroblockd_plane *pd = &xd->plane[plane];
|
||||
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
int pt; /* near block/prev token context index */
|
||||
int c;
|
||||
TOKENEXTRA *t = *tp; /* store tokens starting here */
|
||||
int eob = p->eobs[block];
|
||||
const PLANE_TYPE type = pd->plane_type;
|
||||
const tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
|
||||
const int segment_id = mbmi->segment_id;
|
||||
const int16_t *scan, *nb;
|
||||
const scan_order *so;
|
||||
const int ref = is_inter_block(mbmi);
|
||||
unsigned int (*const counts)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
|
||||
td->rd_counts.coef_counts[tx_size][type][ref];
|
||||
vp9_prob (*const coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
|
||||
cpi->common.fc->coef_probs[tx_size][type][ref];
|
||||
unsigned int (*const eob_branch)[COEFF_CONTEXTS] =
|
||||
td->counts->eob_branch[tx_size][type][ref];
|
||||
const uint8_t *const band = get_band_translate(tx_size);
|
||||
const int seg_eob = get_tx_eob(&cpi->common.seg, segment_id, tx_size);
|
||||
int16_t token;
|
||||
EXTRABIT extra;
|
||||
|
||||
pt = get_entropy_context(tx_size, pd->above_context + blk_col,
|
||||
pd->left_context + blk_row);
|
||||
so = get_scan(xd, tx_size, type, block);
|
||||
scan = so->scan;
|
||||
nb = so->neighbors;
|
||||
c = 0;
|
||||
|
||||
while (c < eob) {
|
||||
int v = 0;
|
||||
int skip_eob = 0;
|
||||
v = qcoeff[scan[c]];
|
||||
|
||||
while (!v) {
|
||||
add_token_no_extra(&t, coef_probs[band[c]][pt], ZERO_TOKEN, skip_eob,
|
||||
counts[band[c]][pt]);
|
||||
eob_branch[band[c]][pt] += !skip_eob;
|
||||
|
||||
skip_eob = 1;
|
||||
token_cache[scan[c]] = 0;
|
||||
++c;
|
||||
pt = get_coef_context(nb, token_cache, c);
|
||||
v = qcoeff[scan[c]];
|
||||
}
|
||||
|
||||
vp9_get_token_extra(v, &token, &extra);
|
||||
|
||||
add_token(&t, coef_probs[band[c]][pt], extra, (uint8_t)token,
|
||||
(uint8_t)skip_eob, counts[band[c]][pt]);
|
||||
eob_branch[band[c]][pt] += !skip_eob;
|
||||
|
||||
token_cache[scan[c]] = vp9_pt_energy_class[token];
|
||||
++c;
|
||||
pt = get_coef_context(nb, token_cache, c);
|
||||
}
|
||||
if (c < seg_eob) {
|
||||
add_token_no_extra(&t, coef_probs[band[c]][pt], EOB_TOKEN, 0,
|
||||
counts[band[c]][pt]);
|
||||
++eob_branch[band[c]][pt];
|
||||
}
|
||||
|
||||
*tp = t;
|
||||
|
||||
vp9_set_contexts(xd, pd, plane_bsize, tx_size, c > 0, blk_col, blk_row);
|
||||
}
|
||||
|
||||
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;
|
||||
@ -607,6 +700,105 @@ int vp9_has_high_freq_in_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void tokenize_tx(VP9_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
|
||||
int dry_run, TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
|
||||
int blk_row, int blk_col, int block, int plane,
|
||||
void *arg) {
|
||||
MACROBLOCK *const x = &td->mb;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
const struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
|
||||
(blk_col >> (1 - pd->subsampling_x));
|
||||
TX_SIZE plane_tx_size = plane ?
|
||||
get_uv_tx_size_impl(mbmi->inter_tx_size[tx_idx], plane_bsize, 0, 0) :
|
||||
mbmi->inter_tx_size[tx_idx];
|
||||
|
||||
int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
|
||||
int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
|
||||
|
||||
if (xd->mb_to_bottom_edge < 0)
|
||||
max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
|
||||
if (xd->mb_to_right_edge < 0)
|
||||
max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
|
||||
|
||||
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
|
||||
return;
|
||||
|
||||
if (tx_size == plane_tx_size) {
|
||||
if (!dry_run)
|
||||
tokenize_b_inter(plane, block, plane_bsize,
|
||||
blk_row, blk_col, tx_size, arg);
|
||||
else
|
||||
set_entropy_context_b_inter(plane, block, plane_bsize,
|
||||
blk_row, blk_col, tx_size, arg);
|
||||
} else {
|
||||
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
||||
int bh = num_4x4_blocks_wide_lookup[bsize];
|
||||
int i;
|
||||
|
||||
assert(num_4x4_blocks_high_lookup[bsize] ==
|
||||
num_4x4_blocks_wide_lookup[bsize]);
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
int offsetr = (i >> 1) * bh / 2;
|
||||
int offsetc = (i & 0x01) * bh / 2;
|
||||
int step = 1 << (2 * (tx_size - 1));
|
||||
tokenize_tx(cpi, td, t, dry_run, tx_size - 1, plane_bsize,
|
||||
blk_row + offsetr, blk_col + offsetc,
|
||||
block + i * step, plane, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vp9_tokenize_sb_inter(VP9_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
|
||||
int dry_run, BLOCK_SIZE bsize) {
|
||||
VP9_COMMON *const cm = &cpi->common;
|
||||
MACROBLOCK *const x = &td->mb;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
TOKENEXTRA *t_backup = *t;
|
||||
const int ctx = vp9_get_skip_context(xd);
|
||||
const int skip_inc = !vp9_segfeature_active(&cm->seg, mbmi->segment_id,
|
||||
SEG_LVL_SKIP);
|
||||
struct tokenize_b_args arg = {cpi, td, t};
|
||||
int plane;
|
||||
|
||||
if (mbmi->skip) {
|
||||
if (!dry_run)
|
||||
td->counts->skip[ctx][1] += skip_inc;
|
||||
reset_skip_context(xd, bsize);
|
||||
if (dry_run)
|
||||
*t = t_backup;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dry_run)
|
||||
td->counts->skip[ctx][0] += skip_inc;
|
||||
else
|
||||
*t = t_backup;
|
||||
|
||||
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
|
||||
const struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
|
||||
const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
|
||||
const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
|
||||
BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
|
||||
int bh = num_4x4_blocks_wide_lookup[txb_size];
|
||||
int idx, idy;
|
||||
int block = 0;
|
||||
int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
|
||||
|
||||
for (idy = 0; idy < mi_height; idy += bh) {
|
||||
for (idx = 0; idx < mi_width; idx += bh) {
|
||||
tokenize_tx(cpi, td, t, dry_run, max_txsize_lookup[plane_bsize],
|
||||
plane_bsize, idy, idx, block, plane, &arg);
|
||||
block += step;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vp9_tokenize_sb(VP9_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
|
||||
int dry_run, BLOCK_SIZE bsize) {
|
||||
VP9_COMMON *const cm = &cpi->common;
|
||||
|
@ -51,6 +51,9 @@ int vp9_has_high_freq_in_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane);
|
||||
struct VP9_COMP;
|
||||
struct ThreadData;
|
||||
|
||||
void vp9_tokenize_sb_inter(struct VP9_COMP *cpi, struct ThreadData *td,
|
||||
TOKENEXTRA **t, int dry_run, BLOCK_SIZE bsize);
|
||||
|
||||
void vp9_tokenize_sb(struct VP9_COMP *cpi, struct ThreadData *td,
|
||||
TOKENEXTRA **t, int dry_run, BLOCK_SIZE bsize);
|
||||
|
||||
|
@ -59,7 +59,7 @@ extern "C" {
|
||||
* types, removing or reassigning enums, adding/removing/rearranging
|
||||
* fields to structures
|
||||
*/
|
||||
#define VPX_ENCODER_ABI_VERSION (4 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/
|
||||
#define VPX_ENCODER_ABI_VERSION (5 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/
|
||||
|
||||
|
||||
/*! \brief Encoder capabilities bitfield
|
||||
|
Loading…
x
Reference in New Issue
Block a user