summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/make/obj_int_extract.c2
-rw-r--r--libs.mk1
-rw-r--r--test/borders_test.cc2
-rw-r--r--test/codec_factory.h2
-rw-r--r--test/datarate_test.cc6
-rw-r--r--test/decode_test_driver.cc1
-rw-r--r--test/decode_test_driver.h14
-rw-r--r--test/error_resilience_test.cc16
-rw-r--r--test/external_frame_buffer_test.cc309
-rw-r--r--test/lru_frame_buffer_test.cc207
-rw-r--r--test/sixtap_predict_test.cc16
-rw-r--r--test/test-data.sha12
-rw-r--r--test/test.mk4
-rw-r--r--test/test_vector_test.cc174
-rw-r--r--test/test_vectors.cc167
-rw-r--r--test/test_vectors.h35
-rw-r--r--test/tile_independence_test.cc14
-rw-r--r--test/vp8_fdct4x4_test.cc19
-rw-r--r--test/vp9_lossless_test.cc16
-rw-r--r--test/webm_video_source.h10
-rw-r--r--vp8/vp8_dx_iface.c1
-rw-r--r--vp9/common/vp9_alloccommon.c28
-rw-r--r--vp9/common/vp9_convolve.c263
-rw-r--r--vp9/common/vp9_entropy.h2
-rw-r--r--vp9/common/vp9_findnearmv.c65
-rw-r--r--vp9/common/vp9_findnearmv.h6
-rw-r--r--vp9/common/vp9_mv.h4
-rw-r--r--vp9/common/vp9_onyx.h2
-rw-r--r--vp9/common/vp9_onyxc_int.h39
-rw-r--r--vp9/common/vp9_pred_common.h4
-rw-r--r--vp9/common/vp9_reconinter.c2
-rw-r--r--vp9/common/vp9_rtcd_defs.sh9
-rw-r--r--vp9/decoder/vp9_decodeframe.c38
-rw-r--r--vp9/decoder/vp9_decodemv.c51
-rw-r--r--vp9/encoder/vp9_bitstream.c54
-rw-r--r--vp9/encoder/vp9_block.h1
-rw-r--r--vp9/encoder/vp9_boolhuff.h1
-rw-r--r--vp9/encoder/vp9_encodeframe.c106
-rw-r--r--vp9/encoder/vp9_encodemb.c57
-rw-r--r--vp9/encoder/vp9_encodemv.c16
-rw-r--r--vp9/encoder/vp9_firstpass.c63
-rw-r--r--vp9/encoder/vp9_mbgraph.c2
-rw-r--r--vp9/encoder/vp9_mcomp.c384
-rw-r--r--vp9/encoder/vp9_mcomp.h14
-rw-r--r--vp9/encoder/vp9_onyx_if.c37
-rw-r--r--vp9/encoder/vp9_onyx_int.h4
-rw-r--r--vp9/encoder/vp9_rdopt.c45
-rw-r--r--vp9/encoder/vp9_treewriter.h55
-rw-r--r--vp9/vp9_cx_iface.c14
-rw-r--r--vp9/vp9_dx_iface.c82
-rw-r--r--vpx/exports_dec1
-rw-r--r--vpx/internal/vpx_codec_internal.h33
-rw-r--r--vpx/src/vpx_decoder.c19
-rw-r--r--vpx/vp8dx.h8
-rw-r--r--vpx/vpx_codec.mk2
-rw-r--r--vpx/vpx_decoder.h48
-rw-r--r--vpx/vpx_external_frame_buffer.h53
-rw-r--r--vpx_scale/generic/yv12config.c57
-rw-r--r--vpx_scale/yv12config.h14
-rw-r--r--vpxdec.c66
-rw-r--r--webmdec.c9
61 files changed, 1862 insertions, 914 deletions
diff --git a/build/make/obj_int_extract.c b/build/make/obj_int_extract.c
index feed9d983..495e9d7fa 100644
--- a/build/make/obj_int_extract.c
+++ b/build/make/obj_int_extract.c
@@ -321,7 +321,7 @@ bail:
return 1;
}
-char *parse_elf_string_table(elf_obj_t *elf, int s_idx, int idx) {
+const char *parse_elf_string_table(elf_obj_t *elf, int s_idx, int idx) {
if (elf->bits == 32) {
Elf32_Shdr shdr;
diff --git a/libs.mk b/libs.mk
index 40628338f..8340eeebe 100644
--- a/libs.mk
+++ b/libs.mk
@@ -183,6 +183,7 @@ CODEC_EXPORTS-$(CONFIG_DECODERS) += vpx/exports_dec
INSTALL-LIBS-yes += include/vpx/vpx_codec.h
INSTALL-LIBS-yes += include/vpx/vpx_image.h
+INSTALL-LIBS-yes += include/vpx/vpx_external_frame_buffer.h
INSTALL-LIBS-yes += include/vpx/vpx_integer.h
INSTALL-LIBS-$(CONFIG_DECODERS) += include/vpx/vpx_decoder.h
INSTALL-LIBS-$(CONFIG_ENCODERS) += include/vpx/vpx_encoder.h
diff --git a/test/borders_test.cc b/test/borders_test.cc
index dcdedcfab..5071541ab 100644
--- a/test/borders_test.cc
+++ b/test/borders_test.cc
@@ -67,7 +67,7 @@ TEST_P(BordersTest, TestLowBitrate) {
cfg_.g_lag_in_frames = 25;
cfg_.rc_2pass_vbr_minsection_pct = 5;
- cfg_.rc_2pass_vbr_minsection_pct = 2000;
+ cfg_.rc_2pass_vbr_maxsection_pct = 2000;
cfg_.rc_target_bitrate = 200;
cfg_.rc_min_quantizer = 40;
diff --git a/test/codec_factory.h b/test/codec_factory.h
index cc7b53f06..2ca6ff086 100644
--- a/test/codec_factory.h
+++ b/test/codec_factory.h
@@ -26,6 +26,8 @@ extern "C" {
#include "test/encode_test_driver.h"
namespace libvpx_test {
+const int kCodecFactoryParam = 0;
+
class CodecFactory {
public:
CodecFactory() {}
diff --git a/test/datarate_test.cc b/test/datarate_test.cc
index 5785a0aac..2d4652271 100644
--- a/test/datarate_test.cc
+++ b/test/datarate_test.cc
@@ -248,9 +248,11 @@ TEST_P(DatarateTestVP9, BasicRateTargeting) {
cfg_.rc_target_bitrate = i;
ResetModel();
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
- ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.9)
+ ASSERT_GE(static_cast<double>(cfg_.rc_target_bitrate),
+ effective_datarate_ * 0.85)
<< " The datarate for the file exceeds the target by too much!";
- ASSERT_LE(cfg_.rc_target_bitrate, effective_datarate_ * 1.1)
+ ASSERT_LE(static_cast<double>(cfg_.rc_target_bitrate),
+ effective_datarate_ * 1.15)
<< " The datarate for the file missed the target!";
}
}
diff --git a/test/decode_test_driver.cc b/test/decode_test_driver.cc
index 1f6d54064..7a93e50c2 100644
--- a/test/decode_test_driver.cc
+++ b/test/decode_test_driver.cc
@@ -30,6 +30,7 @@ void DecoderTest::RunLoop(CompressedVideoSource *video) {
// Decode frames.
for (video->Begin(); video->cxdata(); video->Next()) {
+ PreDecodeFrameHook(*video, decoder);
vpx_codec_err_t res_dec = decoder->DecodeFrame(video->cxdata(),
video->frame_size());
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError();
diff --git a/test/decode_test_driver.h b/test/decode_test_driver.h
index 055c45e06..79db6e1bc 100644
--- a/test/decode_test_driver.h
+++ b/test/decode_test_driver.h
@@ -76,6 +76,16 @@ class Decoder {
return detail ? detail : vpx_codec_error(&decoder_);
}
+ // Passes the external frame buffer information to libvpx.
+ vpx_codec_err_t SetExternalFrameBuffers(
+ vpx_codec_frame_buffer_t *fb_list, int fb_count,
+ vpx_realloc_frame_buffer_cb_fn_t cb, void *user_priv) {
+ InitOnce();
+ return vpx_codec_set_frame_buffers(&decoder_,
+ fb_list, fb_count,
+ cb, user_priv);
+ }
+
protected:
virtual const vpx_codec_iface_t* CodecInterface() const = 0;
@@ -101,6 +111,10 @@ class DecoderTest {
// Main decoding loop
virtual void RunLoop(CompressedVideoSource *video);
+ // Hook to be called before decompressing every frame.
+ virtual void PreDecodeFrameHook(const CompressedVideoSource& video,
+ Decoder *decoder) {}
+
// Hook to be called on every decompressed frame.
virtual void DecompressedFrameHook(const vpx_image_t& img,
const unsigned int frame_number) {}
diff --git a/test/error_resilience_test.cc b/test/error_resilience_test.cc
index 16d250c76..30c20e91f 100644
--- a/test/error_resilience_test.cc
+++ b/test/error_resilience_test.cc
@@ -1,12 +1,12 @@
/*
- Copyright (c) 2012 The WebM project authors. All Rights Reserved.
-
- Use of this source code is governed by a BSD-style license
- that can be found in the LICENSE file in the root of the source
- tree. An additional intellectual property rights grant can be found
- in the file PATENTS. All contributing project authors may
- be found in the AUTHORS file in the root of the source tree.
-*/
+ * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
diff --git a/test/external_frame_buffer_test.cc b/test/external_frame_buffer_test.cc
new file mode 100644
index 000000000..874d1997c
--- /dev/null
+++ b/test/external_frame_buffer_test.cc
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <string>
+
+#include "test/codec_factory.h"
+#include "test/decode_test_driver.h"
+#include "test/ivf_video_source.h"
+#include "test/md5_helper.h"
+#include "test/test_vectors.h"
+#include "test/util.h"
+#include "test/webm_video_source.h"
+
+namespace {
+
+const int kVideoNameParam = 1;
+const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
+
+// Callback used by libvpx to request the application to allocate a frame
+// buffer of at least |new_size| in bytes.
+int realloc_vp9_frame_buffer(void *user_priv, size_t new_size,
+ vpx_codec_frame_buffer_t *fb) {
+ (void)user_priv;
+ if (fb == NULL)
+ return -1;
+
+ delete [] fb->data;
+ fb->data = new uint8_t[new_size];
+ fb->size = new_size;
+ return 0;
+}
+
+// Callback will not allocate data for frame buffer.
+int zero_realloc_vp9_frame_buffer(void *user_priv, size_t new_size,
+ vpx_codec_frame_buffer_t *fb) {
+ (void)user_priv;
+ if (fb == NULL)
+ return -1;
+
+ delete [] fb->data;
+ fb->data = NULL;
+ fb->size = new_size;
+ return 0;
+}
+
+// Callback will allocate one less byte.
+int one_less_byte_realloc_vp9_frame_buffer(void *user_priv, size_t new_size,
+ vpx_codec_frame_buffer_t *fb) {
+ (void)user_priv;
+ if (fb == NULL)
+ return -1;
+
+ delete [] fb->data;
+
+ const size_t error_size = new_size - 1;
+ fb->data = new uint8_t[error_size];
+ fb->size = error_size;
+ return 0;
+}
+
+// Class for testing passing in external frame buffers to libvpx.
+class ExternalFrameBufferMD5Test
+ : public ::libvpx_test::DecoderTest,
+ public ::libvpx_test::CodecTestWithParam<const char*> {
+ protected:
+ ExternalFrameBufferMD5Test()
+ : DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)),
+ md5_file_(NULL),
+ num_buffers_(0),
+ frame_buffers_(NULL) {}
+
+ virtual ~ExternalFrameBufferMD5Test() {
+ for (int i = 0; i < num_buffers_; ++i) {
+ delete [] frame_buffers_[i].data;
+ }
+ delete [] frame_buffers_;
+
+ if (md5_file_ != NULL)
+ fclose(md5_file_);
+ }
+
+ virtual void PreDecodeFrameHook(
+ const libvpx_test::CompressedVideoSource &video,
+ libvpx_test::Decoder *decoder) {
+ if (num_buffers_ > 0 && video.frame_number() == 0) {
+ // Have libvpx use frame buffers we create.
+ frame_buffers_ = new vpx_codec_frame_buffer_t[num_buffers_];
+ memset(frame_buffers_, 0, sizeof(frame_buffers_[0]) * num_buffers_);
+
+ ASSERT_EQ(VPX_CODEC_OK,
+ decoder->SetExternalFrameBuffers(
+ frame_buffers_, num_buffers_,
+ realloc_vp9_frame_buffer, NULL));
+ }
+ }
+
+ void OpenMD5File(const std::string &md5_file_name_) {
+ md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
+ ASSERT_TRUE(md5_file_ != NULL) << "Md5 file open failed. Filename: "
+ << md5_file_name_;
+ }
+
+ virtual void DecompressedFrameHook(const vpx_image_t &img,
+ const unsigned int frame_number) {
+ ASSERT_TRUE(md5_file_ != NULL);
+ char expected_md5[33];
+ char junk[128];
+
+ // Read correct md5 checksums.
+ const int res = fscanf(md5_file_, "%s %s", expected_md5, junk);
+ ASSERT_NE(EOF, res) << "Read md5 data failed";
+ expected_md5[32] = '\0';
+
+ ::libvpx_test::MD5 md5_res;
+ md5_res.Add(&img);
+ const char *const actual_md5 = md5_res.Get();
+
+ // Check md5 match.
+ ASSERT_STREQ(expected_md5, actual_md5)
+ << "Md5 checksums don't match: frame number = " << frame_number;
+ }
+
+ void set_num_buffers(int num_buffers) { num_buffers_ = num_buffers; }
+ int num_buffers() const { return num_buffers_; }
+
+ private:
+ FILE *md5_file_;
+ int num_buffers_;
+ vpx_codec_frame_buffer_t *frame_buffers_;
+};
+
+class ExternalFrameBufferTest : public ::testing::Test {
+ protected:
+ ExternalFrameBufferTest()
+ : video_(NULL),
+ decoder_(NULL),
+ num_buffers_(0),
+ frame_buffers_(NULL) {}
+
+ virtual void SetUp() {
+ video_ = new libvpx_test::WebMVideoSource(kVP9TestFile);
+ video_->Init();
+ video_->Begin();
+
+ vpx_codec_dec_cfg_t cfg = {0};
+ decoder_ = new libvpx_test::VP9Decoder(cfg, 0);
+ }
+
+ virtual void TearDown() {
+ for (int i = 0; i < num_buffers_; ++i) {
+ delete [] frame_buffers_[i].data;
+ }
+ delete [] frame_buffers_;
+ delete decoder_;
+ delete video_;
+ }
+
+ // Passes the external frame buffer information to libvpx.
+ vpx_codec_err_t SetExternalFrameBuffers(
+ int num_buffers,
+ vpx_realloc_frame_buffer_cb_fn_t cb) {
+ if (num_buffers > 0) {
+ num_buffers_ = num_buffers;
+
+ // Have libvpx use frame buffers we create.
+ frame_buffers_ = new vpx_codec_frame_buffer_t[num_buffers_];
+ memset(frame_buffers_, 0, sizeof(frame_buffers_[0]) * num_buffers_);
+ }
+
+ return decoder_->SetExternalFrameBuffers(frame_buffers_, num_buffers_,
+ cb, NULL);
+ }
+
+ // Pass Null frame buffer list to libvpx.
+ vpx_codec_err_t SetNullFrameBuffers(
+ int num_buffers,
+ vpx_realloc_frame_buffer_cb_fn_t cb) {
+ return decoder_->SetExternalFrameBuffers(NULL, num_buffers,
+ cb, NULL);
+ }
+
+ vpx_codec_err_t DecodeOneFrame() {
+ const vpx_codec_err_t res =
+ decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
+ if (res == VPX_CODEC_OK)
+ video_->Next();
+ return res;
+ }
+
+ vpx_codec_err_t DecodeRemainingFrames() {
+ for (; video_->cxdata(); video_->Next()) {
+ const vpx_codec_err_t res =
+ decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
+ if (res != VPX_CODEC_OK)
+ return res;
+
+ libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
+ const vpx_image_t *img = NULL;
+
+ // Get decompressed data
+ while ((img = dec_iter.Next())) {
+ }
+ }
+ return VPX_CODEC_OK;
+ }
+
+ libvpx_test::WebMVideoSource *video_;
+ libvpx_test::VP9Decoder *decoder_;
+ int num_buffers_;
+ vpx_codec_frame_buffer_t *frame_buffers_;
+};
+
+
+// This test runs through the set of test vectors, and decodes them.
+// Libvpx will call into the application to allocate a frame buffer when
+// needed. The md5 checksums are computed for each frame in the video file.
+// If md5 checksums match the correct md5 data, then the test is passed.
+// Otherwise, the test failed.
+TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
+ const std::string filename = GET_PARAM(kVideoNameParam);
+ libvpx_test::CompressedVideoSource *video = NULL;
+
+ // Number of buffers equals number of possible reference buffers(8), plus
+ // one working buffer, plus four jitter buffers.
+ const int num_buffers = 13;
+ set_num_buffers(num_buffers);
+
+ // Tell compiler we are not using kVP8TestVectors.
+ (void)libvpx_test::kVP8TestVectors;
+
+ // Open compressed video file.
+ if (filename.substr(filename.length() - 3, 3) == "ivf") {
+ video = new libvpx_test::IVFVideoSource(filename);
+ } else if (filename.substr(filename.length() - 4, 4) == "webm") {
+ video = new libvpx_test::WebMVideoSource(filename);
+ }
+ video->Init();
+
+ // Construct md5 file name.
+ const std::string md5_filename = filename + ".md5";
+ OpenMD5File(md5_filename);
+
+ // Decode frame, and check the md5 matching.
+ ASSERT_NO_FATAL_FAILURE(RunLoop(video));
+ delete video;
+}
+
+TEST_F(ExternalFrameBufferTest, EightFrameBuffers) {
+ // Minimum number of reference buffers for VP9 is 8.
+ const int num_buffers = 8;
+ ASSERT_EQ(VPX_CODEC_OK,
+ SetExternalFrameBuffers(num_buffers, realloc_vp9_frame_buffer));
+ ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
+}
+
+TEST_F(ExternalFrameBufferTest, EightJitterBuffers) {
+ // Number of buffers equals number of possible reference buffers(8), plus
+ // one working buffer, plus eight jitter buffers.
+ const int num_buffers = 17;
+ ASSERT_EQ(VPX_CODEC_OK,
+ SetExternalFrameBuffers(num_buffers, realloc_vp9_frame_buffer));
+ ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
+}
+
+TEST_F(ExternalFrameBufferTest, NotEnoughBuffers) {
+ // Minimum number of reference buffers for VP9 is 8.
+ const int num_buffers = 7;
+ ASSERT_EQ(VPX_CODEC_INVALID_PARAM,
+ SetExternalFrameBuffers(num_buffers, realloc_vp9_frame_buffer));
+}
+
+TEST_F(ExternalFrameBufferTest, NullFrameBufferList) {
+ // Number of buffers equals number of possible reference buffers(8), plus
+ // one working buffer, plus four jitter buffers.
+ const int num_buffers = 13;
+ ASSERT_EQ(VPX_CODEC_INVALID_PARAM,
+ SetNullFrameBuffers(num_buffers, realloc_vp9_frame_buffer));
+}
+
+TEST_F(ExternalFrameBufferTest, NullRealloc) {
+ // Number of buffers equals number of possible reference buffers(8), plus
+ // one working buffer, plus four jitter buffers.
+ const int num_buffers = 13;
+ ASSERT_EQ(VPX_CODEC_OK,
+ SetExternalFrameBuffers(num_buffers,
+ zero_realloc_vp9_frame_buffer));
+ ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame());
+}
+
+TEST_F(ExternalFrameBufferTest, ReallocOneLessByte) {
+ // Number of buffers equals number of possible reference buffers(8), plus
+ // one working buffer, plus four jitter buffers.
+ const int num_buffers = 13;
+ ASSERT_EQ(VPX_CODEC_OK,
+ SetExternalFrameBuffers(num_buffers,
+ one_less_byte_realloc_vp9_frame_buffer));
+ ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame());
+}
+
+VP9_INSTANTIATE_TEST_CASE(ExternalFrameBufferMD5Test,
+ ::testing::ValuesIn(libvpx_test::kVP9TestVectors));
+} // namespace
diff --git a/test/lru_frame_buffer_test.cc b/test/lru_frame_buffer_test.cc
new file mode 100644
index 000000000..cd6b432d8
--- /dev/null
+++ b/test/lru_frame_buffer_test.cc
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <queue>
+#include <string>
+
+#include "test/codec_factory.h"
+#include "test/decode_test_driver.h"
+#include "test/ivf_video_source.h"
+#include "test/md5_helper.h"
+#include "test/util.h"
+#include "test/webm_video_source.h"
+
+namespace {
+
+const int kVideoNameParam = 1;
+
+const char *kLRUTestVectors[] = {
+ "vp90-2-02-size-lf-1920x1080.webm",
+ "vp90-2-05-resize.ivf",
+};
+
+// Callback used by libvpx to request the application to allocate a frame
+// buffer of at least |new_size| in bytes.
+int realloc_vp9_frame_buffer(void *user_priv, size_t new_size,
+ vpx_codec_frame_buffer_t *fb) {
+ (void)user_priv;
+ if (fb == NULL)
+ return -1;
+
+ delete [] fb->data;
+ fb->data = new uint8_t[new_size];
+ fb->size = new_size;
+
+ return 0;
+}
+
+// Class for testing libvpx is using the least recently
+// used frame buffer when a new buffer is requested.
+class LRUFrameBufferTest
+ : public ::libvpx_test::DecoderTest,
+ public ::libvpx_test::CodecTestWithParam<const char*> {
+ protected:
+ struct FrameBufferMD5Sum {
+ int frame_buffer_index;
+ vpx_image_t img;
+ std::string md5;
+ };
+
+ LRUFrameBufferTest()
+ : DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)),
+ num_buffers_(0),
+ num_jitter_buffers_(0),
+ frame_buffers_(NULL) {}
+
+ virtual ~LRUFrameBufferTest() {
+ for (int i = 0; i < num_buffers_; ++i) {
+ delete [] frame_buffers_[i].data;
+ }
+ delete [] frame_buffers_;
+ }
+
+ virtual void PreDecodeFrameHook(
+ const libvpx_test::CompressedVideoSource &video,
+ libvpx_test::Decoder *decoder) {
+ // Use external buffers for testing jitter buffers.
+ if (num_jitter_buffers_ > 0 && video.frame_number() == 0) {
+ const int max_reference_buffers = 8;
+
+ // Add 1 for a work buffer.
+ num_buffers_ = max_reference_buffers + 1 + num_jitter_buffers_;
+
+ // Have libvpx use frame buffers we create.
+ frame_buffers_ = new vpx_codec_frame_buffer_t[num_buffers_];
+ memset(frame_buffers_, 0, sizeof(frame_buffers_[0]) * num_buffers_);
+
+ decoder->SetExternalFrameBuffers(frame_buffers_, num_buffers_,
+ realloc_vp9_frame_buffer, NULL);
+ }
+
+ // Turn on frame buffer LRU cache.
+ decoder->Control(VP9D_SET_FRAME_BUFFER_LRU_CACHE, 1);
+ }
+
+ virtual void DecompressedFrameHook(const vpx_image_t &img,
+ const unsigned int frame_number) {
+ const uint32_t ximg_y_plane = 0;
+ const uint8_t *const y_buffer = img.planes[ximg_y_plane];
+
+ // Find which external buffer contains the y_buffer.
+ int i = 0;
+ for (i = 0; i < num_buffers_; ++i) {
+ if (y_buffer >= frame_buffers_[i].data &&
+ y_buffer < (frame_buffers_[i].data + frame_buffers_[i].size)) {
+ break;
+ }
+ }
+
+ FrameBufferMD5Sum fb_md5;
+ fb_md5.frame_buffer_index = i;
+ fb_md5.img = img;
+
+ libvpx_test::MD5 md5;
+ md5.Add(&img);
+ fb_md5.md5 = md5.Get();
+ jitter_buffer_md5_sums_.push(fb_md5);
+
+ // Check to see if any of the reconstructed image changed.
+ if (jitter_buffer_md5_sums_.size() >
+ static_cast<size_t>(num_jitter_buffers_)) {
+ fb_md5 = jitter_buffer_md5_sums_.front();
+
+ libvpx_test::MD5 md5;
+ md5.Add(&fb_md5.img);
+ const std::string check_str = md5.Get();
+
+ ASSERT_EQ(fb_md5.md5, check_str);
+ jitter_buffer_md5_sums_.pop();
+ }
+ }
+
+ libvpx_test::CompressedVideoSource *OpenCompressedFile(
+ const std::string &filename) {
+ if (filename.substr(filename.length() - 3, 3) == "ivf") {
+ return new libvpx_test::IVFVideoSource(filename);
+ } else if (filename.substr(filename.length() - 4, 4) == "webm") {
+ return new libvpx_test::WebMVideoSource(filename);
+ }
+ return NULL;
+ }
+
+ void set_num_jitter_buffers(int num_buffers) {
+ num_jitter_buffers_ = num_buffers;
+ }
+
+ private:
+ // Total number of external frame buffers.
+ int num_buffers_;
+ int num_jitter_buffers_;
+
+ // External frame buffers used by libvpx.
+ vpx_codec_frame_buffer_t *frame_buffers_;
+
+ // Save the md5 checksums for later comparison.
+ std::queue<FrameBufferMD5Sum> jitter_buffer_md5_sums_;
+};
+
+// This test runs through a set of test vectors, and decodes them.
+// Libvpx will call into the application to allocate a frame buffer when
+// needed. The md5 checksums are computed for each frame after it is
+// decoded and stored to be checked later. After a jitter frame buffer
+// has expired, the md5 checksum is computed again for the expired jitter
+// buffer frame and checked against the md5 checksum after the frame was
+// decoded. If md5 checksums match, then the test is passed. Otherwise,
+// the test failed.
+TEST_P(LRUFrameBufferTest, CheckLRUOneJitterBuffer) {
+ const std::string filename = GET_PARAM(kVideoNameParam);
+
+ set_num_jitter_buffers(1);
+
+ libvpx_test::CompressedVideoSource *const video =
+ OpenCompressedFile(filename);
+ video->Init();
+
+ // Decode frame, and check the md5 matching.
+ ASSERT_NO_FATAL_FAILURE(RunLoop(video));
+ delete video;
+}
+
+TEST_P(LRUFrameBufferTest, CheckLRUFourJitterBuffers) {
+ const std::string filename = GET_PARAM(kVideoNameParam);
+
+ set_num_jitter_buffers(4);
+
+ libvpx_test::CompressedVideoSource *const video =
+ OpenCompressedFile(filename);
+ video->Init();
+
+ // Decode frame, and check the md5 matching.
+ ASSERT_NO_FATAL_FAILURE(RunLoop(video));
+ delete video;
+}
+
+TEST_P(LRUFrameBufferTest, CheckLRUEightJitterBuffers) {
+ const std::string filename = GET_PARAM(kVideoNameParam);
+
+ set_num_jitter_buffers(8);
+
+ libvpx_test::CompressedVideoSource *const video =
+ OpenCompressedFile(filename);
+ video->Init();
+
+ // Decode frame, and check the md5 matching.
+ ASSERT_NO_FATAL_FAILURE(RunLoop(video));
+ delete video;
+}
+
+VP9_INSTANTIATE_TEST_CASE(LRUFrameBufferTest,
+ ::testing::ValuesIn(kLRUTestVectors));
+} // namespace
diff --git a/test/sixtap_predict_test.cc b/test/sixtap_predict_test.cc
index 655146dbf..0f5c0a5e8 100644
--- a/test/sixtap_predict_test.cc
+++ b/test/sixtap_predict_test.cc
@@ -1,12 +1,12 @@
/*
-* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
-*
-* Use of this source code is governed by a BSD-style license
-* that can be found in the LICENSE file in the root of the source
-* tree. An additional intellectual property rights grant can be found
-* in the file PATENTS. All contributing project authors may
-* be found in the AUTHORS file in the root of the source tree.
-*/
+ * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
#include <math.h>
#include <stdlib.h>
diff --git a/test/test-data.sha1 b/test/test-data.sha1
index 445147986..442bfd23f 100644
--- a/test/test-data.sha1
+++ b/test/test-data.sha1
@@ -567,3 +567,5 @@ c64b03b5c090e6888cb39685c31f00a6b79fa45c vp90-2-tos_854x356_tile_1x2_656kbps.we
c9b6850af28579b031791066457f4cb40df6e1c7 vp90-2-08-tile_1x8_frame_parallel.webm.md5
e448b6e83490bca0f8d58b4f4b1126a17baf4b0c vp90-2-08-tile_1x8.webm
5e524165f0397e6141d914f4f0a66267d7658376 vp90-2-08-tile_1x8.webm.md5
+a34e14923d6d17b1144254d8187d7f85b700a63c vp90-2-02-size-lf-1920x1080.webm
+e3b28ddcfaeb37fb4d132b93f92642a9ad17c22d vp90-2-02-size-lf-1920x1080.webm.md5
diff --git a/test/test.mk b/test/test.mk
index 98e5c7b72..361a34fa4 100644
--- a/test/test.mk
+++ b/test/test.mk
@@ -7,6 +7,8 @@ LIBVPX_TEST_SRCS-yes += codec_factory.h
LIBVPX_TEST_SRCS-yes += test_libvpx.cc
LIBVPX_TEST_SRCS-yes += util.h
LIBVPX_TEST_SRCS-yes += video_source.h
+LIBVPX_TEST_SRCS-yes += test_vectors.h
+LIBVPX_TEST_SRCS-yes += test_vectors.cc
##
## BLACK BOX TESTS
@@ -32,6 +34,8 @@ LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../md5_utils.h ../md5_utils.c
LIBVPX_TEST_SRCS-yes += decode_test_driver.cc
LIBVPX_TEST_SRCS-yes += decode_test_driver.h
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ivf_video_source.h
+LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += external_frame_buffer_test.cc
+LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += lru_frame_buffer_test.cc
## WebM Parsing
NESTEGG_SRCS += ../nestegg/halloc/halloc.h
diff --git a/test/test_vector_test.cc b/test/test_vector_test.cc
index ee610fa90..6d93bb88f 100644
--- a/test/test_vector_test.cc
+++ b/test/test_vector_test.cc
@@ -1,11 +1,11 @@
/*
- Copyright (c) 2012 The WebM project authors. All Rights Reserved.
-
- Use of this source code is governed by a BSD-style license
- that can be found in the LICENSE file in the root of the source
- tree. An additional intellectual property rights grant can be found
- in the file PATENTS. All contributing project authors may
- be found in the AUTHORS file in the root of the source tree.
+ * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
*/
#include <cstdio>
@@ -15,165 +15,15 @@
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/ivf_video_source.h"
-#include "test/webm_video_source.h"
-#include "test/util.h"
#include "test/md5_helper.h"
+#include "test/test_vectors.h"
+#include "test/util.h"
+#include "test/webm_video_source.h"
extern "C" {
#include "vpx_mem/vpx_mem.h"
}
namespace {
-#if CONFIG_VP8_DECODER
-const char *kVP8TestVectors[] = {
- "vp80-00-comprehensive-001.ivf",
- "vp80-00-comprehensive-002.ivf", "vp80-00-comprehensive-003.ivf",
- "vp80-00-comprehensive-004.ivf", "vp80-00-comprehensive-005.ivf",
- "vp80-00-comprehensive-006.ivf", "vp80-00-comprehensive-007.ivf",
- "vp80-00-comprehensive-008.ivf", "vp80-00-comprehensive-009.ivf",
- "vp80-00-comprehensive-010.ivf", "vp80-00-comprehensive-011.ivf",
- "vp80-00-comprehensive-012.ivf", "vp80-00-comprehensive-013.ivf",
- "vp80-00-comprehensive-014.ivf", "vp80-00-comprehensive-015.ivf",
- "vp80-00-comprehensive-016.ivf", "vp80-00-comprehensive-017.ivf",
- "vp80-00-comprehensive-018.ivf", "vp80-01-intra-1400.ivf",
- "vp80-01-intra-1411.ivf", "vp80-01-intra-1416.ivf",
- "vp80-01-intra-1417.ivf", "vp80-02-inter-1402.ivf",
- "vp80-02-inter-1412.ivf", "vp80-02-inter-1418.ivf",
- "vp80-02-inter-1424.ivf", "vp80-03-segmentation-01.ivf",
- "vp80-03-segmentation-02.ivf", "vp80-03-segmentation-03.ivf",
- "vp80-03-segmentation-04.ivf", "vp80-03-segmentation-1401.ivf",
- "vp80-03-segmentation-1403.ivf", "vp80-03-segmentation-1407.ivf",
- "vp80-03-segmentation-1408.ivf", "vp80-03-segmentation-1409.ivf",
- "vp80-03-segmentation-1410.ivf", "vp80-03-segmentation-1413.ivf",
- "vp80-03-segmentation-1414.ivf", "vp80-03-segmentation-1415.ivf",
- "vp80-03-segmentation-1425.ivf", "vp80-03-segmentation-1426.ivf",
- "vp80-03-segmentation-1427.ivf", "vp80-03-segmentation-1432.ivf",
- "vp80-03-segmentation-1435.ivf", "vp80-03-segmentation-1436.ivf",
- "vp80-03-segmentation-1437.ivf", "vp80-03-segmentation-1441.ivf",
- "vp80-03-segmentation-1442.ivf", "vp80-04-partitions-1404.ivf",
- "vp80-04-partitions-1405.ivf", "vp80-04-partitions-1406.ivf",
- "vp80-05-sharpness-1428.ivf", "vp80-05-sharpness-1429.ivf",
- "vp80-05-sharpness-1430.ivf", "vp80-05-sharpness-1431.ivf",
- "vp80-05-sharpness-1433.ivf", "vp80-05-sharpness-1434.ivf",
- "vp80-05-sharpness-1438.ivf", "vp80-05-sharpness-1439.ivf",
- "vp80-05-sharpness-1440.ivf", "vp80-05-sharpness-1443.ivf",
- "vp80-06-smallsize.ivf"
-};
-#endif
-#if CONFIG_VP9_DECODER
-const char *kVP9TestVectors[] = {
- "vp90-2-00-quantizer-00.webm", "vp90-2-00-quantizer-01.webm",
- "vp90-2-00-quantizer-02.webm", "vp90-2-00-quantizer-03.webm",
- "vp90-2-00-quantizer-04.webm", "vp90-2-00-quantizer-05.webm",
- "vp90-2-00-quantizer-06.webm", "vp90-2-00-quantizer-07.webm",
- "vp90-2-00-quantizer-08.webm", "vp90-2-00-quantizer-09.webm",
- "vp90-2-00-quantizer-10.webm", "vp90-2-00-quantizer-11.webm",
- "vp90-2-00-quantizer-12.webm", "vp90-2-00-quantizer-13.webm",
- "vp90-2-00-quantizer-14.webm", "vp90-2-00-quantizer-15.webm",
- "vp90-2-00-quantizer-16.webm", "vp90-2-00-quantizer-17.webm",
- "vp90-2-00-quantizer-18.webm", "vp90-2-00-quantizer-19.webm",
- "vp90-2-00-quantizer-20.webm", "vp90-2-00-quantizer-21.webm",
- "vp90-2-00-quantizer-22.webm", "vp90-2-00-quantizer-23.webm",
- "vp90-2-00-quantizer-24.webm", "vp90-2-00-quantizer-25.webm",
- "vp90-2-00-quantizer-26.webm", "vp90-2-00-quantizer-27.webm",
- "vp90-2-00-quantizer-28.webm", "vp90-2-00-quantizer-29.webm",
- "vp90-2-00-quantizer-30.webm", "vp90-2-00-quantizer-31.webm",
- "vp90-2-00-quantizer-32.webm", "vp90-2-00-quantizer-33.webm",
- "vp90-2-00-quantizer-34.webm", "vp90-2-00-quantizer-35.webm",
- "vp90-2-00-quantizer-36.webm", "vp90-2-00-quantizer-37.webm",
- "vp90-2-00-quantizer-38.webm", "vp90-2-00-quantizer-39.webm",
- "vp90-2-00-quantizer-40.webm", "vp90-2-00-quantizer-41.webm",
- "vp90-2-00-quantizer-42.webm", "vp90-2-00-quantizer-43.webm",
- "vp90-2-00-quantizer-44.webm", "vp90-2-00-quantizer-45.webm",
- "vp90-2-00-quantizer-46.webm", "vp90-2-00-quantizer-47.webm",
- "vp90-2-00-quantizer-48.webm", "vp90-2-00-quantizer-49.webm",
- "vp90-2-00-quantizer-50.webm", "vp90-2-00-quantizer-51.webm",
- "vp90-2-00-quantizer-52.webm", "vp90-2-00-quantizer-53.webm",
- "vp90-2-00-quantizer-54.webm", "vp90-2-00-quantizer-55.webm",
- "vp90-2-00-quantizer-56.webm", "vp90-2-00-quantizer-57.webm",
- "vp90-2-00-quantizer-58.webm", "vp90-2-00-quantizer-59.webm",
- "vp90-2-00-quantizer-60.webm", "vp90-2-00-quantizer-61.webm",
- "vp90-2-00-quantizer-62.webm", "vp90-2-00-quantizer-63.webm",
- "vp90-2-01-sharpness-1.webm", "vp90-2-01-sharpness-2.webm",
- "vp90-2-01-sharpness-3.webm", "vp90-2-01-sharpness-4.webm",
- "vp90-2-01-sharpness-5.webm", "vp90-2-01-sharpness-6.webm",
- "vp90-2-01-sharpness-7.webm", "vp90-2-02-size-08x08.webm",
- "vp90-2-02-size-08x10.webm", "vp90-2-02-size-08x16.webm",
- "vp90-2-02-size-08x18.webm", "vp90-2-02-size-08x32.webm",
- "vp90-2-02-size-08x34.webm", "vp90-2-02-size-08x64.webm",
- "vp90-2-02-size-08x66.webm", "vp90-2-02-size-10x08.webm",
- "vp90-2-02-size-10x10.webm", "vp90-2-02-size-10x16.webm",
- "vp90-2-02-size-10x18.webm", "vp90-2-02-size-10x32.webm",
- "vp90-2-02-size-10x34.webm", "vp90-2-02-size-10x64.webm",
- "vp90-2-02-size-10x66.webm", "vp90-2-02-size-16x08.webm",
- "vp90-2-02-size-16x10.webm", "vp90-2-02-size-16x16.webm",
- "vp90-2-02-size-16x18.webm", "vp90-2-02-size-16x32.webm",
- "vp90-2-02-size-16x34.webm", "vp90-2-02-size-16x64.webm",
- "vp90-2-02-size-16x66.webm", "vp90-2-02-size-18x08.webm",
- "vp90-2-02-size-18x10.webm", "vp90-2-02-size-18x16.webm",
- "vp90-2-02-size-18x18.webm", "vp90-2-02-size-18x32.webm",
- "vp90-2-02-size-18x34.webm", "vp90-2-02-size-18x64.webm",
- "vp90-2-02-size-18x66.webm", "vp90-2-02-size-32x08.webm",
- "vp90-2-02-size-32x10.webm", "vp90-2-02-size-32x16.webm",
- "vp90-2-02-size-32x18.webm", "vp90-2-02-size-32x32.webm",
- "vp90-2-02-size-32x34.webm", "vp90-2-02-size-32x64.webm",
- "vp90-2-02-size-32x66.webm", "vp90-2-02-size-34x08.webm",
- "vp90-2-02-size-34x10.webm", "vp90-2-02-size-34x16.webm",
- "vp90-2-02-size-34x18.webm", "vp90-2-02-size-34x32.webm",
- "vp90-2-02-size-34x34.webm", "vp90-2-02-size-34x64.webm",
- "vp90-2-02-size-34x66.webm", "vp90-2-02-size-64x08.webm",
- "vp90-2-02-size-64x10.webm", "vp90-2-02-size-64x16.webm",
- "vp90-2-02-size-64x18.webm", "vp90-2-02-size-64x32.webm",
- "vp90-2-02-size-64x34.webm", "vp90-2-02-size-64x64.webm",
- "vp90-2-02-size-64x66.webm", "vp90-2-02-size-66x08.webm",
- "vp90-2-02-size-66x10.webm", "vp90-2-02-size-66x16.webm",
- "vp90-2-02-size-66x18.webm", "vp90-2-02-size-66x32.webm",
- "vp90-2-02-size-66x34.webm", "vp90-2-02-size-66x64.webm",
- "vp90-2-02-size-66x66.webm", "vp90-2-03-size-196x196.webm",
- "vp90-2-03-size-196x198.webm", "vp90-2-03-size-196x200.webm",
- "vp90-2-03-size-196x202.webm", "vp90-2-03-size-196x208.webm",
- "vp90-2-03-size-196x210.webm", "vp90-2-03-size-196x224.webm",
- "vp90-2-03-size-196x226.webm", "vp90-2-03-size-198x196.webm",
- "vp90-2-03-size-198x198.webm", "vp90-2-03-size-198x200.webm",
- "vp90-2-03-size-198x202.webm", "vp90-2-03-size-198x208.webm",
- "vp90-2-03-size-198x210.webm", "vp90-2-03-size-198x224.webm",
- "vp90-2-03-size-198x226.webm", "vp90-2-03-size-200x196.webm",
- "vp90-2-03-size-200x198.webm", "vp90-2-03-size-200x200.webm",
- "vp90-2-03-size-200x202.webm", "vp90-2-03-size-200x208.webm",
- "vp90-2-03-size-200x210.webm", "vp90-2-03-size-200x224.webm",
- "vp90-2-03-size-200x226.webm", "vp90-2-03-size-202x196.webm",
- "vp90-2-03-size-202x198.webm", "vp90-2-03-size-202x200.webm",
- "vp90-2-03-size-202x202.webm", "vp90-2-03-size-202x208.webm",
- "vp90-2-03-size-202x210.webm", "vp90-2-03-size-202x224.webm",
- "vp90-2-03-size-202x226.webm", "vp90-2-03-size-208x196.webm",
- "vp90-2-03-size-208x198.webm", "vp90-2-03-size-208x200.webm",
- "vp90-2-03-size-208x202.webm", "vp90-2-03-size-208x208.webm",
- "vp90-2-03-size-208x210.webm", "vp90-2-03-size-208x224.webm",
- "vp90-2-03-size-208x226.webm", "vp90-2-03-size-210x196.webm",
- "vp90-2-03-size-210x198.webm", "vp90-2-03-size-210x200.webm",
- "vp90-2-03-size-210x202.webm", "vp90-2-03-size-210x208.webm",
- "vp90-2-03-size-210x210.webm", "vp90-2-03-size-210x224.webm",
- "vp90-2-03-size-210x226.webm", "vp90-2-03-size-224x196.webm",
- "vp90-2-03-size-224x198.webm", "vp90-2-03-size-224x200.webm",
- "vp90-2-03-size-224x202.webm", "vp90-2-03-size-224x208.webm",
- "vp90-2-03-size-224x210.webm", "vp90-2-03-size-224x224.webm",
- "vp90-2-03-size-224x226.webm", "vp90-2-03-size-226x196.webm",
- "vp90-2-03-size-226x198.webm", "vp90-2-03-size-226x200.webm",
- "vp90-2-03-size-226x202.webm", "vp90-2-03-size-226x208.webm",
- "vp90-2-03-size-226x210.webm", "vp90-2-03-size-226x224.webm",
- "vp90-2-03-size-226x226.webm", "vp90-2-03-deltaq.webm",
- "vp90-2-05-resize.ivf", "vp90-2-06-bilinear.webm",
- "vp90-2-07-frame_parallel.webm",
- "vp90-2-08-tile_1x2_frame_parallel.webm", "vp90-2-08-tile_1x2.webm",
- "vp90-2-08-tile_1x4_frame_parallel.webm", "vp90-2-08-tile_1x4.webm",
- "vp90-2-08-tile_1x8_frame_parallel.webm", "vp90-2-08-tile_1x8.webm",
- "vp90-2-08-tile-4x4.webm", "vp90-2-08-tile-4x1.webm",
- "vp90-2-09-subpixel-00.ivf",
- "vp90-2-02-size-lf-1920x1080.webm",
-#if CONFIG_NON420
- "vp91-2-04-yv444.webm"
-#endif
-};
-#endif
class TestVectorTest : public ::libvpx_test::DecoderTest,
public ::libvpx_test::CodecTestWithParam<const char*> {
@@ -241,8 +91,8 @@ TEST_P(TestVectorTest, MD5Match) {
}
VP8_INSTANTIATE_TEST_CASE(TestVectorTest,
- ::testing::ValuesIn(kVP8TestVectors));
+ ::testing::ValuesIn(libvpx_test::kVP8TestVectors));
VP9_INSTANTIATE_TEST_CASE(TestVectorTest,
- ::testing::ValuesIn(kVP9TestVectors));
+ ::testing::ValuesIn(libvpx_test::kVP9TestVectors));
} // namespace
diff --git a/test/test_vectors.cc b/test/test_vectors.cc
new file mode 100644
index 000000000..7ffecf087
--- /dev/null
+++ b/test/test_vectors.cc
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "test/test_vectors.h"
+
+namespace libvpx_test {
+
+#if CONFIG_VP8_DECODER
+const char *kVP8TestVectors[kNumVp8TestVectors] = {
+ "vp80-00-comprehensive-001.ivf",
+ "vp80-00-comprehensive-002.ivf", "vp80-00-comprehensive-003.ivf",
+ "vp80-00-comprehensive-004.ivf", "vp80-00-comprehensive-005.ivf",
+ "vp80-00-comprehensive-006.ivf", "vp80-00-comprehensive-007.ivf",
+ "vp80-00-comprehensive-008.ivf", "vp80-00-comprehensive-009.ivf",
+ "vp80-00-comprehensive-010.ivf", "vp80-00-comprehensive-011.ivf",
+ "vp80-00-comprehensive-012.ivf", "vp80-00-comprehensive-013.ivf",
+ "vp80-00-comprehensive-014.ivf", "vp80-00-comprehensive-015.ivf",
+ "vp80-00-comprehensive-016.ivf", "vp80-00-comprehensive-017.ivf",
+ "vp80-00-comprehensive-018.ivf", "vp80-01-intra-1400.ivf",
+ "vp80-01-intra-1411.ivf", "vp80-01-intra-1416.ivf",
+ "vp80-01-intra-1417.ivf", "vp80-02-inter-1402.ivf",
+ "vp80-02-inter-1412.ivf", "vp80-02-inter-1418.ivf",
+ "vp80-02-inter-1424.ivf", "vp80-03-segmentation-01.ivf",
+ "vp80-03-segmentation-02.ivf", "vp80-03-segmentation-03.ivf",
+ "vp80-03-segmentation-04.ivf", "vp80-03-segmentation-1401.ivf",
+ "vp80-03-segmentation-1403.ivf", "vp80-03-segmentation-1407.ivf",
+ "vp80-03-segmentation-1408.ivf", "vp80-03-segmentation-1409.ivf",
+ "vp80-03-segmentation-1410.ivf", "vp80-03-segmentation-1413.ivf",
+ "vp80-03-segmentation-1414.ivf", "vp80-03-segmentation-1415.ivf",
+ "vp80-03-segmentation-1425.ivf", "vp80-03-segmentation-1426.ivf",
+ "vp80-03-segmentation-1427.ivf", "vp80-03-segmentation-1432.ivf",
+ "vp80-03-segmentation-1435.ivf", "vp80-03-segmentation-1436.ivf",
+ "vp80-03-segmentation-1437.ivf", "vp80-03-segmentation-1441.ivf",
+ "vp80-03-segmentation-1442.ivf", "vp80-04-partitions-1404.ivf",
+ "vp80-04-partitions-1405.ivf", "vp80-04-partitions-1406.ivf",
+ "vp80-05-sharpness-1428.ivf", "vp80-05-sharpness-1429.ivf",
+ "vp80-05-sharpness-1430.ivf", "vp80-05-sharpness-1431.ivf",
+ "vp80-05-sharpness-1433.ivf", "vp80-05-sharpness-1434.ivf",
+ "vp80-05-sharpness-1438.ivf", "vp80-05-sharpness-1439.ivf",
+ "vp80-05-sharpness-1440.ivf", "vp80-05-sharpness-1443.ivf",
+ "vp80-06-smallsize.ivf"
+};
+#endif // CONFIG_VP8_DECODER
+#if CONFIG_VP9_DECODER
+const char *kVP9TestVectors[kNumVp9TestVectors] = {
+ "vp90-2-00-quantizer-00.webm", "vp90-2-00-quantizer-01.webm",
+ "vp90-2-00-quantizer-02.webm", "vp90-2-00-quantizer-03.webm",
+ "vp90-2-00-quantizer-04.webm", "vp90-2-00-quantizer-05.webm",
+ "vp90-2-00-quantizer-06.webm", "vp90-2-00-quantizer-07.webm",
+ "vp90-2-00-quantizer-08.webm", "vp90-2-00-quantizer-09.webm",
+ "vp90-2-00-quantizer-10.webm", "vp90-2-00-quantizer-11.webm",
+ "vp90-2-00-quantizer-12.webm", "vp90-2-00-quantizer-13.webm",
+ "vp90-2-00-quantizer-14.webm", "vp90-2-00-quantizer-15.webm",
+ "vp90-2-00-quantizer-16.webm", "vp90-2-00-quantizer-17.webm",
+ "vp90-2-00-quantizer-18.webm", "vp90-2-00-quantizer-19.webm",
+ "vp90-2-00-quantizer-20.webm", "vp90-2-00-quantizer-21.webm",
+ "vp90-2-00-quantizer-22.webm", "vp90-2-00-quantizer-23.webm",
+ "vp90-2-00-quantizer-24.webm", "vp90-2-00-quantizer-25.webm",
+ "vp90-2-00-quantizer-26.webm", "vp90-2-00-quantizer-27.webm",
+ "vp90-2-00-quantizer-28.webm", "vp90-2-00-quantizer-29.webm",
+ "vp90-2-00-quantizer-30.webm", "vp90-2-00-quantizer-31.webm",
+ "vp90-2-00-quantizer-32.webm", "vp90-2-00-quantizer-33.webm",
+ "vp90-2-00-quantizer-34.webm", "vp90-2-00-quantizer-35.webm",
+ "vp90-2-00-quantizer-36.webm", "vp90-2-00-quantizer-37.webm",
+ "vp90-2-00-quantizer-38.webm", "vp90-2-00-quantizer-39.webm",
+ "vp90-2-00-quantizer-40.webm", "vp90-2-00-quantizer-41.webm",
+ "vp90-2-00-quantizer-42.webm", "vp90-2-00-quantizer-43.webm",
+ "vp90-2-00-quantizer-44.webm", "vp90-2-00-quantizer-45.webm",
+ "vp90-2-00-quantizer-46.webm", "vp90-2-00-quantizer-47.webm",
+ "vp90-2-00-quantizer-48.webm", "vp90-2-00-quantizer-49.webm",
+ "vp90-2-00-quantizer-50.webm", "vp90-2-00-quantizer-51.webm",
+ "vp90-2-00-quantizer-52.webm", "vp90-2-00-quantizer-53.webm",
+ "vp90-2-00-quantizer-54.webm", "vp90-2-00-quantizer-55.webm",
+ "vp90-2-00-quantizer-56.webm", "vp90-2-00-quantizer-57.webm",
+ "vp90-2-00-quantizer-58.webm", "vp90-2-00-quantizer-59.webm",
+ "vp90-2-00-quantizer-60.webm", "vp90-2-00-quantizer-61.webm",
+ "vp90-2-00-quantizer-62.webm", "vp90-2-00-quantizer-63.webm",
+ "vp90-2-01-sharpness-1.webm", "vp90-2-01-sharpness-2.webm",
+ "vp90-2-01-sharpness-3.webm", "vp90-2-01-sharpness-4.webm",
+ "vp90-2-01-sharpness-5.webm", "vp90-2-01-sharpness-6.webm",
+ "vp90-2-01-sharpness-7.webm", "vp90-2-02-size-08x08.webm",
+ "vp90-2-02-size-08x10.webm", "vp90-2-02-size-08x16.webm",
+ "vp90-2-02-size-08x18.webm", "vp90-2-02-size-08x32.webm",
+ "vp90-2-02-size-08x34.webm", "vp90-2-02-size-08x64.webm",
+ "vp90-2-02-size-08x66.webm", "vp90-2-02-size-10x08.webm",
+ "vp90-2-02-size-10x10.webm", "vp90-2-02-size-10x16.webm",
+ "vp90-2-02-size-10x18.webm", "vp90-2-02-size-10x32.webm",
+ "vp90-2-02-size-10x34.webm", "vp90-2-02-size-10x64.webm",
+ "vp90-2-02-size-10x66.webm", "vp90-2-02-size-16x08.webm",
+ "vp90-2-02-size-16x10.webm", "vp90-2-02-size-16x16.webm",
+ "vp90-2-02-size-16x18.webm", "vp90-2-02-size-16x32.webm",
+ "vp90-2-02-size-16x34.webm", "vp90-2-02-size-16x64.webm",
+ "vp90-2-02-size-16x66.webm", "vp90-2-02-size-18x08.webm",
+ "vp90-2-02-size-18x10.webm", "vp90-2-02-size-18x16.webm",
+ "vp90-2-02-size-18x18.webm", "vp90-2-02-size-18x32.webm",
+ "vp90-2-02-size-18x34.webm", "vp90-2-02-size-18x64.webm",
+ "vp90-2-02-size-18x66.webm", "vp90-2-02-size-32x08.webm",
+ "vp90-2-02-size-32x10.webm", "vp90-2-02-size-32x16.webm",
+ "vp90-2-02-size-32x18.webm", "vp90-2-02-size-32x32.webm",
+ "vp90-2-02-size-32x34.webm", "vp90-2-02-size-32x64.webm",
+ "vp90-2-02-size-32x66.webm", "vp90-2-02-size-34x08.webm",
+ "vp90-2-02-size-34x10.webm", "vp90-2-02-size-34x16.webm",
+ "vp90-2-02-size-34x18.webm", "vp90-2-02-size-34x32.webm",
+ "vp90-2-02-size-34x34.webm", "vp90-2-02-size-34x64.webm",
+ "vp90-2-02-size-34x66.webm", "vp90-2-02-size-64x08.webm",
+ "vp90-2-02-size-64x10.webm", "vp90-2-02-size-64x16.webm",
+ "vp90-2-02-size-64x18.webm", "vp90-2-02-size-64x32.webm",
+ "vp90-2-02-size-64x34.webm", "vp90-2-02-size-64x64.webm",
+ "vp90-2-02-size-64x66.webm", "vp90-2-02-size-66x08.webm",
+ "vp90-2-02-size-66x10.webm", "vp90-2-02-size-66x16.webm",
+ "vp90-2-02-size-66x18.webm", "vp90-2-02-size-66x32.webm",
+ "vp90-2-02-size-66x34.webm", "vp90-2-02-size-66x64.webm",
+ "vp90-2-02-size-66x66.webm", "vp90-2-03-size-196x196.webm",
+ "vp90-2-03-size-196x198.webm", "vp90-2-03-size-196x200.webm",
+ "vp90-2-03-size-196x202.webm", "vp90-2-03-size-196x208.webm",
+ "vp90-2-03-size-196x210.webm", "vp90-2-03-size-196x224.webm",
+ "vp90-2-03-size-196x226.webm", "vp90-2-03-size-198x196.webm",
+ "vp90-2-03-size-198x198.webm", "vp90-2-03-size-198x200.webm",
+ "vp90-2-03-size-198x202.webm", "vp90-2-03-size-198x208.webm",
+ "vp90-2-03-size-198x210.webm", "vp90-2-03-size-198x224.webm",
+ "vp90-2-03-size-198x226.webm", "vp90-2-03-size-200x196.webm",
+ "vp90-2-03-size-200x198.webm", "vp90-2-03-size-200x200.webm",
+ "vp90-2-03-size-200x202.webm", "vp90-2-03-size-200x208.webm",
+ "vp90-2-03-size-200x210.webm", "vp90-2-03-size-200x224.webm",
+ "vp90-2-03-size-200x226.webm", "vp90-2-03-size-202x196.webm",
+ "vp90-2-03-size-202x198.webm", "vp90-2-03-size-202x200.webm",
+ "vp90-2-03-size-202x202.webm", "vp90-2-03-size-202x208.webm",
+ "vp90-2-03-size-202x210.webm", "vp90-2-03-size-202x224.webm",
+ "vp90-2-03-size-202x226.webm", "vp90-2-03-size-208x196.webm",
+ "vp90-2-03-size-208x198.webm", "vp90-2-03-size-208x200.webm",
+ "vp90-2-03-size-208x202.webm", "vp90-2-03-size-208x208.webm",
+ "vp90-2-03-size-208x210.webm", "vp90-2-03-size-208x224.webm",
+ "vp90-2-03-size-208x226.webm", "vp90-2-03-size-210x196.webm",
+ "vp90-2-03-size-210x198.webm", "vp90-2-03-size-210x200.webm",
+ "vp90-2-03-size-210x202.webm", "vp90-2-03-size-210x208.webm",
+ "vp90-2-03-size-210x210.webm", "vp90-2-03-size-210x224.webm",
+ "vp90-2-03-size-210x226.webm", "vp90-2-03-size-224x196.webm",
+ "vp90-2-03-size-224x198.webm", "vp90-2-03-size-224x200.webm",
+ "vp90-2-03-size-224x202.webm", "vp90-2-03-size-224x208.webm",
+ "vp90-2-03-size-224x210.webm", "vp90-2-03-size-224x224.webm",
+ "vp90-2-03-size-224x226.webm", "vp90-2-03-size-226x196.webm",
+ "vp90-2-03-size-226x198.webm", "vp90-2-03-size-226x200.webm",
+ "vp90-2-03-size-226x202.webm", "vp90-2-03-size-226x208.webm",
+ "vp90-2-03-size-226x210.webm", "vp90-2-03-size-226x224.webm",
+ "vp90-2-03-size-226x226.webm", "vp90-2-03-deltaq.webm",
+ "vp90-2-05-resize.ivf", "vp90-2-06-bilinear.webm",
+ "vp90-2-07-frame_parallel.webm",
+ "vp90-2-08-tile_1x2_frame_parallel.webm", "vp90-2-08-tile_1x2.webm",
+ "vp90-2-08-tile_1x4_frame_parallel.webm", "vp90-2-08-tile_1x4.webm",
+ "vp90-2-08-tile_1x8_frame_parallel.webm", "vp90-2-08-tile_1x8.webm",
+ "vp90-2-08-tile-4x4.webm", "vp90-2-08-tile-4x1.webm",
+ "vp90-2-09-subpixel-00.ivf",
+ "vp90-2-02-size-lf-1920x1080.webm",
+#if CONFIG_NON420
+ "vp91-2-04-yv444.webm"
+#endif
+};
+#endif // CONFIG_VP9_DECODER
+
+} // namespace libvpx_test
diff --git a/test/test_vectors.h b/test/test_vectors.h
new file mode 100644
index 000000000..942175aa2
--- /dev/null
+++ b/test/test_vectors.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef TEST_TEST_VECTORS_H_
+#define TEST_TEST_VECTORS_H_
+
+#include "./vpx_config.h"
+
+namespace libvpx_test {
+
+#if CONFIG_VP8_DECODER
+const int kNumVp8TestVectors = 62;
+extern const char *kVP8TestVectors[kNumVp8TestVectors];
+#endif
+
+#if CONFIG_VP9_DECODER
+#if CONFIG_NON420
+const int kNumVp9TestVectors = 214;
+#else
+const int kNumVp9TestVectors = 213;
+#endif
+
+extern const char *kVP9TestVectors[kNumVp9TestVectors];
+#endif // CONFIG_VP9_DECODER
+
+} // namespace libvpx_test
+
+#endif // TEST_TEST_VECTORS_H_
diff --git a/test/tile_independence_test.cc b/test/tile_independence_test.cc
index 403dbb6c0..863a3669a 100644
--- a/test/tile_independence_test.cc
+++ b/test/tile_independence_test.cc
@@ -1,11 +1,11 @@
/*
- Copyright (c) 2012 The WebM project authors. All Rights Reserved.
-
- Use of this source code is governed by a BSD-style license
- that can be found in the LICENSE file in the root of the source
- tree. An additional intellectual property rights grant can be found
- in the file PATENTS. All contributing project authors may
- be found in the AUTHORS file in the root of the source tree.
+ * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
*/
#include <cstdio>
diff --git a/test/vp8_fdct4x4_test.cc b/test/vp8_fdct4x4_test.cc
index c82343668..25465c53c 100644
--- a/test/vp8_fdct4x4_test.cc
+++ b/test/vp8_fdct4x4_test.cc
@@ -1,13 +1,12 @@
/*
-* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
-*
-* Use of this source code is governed by a BSD-style license
-* that can be found in the LICENSE file in the root of the source
-* tree. An additional intellectual property rights grant can be found
-* in the file PATENTS. All contributing project authors may
-* be found in the AUTHORS file in the root of the source tree.
-*/
-
+ * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
#include <math.h>
#include <stddef.h>
@@ -16,7 +15,6 @@
#include <string.h>
#include <sys/types.h>
-
extern "C" {
#include "./vp8_rtcd.h"
}
@@ -25,7 +23,6 @@ extern "C" {
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "vpx/vpx_integer.h"
-
namespace {
const int cospi8sqrt2minus1 = 20091;
diff --git a/test/vp9_lossless_test.cc b/test/vp9_lossless_test.cc
index e8c32b41c..03b89f8df 100644
--- a/test/vp9_lossless_test.cc
+++ b/test/vp9_lossless_test.cc
@@ -1,12 +1,12 @@
/*
- Copyright (c) 2012 The WebM project authors. All Rights Reserved.
-
- Use of this source code is governed by a BSD-style license
- that can be found in the LICENSE file in the root of the source
- tree. An additional intellectual property rights grant can be found
- in the file PATENTS. All contributing project authors may
- be found in the AUTHORS file in the root of the source tree.
-*/
+ * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
diff --git a/test/webm_video_source.h b/test/webm_video_source.h
index 9fc854593..53b0ba2b4 100644
--- a/test/webm_video_source.h
+++ b/test/webm_video_source.h
@@ -90,8 +90,12 @@ class WebMVideoSource : public CompressedVideoSource {
virtual ~WebMVideoSource() {
if (input_file_)
fclose(input_file_);
- if (nestegg_ctx_)
+ if (nestegg_ctx_ != NULL) {
+ if (pkt_ != NULL) {
+ nestegg_free_packet(pkt_);
+ }
nestegg_destroy(nestegg_ctx_);
+ }
}
virtual void Init() {
@@ -136,8 +140,10 @@ class WebMVideoSource : public CompressedVideoSource {
do {
/* End of this packet, get another. */
- if (pkt_)
+ if (pkt_ != NULL) {
nestegg_free_packet(pkt_);
+ pkt_ = NULL;
+ }
int again = nestegg_read_packet(nestegg_ctx_, &pkt_);
ASSERT_GE(again, 0) << "nestegg_read_packet failed";
diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c
index 871b8d385..0b4c4cbbf 100644
--- a/vp8/vp8_dx_iface.c
+++ b/vp8/vp8_dx_iface.c
@@ -929,6 +929,7 @@ CODEC_INTERFACE(vpx_codec_vp8_dx) =
vp8_get_si, /* vpx_codec_get_si_fn_t get_si; */
vp8_decode, /* vpx_codec_decode_fn_t decode; */
vp8_get_frame, /* vpx_codec_frame_get_fn_t frame_get; */
+ NOT_IMPLEMENTED,
},
{ /* encoder functions */
NOT_IMPLEMENTED,
diff --git a/vp9/common/vp9_alloccommon.c b/vp9/common/vp9_alloccommon.c
index f56784071..80c48d13c 100644
--- a/vp9/common/vp9_alloccommon.c
+++ b/vp9/common/vp9_alloccommon.c
@@ -34,7 +34,7 @@ void vp9_update_mode_info_border(VP9_COMMON *cm, MODE_INFO *mi) {
void vp9_free_frame_buffers(VP9_COMMON *cm) {
int i;
- for (i = 0; i < FRAME_BUFFERS; i++)
+ for (i = 0; i < cm->fb_count; i++)
vp9_free_frame_buffer(&cm->yv12_fb[i]);
vp9_free_frame_buffer(&cm->post_proc_buffer);
@@ -86,7 +86,7 @@ int vp9_resize_frame_buffers(VP9_COMMON *cm, int width, int height) {
int mi_size;
if (vp9_realloc_frame_buffer(&cm->post_proc_buffer, width, height, ss_x, ss_y,
- VP9BORDERINPIXELS) < 0)
+ VP9BORDERINPIXELS, NULL, NULL, NULL) < 0)
goto fail;
set_mb_mi(cm, aligned_width, aligned_height);
@@ -138,16 +138,28 @@ int vp9_alloc_frame_buffers(VP9_COMMON *cm, int width, int height) {
const int ss_y = cm->subsampling_y;
int mi_size;
+ if (cm->fb_count == 0) {
+ cm->fb_count = FRAME_BUFFERS;
+ CHECK_MEM_ERROR(cm, cm->yv12_fb,
+ vpx_calloc(cm->fb_count, sizeof(*cm->yv12_fb)));
+ CHECK_MEM_ERROR(cm, cm->fb_idx_ref_cnt,
+ vpx_calloc(cm->fb_count, sizeof(*cm->fb_idx_ref_cnt)));
+ if (cm->fb_lru) {
+ CHECK_MEM_ERROR(cm, cm->fb_idx_ref_lru,
+ vpx_calloc(cm->fb_count, sizeof(*cm->fb_idx_ref_lru)));
+ }
+ }
+
vp9_free_frame_buffers(cm);
- for (i = 0; i < FRAME_BUFFERS; i++) {
+ for (i = 0; i < cm->fb_count; i++) {
cm->fb_idx_ref_cnt[i] = 0;
if (vp9_alloc_frame_buffer(&cm->yv12_fb[i], width, height, ss_x, ss_y,
VP9BORDERINPIXELS) < 0)
goto fail;
}
- cm->new_fb_idx = FRAME_BUFFERS - 1;
+ cm->new_fb_idx = cm->fb_count - 1;
cm->fb_idx_ref_cnt[cm->new_fb_idx] = 1;
for (i = 0; i < REFS_PER_FRAME; i++)
@@ -203,6 +215,14 @@ void vp9_create_common(VP9_COMMON *cm) {
void vp9_remove_common(VP9_COMMON *cm) {
vp9_free_frame_buffers(cm);
+
+ vpx_free(cm->yv12_fb);
+ vpx_free(cm->fb_idx_ref_cnt);
+ vpx_free(cm->fb_idx_ref_lru);
+
+ cm->yv12_fb = NULL;
+ cm->fb_idx_ref_cnt = NULL;
+ cm->fb_idx_ref_lru = NULL;
}
void vp9_initialize_common() {
diff --git a/vp9/common/vp9_convolve.c b/vp9/common/vp9_convolve.c
index a2d864c72..6edf7eaca 100644
--- a/vp9/common/vp9_convolve.c
+++ b/vp9/common/vp9_convolve.c
@@ -18,40 +18,21 @@
#include "vpx/vpx_integer.h"
#include "vpx_ports/mem.h"
-static void convolve_horiz_c(const uint8_t *src, ptrdiff_t src_stride,
- uint8_t *dst, ptrdiff_t dst_stride,
- const int16_t *filter_x0, int x_step_q4,
- const int16_t *filter_y, int y_step_q4,
- int w, int h, int taps) {
- int x, y, k;
-
- /* NOTE: This assumes that the filter table is 256-byte aligned. */
- /* TODO(agrange) Modify to make independent of table alignment. */
- const int16_t *const filter_x_base =
- (const int16_t *)(((intptr_t)filter_x0) & ~(intptr_t)0xff);
-
- /* Adjust base pointer address for this source line */
- src -= taps / 2 - 1;
-
+static void convolve_horiz(const uint8_t *src, ptrdiff_t src_stride,
+ uint8_t *dst, ptrdiff_t dst_stride,
+ const subpel_kernel *x_filters,
+ int x0_q4, int x_step_q4, int w, int h) {
+ int x, y;
+ src -= SUBPEL_TAPS / 2 - 1;
for (y = 0; y < h; ++y) {
- /* Initial phase offset */
- int x_q4 = (int)(filter_x0 - filter_x_base) / taps;
-
+ int x_q4 = x0_q4;
for (x = 0; x < w; ++x) {
- /* Per-pixel src offset */
- const int src_x = x_q4 >> SUBPEL_BITS;
- int sum = 0;
-
- /* Pointer to filter to use */
- const int16_t *const filter_x = filter_x_base +
- (x_q4 & SUBPEL_MASK) * taps;
-
- for (k = 0; k < taps; ++k)
- sum += src[src_x + k] * filter_x[k];
-
+ const uint8_t *const src_x = &src[x_q4 >> SUBPEL_BITS];
+ const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK];
+ int k, sum = 0;
+ for (k = 0; k < SUBPEL_TAPS; ++k)
+ sum += src_x[k] * x_filter[k];
dst[x] = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS));
-
- /* Move to the next source pixel */
x_q4 += x_step_q4;
}
src += src_stride;
@@ -59,41 +40,22 @@ static void convolve_horiz_c(const uint8_t *src, ptrdiff_t src_stride,
}
}
-static void convolve_avg_horiz_c(const uint8_t *src, ptrdiff_t src_stride,
- uint8_t *dst, ptrdiff_t dst_stride,
- const int16_t *filter_x0, int x_step_q4,
- const int16_t *filter_y, int y_step_q4,
- int w, int h, int taps) {
- int x, y, k;
-
- /* NOTE: This assumes that the filter table is 256-byte aligned. */
- /* TODO(agrange) Modify to make independent of table alignment. */
- const int16_t *const filter_x_base =
- (const int16_t *)(((intptr_t)filter_x0) & ~(intptr_t)0xff);
-
- /* Adjust base pointer address for this source line */
- src -= taps / 2 - 1;
-
+static void convolve_avg_horiz(const uint8_t *src, ptrdiff_t src_stride,
+ uint8_t *dst, ptrdiff_t dst_stride,
+ const subpel_kernel *x_filters,
+ int x0_q4, int x_step_q4, int w, int h) {
+ int x, y;
+ src -= SUBPEL_TAPS / 2 - 1;
for (y = 0; y < h; ++y) {
- /* Initial phase offset */
- int x_q4 = (int)(filter_x0 - filter_x_base) / taps;
-
+ int x_q4 = x0_q4;
for (x = 0; x < w; ++x) {
- /* Per-pixel src offset */
- const int src_x = x_q4 >> SUBPEL_BITS;
- int sum = 0;
-
- /* Pointer to filter to use */
- const int16_t *const filter_x = filter_x_base +
- (x_q4 & SUBPEL_MASK) * taps;
-
- for (k = 0; k < taps; ++k)
- sum += src[src_x + k] * filter_x[k];
-
+ const uint8_t *const src_x = &src[x_q4 >> SUBPEL_BITS];
+ const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK];
+ int k, sum = 0;
+ for (k = 0; k < SUBPEL_TAPS; ++k)
+ sum += src_x[k] * x_filter[k];
dst[x] = ROUND_POWER_OF_TWO(dst[x] +
- clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)), 1);
-
- /* Move to the next source pixel */
+ clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)), 1);
x_q4 += x_step_q4;
}
src += src_stride;
@@ -101,41 +63,22 @@ static void convolve_avg_horiz_c(const uint8_t *src, ptrdiff_t src_stride,
}
}
-static void convolve_vert_c(const uint8_t *src, ptrdiff_t src_stride,
- uint8_t *dst, ptrdiff_t dst_stride,
- const int16_t *filter_x, int x_step_q4,
- const int16_t *filter_y0, int y_step_q4,
- int w, int h, int taps) {
- int x, y, k;
-
- /* NOTE: This assumes that the filter table is 256-byte aligned. */
- /* TODO(agrange) Modify to make independent of table alignment. */
- const int16_t *const filter_y_base =
- (const int16_t *)(((intptr_t)filter_y0) & ~(intptr_t)0xff);
-
- /* Adjust base pointer address for this source column */
- src -= src_stride * (taps / 2 - 1);
+static void convolve_vert(const uint8_t *src, ptrdiff_t src_stride,
+ uint8_t *dst, ptrdiff_t dst_stride,
+ const subpel_kernel *y_filters,
+ int y0_q4, int y_step_q4, int w, int h) {
+ int x, y;
+ src -= src_stride * (SUBPEL_TAPS / 2 - 1);
for (x = 0; x < w; ++x) {
- /* Initial phase offset */
- int y_q4 = (int)(filter_y0 - filter_y_base) / taps;
-
+ int y_q4 = y0_q4;
for (y = 0; y < h; ++y) {
- /* Per-pixel src offset */
- const int src_y = y_q4 >> SUBPEL_BITS;
- int sum = 0;
-
- /* Pointer to filter to use */
- const int16_t *const filter_y = filter_y_base +
- (y_q4 & SUBPEL_MASK) * taps;
-
- for (k = 0; k < taps; ++k)
- sum += src[(src_y + k) * src_stride] * filter_y[k];
-
- dst[y * dst_stride] =
- clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS));
-
- /* Move to the next source pixel */
+ const unsigned char *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride];
+ const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK];
+ int k, sum = 0;
+ for (k = 0; k < SUBPEL_TAPS; ++k)
+ sum += src_y[k * src_stride] * y_filter[k];
+ dst[y * dst_stride] = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS));
y_q4 += y_step_q4;
}
++src;
@@ -143,41 +86,23 @@ static void convolve_vert_c(const uint8_t *src, ptrdiff_t src_stride,
}
}
-static void convolve_avg_vert_c(const uint8_t *src, ptrdiff_t src_stride,
- uint8_t *dst, ptrdiff_t dst_stride,
- const int16_t *filter_x, int x_step_q4,
- const int16_t *filter_y0, int y_step_q4,
- int w, int h, int taps) {
- int x, y, k;
-
- /* NOTE: This assumes that the filter table is 256-byte aligned. */
- /* TODO(agrange) Modify to make independent of table alignment. */
- const int16_t *const filter_y_base =
- (const int16_t *)(((intptr_t)filter_y0) & ~(intptr_t)0xff);
-
- /* Adjust base pointer address for this source column */
- src -= src_stride * (taps / 2 - 1);
+static void convolve_avg_vert(const uint8_t *src, ptrdiff_t src_stride,
+ uint8_t *dst, ptrdiff_t dst_stride,
+ const subpel_kernel *y_filters,
+ int y0_q4, int y_step_q4, int w, int h) {
+ int x, y;
+ src -= src_stride * (SUBPEL_TAPS / 2 - 1);
for (x = 0; x < w; ++x) {
- /* Initial phase offset */
- int y_q4 = (int)(filter_y0 - filter_y_base) / taps;
-
+ int y_q4 = y0_q4;
for (y = 0; y < h; ++y) {
- /* Per-pixel src offset */
- const int src_y = y_q4 >> SUBPEL_BITS;
- int sum = 0;
-
- /* Pointer to filter to use */
- const int16_t *const filter_y = filter_y_base +
- (y_q4 & SUBPEL_MASK) * taps;
-
- for (k = 0; k < taps; ++k)
- sum += src[(src_y + k) * src_stride] * filter_y[k];
-
+ const unsigned char *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride];
+ const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK];
+ int k, sum = 0;
+ for (k = 0; k < SUBPEL_TAPS; ++k)
+ sum += src_y[k * src_stride] * y_filter[k];
dst[y * dst_stride] = ROUND_POWER_OF_TWO(dst[y * dst_stride] +
- clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)), 1);
-
- /* Move to the next source pixel */
+ clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)), 1);
y_q4 += y_step_q4;
}
++src;
@@ -185,33 +110,42 @@ static void convolve_avg_vert_c(const uint8_t *src, ptrdiff_t src_stride,
}
}
-static void convolve_c(const uint8_t *src, ptrdiff_t src_stride,
- uint8_t *dst, ptrdiff_t dst_stride,
- const int16_t *filter_x, int x_step_q4,
- const int16_t *filter_y, int y_step_q4,
- int w, int h, int taps) {
- /* Fixed size intermediate buffer places limits on parameters.
- * Maximum intermediate_height is 324, for y_step_q4 == 80,
- * h == 64, taps == 8.
- * y_step_q4 of 80 allows for 1/10 scale for 5 layer svc
- */
+static void convolve(const uint8_t *src, ptrdiff_t src_stride,
+ uint8_t *dst, ptrdiff_t dst_stride,
+ const subpel_kernel *const x_filters,
+ int x0_q4, int x_step_q4,
+ const subpel_kernel *const y_filters,
+ int y0_q4, int y_step_q4,
+ int w, int h) {
+ // Fixed size intermediate buffer places limits on parameters.
+ // Maximum intermediate_height is 324, for y_step_q4 == 80,
+ // h == 64, taps == 8.
+ // y_step_q4 of 80 allows for 1/10 scale for 5 layer svc
uint8_t temp[64 * 324];
- int intermediate_height = (((h - 1) * y_step_q4 + 15) >> 4) + taps;
+ int intermediate_height = (((h - 1) * y_step_q4 + 15) >> 4) + SUBPEL_TAPS;
assert(w <= 64);
assert(h <= 64);
- assert(taps <= 8);
assert(y_step_q4 <= 80);
assert(x_step_q4 <= 80);
if (intermediate_height < h)
intermediate_height = h;
- convolve_horiz_c(src - src_stride * (taps / 2 - 1), src_stride, temp, 64,
- filter_x, x_step_q4, filter_y, y_step_q4, w,
- intermediate_height, taps);
- convolve_vert_c(temp + 64 * (taps / 2 - 1), 64, dst, dst_stride, filter_x,
- x_step_q4, filter_y, y_step_q4, w, h, taps);
+ convolve_horiz(src - src_stride * (SUBPEL_TAPS / 2 - 1), src_stride, temp, 64,
+ x_filters, x0_q4, x_step_q4, w, intermediate_height);
+ convolve_vert(temp + 64 * (SUBPEL_TAPS / 2 - 1), 64, dst, dst_stride,
+ y_filters, y0_q4, y_step_q4, w, h);
+}
+
+static const subpel_kernel *get_filter_base(const int16_t *filter) {
+ // NOTE: This assumes that the filter table is 256-byte aligned.
+ // TODO(agrange) Modify to make independent of table alignment.
+ return (const subpel_kernel *)(((intptr_t)filter) & ~((intptr_t)0xFF));
+}
+
+static int get_filter_offset(const int16_t *f, const subpel_kernel *base) {
+ return (const subpel_kernel *)(intptr_t)f - base;
}
void vp9_convolve8_horiz_c(const uint8_t *src, ptrdiff_t src_stride,
@@ -219,8 +153,11 @@ void vp9_convolve8_horiz_c(const uint8_t *src, ptrdiff_t src_stride,
const int16_t *filter_x, int x_step_q4,
const int16_t *filter_y, int y_step_q4,
int w, int h) {
- convolve_horiz_c(src, src_stride, dst, dst_stride,
- filter_x, x_step_q4, filter_y, y_step_q4, w, h, 8);
+ const subpel_kernel *const filters_x = get_filter_base(filter_x);
+ const int x0_q4 = get_filter_offset(filter_x, filters_x);
+
+ convolve_horiz(src, src_stride, dst, dst_stride, filters_x,
+ x0_q4, x_step_q4, w, h);
}
void vp9_convolve8_avg_horiz_c(const uint8_t *src, ptrdiff_t src_stride,
@@ -228,8 +165,11 @@ void vp9_convolve8_avg_horiz_c(const uint8_t *src, ptrdiff_t src_stride,
const int16_t *filter_x, int x_step_q4,
const int16_t *filter_y, int y_step_q4,
int w, int h) {
- convolve_avg_horiz_c(src, src_stride, dst, dst_stride,
- filter_x, x_step_q4, filter_y, y_step_q4, w, h, 8);
+ const subpel_kernel *const filters_x = get_filter_base(filter_x);
+ const int x0_q4 = get_filter_offset(filter_x, filters_x);
+
+ convolve_avg_horiz(src, src_stride, dst, dst_stride, filters_x,
+ x0_q4, x_step_q4, w, h);
}
void vp9_convolve8_vert_c(const uint8_t *src, ptrdiff_t src_stride,
@@ -237,8 +177,10 @@ void vp9_convolve8_vert_c(const uint8_t *src, ptrdiff_t src_stride,
const int16_t *filter_x, int x_step_q4,
const int16_t *filter_y, int y_step_q4,
int w, int h) {
- convolve_vert_c(src, src_stride, dst, dst_stride,
- filter_x, x_step_q4, filter_y, y_step_q4, w, h, 8);
+ const subpel_kernel *const filters_y = get_filter_base(filter_y);
+ const int y0_q4 = get_filter_offset(filter_y, filters_y);
+ convolve_vert(src, src_stride, dst, dst_stride, filters_y,
+ y0_q4, y_step_q4, w, h);
}
void vp9_convolve8_avg_vert_c(const uint8_t *src, ptrdiff_t src_stride,
@@ -246,8 +188,10 @@ void vp9_convolve8_avg_vert_c(const uint8_t *src, ptrdiff_t src_stride,
const int16_t *filter_x, int x_step_q4,
const int16_t *filter_y, int y_step_q4,
int w, int h) {
- convolve_avg_vert_c(src, src_stride, dst, dst_stride,
- filter_x, x_step_q4, filter_y, y_step_q4, w, h, 8);
+ const subpel_kernel *const filters_y = get_filter_base(filter_y);
+ const int y0_q4 = get_filter_offset(filter_y, filters_y);
+ convolve_avg_vert(src, src_stride, dst, dst_stride, filters_y,
+ y0_q4, y_step_q4, w, h);
}
void vp9_convolve8_c(const uint8_t *src, ptrdiff_t src_stride,
@@ -255,8 +199,15 @@ void vp9_convolve8_c(const uint8_t *src, ptrdiff_t src_stride,
const int16_t *filter_x, int x_step_q4,
const int16_t *filter_y, int y_step_q4,
int w, int h) {
- convolve_c(src, src_stride, dst, dst_stride,
- filter_x, x_step_q4, filter_y, y_step_q4, w, h, 8);
+ const subpel_kernel *const filters_x = get_filter_base(filter_x);
+ const int x0_q4 = get_filter_offset(filter_x, filters_x);
+
+ const subpel_kernel *const filters_y = get_filter_base(filter_y);
+ const int y0_q4 = get_filter_offset(filter_y, filters_y);
+
+ convolve(src, src_stride, dst, dst_stride,
+ filters_x, x0_q4, x_step_q4,
+ filters_y, y0_q4, y_step_q4, w, h);
}
void vp9_convolve8_avg_c(const uint8_t *src, ptrdiff_t src_stride,
@@ -269,9 +220,9 @@ void vp9_convolve8_avg_c(const uint8_t *src, ptrdiff_t src_stride,
assert(w <= 64);
assert(h <= 64);
- vp9_convolve8(src, src_stride, temp, 64,
- filter_x, x_step_q4, filter_y, y_step_q4, w, h);
- vp9_convolve_avg(temp, 64, dst, dst_stride, NULL, 0, NULL, 0, w, h);
+ vp9_convolve8_c(src, src_stride, temp, 64,
+ filter_x, x_step_q4, filter_y, y_step_q4, w, h);
+ vp9_convolve_avg_c(temp, 64, dst, dst_stride, NULL, 0, NULL, 0, w, h);
}
void vp9_convolve_copy_c(const uint8_t *src, ptrdiff_t src_stride,
diff --git a/vp9/common/vp9_entropy.h b/vp9/common/vp9_entropy.h
index 721917f05..65b679ad2 100644
--- a/vp9/common/vp9_entropy.h
+++ b/vp9/common/vp9_entropy.h
@@ -166,7 +166,7 @@ static int get_entropy_context(TX_SIZE tx_size, const ENTROPY_CONTEXT *a,
left_ec = !!*(const uint64_t *)l;
break;
default:
- assert(!"Invalid transform size.");
+ assert(0 && "Invalid transform size.");
}
return combine_entropy_contexts(above_ec, left_ec);
diff --git a/vp9/common/vp9_findnearmv.c b/vp9/common/vp9_findnearmv.c
index ad97c0277..7cdf2c1c7 100644
--- a/vp9/common/vp9_findnearmv.c
+++ b/vp9/common/vp9_findnearmv.c
@@ -36,46 +36,49 @@ void vp9_find_best_ref_mvs(MACROBLOCKD *xd, int allow_hp,
void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd,
const TileInfo *const tile,
- int_mv *dst_nearest, int_mv *dst_near,
- int block_idx, int ref_idx,
- int mi_row, int mi_col) {
+ int block, int ref, int mi_row, int mi_col,
+ int_mv *nearest, int_mv *near) {
int_mv mv_list[MAX_MV_REF_CANDIDATES];
MODE_INFO *const mi = xd->mi_8x8[0];
b_mode_info *bmi = mi->bmi;
int n;
- assert(ref_idx == 0 || ref_idx == 1);
assert(MAX_MV_REF_CANDIDATES == 2);
- vp9_find_mv_refs_idx(cm, xd, tile, mi, xd->last_mi,
- mi->mbmi.ref_frame[ref_idx],
- mv_list, block_idx, mi_row, mi_col);
+ vp9_find_mv_refs_idx(cm, xd, tile, mi, xd->last_mi, mi->mbmi.ref_frame[ref],
+ mv_list, block, mi_row, mi_col);
- dst_near->as_int = 0;
- if (block_idx == 0) {
- dst_nearest->as_int = mv_list[0].as_int;
- dst_near->as_int = mv_list[1].as_int;
- } else if (block_idx == 1 || block_idx == 2) {
- dst_nearest->as_int = bmi[0].as_mv[ref_idx].as_int;
- for (n = 0; n < MAX_MV_REF_CANDIDATES; ++n)
- if (dst_nearest->as_int != mv_list[n].as_int) {
- dst_near->as_int = mv_list[n].as_int;
- break;
- }
- } else {
- int_mv candidates[2 + MAX_MV_REF_CANDIDATES];
- candidates[0] = bmi[1].as_mv[ref_idx];
- candidates[1] = bmi[0].as_mv[ref_idx];
- candidates[2] = mv_list[0];
- candidates[3] = mv_list[1];
+ near->as_int = 0;
+ switch (block) {
+ case 0:
+ nearest->as_int = mv_list[0].as_int;
+ near->as_int = mv_list[1].as_int;
+ break;
+ case 1:
+ case 2:
+ nearest->as_int = bmi[0].as_mv[ref].as_int;
+ for (n = 0; n < MAX_MV_REF_CANDIDATES; ++n)
+ if (nearest->as_int != mv_list[n].as_int) {
+ near->as_int = mv_list[n].as_int;
+ break;
+ }
+ break;
+ case 3: {
+ int_mv candidates[2 + MAX_MV_REF_CANDIDATES];
+ candidates[0] = bmi[1].as_mv[ref];
+ candidates[1] = bmi[0].as_mv[ref];
+ candidates[2] = mv_list[0];
+ candidates[3] = mv_list[1];
- assert(block_idx == 3);
- dst_nearest->as_int = bmi[2].as_mv[ref_idx].as_int;
- for (n = 0; n < 2 + MAX_MV_REF_CANDIDATES; ++n) {
- if (dst_nearest->as_int != candidates[n].as_int) {
- dst_near->as_int = candidates[n].as_int;
- break;
- }
+ nearest->as_int = bmi[2].as_mv[ref].as_int;
+ for (n = 0; n < 2 + MAX_MV_REF_CANDIDATES; ++n)
+ if (nearest->as_int != candidates[n].as_int) {
+ near->as_int = candidates[n].as_int;
+ break;
+ }
+ break;
}
+ default:
+ assert("Invalid block index.");
}
}
diff --git a/vp9/common/vp9_findnearmv.h b/vp9/common/vp9_findnearmv.h
index e9d4e1171..5028af77c 100644
--- a/vp9/common/vp9_findnearmv.h
+++ b/vp9/common/vp9_findnearmv.h
@@ -36,9 +36,7 @@ static void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd,
const TileInfo *const tile,
- int_mv *dst_nearest,
- int_mv *dst_near,
- int block_idx, int ref_idx,
- int mi_row, int mi_col);
+ int block, int ref, int mi_row, int mi_col,
+ int_mv *nearest, int_mv *near);
#endif // VP9_COMMON_VP9_FINDNEARMV_H_
diff --git a/vp9/common/vp9_mv.h b/vp9/common/vp9_mv.h
index 31a79b984..155c3f12e 100644
--- a/vp9/common/vp9_mv.h
+++ b/vp9/common/vp9_mv.h
@@ -15,7 +15,7 @@
#include "vp9/common/vp9_common.h"
-typedef struct {
+typedef struct mv {
int16_t row;
int16_t col;
} MV;
@@ -25,7 +25,7 @@ typedef union int_mv {
MV as_mv;
} int_mv; /* facilitates faster equality tests and copies */
-typedef struct {
+typedef struct mv32 {
int32_t row;
int32_t col;
} MV32;
diff --git a/vp9/common/vp9_onyx.h b/vp9/common/vp9_onyx.h
index c5faf88f8..65a2a5ed1 100644
--- a/vp9/common/vp9_onyx.h
+++ b/vp9/common/vp9_onyx.h
@@ -193,7 +193,7 @@ extern "C"
int64_t end_time_stamp);
int vp9_get_compressed_data(VP9_PTR comp, unsigned int *frame_flags,
- unsigned long *size, unsigned char *dest,
+ size_t *size, uint8_t *dest,
int64_t *time_stamp, int64_t *time_end,
int flush);
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h
index a6e5b27e3..bfb94e44c 100644
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -113,8 +113,8 @@ typedef struct VP9Common {
YV12_BUFFER_CONFIG *frame_to_show;
- YV12_BUFFER_CONFIG yv12_fb[FRAME_BUFFERS];
- int fb_idx_ref_cnt[FRAME_BUFFERS]; /* reference counts */
+ YV12_BUFFER_CONFIG *yv12_fb;
+ int *fb_idx_ref_cnt; /* reference counts */
int ref_frame_map[REF_FRAMES]; /* maps fb_idx to reference slot */
// TODO(jkoleszar): could expand active_ref_idx to 4, with 0 as intra, and
@@ -213,6 +213,15 @@ typedef struct VP9Common {
int frame_parallel_decoding_mode;
int log2_tile_cols, log2_tile_rows;
+
+ vpx_codec_frame_buffer_t *fb_list; // External frame buffers
+ int fb_count; // Total number of frame buffers
+ vpx_realloc_frame_buffer_cb_fn_t realloc_fb_cb;
+ void *user_priv; // Private data associated with the external frame buffers.
+
+ int fb_lru; // Flag telling if lru is on/off
+ uint32_t *fb_idx_ref_lru; // Frame buffer lru cache
+ uint32_t fb_idx_ref_lru_count;
} VP9_COMMON;
// ref == 0 => LAST_FRAME
@@ -228,13 +237,27 @@ static YV12_BUFFER_CONFIG *get_frame_new_buffer(VP9_COMMON *cm) {
static int get_free_fb(VP9_COMMON *cm) {
int i;
- for (i = 0; i < FRAME_BUFFERS; i++)
- if (cm->fb_idx_ref_cnt[i] == 0)
- break;
+ uint32_t lru_count = cm->fb_idx_ref_lru_count + 1;
+ int free_buffer_idx = cm->fb_count;
+ for (i = 0; i < cm->fb_count; i++) {
+ if (!cm->fb_lru) {
+ if (cm->fb_idx_ref_cnt[i] == 0) {
+ free_buffer_idx = i;
+ break;
+ }
+ } else {
+ if (cm->fb_idx_ref_cnt[i] == 0 && cm->fb_idx_ref_lru[i] < lru_count) {
+ free_buffer_idx = i;
+ lru_count = cm->fb_idx_ref_lru[i];
+ }
+ }
+ }
- assert(i < FRAME_BUFFERS);
- cm->fb_idx_ref_cnt[i] = 1;
- return i;
+ assert(free_buffer_idx < cm->fb_count);
+ cm->fb_idx_ref_cnt[free_buffer_idx] = 1;
+ if (cm->fb_lru)
+ cm->fb_idx_ref_lru[free_buffer_idx] = ++cm->fb_idx_ref_lru_count;
+ return free_buffer_idx;
}
static void ref_cnt_fb(int *buf, int *idx, int new_idx) {
diff --git a/vp9/common/vp9_pred_common.h b/vp9/common/vp9_pred_common.h
index 66cd15143..23722ba72 100644
--- a/vp9/common/vp9_pred_common.h
+++ b/vp9/common/vp9_pred_common.h
@@ -104,7 +104,7 @@ static const vp9_prob *get_tx_probs(TX_SIZE max_tx_size, int ctx,
case TX_32X32:
return tx_probs->p32x32[ctx];
default:
- assert(!"Invalid max_tx_size.");
+ assert(0 && "Invalid max_tx_size.");
return NULL;
}
}
@@ -124,7 +124,7 @@ static unsigned int *get_tx_counts(TX_SIZE max_tx_size, int ctx,
case TX_32X32:
return tx_counts->p32x32[ctx];
default:
- assert(!"Invalid max_tx_size.");
+ assert(0 && "Invalid max_tx_size.");
return NULL;
}
}
diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c
index a6e51d792..b17725243 100644
--- a/vp9/common/vp9_reconinter.c
+++ b/vp9/common/vp9_reconinter.c
@@ -397,7 +397,7 @@ void vp9_setup_scale_factors(VP9_COMMON *cm, int i) {
const int ref = cm->active_ref_idx[i];
struct scale_factors *const sf = &cm->active_ref_scale[i];
struct scale_factors_common *const sfc = &cm->active_ref_scale_comm[i];
- if (ref >= FRAME_BUFFERS) {
+ if (ref >= cm->fb_count) {
vp9_zero(*sf);
vp9_zero(*sfc);
} else {
diff --git a/vp9/common/vp9_rtcd_defs.sh b/vp9/common/vp9_rtcd_defs.sh
index 19d5fc37d..727f5c437 100644
--- a/vp9/common/vp9_rtcd_defs.sh
+++ b/vp9/common/vp9_rtcd_defs.sh
@@ -14,6 +14,7 @@ struct macroblock;
struct vp9_variance_vtable;
#define DEC_MVCOSTS int *mvjcost, int *mvcost[2]
+struct mv;
union int_mv;
struct yv12_buffer_config;
EOF
@@ -736,20 +737,20 @@ specialize vp9_fdct32x32_rd sse2 avx2
#
# Motion search
#
-prototype int vp9_full_search_sad "struct macroblock *x, union int_mv *ref_mv, int sad_per_bit, int distance, struct vp9_variance_vtable *fn_ptr, DEC_MVCOSTS, union int_mv *center_mv, int n"
+prototype int vp9_full_search_sad "struct macroblock *x, struct mv *ref_mv, int sad_per_bit, int distance, struct vp9_variance_vtable *fn_ptr, DEC_MVCOSTS, const struct mv *center_mv, int n"
specialize vp9_full_search_sad sse3 sse4_1
vp9_full_search_sad_sse3=vp9_full_search_sadx3
vp9_full_search_sad_sse4_1=vp9_full_search_sadx8
-prototype int vp9_refining_search_sad "struct macroblock *x, union int_mv *ref_mv, int sad_per_bit, int distance, struct vp9_variance_vtable *fn_ptr, DEC_MVCOSTS, union int_mv *center_mv"
+prototype int vp9_refining_search_sad "struct macroblock *x, struct mv *ref_mv, int sad_per_bit, int distance, struct vp9_variance_vtable *fn_ptr, DEC_MVCOSTS, const struct mv *center_mv"
specialize vp9_refining_search_sad sse3
vp9_refining_search_sad_sse3=vp9_refining_search_sadx4
-prototype int vp9_diamond_search_sad "struct macroblock *x, union int_mv *ref_mv, union int_mv *best_mv, int search_param, int sad_per_bit, int *num00, struct vp9_variance_vtable *fn_ptr, DEC_MVCOSTS, union int_mv *center_mv"
+prototype int vp9_diamond_search_sad "struct macroblock *x, struct mv *ref_mv, struct mv *best_mv, int search_param, int sad_per_bit, int *num00, struct vp9_variance_vtable *fn_ptr, DEC_MVCOSTS, const struct mv *center_mv"
specialize vp9_diamond_search_sad sse3
vp9_diamond_search_sad_sse3=vp9_diamond_search_sadx4
-prototype int vp9_full_range_search "struct macroblock *x, union int_mv *ref_mv, union int_mv *best_mv, int search_param, int sad_per_bit, int *num00, struct vp9_variance_vtable *fn_ptr, DEC_MVCOSTS, union int_mv *center_mv"
+prototype int vp9_full_range_search "struct macroblock *x, struct mv *ref_mv, struct mv *best_mv, int search_param, int sad_per_bit, int *num00, struct vp9_variance_vtable *fn_ptr, DEC_MVCOSTS, const struct mv *center_mv"
specialize vp9_full_range_search
prototype void vp9_temporal_filter_apply "uint8_t *frame1, unsigned int stride, uint8_t *frame2, unsigned int block_size, int strength, int filter_weight, unsigned int *accumulator, uint16_t *count"
diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c
index 56b05cee1..79f0835a7 100644
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -266,7 +266,7 @@ static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
vp9_idct32x32_add(dqcoeff, dst, stride, eob);
break;
default:
- assert(!"Invalid transform size");
+ assert(0 && "Invalid transform size");
}
if (eob == 1) {
@@ -348,23 +348,27 @@ static void reconstruct_inter_block(int plane, int block,
static void set_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd,
const TileInfo *const tile,
BLOCK_SIZE bsize, int mi_row, int mi_col) {
- const int bh = num_8x8_blocks_high_lookup[bsize];
const int bw = num_8x8_blocks_wide_lookup[bsize];
+ const int bh = num_8x8_blocks_high_lookup[bsize];
+ const int x_mis = MIN(bw, cm->mi_cols - mi_col);
+ const int y_mis = MIN(bh, cm->mi_rows - mi_row);
const int offset = mi_row * cm->mode_info_stride + mi_col;
const int tile_offset = tile->mi_row_start * cm->mode_info_stride +
tile->mi_col_start;
+ int x, y;
xd->mi_8x8 = cm->mi_grid_visible + offset;
xd->prev_mi_8x8 = cm->prev_mi_grid_visible + offset;
-
- // we are using the mode info context stream here
- xd->mi_8x8[0] = xd->mi_stream + offset - tile_offset;
- xd->mi_8x8[0]->mbmi.sb_type = bsize;
-
// Special case: if prev_mi is NULL, the previous mode info context
// cannot be used.
xd->last_mi = cm->prev_mi ? xd->prev_mi_8x8[0] : NULL;
+ xd->mi_8x8[0] = xd->mi_stream + offset - tile_offset;
+ xd->mi_8x8[0]->mbmi.sb_type = bsize;
+ for (y = 0; y < y_mis; ++y)
+ for (x = !y; x < x_mis; ++x)
+ xd->mi_8x8[y * cm->mode_info_stride + x] = xd->mi_8x8[0];
+
set_skip_context(xd, xd->above_context, xd->left_context, mi_row, mi_col);
// Distance of Mb to the various image edges. These are specified to 8th pel
@@ -507,7 +511,7 @@ static void decode_modes_sb(VP9_COMMON *const cm, MACROBLOCKD *const xd,
decode_modes_sb(cm, xd, tile, mi_row + hbs, mi_col + hbs, r, subsize);
break;
default:
- assert(!"Invalid partition type");
+ assert(0 && "Invalid partition type");
}
}
@@ -703,9 +707,21 @@ static void apply_frame_size(VP9D_COMP *pbi, int width, int height) {
vp9_update_frame_size(cm);
}
- vp9_realloc_frame_buffer(get_frame_new_buffer(cm), cm->width, cm->height,
- cm->subsampling_x, cm->subsampling_y,
- VP9BORDERINPIXELS);
+ if (cm->fb_list != NULL) {
+ vpx_codec_frame_buffer_t *const ext_fb = &cm->fb_list[cm->new_fb_idx];
+ if (vp9_realloc_frame_buffer(get_frame_new_buffer(cm),
+ cm->width, cm->height,
+ cm->subsampling_x, cm->subsampling_y,
+ VP9BORDERINPIXELS, ext_fb,
+ cm->realloc_fb_cb, cm->user_priv)) {
+ vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
+ "Failed to allocate external frame buffer");
+ }
+ } else {
+ vp9_realloc_frame_buffer(get_frame_new_buffer(cm), cm->width, cm->height,
+ cm->subsampling_x, cm->subsampling_y,
+ VP9BORDERINPIXELS, NULL, NULL, NULL);
+ }
}
static void setup_frame_size(VP9D_COMP *pbi,
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index 164576d0c..4e2bc3560 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -162,12 +162,12 @@ static int read_skip_coeff(VP9_COMMON *cm, const MACROBLOCKD *xd,
static void read_intra_frame_mode_info(VP9_COMMON *const cm,
MACROBLOCKD *const xd,
- MODE_INFO *const m,
int mi_row, int mi_col, vp9_reader *r) {
- MB_MODE_INFO *const mbmi = &m->mbmi;
- const BLOCK_SIZE bsize = mbmi->sb_type;
+ MODE_INFO *const mi = xd->mi_8x8[0];
+ MB_MODE_INFO *const mbmi = &mi->mbmi;
const MODE_INFO *above_mi = xd->mi_8x8[-cm->mode_info_stride];
const MODE_INFO *left_mi = xd->left_available ? xd->mi_8x8[-1] : NULL;
+ const BLOCK_SIZE bsize = mbmi->sb_type;
mbmi->segment_id = read_intra_segment_id(cm, xd, mi_row, mi_col, r);
mbmi->skip_coeff = read_skip_coeff(cm, xd, mbmi->segment_id, r);
@@ -176,8 +176,8 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
mbmi->ref_frame[1] = NONE;
if (bsize >= BLOCK_8X8) {
- const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, 0);
- const MB_PREDICTION_MODE L = left_block_mode(m, left_mi, 0);
+ const MB_PREDICTION_MODE A = above_block_mode(mi, above_mi, 0);
+ const MB_PREDICTION_MODE L = left_block_mode(mi, left_mi, 0);
mbmi->mode = read_intra_mode(r, vp9_kf_y_mode_prob[A][L]);
} else {
// Only 4x4, 4x8, 8x4 blocks
@@ -188,19 +188,19 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
for (idy = 0; idy < 2; idy += num_4x4_h) {
for (idx = 0; idx < 2; idx += num_4x4_w) {
const int ib = idy * 2 + idx;
- const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, ib);
- const MB_PREDICTION_MODE L = left_block_mode(m, left_mi, ib);
+ const MB_PREDICTION_MODE A = above_block_mode(mi, above_mi, ib);
+ const MB_PREDICTION_MODE L = left_block_mode(mi, left_mi, ib);
const MB_PREDICTION_MODE b_mode = read_intra_mode(r,
vp9_kf_y_mode_prob[A][L]);
- m->bmi[ib].as_mode = b_mode;
+ mi->bmi[ib].as_mode = b_mode;
if (num_4x4_h == 2)
- m->bmi[ib + 2].as_mode = b_mode;
+ mi->bmi[ib + 2].as_mode = b_mode;
if (num_4x4_w == 2)
- m->bmi[ib + 1].as_mode = b_mode;
+ mi->bmi[ib + 1].as_mode = b_mode;
}
}
- mbmi->mode = m->bmi[3].as_mode;
+ mbmi->mode = mi->bmi[3].as_mode;
}
mbmi->uv_mode = read_intra_mode(r, vp9_kf_uv_mode_prob[mbmi->mode]);
@@ -308,7 +308,7 @@ static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd,
ref_frame[1] = NONE;
} else {
- assert(!"Invalid prediction mode.");
+ assert(0 && "Invalid prediction mode.");
}
}
}
@@ -475,8 +475,8 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
if (b_mode == NEARESTMV || b_mode == NEARMV)
for (ref = 0; ref < 1 + is_compound; ++ref)
- vp9_append_sub8x8_mvs_for_idx(cm, xd, tile, &nearest[ref],
- &nearmv[ref], j, ref, mi_row, mi_col);
+ vp9_append_sub8x8_mvs_for_idx(cm, xd, tile, j, ref, mi_row, mi_col,
+ &nearest[ref], &nearmv[ref]);
if (!assign_mv(cm, b_mode, block, best, nearest, nearmv,
is_compound, allow_hp, r)) {
@@ -509,8 +509,8 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
static void read_inter_frame_mode_info(VP9_COMMON *const cm,
MACROBLOCKD *const xd,
const TileInfo *const tile,
- MODE_INFO *const mi,
int mi_row, int mi_col, vp9_reader *r) {
+ MODE_INFO *const mi = xd->mi_8x8[0];
MB_MODE_INFO *const mbmi = &mi->mbmi;
int inter_block;
@@ -528,25 +528,10 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
read_intra_block_mode_info(cm, mi, r);
}
-void vp9_read_mode_info(VP9_COMMON *cm, MACROBLOCKD *xd,
- const TileInfo *const tile,
+void vp9_read_mode_info(VP9_COMMON *cm, MACROBLOCKD *xd, const TileInfo *tile,
int mi_row, int mi_col, vp9_reader *r) {
- MODE_INFO *const mi = xd->mi_8x8[0];
- const BLOCK_SIZE bsize = mi->mbmi.sb_type;
- const int bw = num_8x8_blocks_wide_lookup[bsize];
- const int bh = num_8x8_blocks_high_lookup[bsize];
- const int y_mis = MIN(bh, cm->mi_rows - mi_row);
- const int x_mis = MIN(bw, cm->mi_cols - mi_col);
- int x, y, z;
-
if (frame_is_intra_only(cm))
- read_intra_frame_mode_info(cm, xd, mi, mi_row, mi_col, r);
+ read_intra_frame_mode_info(cm, xd, mi_row, mi_col, r);
else
- read_inter_frame_mode_info(cm, xd, tile, mi, mi_row, mi_col, r);
-
- for (y = 0, z = 0; y < y_mis; y++, z += cm->mode_info_stride) {
- for (x = !y; x < x_mis; x++) {
- xd->mi_8x8[z + x] = mi;
- }
- }
+ read_inter_frame_mode_info(cm, xd, tile, mi_row, mi_col, r);
}
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 1bbb12c7c..88e25ebf2 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -63,14 +63,14 @@ void vp9_entropy_mode_init() {
static void write_intra_mode(vp9_writer *w, MB_PREDICTION_MODE mode,
const vp9_prob *probs) {
- write_token(w, vp9_intra_mode_tree, probs, &intra_mode_encodings[mode]);
+ vp9_write_token(w, vp9_intra_mode_tree, probs, &intra_mode_encodings[mode]);
}
static void write_inter_mode(vp9_writer *w, MB_PREDICTION_MODE mode,
const vp9_prob *probs) {
assert(is_inter_mode(mode));
- write_token(w, vp9_inter_mode_tree, probs,
- &inter_mode_encodings[INTER_OFFSET(mode)]);
+ vp9_write_token(w, vp9_inter_mode_tree, probs,
+ &inter_mode_encodings[INTER_OFFSET(mode)]);
}
static INLINE void write_be32(uint8_t *p, int value) {
@@ -179,12 +179,12 @@ static void pack_mb_tokens(vp9_writer* const w,
if (t >= TWO_TOKEN && t < EOB_TOKEN) {
int len = UNCONSTRAINED_NODES - p->skip_eob_node;
int bits = v >> (n - len);
- treed_write(w, vp9_coef_tree, p->context_tree, bits, len, i);
- treed_write(w, vp9_coef_con_tree,
- vp9_pareto8_full[p->context_tree[PIVOT_NODE] - 1], v, n - len,
- 0);
+ vp9_write_tree(w, vp9_coef_tree, p->context_tree, bits, len, i);
+ vp9_write_tree(w, vp9_coef_con_tree,
+ vp9_pareto8_full[p->context_tree[PIVOT_NODE] - 1],
+ v, n - len, 0);
} else {
- treed_write(w, vp9_coef_tree, p->context_tree, v, n, i);
+ vp9_write_tree(w, vp9_coef_tree, p->context_tree, v, n, i);
}
if (b->base_val) {
@@ -214,7 +214,7 @@ static void pack_mb_tokens(vp9_writer* const w,
static void write_segment_id(vp9_writer *w, const struct segmentation *seg,
int segment_id) {
if (seg->enabled && seg->update_map)
- treed_write(w, vp9_segment_tree, seg->tree_probs, segment_id, 3, 0);
+ vp9_write_tree(w, vp9_segment_tree, seg->tree_probs, segment_id, 3, 0);
}
// This function encodes the reference frame
@@ -332,16 +332,15 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc) {
if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)) {
if (bsize >= BLOCK_8X8) {
write_inter_mode(bc, mode, mv_ref_p);
- ++cm->counts.inter_mode[mi->mode_context[rf]]
- [INTER_OFFSET(mode)];
+ ++cm->counts.inter_mode[mi->mode_context[rf]][INTER_OFFSET(mode)];
}
}
if (cm->mcomp_filter_type == SWITCHABLE) {
const int ctx = vp9_get_pred_context_switchable_interp(xd);
- write_token(bc, vp9_switchable_interp_tree,
- cm->fc.switchable_interp_prob[ctx],
- &switchable_interp_encodings[mi->interp_filter]);
+ vp9_write_token(bc, vp9_switchable_interp_tree,
+ cm->fc.switchable_interp_prob[ctx],
+ &switchable_interp_encodings[mi->interp_filter]);
} else {
assert(mi->interp_filter == cm->mcomp_filter_type);
}
@@ -470,7 +469,7 @@ static void write_partition(VP9_COMP *cpi, int hbs, int mi_row, int mi_col,
const int has_cols = (mi_col + hbs) < cm->mi_cols;
if (has_rows && has_cols) {
- write_token(w, vp9_partition_tree, probs, &partition_encodings[p]);
+ vp9_write_token(w, vp9_partition_tree, probs, &partition_encodings[p]);
} else if (!has_rows && has_cols) {
assert(p == PARTITION_SPLIT || p == PARTITION_HORZ);
vp9_write(w, p == PARTITION_SPLIT, probs[1]);
@@ -778,38 +777,27 @@ static void encode_loopfilter(struct loopfilter *lf,
vp9_wb_write_bit(wb, lf->mode_ref_delta_enabled);
if (lf->mode_ref_delta_enabled) {
- // Do the deltas need to be updated
vp9_wb_write_bit(wb, lf->mode_ref_delta_update);
if (lf->mode_ref_delta_update) {
- // Send update
for (i = 0; i < MAX_REF_LF_DELTAS; i++) {
const int delta = lf->ref_deltas[i];
-
- // Frame level data
- if (delta != lf->last_ref_deltas[i]) {
+ const int changed = delta != lf->last_ref_deltas[i];
+ vp9_wb_write_bit(wb, changed);
+ if (changed) {
lf->last_ref_deltas[i] = delta;
- vp9_wb_write_bit(wb, 1);
-
- assert(delta != 0);
vp9_wb_write_literal(wb, abs(delta) & 0x3F, 6);
vp9_wb_write_bit(wb, delta < 0);
- } else {
- vp9_wb_write_bit(wb, 0);
}
}
- // Send update
for (i = 0; i < MAX_MODE_LF_DELTAS; i++) {
const int delta = lf->mode_deltas[i];
- if (delta != lf->last_mode_deltas[i]) {
+ const int changed = delta != lf->last_mode_deltas[i];
+ vp9_wb_write_bit(wb, changed);
+ if (changed) {
lf->last_mode_deltas[i] = delta;
- vp9_wb_write_bit(wb, 1);
-
- assert(delta != 0);
vp9_wb_write_literal(wb, abs(delta) & 0x3F, 6);
vp9_wb_write_bit(wb, delta < 0);
- } else {
- vp9_wb_write_bit(wb, 0);
}
}
}
@@ -1304,7 +1292,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
return header_bc.pos;
}
-void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
+void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, size_t *size) {
uint8_t *data = dest;
size_t first_part_size;
struct vp9_write_bit_buffer wb = {data, 0};
diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h
index 00883385e..737fad4c2 100644
--- a/vp9/encoder/vp9_block.h
+++ b/vp9/encoder/vp9_block.h
@@ -59,6 +59,7 @@ typedef struct {
// motion vector cache for adaptive motion search control in partition
// search loop
int_mv pred_mv[MAX_REF_FRAMES];
+ int pred_filter_type;
// Bit flag for each mode whether it has high error in comparison to others.
unsigned int modes_with_high_error;
diff --git a/vp9/encoder/vp9_boolhuff.h b/vp9/encoder/vp9_boolhuff.h
index c3f340d1b..a0fff3861 100644
--- a/vp9/encoder/vp9_boolhuff.h
+++ b/vp9/encoder/vp9_boolhuff.h
@@ -111,5 +111,6 @@ static void vp9_write_literal(vp9_writer *w, int data, int bits) {
vp9_write_bit(w, 1 & (data >> bit));
}
+#define vp9_write_prob(w, v) vp9_write_literal((w), (v), 8)
#endif // VP9_ENCODER_VP9_BOOLHUFF_H_
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 20c4e42e7..b845bc4f1 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -857,16 +857,9 @@ static void save_context(VP9_COMP *cpi, int mi_row, int mi_col,
static void encode_b(VP9_COMP *cpi, const TileInfo *const tile,
TOKENEXTRA **tp, int mi_row, int mi_col,
- int output_enabled, BLOCK_SIZE bsize, int sub_index) {
- VP9_COMMON *const cm = &cpi->common;
+ int output_enabled, BLOCK_SIZE bsize) {
MACROBLOCK *const x = &cpi->mb;
- if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
- return;
-
- if (sub_index != -1)
- *get_sb_index(x, bsize) = sub_index;
-
if (bsize < BLOCK_8X8) {
// When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
// there is nothing to be done.
@@ -890,64 +883,73 @@ static void encode_sb(VP9_COMP *cpi, const TileInfo *const tile,
int output_enabled, BLOCK_SIZE bsize) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
- BLOCK_SIZE c1 = BLOCK_8X8;
- const int bsl = b_width_log2(bsize), bs = (1 << bsl) / 4;
- int pl = 0;
+ const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
+ int ctx;
PARTITION_TYPE partition;
BLOCK_SIZE subsize;
- int i;
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
return;
- c1 = BLOCK_4X4;
if (bsize >= BLOCK_8X8) {
- pl = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context,
+ ctx = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context,
mi_row, mi_col, bsize);
- c1 = *(get_sb_partitioning(x, bsize));
+ subsize = *get_sb_partitioning(x, bsize);
+ } else {
+ ctx = 0;
+ subsize = BLOCK_4X4;
}
- partition = partition_lookup[bsl][c1];
+
+ partition = partition_lookup[bsl][subsize];
switch (partition) {
case PARTITION_NONE:
if (output_enabled && bsize >= BLOCK_8X8)
- cm->counts.partition[pl][PARTITION_NONE]++;
- encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, c1, -1);
+ cm->counts.partition[ctx][PARTITION_NONE]++;
+ encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
break;
case PARTITION_VERT:
if (output_enabled)
- cm->counts.partition[pl][PARTITION_VERT]++;
- encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, c1, 0);
- encode_b(cpi, tile, tp, mi_row, mi_col + bs, output_enabled, c1, 1);
+ cm->counts.partition[ctx][PARTITION_VERT]++;
+ *get_sb_index(x, subsize) = 0;
+ encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
+ if (mi_col + hbs < cm->mi_cols) {
+ *get_sb_index(x, subsize) = 1;
+ encode_b(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, subsize);
+ }
break;
case PARTITION_HORZ:
if (output_enabled)
- cm->counts.partition[pl][PARTITION_HORZ]++;
- encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, c1, 0);
- encode_b(cpi, tile, tp, mi_row + bs, mi_col, output_enabled, c1, 1);
+ cm->counts.partition[ctx][PARTITION_HORZ]++;
+ *get_sb_index(x, subsize) = 0;
+ encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
+ if (mi_row + hbs < cm->mi_rows) {
+ *get_sb_index(x, subsize) = 1;
+ encode_b(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, subsize);
+ }
break;
case PARTITION_SPLIT:
subsize = get_subsize(bsize, PARTITION_SPLIT);
-
if (output_enabled)
- cm->counts.partition[pl][PARTITION_SPLIT]++;
+ cm->counts.partition[ctx][PARTITION_SPLIT]++;
- for (i = 0; i < 4; i++) {
- const int x_idx = i & 1, y_idx = i >> 1;
-
- *get_sb_index(x, subsize) = i;
- encode_sb(cpi, tile, tp, mi_row + y_idx * bs, mi_col + x_idx * bs,
- output_enabled, subsize);
- }
+ *get_sb_index(x, subsize) = 0;
+ encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
+ *get_sb_index(x, subsize) = 1;
+ encode_sb(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, subsize);
+ *get_sb_index(x, subsize) = 2;
+ encode_sb(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, subsize);
+ *get_sb_index(x, subsize) = 3;
+ encode_sb(cpi, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled,
+ subsize);
break;
default:
- assert(0);
- break;
+ assert("Invalid partition type.");
}
if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
update_partition_context(cpi->above_seg_context, cpi->left_seg_context,
- mi_row, mi_col, c1, bsize);
+ mi_row, mi_col, subsize, bsize);
}
// Check to see if the given partition size is allowed for a specified number
@@ -1686,6 +1688,10 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
*get_sb_index(x, subsize) = i;
if (cpi->sf.adaptive_motion_search)
load_pred_mv(x, get_block_context(x, bsize));
+ if (cpi->sf.adaptive_pred_filter_type && bsize == BLOCK_8X8 &&
+ partition_none_allowed)
+ get_block_context(x, subsize)->pred_filter_type =
+ get_block_context(x, bsize)->mic.mbmi.interp_filter;
rd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, subsize,
&this_rate, &this_dist, i != 3, best_rd - sum_rd);
@@ -1733,6 +1739,10 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
*get_sb_index(x, subsize) = 0;
if (cpi->sf.adaptive_motion_search)
load_pred_mv(x, get_block_context(x, bsize));
+ if (cpi->sf.adaptive_pred_filter_type && bsize == BLOCK_8X8 &&
+ partition_none_allowed)
+ get_block_context(x, subsize)->pred_filter_type =
+ get_block_context(x, bsize)->mic.mbmi.interp_filter;
pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
get_block_context(x, subsize), best_rd);
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
@@ -1744,6 +1754,10 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
*get_sb_index(x, subsize) = 1;
if (cpi->sf.adaptive_motion_search)
load_pred_mv(x, get_block_context(x, bsize));
+ if (cpi->sf.adaptive_pred_filter_type && bsize == BLOCK_8X8 &&
+ partition_none_allowed)
+ get_block_context(x, subsize)->pred_filter_type =
+ get_block_context(x, bsize)->mic.mbmi.interp_filter;
pick_sb_modes(cpi, tile, mi_row + ms, mi_col, &this_rate,
&this_dist, subsize, get_block_context(x, subsize),
best_rd - sum_rd);
@@ -1778,6 +1792,10 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
*get_sb_index(x, subsize) = 0;
if (cpi->sf.adaptive_motion_search)
load_pred_mv(x, get_block_context(x, bsize));
+ if (cpi->sf.adaptive_pred_filter_type && bsize == BLOCK_8X8 &&
+ partition_none_allowed)
+ get_block_context(x, subsize)->pred_filter_type =
+ get_block_context(x, bsize)->mic.mbmi.interp_filter;
pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
get_block_context(x, subsize), best_rd);
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
@@ -1788,6 +1806,10 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
*get_sb_index(x, subsize) = 1;
if (cpi->sf.adaptive_motion_search)
load_pred_mv(x, get_block_context(x, bsize));
+ if (cpi->sf.adaptive_pred_filter_type && bsize == BLOCK_8X8 &&
+ partition_none_allowed)
+ get_block_context(x, subsize)->pred_filter_type =
+ get_block_context(x, bsize)->mic.mbmi.interp_filter;
pick_sb_modes(cpi, tile, mi_row, mi_col + ms, &this_rate,
&this_dist, subsize, get_block_context(x, subsize),
best_rd - sum_rd);
@@ -1889,6 +1911,18 @@ static void encode_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
int dummy_rate;
int64_t dummy_dist;
+ BLOCK_SIZE i;
+ MACROBLOCK *x = &cpi->mb;
+ for (i = BLOCK_4X4; i < BLOCK_8X8; ++i) {
+ const int num_4x4_w = num_4x4_blocks_wide_lookup[i];
+ const int num_4x4_h = num_4x4_blocks_high_lookup[i];
+ const int num_4x4_blk = MAX(4, num_4x4_w * num_4x4_h);
+ for (x->sb_index = 0; x->sb_index < 4; ++x->sb_index)
+ for (x->mb_index = 0; x->mb_index < 4; ++x->mb_index)
+ for (x->b_index = 0; x->b_index < 16 / num_4x4_blk; ++x->b_index)
+ get_block_context(x, i)->pred_filter_type = SWITCHABLE;
+ }
+
vp9_zero(cpi->mb.pred_mv);
if (cpi->sf.reference_masking)
diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c
index 0821c263a..e05ba1b76 100644
--- a/vp9/encoder/vp9_encodemb.c
+++ b/vp9/encoder/vp9_encodemb.c
@@ -369,7 +369,7 @@ void vp9_xform_quant(int plane, int block, BLOCK_SIZE plane_bsize,
int16_t *coeff = BLOCK_OFFSET(p->coeff, block);
int16_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
int16_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
- const scan_order *so;
+ const scan_order *scan_order;
uint16_t *eob = &p->eobs[block];
const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
int i, j;
@@ -379,36 +379,39 @@ void vp9_xform_quant(int plane, int block, BLOCK_SIZE plane_bsize,
switch (tx_size) {
case TX_32X32:
- so = &vp9_default_scan_orders[TX_32X32];
+ scan_order = &vp9_default_scan_orders[TX_32X32];
if (x->use_lp32x32fdct)
vp9_fdct32x32_rd(src_diff, coeff, diff_stride);
else
vp9_fdct32x32(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, p->zbin_extra, eob, so->scan,
- so->iscan);
+ pd->dequant, p->zbin_extra, eob, scan_order->scan,
+ scan_order->iscan);
break;
case TX_16X16:
- so = &vp9_default_scan_orders[TX_16X16];
+ scan_order = &vp9_default_scan_orders[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, p->zbin_extra, eob, so->scan, so->iscan);
+ pd->dequant, p->zbin_extra, eob,
+ scan_order->scan, scan_order->iscan);
break;
case TX_8X8:
- so = &vp9_default_scan_orders[TX_8X8];
+ scan_order = &vp9_default_scan_orders[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, p->zbin_extra, eob, so->scan, so->iscan);
+ pd->dequant, p->zbin_extra, eob,
+ scan_order->scan, scan_order->iscan);
break;
case TX_4X4:
- so = &vp9_default_scan_orders[TX_4X4];
+ scan_order = &vp9_default_scan_orders[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, p->zbin_extra, eob, so->scan, so->iscan);
+ pd->dequant, p->zbin_extra, eob,
+ scan_order->scan, scan_order->iscan);
break;
default:
assert(0);
@@ -468,7 +471,7 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
xd->itxm_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
break;
default:
- assert(!"Invalid transform size");
+ assert(0 && "Invalid transform size");
}
}
@@ -533,7 +536,7 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
int16_t *coeff = BLOCK_OFFSET(p->coeff, block);
int16_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
int16_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
- const scan_order *so;
+ const scan_order *scan_order;
TX_TYPE tx_type;
MB_PREDICTION_MODE mode;
const int bwl = b_width_log2(plane_bsize);
@@ -555,10 +558,9 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
switch (tx_size) {
case TX_32X32:
- so = &vp9_default_scan_orders[TX_32X32];
+ scan_order = &vp9_default_scan_orders[TX_32X32];
mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
- block >>= 6;
- vp9_predict_intra_block(xd, block, bwl, TX_32X32, mode,
+ vp9_predict_intra_block(xd, block >> 6, bwl, TX_32X32, mode,
x->skip_encode ? src : dst,
x->skip_encode ? p->src.stride : pd->dst.stride,
dst, pd->dst.stride);
@@ -571,18 +573,17 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
vp9_fdct32x32(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, p->zbin_extra, eob, so->scan,
- so->iscan);
+ pd->dequant, p->zbin_extra, eob, scan_order->scan,
+ scan_order->iscan);
}
if (!x->skip_encode && *eob)
vp9_idct32x32_add(dqcoeff, dst, pd->dst.stride, *eob);
break;
case TX_16X16:
tx_type = get_tx_type_16x16(pd->plane_type, xd);
- so = &vp9_scan_orders[TX_16X16][tx_type];
+ scan_order = &vp9_scan_orders[TX_16X16][tx_type];
mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
- block >>= 4;
- vp9_predict_intra_block(xd, block, bwl, TX_16X16, mode,
+ vp9_predict_intra_block(xd, block >> 4, bwl, TX_16X16, mode,
x->skip_encode ? src : dst,
x->skip_encode ? p->src.stride : pd->dst.stride,
dst, pd->dst.stride);
@@ -592,17 +593,17 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
vp9_fht16x16(tx_type, 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, p->zbin_extra, eob, so->scan, so->iscan);
+ pd->dequant, p->zbin_extra, eob, scan_order->scan,
+ scan_order->iscan);
}
if (!x->skip_encode && *eob)
vp9_iht16x16_add(tx_type, dqcoeff, dst, pd->dst.stride, *eob);
break;
case TX_8X8:
tx_type = get_tx_type_8x8(pd->plane_type, xd);
- so = &vp9_scan_orders[TX_8X8][tx_type];
+ scan_order = &vp9_scan_orders[TX_8X8][tx_type];
mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
- block >>= 2;
- vp9_predict_intra_block(xd, block, bwl, TX_8X8, mode,
+ vp9_predict_intra_block(xd, block >> 2, bwl, TX_8X8, mode,
x->skip_encode ? src : dst,
x->skip_encode ? p->src.stride : pd->dst.stride,
dst, pd->dst.stride);
@@ -612,14 +613,15 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
vp9_fht8x8(tx_type, 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, p->zbin_extra, eob, so->scan, so->iscan);
+ pd->dequant, p->zbin_extra, eob, scan_order->scan,
+ scan_order->iscan);
}
if (!x->skip_encode && *eob)
vp9_iht8x8_add(tx_type, dqcoeff, dst, pd->dst.stride, *eob);
break;
case TX_4X4:
tx_type = get_tx_type_4x4(pd->plane_type, xd, block);
- so = &vp9_scan_orders[TX_4X4][tx_type];
+ scan_order = &vp9_scan_orders[TX_4X4][tx_type];
if (mbmi->sb_type < BLOCK_8X8 && plane == 0)
mode = xd->mi_8x8[0]->bmi[block].as_mode;
else
@@ -639,7 +641,8 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
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, p->zbin_extra, eob, so->scan, so->iscan);
+ pd->dequant, p->zbin_extra, eob, scan_order->scan,
+ scan_order->iscan);
}
if (!x->skip_encode && *eob) {
diff --git a/vp9/encoder/vp9_encodemv.c b/vp9/encoder/vp9_encodemv.c
index fad1ee032..dae89ad1d 100644
--- a/vp9/encoder/vp9_encodemv.c
+++ b/vp9/encoder/vp9_encodemv.c
@@ -47,13 +47,13 @@ static void encode_mv_component(vp9_writer* w, int comp,
vp9_write(w, sign, mvcomp->sign);
// Class
- write_token(w, vp9_mv_class_tree, mvcomp->classes,
- &mv_class_encodings[mv_class]);
+ vp9_write_token(w, vp9_mv_class_tree, mvcomp->classes,
+ &mv_class_encodings[mv_class]);
// Integer bits
if (mv_class == MV_CLASS_0) {
- write_token(w, vp9_mv_class0_tree, mvcomp->class0,
- &mv_class0_encodings[d]);
+ vp9_write_token(w, vp9_mv_class0_tree, mvcomp->class0,
+ &mv_class0_encodings[d]);
} else {
int i;
const int n = mv_class + CLASS0_BITS - 1; // number of bits
@@ -62,9 +62,9 @@ static void encode_mv_component(vp9_writer* w, int comp,
}
// Fractional bits
- write_token(w, vp9_mv_fp_tree,
- mv_class == MV_CLASS_0 ? mvcomp->class0_fp[d] : mvcomp->fp,
- &mv_fp_encodings[fr]);
+ vp9_write_token(w, vp9_mv_fp_tree,
+ mv_class == MV_CLASS_0 ? mvcomp->class0_fp[d] : mvcomp->fp,
+ &mv_fp_encodings[fr]);
// High precision bit
if (usehp)
@@ -209,7 +209,7 @@ void vp9_encode_mv(VP9_COMP* cpi, vp9_writer* w,
const MV_JOINT_TYPE j = vp9_get_mv_joint(&diff);
usehp = usehp && vp9_use_mv_hp(ref);
- write_token(w, vp9_mv_joint_tree, mvctx->joints, &mv_joint_encodings[j]);
+ vp9_write_token(w, vp9_mv_joint_tree, mvctx->joints, &mv_joint_encodings[j]);
if (mv_joint_vertical(j))
encode_mv_component(w, diff.row, &mvctx->comps[0], usehp);
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 5f42d0e76..cd6831af2 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -364,36 +364,32 @@ void vp9_end_first_pass(VP9_COMP *cpi) {
output_stats(cpi, cpi->output_pkt_list, &cpi->twopass.total_stats);
}
-static void zz_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
- YV12_BUFFER_CONFIG *recon_buffer,
- int *best_motion_err, int recon_yoffset) {
+static unsigned int zz_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
+ YV12_BUFFER_CONFIG *recon_buffer,
+ int recon_yoffset) {
MACROBLOCKD *const xd = &x->e_mbd;
+ const uint8_t *const src = x->plane[0].src.buf;
+ const int src_stride = x->plane[0].src.stride;
+ const uint8_t *const ref = xd->plane[0].pre[0].buf
+ = recon_buffer->y_buffer + recon_yoffset;
+ const int ref_stride = xd->plane[0].pre[0].stride;
- // Set up pointers for this macro block recon buffer
- xd->plane[0].pre[0].buf = recon_buffer->y_buffer + recon_yoffset;
-
+ unsigned int sse;
switch (xd->mi_8x8[0]->mbmi.sb_type) {
case BLOCK_8X8:
- vp9_mse8x8(x->plane[0].src.buf, x->plane[0].src.stride,
- xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride,
- (unsigned int *)(best_motion_err));
+ vp9_mse8x8(src, src_stride, ref, ref_stride, &sse);
break;
case BLOCK_16X8:
- vp9_mse16x8(x->plane[0].src.buf, x->plane[0].src.stride,
- xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride,
- (unsigned int *)(best_motion_err));
+ vp9_mse16x8(src, src_stride, ref, ref_stride, &sse);
break;
case BLOCK_8X16:
- vp9_mse8x16(x->plane[0].src.buf, x->plane[0].src.stride,
- xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride,
- (unsigned int *)(best_motion_err));
+ vp9_mse8x16(src, src_stride, ref, ref_stride, &sse);
break;
default:
- vp9_mse16x16(x->plane[0].src.buf, x->plane[0].src.stride,
- xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride,
- (unsigned int *)(best_motion_err));
+ vp9_mse16x16(src, src_stride, ref, ref_stride, &sse);
break;
}
+ return sse;
}
static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
@@ -410,8 +406,7 @@ static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
int step_param = 3;
int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
int n;
- vp9_variance_fn_ptr_t v_fn_ptr =
- cpi->fn_ptr[xd->mi_8x8[0]->mbmi.sb_type];
+ vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[xd->mi_8x8[0]->mbmi.sb_type];
int new_mv_mode_penalty = 256;
int sr = 0;
@@ -448,10 +443,11 @@ static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
tmp_mv.as_int = 0;
ref_mv_full.as_mv.col = ref_mv->as_mv.col >> 3;
ref_mv_full.as_mv.row = ref_mv->as_mv.row >> 3;
- tmp_err = cpi->diamond_search_sad(x, &ref_mv_full, &tmp_mv, step_param,
+ tmp_err = cpi->diamond_search_sad(x, &ref_mv_full.as_mv, &tmp_mv.as_mv,
+ step_param,
x->sadperbit16, &num00, &v_fn_ptr,
x->nmvjointcost,
- x->mvcost, ref_mv);
+ x->mvcost, &ref_mv->as_mv);
if (tmp_err < INT_MAX - new_mv_mode_penalty)
tmp_err += new_mv_mode_penalty;
@@ -471,11 +467,11 @@ static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
if (num00) {
num00--;
} else {
- tmp_err = cpi->diamond_search_sad(x, &ref_mv_full, &tmp_mv,
+ tmp_err = cpi->diamond_search_sad(x, &ref_mv_full.as_mv, &tmp_mv.as_mv,
step_param + n, x->sadperbit16,
&num00, &v_fn_ptr,
x->nmvjointcost,
- x->mvcost, ref_mv);
+ x->mvcost, &ref_mv->as_mv);
if (tmp_err < INT_MAX - new_mv_mode_penalty)
tmp_err += new_mv_mode_penalty;
@@ -583,10 +579,9 @@ void vp9_first_pass(VP9_COMP *cpi) {
int this_error;
int gf_motion_error = INT_MAX;
int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
- double error_weight;
+ double error_weight = 1.0;
vp9_clear_system_state(); // __asm emms;
- error_weight = 1.0; // avoid uninitialized warnings
xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset;
xd->plane[1].dst.buf = new_yv12->u_buffer + recon_uvoffset;
@@ -647,11 +642,9 @@ void vp9_first_pass(VP9_COMP *cpi) {
// Other than for the first frame do a motion search
if (cm->current_video_frame > 0) {
int tmp_err;
- int motion_error = INT_MAX;
+ int motion_error = zz_motion_search(cpi, x, lst_yv12, recon_yoffset);
int_mv mv, tmp_mv;
-
// Simple 0,0 motion with no mv overhead
- zz_motion_search(cpi, x, lst_yv12, &motion_error, recon_yoffset);
mv.as_int = tmp_mv.as_int = 0;
// Test last reference frame using the previous best mv as the
@@ -684,8 +677,7 @@ void vp9_first_pass(VP9_COMP *cpi) {
// Experimental search in an older reference frame
if (cm->current_video_frame > 1) {
// Simple 0,0 motion with no mv overhead
- zz_motion_search(cpi, x, gld_yv12,
- &gf_motion_error, recon_yoffset);
+ gf_motion_error = zz_motion_search(cpi, x, gld_yv12, recon_yoffset);
first_pass_motion_search(cpi, x, &zero_ref_mv,
&tmp_mv.as_mv, gld_yv12,
@@ -724,11 +716,9 @@ void vp9_first_pass(VP9_COMP *cpi) {
// very close and very low. This helps with scene cut
// detection for example in cropped clips with black bars
// at the sides or top and bottom.
- if ((((this_error - intrapenalty) * 9) <=
- (motion_error * 10)) &&
- (this_error < (2 * intrapenalty))) {
+ if (((this_error - intrapenalty) * 9 <= motion_error * 10) &&
+ this_error < 2 * intrapenalty)
neutral_count++;
- }
mv.as_mv.row *= 8;
mv.as_mv.col *= 8;
@@ -737,8 +727,7 @@ void vp9_first_pass(VP9_COMP *cpi) {
xd->mi_8x8[0]->mbmi.tx_size = TX_4X4;
xd->mi_8x8[0]->mbmi.ref_frame[0] = LAST_FRAME;
xd->mi_8x8[0]->mbmi.ref_frame[1] = NONE;
- vp9_build_inter_predictors_sby(xd, mb_row << 1,
- mb_col << 1,
+ vp9_build_inter_predictors_sby(xd, mb_row << 1, mb_col << 1,
xd->mi_8x8[0]->mbmi.sb_type);
vp9_encode_sby(x, xd->mi_8x8[0]->mbmi.sb_type);
sum_mvr += mv.as_mv.row;
diff --git a/vp9/encoder/vp9_mbgraph.c b/vp9/encoder/vp9_mbgraph.c
index 544f1304d..e2ef256dd 100644
--- a/vp9/encoder/vp9_mbgraph.c
+++ b/vp9/encoder/vp9_mbgraph.c
@@ -42,7 +42,7 @@ static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi,
(cpi->speed < 8 ? (cpi->speed > 5 ? 1 : 0) : 2);
step_param = MIN(step_param, (cpi->sf.max_step_search_steps - 2));
- vp9_clamp_mv_min_max(x, &ref_mv->as_mv);
+ vp9_set_mv_search_range(x, &ref_mv->as_mv);
ref_full.as_mv.col = ref_mv->as_mv.col >> 3;
ref_full.as_mv.row = ref_mv->as_mv.row >> 3;
diff --git a/vp9/encoder/vp9_mcomp.c b/vp9/encoder/vp9_mcomp.c
index fee11fd2b..87b5988c2 100644
--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -24,7 +24,7 @@
// #define NEW_DIAMOND_SEARCH
-void vp9_clamp_mv_min_max(MACROBLOCK *x, MV *mv) {
+void vp9_set_mv_search_range(MACROBLOCK *x, MV *mv) {
const int col_min = (mv->col >> 3) - MAX_FULL_PEL_VAL + (mv->col & 7 ? 1 : 0);
const int row_min = (mv->row >> 3) - MAX_FULL_PEL_VAL + (mv->row & 7 ? 1 : 0);
const int col_max = (mv->col >> 3) + MAX_FULL_PEL_VAL;
@@ -1066,10 +1066,10 @@ int vp9_square_search(MACROBLOCK *x,
#undef CHECK_POINT
#undef CHECK_BETTER
-int vp9_full_range_search_c(MACROBLOCK *x, int_mv *ref_mv, int_mv *best_mv,
+int vp9_full_range_search_c(MACROBLOCK *x, MV *ref_mv, MV *best_mv,
int search_param, int sad_per_bit, int *num00,
vp9_variance_fn_ptr_t *fn_ptr, int *mvjcost,
- int *mvcost[2], int_mv *center_mv) {
+ int *mvcost[2], const MV *center_mv) {
const MACROBLOCKD* const xd = &x->e_mbd;
uint8_t *what = x->plane[0].src.buf;
int what_stride = x->plane[0].src.stride;
@@ -1077,14 +1077,14 @@ int vp9_full_range_search_c(MACROBLOCK *x, int_mv *ref_mv, int_mv *best_mv,
int in_what_stride = xd->plane[0].pre[0].stride;
uint8_t *best_address;
- int_mv this_mv;
+ MV this_mv;
int bestsad = INT_MAX;
int ref_row, ref_col;
uint8_t *check_here;
int thissad;
- int_mv fcenter_mv;
+ MV fcenter_mv;
int *mvjsadcost = x->nmvjointsadcost;
int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]};
@@ -1098,16 +1098,15 @@ int vp9_full_range_search_c(MACROBLOCK *x, int_mv *ref_mv, int_mv *best_mv,
int start_row, end_row;
int i;
- fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
- fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
+ fcenter_mv.row = center_mv->row >> 3;
+ fcenter_mv.col = center_mv->col >> 3;
- clamp_mv(&ref_mv->as_mv,
- x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
- ref_row = ref_mv->as_mv.row;
- ref_col = ref_mv->as_mv.col;
+ clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
+ ref_row = ref_mv->row;
+ ref_col = ref_mv->col;
*num00 = 11;
- best_mv->as_mv.row = ref_row;
- best_mv->as_mv.col = ref_col;
+ best_mv->row = ref_row;
+ best_mv->col = ref_col;
// Work out the start point for the search
in_what = (uint8_t *)(xd->plane[0].pre[0].buf +
@@ -1116,7 +1115,7 @@ int vp9_full_range_search_c(MACROBLOCK *x, int_mv *ref_mv, int_mv *best_mv,
// Check the starting position
bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride, 0x7fffffff)
- + mvsad_err_cost(&best_mv->as_mv, &fcenter_mv.as_mv,
+ + mvsad_err_cost(best_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
start_row = MAX(-range, x->mv_row_min - ref_row);
@@ -1136,10 +1135,10 @@ int vp9_full_range_search_c(MACROBLOCK *x, int_mv *ref_mv, int_mv *best_mv,
for (i = 0; i < 4; ++i) {
if (sad_array[i] < bestsad) {
- this_mv.as_mv.row = ref_row + tr;
- this_mv.as_mv.col = ref_col + tc + i;
+ this_mv.row = ref_row + tr;
+ this_mv.col = ref_col + tc + i;
thissad = sad_array[i] +
- mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ mvsad_err_cost(&this_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (thissad < bestsad) {
bestsad = thissad;
@@ -1155,9 +1154,9 @@ int vp9_full_range_search_c(MACROBLOCK *x, int_mv *ref_mv, int_mv *best_mv,
bestsad);
if (thissad < bestsad) {
- this_mv.as_mv.row = ref_row + tr;
- this_mv.as_mv.col = ref_col + tc + i;
- thissad += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.row = ref_row + tr;
+ this_mv.col = ref_col + tc + i;
+ thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (thissad < bestsad) {
@@ -1171,26 +1170,26 @@ int vp9_full_range_search_c(MACROBLOCK *x, int_mv *ref_mv, int_mv *best_mv,
}
}
- best_mv->as_mv.row += best_tr;
- best_mv->as_mv.col += best_tc;
+ best_mv->row += best_tr;
+ best_mv->col += best_tc;
- this_mv.as_mv.row = best_mv->as_mv.row * 8;
- this_mv.as_mv.col = best_mv->as_mv.col * 8;
+ this_mv.row = best_mv->row * 8;
+ this_mv.col = best_mv->col * 8;
if (bestsad == INT_MAX)
return INT_MAX;
return fn_ptr->vf(what, what_stride, best_address, in_what_stride,
(unsigned int *)(&thissad)) +
- mv_err_cost(&this_mv.as_mv, &center_mv->as_mv,
+ mv_err_cost(&this_mv, center_mv,
mvjcost, mvcost, x->errorperbit);
}
int vp9_diamond_search_sad_c(MACROBLOCK *x,
- int_mv *ref_mv, int_mv *best_mv,
+ MV *ref_mv, MV *best_mv,
int search_param, int sad_per_bit, int *num00,
vp9_variance_fn_ptr_t *fn_ptr, int *mvjcost,
- int *mvcost[2], int_mv *center_mv) {
+ int *mvcost[2], const MV *center_mv) {
int i, j, step;
const MACROBLOCKD* const xd = &x->e_mbd;
@@ -1201,7 +1200,7 @@ int vp9_diamond_search_sad_c(MACROBLOCK *x,
uint8_t *best_address;
int tot_steps;
- int_mv this_mv;
+ MV this_mv;
int bestsad = INT_MAX;
int best_site = 0;
@@ -1218,16 +1217,15 @@ int vp9_diamond_search_sad_c(MACROBLOCK *x,
int *mvjsadcost = x->nmvjointsadcost;
int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]};
- fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
- fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
+ fcenter_mv.as_mv.row = center_mv->row >> 3;
+ fcenter_mv.as_mv.col = center_mv->col >> 3;
- clamp_mv(&ref_mv->as_mv,
- x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
- ref_row = ref_mv->as_mv.row;
- ref_col = ref_mv->as_mv.col;
+ clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
+ ref_row = ref_mv->row;
+ ref_col = ref_mv->col;
*num00 = 0;
- best_mv->as_mv.row = ref_row;
- best_mv->as_mv.col = ref_col;
+ best_mv->row = ref_row;
+ best_mv->col = ref_col;
// Work out the start point for the search
in_what = (uint8_t *)(xd->plane[0].pre[0].buf +
@@ -1236,7 +1234,7 @@ int vp9_diamond_search_sad_c(MACROBLOCK *x,
// Check the starting position
bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride, 0x7fffffff)
- + mvsad_err_cost(&best_mv->as_mv, &fcenter_mv.as_mv,
+ + mvsad_err_cost(best_mv, &fcenter_mv.as_mv,
mvjsadcost, mvsadcost, sad_per_bit);
// search_param determines the length of the initial step and hence the number
@@ -1251,8 +1249,8 @@ int vp9_diamond_search_sad_c(MACROBLOCK *x,
for (step = 0; step < tot_steps; step++) {
for (j = 0; j < x->searches_per_step; j++) {
// Trap illegal vectors
- this_row_offset = best_mv->as_mv.row + ss[i].mv.row;
- this_col_offset = best_mv->as_mv.col + ss[i].mv.col;
+ this_row_offset = best_mv->row + ss[i].mv.row;
+ this_col_offset = best_mv->col + ss[i].mv.col;
if ((this_col_offset > x->mv_col_min) &&
(this_col_offset < x->mv_col_max) &&
@@ -1263,9 +1261,9 @@ int vp9_diamond_search_sad_c(MACROBLOCK *x,
bestsad);
if (thissad < bestsad) {
- this_mv.as_mv.row = this_row_offset;
- this_mv.as_mv.col = this_col_offset;
- thissad += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.row = this_row_offset;
+ this_mv.col = this_col_offset;
+ thissad += mvsad_err_cost(&this_mv, &fcenter_mv.as_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (thissad < bestsad) {
@@ -1279,14 +1277,14 @@ int vp9_diamond_search_sad_c(MACROBLOCK *x,
}
if (best_site != last_site) {
- best_mv->as_mv.row += ss[best_site].mv.row;
- best_mv->as_mv.col += ss[best_site].mv.col;
+ best_mv->row += ss[best_site].mv.row;
+ best_mv->col += ss[best_site].mv.col;
best_address += ss[best_site].offset;
last_site = best_site;
#if defined(NEW_DIAMOND_SEARCH)
while (1) {
- this_row_offset = best_mv->as_mv.row + ss[best_site].mv.row;
- this_col_offset = best_mv->as_mv.col + ss[best_site].mv.col;
+ this_row_offset = best_mv->row + ss[best_site].mv.row;
+ this_col_offset = best_mv->col + ss[best_site].mv.col;
if ((this_col_offset > x->mv_col_min) &&
(this_col_offset < x->mv_col_max) &&
(this_row_offset > x->mv_row_min) &&
@@ -1295,14 +1293,14 @@ int vp9_diamond_search_sad_c(MACROBLOCK *x,
thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride,
bestsad);
if (thissad < bestsad) {
- this_mv.as_mv.row = this_row_offset;
- this_mv.as_mv.col = this_col_offset;
- thissad += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.row = this_row_offset;
+ this_mv.col = this_col_offset;
+ thissad += mvsad_err_cost(&this_mv, &fcenter_mv.as_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (thissad < bestsad) {
bestsad = thissad;
- best_mv->as_mv.row += ss[best_site].mv.row;
- best_mv->as_mv.col += ss[best_site].mv.col;
+ best_mv->row += ss[best_site].mv.row;
+ best_mv->col += ss[best_site].mv.col;
best_address += ss[best_site].offset;
continue;
}
@@ -1316,23 +1314,24 @@ int vp9_diamond_search_sad_c(MACROBLOCK *x,
}
}
- this_mv.as_mv.row = best_mv->as_mv.row * 8;
- this_mv.as_mv.col = best_mv->as_mv.col * 8;
+ this_mv.row = best_mv->row * 8;
+ this_mv.col = best_mv->col * 8;
if (bestsad == INT_MAX)
return INT_MAX;
return fn_ptr->vf(what, what_stride, best_address, in_what_stride,
(unsigned int *)(&thissad)) +
- mv_err_cost(&this_mv.as_mv, &center_mv->as_mv,
+ mv_err_cost(&this_mv, center_mv,
mvjcost, mvcost, x->errorperbit);
}
int vp9_diamond_search_sadx4(MACROBLOCK *x,
- int_mv *ref_mv, int_mv *best_mv, int search_param,
+ MV *ref_mv, MV *best_mv, int search_param,
int sad_per_bit, int *num00,
vp9_variance_fn_ptr_t *fn_ptr,
- int *mvjcost, int *mvcost[2], int_mv *center_mv) {
+ int *mvjcost, int *mvcost[2],
+ const MV *center_mv) {
int i, j, step;
const MACROBLOCKD* const xd = &x->e_mbd;
@@ -1343,7 +1342,7 @@ int vp9_diamond_search_sadx4(MACROBLOCK *x,
uint8_t *best_address;
int tot_steps;
- int_mv this_mv;
+ MV this_mv;
unsigned int bestsad = INT_MAX;
int best_site = 0;
@@ -1362,16 +1361,15 @@ int vp9_diamond_search_sadx4(MACROBLOCK *x,
int *mvjsadcost = x->nmvjointsadcost;
int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]};
- fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
- fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
+ fcenter_mv.as_mv.row = center_mv->row >> 3;
+ fcenter_mv.as_mv.col = center_mv->col >> 3;
- clamp_mv(&ref_mv->as_mv,
- x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
- ref_row = ref_mv->as_mv.row;
- ref_col = ref_mv->as_mv.col;
+ clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
+ ref_row = ref_mv->row;
+ ref_col = ref_mv->col;
*num00 = 0;
- best_mv->as_mv.row = ref_row;
- best_mv->as_mv.col = ref_col;
+ best_mv->row = ref_row;
+ best_mv->col = ref_col;
// Work out the start point for the search
in_what = (uint8_t *)(xd->plane[0].pre[0].buf +
@@ -1380,7 +1378,7 @@ int vp9_diamond_search_sadx4(MACROBLOCK *x,
// Check the starting position
bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride, 0x7fffffff)
- + mvsad_err_cost(&best_mv->as_mv, &fcenter_mv.as_mv,
+ + mvsad_err_cost(best_mv, &fcenter_mv.as_mv,
mvjsadcost, mvsadcost, sad_per_bit);
// search_param determines the length of the initial step and hence the number
@@ -1398,10 +1396,10 @@ int vp9_diamond_search_sadx4(MACROBLOCK *x,
// All_in is true if every one of the points we are checking are within
// the bounds of the image.
- all_in &= ((best_mv->as_mv.row + ss[i].mv.row) > x->mv_row_min);
- all_in &= ((best_mv->as_mv.row + ss[i + 1].mv.row) < x->mv_row_max);
- all_in &= ((best_mv->as_mv.col + ss[i + 2].mv.col) > x->mv_col_min);
- all_in &= ((best_mv->as_mv.col + ss[i + 3].mv.col) < x->mv_col_max);
+ all_in &= ((best_mv->row + ss[i].mv.row) > x->mv_row_min);
+ all_in &= ((best_mv->row + ss[i + 1].mv.row) < x->mv_row_max);
+ all_in &= ((best_mv->col + ss[i + 2].mv.col) > x->mv_col_min);
+ all_in &= ((best_mv->col + ss[i + 3].mv.col) < x->mv_col_max);
// If all the pixels are within the bounds we don't check whether the
// search point is valid in this loop, otherwise we check each point
@@ -1420,9 +1418,9 @@ int vp9_diamond_search_sadx4(MACROBLOCK *x,
for (t = 0; t < 4; t++, i++) {
if (sad_array[t] < bestsad) {
- this_mv.as_mv.row = best_mv->as_mv.row + ss[i].mv.row;
- this_mv.as_mv.col = best_mv->as_mv.col + ss[i].mv.col;
- sad_array[t] += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.row = best_mv->row + ss[i].mv.row;
+ this_mv.col = best_mv->col + ss[i].mv.col;
+ sad_array[t] += mvsad_err_cost(&this_mv, &fcenter_mv.as_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (sad_array[t] < bestsad) {
@@ -1435,8 +1433,8 @@ int vp9_diamond_search_sadx4(MACROBLOCK *x,
} else {
for (j = 0; j < x->searches_per_step; j++) {
// Trap illegal vectors
- this_row_offset = best_mv->as_mv.row + ss[i].mv.row;
- this_col_offset = best_mv->as_mv.col + ss[i].mv.col;
+ this_row_offset = best_mv->row + ss[i].mv.row;
+ this_col_offset = best_mv->col + ss[i].mv.col;
if ((this_col_offset > x->mv_col_min) &&
(this_col_offset < x->mv_col_max) &&
@@ -1447,9 +1445,9 @@ int vp9_diamond_search_sadx4(MACROBLOCK *x,
bestsad);
if (thissad < bestsad) {
- this_mv.as_mv.row = this_row_offset;
- this_mv.as_mv.col = this_col_offset;
- thissad += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.row = this_row_offset;
+ this_mv.col = this_col_offset;
+ thissad += mvsad_err_cost(&this_mv, &fcenter_mv.as_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (thissad < bestsad) {
@@ -1462,14 +1460,14 @@ int vp9_diamond_search_sadx4(MACROBLOCK *x,
}
}
if (best_site != last_site) {
- best_mv->as_mv.row += ss[best_site].mv.row;
- best_mv->as_mv.col += ss[best_site].mv.col;
+ best_mv->row += ss[best_site].mv.row;
+ best_mv->col += ss[best_site].mv.col;
best_address += ss[best_site].offset;
last_site = best_site;
#if defined(NEW_DIAMOND_SEARCH)
while (1) {
- this_row_offset = best_mv->as_mv.row + ss[best_site].mv.row;
- this_col_offset = best_mv->as_mv.col + ss[best_site].mv.col;
+ this_row_offset = best_mv->row + ss[best_site].mv.row;
+ this_col_offset = best_mv->col + ss[best_site].mv.col;
if ((this_col_offset > x->mv_col_min) &&
(this_col_offset < x->mv_col_max) &&
(this_row_offset > x->mv_row_min) &&
@@ -1478,14 +1476,14 @@ int vp9_diamond_search_sadx4(MACROBLOCK *x,
thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride,
bestsad);
if (thissad < bestsad) {
- this_mv.as_mv.row = this_row_offset;
- this_mv.as_mv.col = this_col_offset;
- thissad += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.row = this_row_offset;
+ this_mv.col = this_col_offset;
+ thissad += mvsad_err_cost(&this_mv, &fcenter_mv.as_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (thissad < bestsad) {
bestsad = thissad;
- best_mv->as_mv.row += ss[best_site].mv.row;
- best_mv->as_mv.col += ss[best_site].mv.col;
+ best_mv->row += ss[best_site].mv.row;
+ best_mv->col += ss[best_site].mv.col;
best_address += ss[best_site].offset;
continue;
}
@@ -1499,15 +1497,15 @@ int vp9_diamond_search_sadx4(MACROBLOCK *x,
}
}
- this_mv.as_mv.row = best_mv->as_mv.row * 8;
- this_mv.as_mv.col = best_mv->as_mv.col * 8;
+ this_mv.row = best_mv->row * 8;
+ this_mv.col = best_mv->col * 8;
if (bestsad == INT_MAX)
return INT_MAX;
return fn_ptr->vf(what, what_stride, best_address, in_what_stride,
(unsigned int *)(&thissad)) +
- mv_err_cost(&this_mv.as_mv, &center_mv->as_mv,
+ mv_err_cost(&this_mv, center_mv,
mvjcost, mvcost, x->errorperbit);
}
@@ -1522,10 +1520,10 @@ int vp9_full_pixel_diamond(VP9_COMP *cpi, MACROBLOCK *x,
int_mv *ref_mv, int_mv *dst_mv) {
int_mv temp_mv;
int thissme, n, num00;
- int bestsme = cpi->diamond_search_sad(x, mvp_full, &temp_mv,
+ int bestsme = cpi->diamond_search_sad(x, &mvp_full->as_mv, &temp_mv.as_mv,
step_param, sadpb, &num00,
fn_ptr, x->nmvjointcost,
- x->mvcost, ref_mv);
+ x->mvcost, &ref_mv->as_mv);
dst_mv->as_int = temp_mv.as_int;
n = num00;
@@ -1542,10 +1540,10 @@ int vp9_full_pixel_diamond(VP9_COMP *cpi, MACROBLOCK *x,
if (num00) {
num00--;
} else {
- thissme = cpi->diamond_search_sad(x, mvp_full, &temp_mv,
+ thissme = cpi->diamond_search_sad(x, &mvp_full->as_mv, &temp_mv.as_mv,
step_param + n, sadpb, &num00,
fn_ptr, x->nmvjointcost, x->mvcost,
- ref_mv);
+ &ref_mv->as_mv);
/* check to see if refining search is needed. */
if (num00 > (further_steps - n))
@@ -1563,9 +1561,9 @@ int vp9_full_pixel_diamond(VP9_COMP *cpi, MACROBLOCK *x,
int search_range = 8;
int_mv best_mv;
best_mv.as_int = dst_mv->as_int;
- thissme = cpi->refining_search_sad(x, &best_mv, sadpb, search_range,
+ thissme = cpi->refining_search_sad(x, &best_mv.as_mv, sadpb, search_range,
fn_ptr, x->nmvjointcost, x->mvcost,
- ref_mv);
+ &ref_mv->as_mv);
if (thissme < bestsme) {
bestsme = thissme;
@@ -1575,11 +1573,11 @@ int vp9_full_pixel_diamond(VP9_COMP *cpi, MACROBLOCK *x,
return bestsme;
}
-int vp9_full_search_sad_c(MACROBLOCK *x, int_mv *ref_mv,
+int vp9_full_search_sad_c(MACROBLOCK *x, MV *ref_mv,
int sad_per_bit, int distance,
vp9_variance_fn_ptr_t *fn_ptr, int *mvjcost,
int *mvcost[2],
- int_mv *center_mv, int n) {
+ const MV *center_mv, int n) {
const MACROBLOCKD* const xd = &x->e_mbd;
uint8_t *what = x->plane[0].src.buf;
int what_stride = x->plane[0].src.stride;
@@ -1588,27 +1586,27 @@ int vp9_full_search_sad_c(MACROBLOCK *x, int_mv *ref_mv,
int mv_stride = xd->plane[0].pre[0].stride;
uint8_t *bestaddress;
int_mv *best_mv = &x->e_mbd.mi_8x8[0]->bmi[n].as_mv[0];
- int_mv this_mv;
+ MV this_mv;
int bestsad = INT_MAX;
int r, c;
uint8_t *check_here;
int thissad;
- int ref_row = ref_mv->as_mv.row;
- int ref_col = ref_mv->as_mv.col;
+ int ref_row = ref_mv->row;
+ int ref_col = ref_mv->col;
int row_min = ref_row - distance;
int row_max = ref_row + distance;
int col_min = ref_col - distance;
int col_max = ref_col + distance;
- int_mv fcenter_mv;
+ MV fcenter_mv;
int *mvjsadcost = x->nmvjointsadcost;
int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]};
- fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
- fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
+ fcenter_mv.row = center_mv->row >> 3;
+ fcenter_mv.col = center_mv->col >> 3;
// Work out the mid point for the search
in_what = xd->plane[0].pre[0].buf;
@@ -1620,7 +1618,7 @@ int vp9_full_search_sad_c(MACROBLOCK *x, int_mv *ref_mv,
// Baseline value at the centre
bestsad = fn_ptr->sdf(what, what_stride, bestaddress,
in_what_stride, 0x7fffffff)
- + mvsad_err_cost(&best_mv->as_mv, &fcenter_mv.as_mv,
+ + mvsad_err_cost(&best_mv->as_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
// Apply further limits to prevent us looking using vectors that stretch
@@ -1631,15 +1629,15 @@ int vp9_full_search_sad_c(MACROBLOCK *x, int_mv *ref_mv,
row_max = MIN(row_max, x->mv_row_max);
for (r = row_min; r < row_max; r++) {
- this_mv.as_mv.row = r;
+ this_mv.row = r;
check_here = r * mv_stride + in_what + col_min;
for (c = col_min; c < col_max; c++) {
thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride,
bestsad);
- this_mv.as_mv.col = c;
- thissad += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.col = c;
+ thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (thissad < bestsad) {
@@ -1653,22 +1651,22 @@ int vp9_full_search_sad_c(MACROBLOCK *x, int_mv *ref_mv,
}
}
- this_mv.as_mv.row = best_mv->as_mv.row * 8;
- this_mv.as_mv.col = best_mv->as_mv.col * 8;
+ this_mv.row = best_mv->as_mv.row * 8;
+ this_mv.col = best_mv->as_mv.col * 8;
if (bestsad < INT_MAX)
return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride,
(unsigned int *)(&thissad)) +
- mv_err_cost(&this_mv.as_mv, &center_mv->as_mv,
+ mv_err_cost(&this_mv, center_mv,
mvjcost, mvcost, x->errorperbit);
else
return INT_MAX;
}
-int vp9_full_search_sadx3(MACROBLOCK *x, int_mv *ref_mv,
+int vp9_full_search_sadx3(MACROBLOCK *x, MV *ref_mv,
int sad_per_bit, int distance,
vp9_variance_fn_ptr_t *fn_ptr, int *mvjcost,
- int *mvcost[2], int_mv *center_mv, int n) {
+ int *mvcost[2], const MV *center_mv, int n) {
const MACROBLOCKD* const xd = &x->e_mbd;
uint8_t *what = x->plane[0].src.buf;
int what_stride = x->plane[0].src.stride;
@@ -1677,15 +1675,15 @@ int vp9_full_search_sadx3(MACROBLOCK *x, int_mv *ref_mv,
int mv_stride = xd->plane[0].pre[0].stride;
uint8_t *bestaddress;
int_mv *best_mv = &x->e_mbd.mi_8x8[0]->bmi[n].as_mv[0];
- int_mv this_mv;
+ MV this_mv;
unsigned int bestsad = INT_MAX;
int r, c;
uint8_t *check_here;
unsigned int thissad;
- int ref_row = ref_mv->as_mv.row;
- int ref_col = ref_mv->as_mv.col;
+ int ref_row = ref_mv->row;
+ int ref_col = ref_mv->col;
int row_min = ref_row - distance;
int row_max = ref_row + distance;
@@ -1693,13 +1691,13 @@ int vp9_full_search_sadx3(MACROBLOCK *x, int_mv *ref_mv,
int col_max = ref_col + distance;
unsigned int sad_array[3];
- int_mv fcenter_mv;
+ MV fcenter_mv;
int *mvjsadcost = x->nmvjointsadcost;
int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]};
- fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
- fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
+ fcenter_mv.row = center_mv->row >> 3;
+ fcenter_mv.col = center_mv->col >> 3;
// Work out the mid point for the search
in_what = xd->plane[0].pre[0].buf;
@@ -1711,7 +1709,7 @@ int vp9_full_search_sadx3(MACROBLOCK *x, int_mv *ref_mv,
// Baseline value at the centre
bestsad = fn_ptr->sdf(what, what_stride,
bestaddress, in_what_stride, 0x7fffffff)
- + mvsad_err_cost(&best_mv->as_mv, &fcenter_mv.as_mv,
+ + mvsad_err_cost(&best_mv->as_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
// Apply further limits to prevent us looking using vectors that stretch
@@ -1722,7 +1720,7 @@ int vp9_full_search_sadx3(MACROBLOCK *x, int_mv *ref_mv,
row_max = MIN(row_max, x->mv_row_max);
for (r = row_min; r < row_max; r++) {
- this_mv.as_mv.row = r;
+ this_mv.row = r;
check_here = r * mv_stride + in_what + col_min;
c = col_min;
@@ -1735,8 +1733,8 @@ int vp9_full_search_sadx3(MACROBLOCK *x, int_mv *ref_mv,
thissad = sad_array[i];
if (thissad < bestsad) {
- this_mv.as_mv.col = c;
- thissad += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.col = c;
+ thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (thissad < bestsad) {
@@ -1757,8 +1755,8 @@ int vp9_full_search_sadx3(MACROBLOCK *x, int_mv *ref_mv,
bestsad);
if (thissad < bestsad) {
- this_mv.as_mv.col = c;
- thissad += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.col = c;
+ thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (thissad < bestsad) {
@@ -1774,23 +1772,23 @@ int vp9_full_search_sadx3(MACROBLOCK *x, int_mv *ref_mv,
}
}
- this_mv.as_mv.row = best_mv->as_mv.row * 8;
- this_mv.as_mv.col = best_mv->as_mv.col * 8;
+ this_mv.row = best_mv->as_mv.row * 8;
+ this_mv.col = best_mv->as_mv.col * 8;
if (bestsad < INT_MAX)
return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride,
(unsigned int *)(&thissad)) +
- mv_err_cost(&this_mv.as_mv, &center_mv->as_mv,
+ mv_err_cost(&this_mv, center_mv,
mvjcost, mvcost, x->errorperbit);
else
return INT_MAX;
}
-int vp9_full_search_sadx8(MACROBLOCK *x, int_mv *ref_mv,
+int vp9_full_search_sadx8(MACROBLOCK *x, MV *ref_mv,
int sad_per_bit, int distance,
vp9_variance_fn_ptr_t *fn_ptr,
int *mvjcost, int *mvcost[2],
- int_mv *center_mv, int n) {
+ const MV *center_mv, int n) {
const MACROBLOCKD* const xd = &x->e_mbd;
uint8_t *what = x->plane[0].src.buf;
int what_stride = x->plane[0].src.stride;
@@ -1799,15 +1797,15 @@ int vp9_full_search_sadx8(MACROBLOCK *x, int_mv *ref_mv,
int mv_stride = xd->plane[0].pre[0].stride;
uint8_t *bestaddress;
int_mv *best_mv = &x->e_mbd.mi_8x8[0]->bmi[n].as_mv[0];
- int_mv this_mv;
+ MV this_mv;
unsigned int bestsad = INT_MAX;
int r, c;
uint8_t *check_here;
unsigned int thissad;
- int ref_row = ref_mv->as_mv.row;
- int ref_col = ref_mv->as_mv.col;
+ int ref_row = ref_mv->row;
+ int ref_col = ref_mv->col;
int row_min = ref_row - distance;
int row_max = ref_row + distance;
@@ -1816,13 +1814,13 @@ int vp9_full_search_sadx8(MACROBLOCK *x, int_mv *ref_mv,
DECLARE_ALIGNED_ARRAY(16, uint32_t, sad_array8, 8);
unsigned int sad_array[3];
- int_mv fcenter_mv;
+ MV fcenter_mv;
int *mvjsadcost = x->nmvjointsadcost;
int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]};
- fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
- fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
+ fcenter_mv.row = center_mv->row >> 3;
+ fcenter_mv.col = center_mv->col >> 3;
// Work out the mid point for the search
in_what = xd->plane[0].pre[0].buf;
@@ -1834,7 +1832,7 @@ int vp9_full_search_sadx8(MACROBLOCK *x, int_mv *ref_mv,
// Baseline value at the centre
bestsad = fn_ptr->sdf(what, what_stride,
bestaddress, in_what_stride, 0x7fffffff)
- + mvsad_err_cost(&best_mv->as_mv, &fcenter_mv.as_mv,
+ + mvsad_err_cost(&best_mv->as_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
// Apply further limits to prevent us looking using vectors that stretch
@@ -1845,7 +1843,7 @@ int vp9_full_search_sadx8(MACROBLOCK *x, int_mv *ref_mv,
row_max = MIN(row_max, x->mv_row_max);
for (r = row_min; r < row_max; r++) {
- this_mv.as_mv.row = r;
+ this_mv.row = r;
check_here = r * mv_stride + in_what + col_min;
c = col_min;
@@ -1858,8 +1856,8 @@ int vp9_full_search_sadx8(MACROBLOCK *x, int_mv *ref_mv,
thissad = (unsigned int)sad_array8[i];
if (thissad < bestsad) {
- this_mv.as_mv.col = c;
- thissad += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.col = c;
+ thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (thissad < bestsad) {
@@ -1884,8 +1882,8 @@ int vp9_full_search_sadx8(MACROBLOCK *x, int_mv *ref_mv,
thissad = sad_array[i];
if (thissad < bestsad) {
- this_mv.as_mv.col = c;
- thissad += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.col = c;
+ thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (thissad < bestsad) {
@@ -1906,8 +1904,8 @@ int vp9_full_search_sadx8(MACROBLOCK *x, int_mv *ref_mv,
bestsad);
if (thissad < bestsad) {
- this_mv.as_mv.col = c;
- thissad += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.col = c;
+ thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (thissad < bestsad) {
@@ -1923,21 +1921,22 @@ int vp9_full_search_sadx8(MACROBLOCK *x, int_mv *ref_mv,
}
}
- this_mv.as_mv.row = best_mv->as_mv.row * 8;
- this_mv.as_mv.col = best_mv->as_mv.col * 8;
+ this_mv.row = best_mv->as_mv.row * 8;
+ this_mv.col = best_mv->as_mv.col * 8;
if (bestsad < INT_MAX)
return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride,
(unsigned int *)(&thissad)) +
- mv_err_cost(&this_mv.as_mv, &center_mv->as_mv,
+ mv_err_cost(&this_mv, center_mv,
mvjcost, mvcost, x->errorperbit);
else
return INT_MAX;
}
int vp9_refining_search_sad_c(MACROBLOCK *x,
- int_mv *ref_mv, int error_per_bit,
+ MV *ref_mv, int error_per_bit,
int search_range, vp9_variance_fn_ptr_t *fn_ptr,
- int *mvjcost, int *mvcost[2], int_mv *center_mv) {
+ int *mvjcost, int *mvcost[2],
+ const MV *center_mv) {
const MACROBLOCKD* const xd = &x->e_mbd;
MV neighbors[4] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}};
int i, j;
@@ -1947,31 +1946,31 @@ int vp9_refining_search_sad_c(MACROBLOCK *x,
int in_what_stride = xd->plane[0].pre[0].stride;
uint8_t *what = x->plane[0].src.buf;
uint8_t *best_address = xd->plane[0].pre[0].buf +
- (ref_mv->as_mv.row * xd->plane[0].pre[0].stride) +
- ref_mv->as_mv.col;
+ (ref_mv->row * xd->plane[0].pre[0].stride) +
+ ref_mv->col;
uint8_t *check_here;
unsigned int thissad;
- int_mv this_mv;
+ MV this_mv;
unsigned int bestsad = INT_MAX;
- int_mv fcenter_mv;
+ MV fcenter_mv;
int *mvjsadcost = x->nmvjointsadcost;
int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]};
- fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
- fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
+ fcenter_mv.row = center_mv->row >> 3;
+ fcenter_mv.col = center_mv->col >> 3;
bestsad = fn_ptr->sdf(what, what_stride, best_address,
in_what_stride, 0x7fffffff) +
- mvsad_err_cost(&ref_mv->as_mv, &fcenter_mv.as_mv,
+ mvsad_err_cost(ref_mv, &fcenter_mv,
mvjsadcost, mvsadcost, error_per_bit);
for (i = 0; i < search_range; i++) {
int best_site = -1;
for (j = 0; j < 4; j++) {
- this_row_offset = ref_mv->as_mv.row + neighbors[j].row;
- this_col_offset = ref_mv->as_mv.col + neighbors[j].col;
+ this_row_offset = ref_mv->row + neighbors[j].row;
+ this_col_offset = ref_mv->col + neighbors[j].col;
if ((this_col_offset > x->mv_col_min) &&
(this_col_offset < x->mv_col_max) &&
@@ -1983,9 +1982,9 @@ int vp9_refining_search_sad_c(MACROBLOCK *x,
bestsad);
if (thissad < bestsad) {
- this_mv.as_mv.row = this_row_offset;
- this_mv.as_mv.col = this_col_offset;
- thissad += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.row = this_row_offset;
+ this_mv.col = this_col_offset;
+ thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
mvjsadcost, mvsadcost, error_per_bit);
if (thissad < bestsad) {
@@ -1999,29 +1998,30 @@ int vp9_refining_search_sad_c(MACROBLOCK *x,
if (best_site == -1) {
break;
} else {
- ref_mv->as_mv.row += neighbors[best_site].row;
- ref_mv->as_mv.col += neighbors[best_site].col;
+ ref_mv->row += neighbors[best_site].row;
+ ref_mv->col += neighbors[best_site].col;
best_address += (neighbors[best_site].row) * in_what_stride +
neighbors[best_site].col;
}
}
- this_mv.as_mv.row = ref_mv->as_mv.row * 8;
- this_mv.as_mv.col = ref_mv->as_mv.col * 8;
+ this_mv.row = ref_mv->row * 8;
+ this_mv.col = ref_mv->col * 8;
if (bestsad < INT_MAX)
return fn_ptr->vf(what, what_stride, best_address, in_what_stride,
(unsigned int *)(&thissad)) +
- mv_err_cost(&this_mv.as_mv, &center_mv->as_mv,
+ mv_err_cost(&this_mv, center_mv,
mvjcost, mvcost, x->errorperbit);
else
return INT_MAX;
}
int vp9_refining_search_sadx4(MACROBLOCK *x,
- int_mv *ref_mv, int error_per_bit,
+ MV *ref_mv, int error_per_bit,
int search_range, vp9_variance_fn_ptr_t *fn_ptr,
- int *mvjcost, int *mvcost[2], int_mv *center_mv) {
+ int *mvjcost, int *mvcost[2],
+ const MV *center_mv) {
const MACROBLOCKD* const xd = &x->e_mbd;
MV neighbors[4] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}};
int i, j;
@@ -2031,31 +2031,31 @@ int vp9_refining_search_sadx4(MACROBLOCK *x,
int in_what_stride = xd->plane[0].pre[0].stride;
uint8_t *what = x->plane[0].src.buf;
uint8_t *best_address = xd->plane[0].pre[0].buf +
- (ref_mv->as_mv.row * xd->plane[0].pre[0].stride) +
- ref_mv->as_mv.col;
+ (ref_mv->row * xd->plane[0].pre[0].stride) +
+ ref_mv->col;
uint8_t *check_here;
unsigned int thissad;
- int_mv this_mv;
+ MV this_mv;
unsigned int bestsad = INT_MAX;
- int_mv fcenter_mv;
+ MV fcenter_mv;
int *mvjsadcost = x->nmvjointsadcost;
int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]};
- fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
- fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
+ fcenter_mv.row = center_mv->row >> 3;
+ fcenter_mv.col = center_mv->col >> 3;
bestsad = fn_ptr->sdf(what, what_stride, best_address,
in_what_stride, 0x7fffffff) +
- mvsad_err_cost(&ref_mv->as_mv, &fcenter_mv.as_mv,
+ mvsad_err_cost(ref_mv, &fcenter_mv,
mvjsadcost, mvsadcost, error_per_bit);
for (i = 0; i < search_range; i++) {
int best_site = -1;
- int all_in = ((ref_mv->as_mv.row - 1) > x->mv_row_min) &
- ((ref_mv->as_mv.row + 1) < x->mv_row_max) &
- ((ref_mv->as_mv.col - 1) > x->mv_col_min) &
- ((ref_mv->as_mv.col + 1) < x->mv_col_max);
+ int all_in = ((ref_mv->row - 1) > x->mv_row_min) &
+ ((ref_mv->row + 1) < x->mv_row_max) &
+ ((ref_mv->col - 1) > x->mv_col_min) &
+ ((ref_mv->col + 1) < x->mv_col_max);
if (all_in) {
unsigned int sad_array[4];
@@ -2070,9 +2070,9 @@ int vp9_refining_search_sadx4(MACROBLOCK *x,
for (j = 0; j < 4; j++) {
if (sad_array[j] < bestsad) {
- this_mv.as_mv.row = ref_mv->as_mv.row + neighbors[j].row;
- this_mv.as_mv.col = ref_mv->as_mv.col + neighbors[j].col;
- sad_array[j] += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.row = ref_mv->row + neighbors[j].row;
+ this_mv.col = ref_mv->col + neighbors[j].col;
+ sad_array[j] += mvsad_err_cost(&this_mv, &fcenter_mv,
mvjsadcost, mvsadcost, error_per_bit);
if (sad_array[j] < bestsad) {
@@ -2083,8 +2083,8 @@ int vp9_refining_search_sadx4(MACROBLOCK *x,
}
} else {
for (j = 0; j < 4; j++) {
- this_row_offset = ref_mv->as_mv.row + neighbors[j].row;
- this_col_offset = ref_mv->as_mv.col + neighbors[j].col;
+ this_row_offset = ref_mv->row + neighbors[j].row;
+ this_col_offset = ref_mv->col + neighbors[j].col;
if ((this_col_offset > x->mv_col_min) &&
(this_col_offset < x->mv_col_max) &&
@@ -2096,9 +2096,9 @@ int vp9_refining_search_sadx4(MACROBLOCK *x,
bestsad);
if (thissad < bestsad) {
- this_mv.as_mv.row = this_row_offset;
- this_mv.as_mv.col = this_col_offset;
- thissad += mvsad_err_cost(&this_mv.as_mv, &fcenter_mv.as_mv,
+ this_mv.row = this_row_offset;
+ this_mv.col = this_col_offset;
+ thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
mvjsadcost, mvsadcost, error_per_bit);
if (thissad < bestsad) {
@@ -2113,20 +2113,20 @@ int vp9_refining_search_sadx4(MACROBLOCK *x,
if (best_site == -1) {
break;
} else {
- ref_mv->as_mv.row += neighbors[best_site].row;
- ref_mv->as_mv.col += neighbors[best_site].col;
+ ref_mv->row += neighbors[best_site].row;
+ ref_mv->col += neighbors[best_site].col;
best_address += (neighbors[best_site].row) * in_what_stride +
neighbors[best_site].col;
}
}
- this_mv.as_mv.row = ref_mv->as_mv.row * 8;
- this_mv.as_mv.col = ref_mv->as_mv.col * 8;
+ this_mv.row = ref_mv->row * 8;
+ this_mv.col = ref_mv->col * 8;
if (bestsad < INT_MAX)
return fn_ptr->vf(what, what_stride, best_address, in_what_stride,
(unsigned int *)(&thissad)) +
- mv_err_cost(&this_mv.as_mv, &center_mv->as_mv,
+ mv_err_cost(&this_mv, center_mv,
mvjcost, mvcost, x->errorperbit);
else
return INT_MAX;
diff --git a/vp9/encoder/vp9_mcomp.h b/vp9/encoder/vp9_mcomp.h
index 10c2e4fca..c574e61ab 100644
--- a/vp9/encoder/vp9_mcomp.h
+++ b/vp9/encoder/vp9_mcomp.h
@@ -28,7 +28,7 @@
#define BORDER_MV_PIXELS_B16 (16 + VP9_INTERP_EXTEND)
-void vp9_clamp_mv_min_max(MACROBLOCK *x, MV *mv);
+void vp9_set_mv_search_range(MACROBLOCK *x, MV *mv);
int vp9_mv_bit_cost(const MV *mv, const MV *ref,
const int *mvjcost, int *mvcost[2], int weight);
void vp9_init_dsmotion_compensation(MACROBLOCK *x, int stride);
@@ -103,25 +103,25 @@ extern fractional_mv_step_comp_fp vp9_find_best_sub_pixel_comp_iterative;
extern fractional_mv_step_comp_fp vp9_find_best_sub_pixel_comp_tree;
typedef int (*vp9_full_search_fn_t)(MACROBLOCK *x,
- int_mv *ref_mv, int sad_per_bit,
+ MV *ref_mv, int sad_per_bit,
int distance, vp9_variance_fn_ptr_t *fn_ptr,
int *mvjcost, int *mvcost[2],
- int_mv *center_mv, int n);
+ const MV *center_mv, int n);
typedef int (*vp9_refining_search_fn_t)(MACROBLOCK *x,
- int_mv *ref_mv, int sad_per_bit,
+ MV *ref_mv, int sad_per_bit,
int distance,
vp9_variance_fn_ptr_t *fn_ptr,
int *mvjcost, int *mvcost[2],
- int_mv *center_mv);
+ const MV *center_mv);
typedef int (*vp9_diamond_search_fn_t)(MACROBLOCK *x,
- int_mv *ref_mv, int_mv *best_mv,
+ MV *ref_mv, MV *best_mv,
int search_param, int sad_per_bit,
int *num00,
vp9_variance_fn_ptr_t *fn_ptr,
int *mvjcost, int *mvcost[2],
- int_mv *center_mv);
+ const MV *center_mv);
int vp9_refining_search_8p_c(MACROBLOCK *x,
int_mv *ref_mv, int error_per_bit,
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index fac074adb..9747eb5a2 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -654,6 +654,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->tx_size_search_method = USE_FULL_RD;
sf->use_lp32x32fdct = 0;
sf->adaptive_motion_search = 0;
+ sf->adaptive_pred_filter_type = 0;
sf->use_avoid_tested_higherror = 0;
sf->reference_masking = 0;
sf->use_one_partition_size_always = 0;
@@ -717,6 +718,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->use_rd_breakout = 1;
sf->adaptive_motion_search = 1;
+ sf->adaptive_pred_filter_type = 1;
sf->auto_mv_step_size = 1;
sf->adaptive_rd_thresh = 2;
sf->recode_loop = 2;
@@ -744,9 +746,10 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->use_rd_breakout = 1;
sf->adaptive_motion_search = 1;
+ sf->adaptive_pred_filter_type = 2;
sf->auto_mv_step_size = 1;
- sf->disable_filter_search_var_thresh = 16;
+ sf->disable_filter_search_var_thresh = 50;
sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
sf->auto_min_max_partition_size = 1;
@@ -779,9 +782,10 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->use_rd_breakout = 1;
sf->adaptive_motion_search = 1;
+ sf->adaptive_pred_filter_type = 2;
sf->auto_mv_step_size = 1;
- sf->disable_filter_search_var_thresh = 16;
+ sf->disable_filter_search_var_thresh = 100;
sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
sf->auto_min_max_partition_size = 1;
@@ -812,9 +816,10 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->use_rd_breakout = 1;
sf->adaptive_motion_search = 1;
+ sf->adaptive_pred_filter_type = 2;
sf->auto_mv_step_size = 1;
- sf->disable_filter_search_var_thresh = 16;
+ sf->disable_filter_search_var_thresh = 200;
sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
sf->auto_min_max_partition_size = 1;
@@ -860,7 +865,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->search_method = HEX;
sf->subpel_iters_per_step = 1;
sf->disable_split_var_thresh = 64;
- sf->disable_filter_search_var_thresh = 96;
+ sf->disable_filter_search_var_thresh = 500;
for (i = 0; i < TX_SIZES; i++) {
sf->intra_y_mode_mask[i] = INTRA_DC_ONLY;
sf->intra_uv_mode_mask[i] = INTRA_DC_ONLY;
@@ -921,7 +926,7 @@ static void alloc_raw_frame_buffers(VP9_COMP *cpi) {
if (vp9_realloc_frame_buffer(&cpi->alt_ref_buffer,
cpi->oxcf.width, cpi->oxcf.height,
cm->subsampling_x, cm->subsampling_y,
- VP9BORDERINPIXELS))
+ VP9BORDERINPIXELS, NULL, NULL, NULL))
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate altref buffer");
}
@@ -989,14 +994,14 @@ static void update_frame_size(VP9_COMP *cpi) {
if (vp9_realloc_frame_buffer(&cpi->last_frame_uf,
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
- VP9BORDERINPIXELS))
+ VP9BORDERINPIXELS, NULL, NULL, NULL))
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to reallocate last frame buffer");
if (vp9_realloc_frame_buffer(&cpi->scaled_source,
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
- VP9BORDERINPIXELS))
+ VP9BORDERINPIXELS, NULL, NULL, NULL))
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to reallocate scaled source buffer");
@@ -2564,7 +2569,7 @@ static void scale_references(VP9_COMP *cpi) {
vp9_realloc_frame_buffer(&cm->yv12_fb[new_fb],
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
- VP9BORDERINPIXELS);
+ VP9BORDERINPIXELS, NULL, NULL, NULL);
scale_and_extend_frame(ref, &cm->yv12_fb[new_fb]);
cpi->scaled_ref_idx[i] = new_fb;
} else {
@@ -2662,7 +2667,7 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) {
#endif
static void encode_with_recode_loop(VP9_COMP *cpi,
- unsigned long *size,
+ size_t *size,
uint8_t *dest,
int *q,
int bottom_index,
@@ -2859,7 +2864,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
}
static void encode_frame_to_data_rate(VP9_COMP *cpi,
- unsigned long *size,
+ size_t *size,
uint8_t *dest,
unsigned int *frame_flags) {
VP9_COMMON *const cm = &cpi->common;
@@ -3238,12 +3243,12 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mode_info_stride + 1;
}
-static void Pass0Encode(VP9_COMP *cpi, unsigned long *size, unsigned char *dest,
+static void Pass0Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest,
unsigned int *frame_flags) {
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
}
-static void Pass1Encode(VP9_COMP *cpi, unsigned long *size, unsigned char *dest,
+static void Pass1Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest,
unsigned int *frame_flags) {
(void) size;
(void) dest;
@@ -3253,8 +3258,8 @@ static void Pass1Encode(VP9_COMP *cpi, unsigned long *size, unsigned char *dest,
vp9_first_pass(cpi);
}
-static void Pass2Encode(VP9_COMP *cpi, unsigned long *size,
- unsigned char *dest, unsigned int *frame_flags) {
+static void Pass2Encode(VP9_COMP *cpi, size_t *size,
+ uint8_t *dest, unsigned int *frame_flags) {
cpi->enable_encode_breakout = 1;
if (!cpi->refresh_alt_ref_frame)
@@ -3319,7 +3324,7 @@ int is_next_frame_arf(VP9_COMP *cpi) {
#endif
int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
- unsigned long *size, unsigned char *dest,
+ size_t *size, uint8_t *dest,
int64_t *time_stamp, int64_t *time_end, int flush) {
VP9_COMP *cpi = (VP9_COMP *) ptr;
VP9_COMMON *cm = &cpi->common;
@@ -3554,7 +3559,7 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
vp9_realloc_frame_buffer(get_frame_new_buffer(cm),
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
- VP9BORDERINPIXELS);
+ VP9BORDERINPIXELS, NULL, NULL, NULL);
// Calculate scaling factors for each of the 3 available references
for (i = 0; i < REFS_PER_FRAME; ++i) {
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index dcd853fbf..5f37a0789 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -270,6 +270,7 @@ typedef struct {
int using_small_partition_info;
// TODO(jingning): combine the related motion search speed features
int adaptive_motion_search;
+ int adaptive_pred_filter_type;
// Implements various heuristics to skip searching modes
// The heuristics selected are based on flags
@@ -681,8 +682,7 @@ static int get_scale_ref_frame_idx(VP9_COMP *cpi,
void vp9_encode_frame(VP9_COMP *cpi);
-void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
- unsigned long *size);
+void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, size_t *size);
void vp9_activity_masking(VP9_COMP *cpi, MACROBLOCK *x);
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 3e1832783..5702e5aec 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -686,7 +686,7 @@ void vp9_get_entropy_contexts(TX_SIZE tx_size,
t_left[i] = !!*(const uint64_t *)&left[i];
break;
default:
- assert(!"Invalid transform size.");
+ assert(0 && "Invalid transform size.");
}
}
@@ -1669,15 +1669,15 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
frame_mv[ZEROMV][mbmi->ref_frame[0]].as_int = 0;
vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd, tile,
+ i, 0, mi_row, mi_col,
&frame_mv[NEARESTMV][mbmi->ref_frame[0]],
- &frame_mv[NEARMV][mbmi->ref_frame[0]],
- i, 0, mi_row, mi_col);
+ &frame_mv[NEARMV][mbmi->ref_frame[0]]);
if (has_second_rf) {
frame_mv[ZEROMV][mbmi->ref_frame[1]].as_int = 0;
vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd, tile,
+ i, 1, mi_row, mi_col,
&frame_mv[NEARESTMV][mbmi->ref_frame[1]],
- &frame_mv[NEARMV][mbmi->ref_frame[1]],
- i, 1, mi_row, mi_col);
+ &frame_mv[NEARMV][mbmi->ref_frame[1]]);
}
// search for the best motion vector on this segment
for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
@@ -1781,7 +1781,7 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
// adjust src pointer for this block
mi_buf_shift(x, i);
- vp9_clamp_mv_min_max(x, &bsi->ref_mv->as_mv);
+ vp9_set_mv_search_range(x, &bsi->ref_mv->as_mv);
if (cpi->sf.search_method == HEX) {
bestsme = vp9_hex_search(x, &mvp_full.as_mv,
@@ -1813,10 +1813,10 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
clamp_mv(&mvp_full.as_mv, x->mv_col_min, x->mv_col_max,
x->mv_row_min, x->mv_row_max);
- thissme = cpi->full_search_sad(x, &mvp_full,
+ thissme = cpi->full_search_sad(x, &mvp_full.as_mv,
sadpb, 16, v_fn_ptr,
x->nmvjointcost, x->mvcost,
- bsi->ref_mv, i);
+ &bsi->ref_mv->as_mv, i);
if (thissme < bestsme) {
bestsme = thissme;
@@ -2344,7 +2344,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
}
- vp9_clamp_mv_min_max(x, &ref_mv.as_mv);
+ vp9_set_mv_search_range(x, &ref_mv.as_mv);
// Adjust search parameters based on small partitions' result.
if (x->fast_ms) {
@@ -2523,7 +2523,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
// Compound motion search on first ref frame.
if (id)
xd->plane[0].pre[0] = ref_yv12[id];
- vp9_clamp_mv_min_max(x, &ref_mv[id].as_mv);
+ vp9_set_mv_search_range(x, &ref_mv[id].as_mv);
// Use mv result from single mode as mvp.
tmp_mv.as_int = frame_mv[refs[id]].as_int;
@@ -3237,7 +3237,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
break;
case NONE:
case MAX_REF_FRAMES:
- assert(!"Invalid Reference frame");
+ assert(0 && "Invalid Reference frame");
}
}
if (cpi->mode_skip_mask & ((int64_t)1 << mode_index))
@@ -3811,8 +3811,6 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
int skip_uv[TX_SIZES];
MB_PREDICTION_MODE mode_uv[TX_SIZES] = { 0 };
struct scale_factors scale_factor[4];
- unsigned int ref_frame_mask = 0;
- unsigned int mode_mask = 0;
int intra_cost_penalty = 20 * vp9_dc_quant(cpi->common.base_qindex,
cpi->common.y_dc_delta_q);
int_mv seg_mvs[4][MAX_REF_FRAMES];
@@ -3842,15 +3840,6 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
*returnrate = INT_MAX;
- // Create a mask set to 1 for each reference frame used by a smaller
- // resolution.
- if (cpi->sf.use_avoid_tested_higherror) {
- ref_frame_mask = 0;
- mode_mask = 0;
- ref_frame_mask = ~ref_frame_mask;
- mode_mask = ~mode_mask;
- }
-
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
if (cpi->ref_frame_flags & flag_list[ref_frame]) {
setup_buffer_inter(cpi, x, tile, idx_list[ref_frame], ref_frame,
@@ -3902,7 +3891,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
break;
case NONE:
case MAX_REF_FRAMES:
- assert(!"Invalid Reference frame");
+ assert(0 && "Invalid Reference frame");
}
}
if (cpi->mode_skip_mask & ((int64_t)1 << mode_index))
@@ -4075,6 +4064,14 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
cpi->sf.disable_filter_search_var_thresh) {
tmp_best_filter = EIGHTTAP;
vp9_zero(cpi->rd_filter_cache);
+ } else if (cpi->sf.adaptive_pred_filter_type == 1 &&
+ ctx->pred_filter_type < SWITCHABLE) {
+ tmp_best_filter = ctx->pred_filter_type;
+ vp9_zero(cpi->rd_filter_cache);
+ } else if (cpi->sf.adaptive_pred_filter_type == 2) {
+ tmp_best_filter = ctx->pred_filter_type < SWITCHABLE ?
+ ctx->pred_filter_type : 0;
+ vp9_zero(cpi->rd_filter_cache);
} else {
for (switchable_filter_index = 0;
switchable_filter_index < SWITCHABLE_FILTERS;
@@ -4141,7 +4138,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
}
}
- if (tmp_best_rdu == INT64_MAX)
+ if (tmp_best_rdu == INT64_MAX && pred_exists)
continue;
mbmi->interp_filter = (cm->mcomp_filter_type == SWITCHABLE ?
diff --git a/vp9/encoder/vp9_treewriter.h b/vp9/encoder/vp9_treewriter.h
index a2f9df139..703272c64 100644
--- a/vp9/encoder/vp9_treewriter.h
+++ b/vp9/encoder/vp9_treewriter.h
@@ -8,19 +8,12 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-
#ifndef VP9_ENCODER_VP9_TREEWRITER_H_
#define VP9_ENCODER_VP9_TREEWRITER_H_
-/* Trees map alphabets into huffman-like codes suitable for an arithmetic
- bit coder. Timothy S Murphy 11 October 2004 */
-
#include "vp9/common/vp9_treecoder.h"
-
#include "vp9/encoder/vp9_boolhuff.h" /* for now */
-#define vp9_write_prob(w, v) vp9_write_literal((w), (v), 8)
-
#define vp9_cost_zero(prob) (vp9_prob_cost[prob])
#define vp9_cost_one(prob) vp9_cost_zero(vp9_complement(prob))
@@ -33,31 +26,6 @@ static INLINE unsigned int cost_branch256(const unsigned int ct[2],
return ct[0] * vp9_cost_zero(p) + ct[1] * vp9_cost_one(p);
}
-static INLINE void treed_write(vp9_writer *w,
- vp9_tree tree, const vp9_prob *probs,
- int bits, int len,
- vp9_tree_index i) {
- do {
- const int bit = (bits >> --len) & 1;
- vp9_write(w, bit, probs[i >> 1]);
- i = tree[i + bit];
- } while (len);
-}
-
-struct vp9_token {
- int value;
- int len;
-};
-
-
-void vp9_tokens_from_tree(struct vp9_token*, const vp9_tree_index *);
-
-static INLINE void write_token(vp9_writer *w, vp9_tree tree,
- const vp9_prob *probs,
- const struct vp9_token *token) {
- treed_write(w, tree, probs, token->value, token->len, 0);
-}
-
static INLINE int treed_cost(vp9_tree tree, const vp9_prob *probs,
int bits, int len) {
int cost = 0;
@@ -79,4 +47,27 @@ void vp9_tree_probs_from_distribution(vp9_tree tree,
unsigned int branch_ct[ /* n - 1 */ ][2],
const unsigned int num_events[ /* n */ ]);
+struct vp9_token {
+ int value;
+ int len;
+};
+
+void vp9_tokens_from_tree(struct vp9_token*, const vp9_tree_index *);
+
+static INLINE void vp9_write_tree(vp9_writer *w, const vp9_tree_index *tree,
+ const vp9_prob *probs, int bits, int len,
+ vp9_tree_index i) {
+ do {
+ const int bit = (bits >> --len) & 1;
+ vp9_write(w, bit, probs[i >> 1]);
+ i = tree[i + bit];
+ } while (len);
+}
+
+static INLINE void vp9_write_token(vp9_writer *w, const vp9_tree_index *tree,
+ const vp9_prob *probs,
+ const struct vp9_token *token) {
+ vp9_write_tree(w, tree, probs, token->value, token->len, 0);
+}
+
#endif // VP9_ENCODER_VP9_TREEWRITER_H_
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index 5d53a4149..6bfca8d80 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -77,14 +77,14 @@ struct vpx_codec_alg_priv {
vpx_codec_enc_cfg_t cfg;
struct vp9_extracfg vp8_cfg;
VP9_CONFIG oxcf;
- VP9_PTR cpi;
+ VP9_PTR cpi;
unsigned char *cx_data;
- unsigned int cx_data_sz;
+ size_t cx_data_sz;
unsigned char *pending_cx_data;
- unsigned int pending_cx_data_sz;
+ size_t pending_cx_data_sz;
int pending_frame_count;
- uint32_t pending_frame_sizes[8];
- uint32_t pending_frame_magnitude;
+ size_t pending_frame_sizes[8];
+ size_t pending_frame_magnitude;
vpx_image_t preview_img;
vp8_postproc_cfg_t preview_ppcfg;
vpx_codec_pkt_list_decl(64) pkt_list;
@@ -100,7 +100,7 @@ static VP9_REFFRAME ref_frame_to_vp9_reframe(vpx_ref_frame_type_t frame) {
case VP8_ALTR_FRAME:
return VP9_ALT_FLAG;
}
- assert(!"Invalid Reference Frame");
+ assert(0 && "Invalid Reference Frame");
return VP9_LAST_FLAG;
}
@@ -708,7 +708,7 @@ static vpx_codec_err_t vp9e_encode(vpx_codec_alg_priv_t *ctx,
unsigned int lib_flags;
YV12_BUFFER_CONFIG sd;
int64_t dst_time_stamp, dst_end_time_stamp;
- unsigned long size, cx_data_sz;
+ size_t size, cx_data_sz;
unsigned char *cx_data;
/* Set up internal flags */
diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c
index fde73e4ab..c123c4653 100644
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -59,6 +59,13 @@ struct vpx_codec_alg_priv {
int img_setup;
int img_avail;
int invert_tile_order;
+ int fb_lru;
+
+ /* External buffer info to save for VP9 common. */
+ vpx_codec_frame_buffer_t *fb_list; // External frame buffers
+ int fb_count; // Total number of frame buffers
+ vpx_realloc_frame_buffer_cb_fn_t realloc_fb_cb;
+ void *user_priv; // Private data associated with the external frame buffers.
};
static unsigned long priv_sz(const vpx_codec_dec_cfg_t *si,
@@ -307,10 +314,32 @@ static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
ctx->postproc_cfg.noise_level = 0;
}
- if (!optr)
+ if (!optr) {
res = VPX_CODEC_ERROR;
- else
+ } else {
+ VP9D_COMP *const pbi = (VP9D_COMP*)optr;
+ VP9_COMMON *const cm = &pbi->common;
+ if (ctx->fb_list != NULL && ctx->realloc_fb_cb != NULL &&
+ ctx->fb_count > 0) {
+ cm->fb_list = ctx->fb_list;
+ cm->fb_count = ctx->fb_count;
+ cm->realloc_fb_cb = ctx->realloc_fb_cb;
+ cm->user_priv = ctx->user_priv;
+ } else {
+ cm->fb_count = FRAME_BUFFERS;
+ }
+ cm->fb_lru = ctx->fb_lru;
+ CHECK_MEM_ERROR(cm, cm->yv12_fb,
+ vpx_calloc(cm->fb_count, sizeof(*cm->yv12_fb)));
+ CHECK_MEM_ERROR(cm, cm->fb_idx_ref_cnt,
+ vpx_calloc(cm->fb_count, sizeof(*cm->fb_idx_ref_cnt)));
+ if (cm->fb_lru) {
+ CHECK_MEM_ERROR(cm, cm->fb_idx_ref_lru,
+ vpx_calloc(cm->fb_count,
+ sizeof(*cm->fb_idx_ref_lru)));
+ }
ctx->pbi = optr;
+ }
}
ctx->decoder_init = 1;
@@ -347,7 +376,7 @@ static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
}
if (vp9_receive_compressed_data(ctx->pbi, data_sz, data, deadline)) {
- VP9D_COMP *pbi = (VP9D_COMP *)ctx->pbi;
+ VP9D_COMP *pbi = (VP9D_COMP*)ctx->pbi;
res = update_error_state(ctx, &pbi->common.error);
}
@@ -475,6 +504,27 @@ static vpx_image_t *vp9_get_frame(vpx_codec_alg_priv_t *ctx,
return img;
}
+static vpx_codec_err_t vp9_set_frame_buffers(
+ vpx_codec_alg_priv_t *ctx,
+ vpx_codec_frame_buffer_t *fb_list, int fb_count,
+ vpx_realloc_frame_buffer_cb_fn_t cb, void *user_priv) {
+ if (fb_count < REF_FRAMES) {
+ /* The application must pass in at least REF_FRAMES frame buffers. */
+ return VPX_CODEC_INVALID_PARAM;
+ } else if (!ctx->pbi) {
+ /* If the decoder has already been initialized, do not accept external
+ * frame buffers.
+ */
+ ctx->fb_list = fb_list;
+ ctx->fb_count = fb_count;
+ ctx->realloc_fb_cb = cb;
+ ctx->user_priv = user_priv;
+ return VPX_CODEC_OK;
+ }
+
+ return VPX_CODEC_ERROR;
+}
+
static vpx_codec_err_t vp9_xma_get_mmap(const vpx_codec_ctx_t *ctx,
vpx_codec_mmap_t *mmap,
vpx_codec_iter_t *iter) {
@@ -639,7 +689,7 @@ static vpx_codec_err_t get_last_ref_updates(vpx_codec_alg_priv_t *ctx,
int ctrl_id,
va_list args) {
int *update_info = va_arg(args, int *);
- VP9D_COMP *pbi = (VP9D_COMP *)ctx->pbi;
+ VP9D_COMP *pbi = (VP9D_COMP*)ctx->pbi;
if (update_info) {
*update_info = pbi->refresh_frame_flags;
@@ -657,7 +707,7 @@ static vpx_codec_err_t get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
int *corrupted = va_arg(args, int *);
if (corrupted) {
- VP9D_COMP *pbi = (VP9D_COMP *)ctx->pbi;
+ VP9D_COMP *pbi = (VP9D_COMP*)ctx->pbi;
if (pbi)
*corrupted = pbi->common.frame_to_show->corrupted;
else
@@ -674,7 +724,7 @@ static vpx_codec_err_t get_display_size(vpx_codec_alg_priv_t *ctx,
int *const display_size = va_arg(args, int *);
if (display_size) {
- const VP9D_COMP *const pbi = (VP9D_COMP *)ctx->pbi;
+ const VP9D_COMP *const pbi = (VP9D_COMP*)ctx->pbi;
if (pbi) {
display_size[0] = pbi->common.display_width;
display_size[1] = pbi->common.display_height;
@@ -694,6 +744,21 @@ static vpx_codec_err_t set_invert_tile_order(vpx_codec_alg_priv_t *ctx,
return VPX_CODEC_OK;
}
+static vpx_codec_err_t set_frame_buffer_lru_cache(vpx_codec_alg_priv_t *ctx,
+ int ctr_id,
+ va_list args) {
+ VP9D_COMP *const pbi = (VP9D_COMP*)ctx->pbi;
+
+ // Save for later to pass into vp9 common.
+ ctx->fb_lru = va_arg(args, int);
+
+ if (pbi) {
+ VP9_COMMON *const cm = &pbi->common;
+ cm->fb_lru = ctx->fb_lru;
+ }
+ return VPX_CODEC_OK;
+}
+
static vpx_codec_ctrl_fn_map_t ctf_maps[] = {
{VP8_SET_REFERENCE, set_reference},
{VP8_COPY_REFERENCE, copy_reference},
@@ -707,6 +772,7 @@ static vpx_codec_ctrl_fn_map_t ctf_maps[] = {
{VP9_GET_REFERENCE, get_reference},
{VP9D_GET_DISPLAY_SIZE, get_display_size},
{VP9_INVERT_TILE_DECODE_ORDER, set_invert_tile_order},
+ {VP9D_SET_FRAME_BUFFER_LRU_CACHE, set_frame_buffer_lru_cache},
{ -1, NULL},
};
@@ -717,7 +783,8 @@ static vpx_codec_ctrl_fn_map_t ctf_maps[] = {
CODEC_INTERFACE(vpx_codec_vp9_dx) = {
"WebM Project VP9 Decoder" VERSION_STRING,
VPX_CODEC_INTERNAL_ABI_VERSION,
- VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC,
+ VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC |
+ VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER,
/* vpx_codec_caps_t caps; */
vp9_init, /* vpx_codec_init_fn_t init; */
vp9_destroy, /* vpx_codec_destroy_fn_t destroy; */
@@ -729,6 +796,7 @@ CODEC_INTERFACE(vpx_codec_vp9_dx) = {
vp9_get_si, /* vpx_codec_get_si_fn_t get_si; */
vp9_decode, /* vpx_codec_decode_fn_t decode; */
vp9_get_frame, /* vpx_codec_frame_get_fn_t frame_get; */
+ vp9_set_frame_buffers, /* vpx_codec_set_frame_buffers_fn_t set_fb; */
},
{ // NOLINT
/* encoder functions */
diff --git a/vpx/exports_dec b/vpx/exports_dec
index ed121f7ec..d058c9bdb 100644
--- a/vpx/exports_dec
+++ b/vpx/exports_dec
@@ -7,3 +7,4 @@ text vpx_codec_peek_stream_info
text vpx_codec_register_put_frame_cb
text vpx_codec_register_put_slice_cb
text vpx_codec_set_mem_map
+text vpx_codec_set_frame_buffers
diff --git a/vpx/internal/vpx_codec_internal.h b/vpx/internal/vpx_codec_internal.h
index 05fed977e..75b4a1877 100644
--- a/vpx/internal/vpx_codec_internal.h
+++ b/vpx/internal/vpx_codec_internal.h
@@ -56,7 +56,7 @@
* types, removing or reassigning enums, adding/removing/rearranging
* fields to structures
*/
-#define VPX_CODEC_INTERNAL_ABI_VERSION (4) /**<\hideinitializer*/
+#define VPX_CODEC_INTERNAL_ABI_VERSION (5) /**<\hideinitializer*/
typedef struct vpx_codec_alg_priv vpx_codec_alg_priv_t;
typedef struct vpx_codec_priv_enc_mr_cfg vpx_codec_priv_enc_mr_cfg_t;
@@ -215,6 +215,36 @@ typedef vpx_codec_err_t (*vpx_codec_decode_fn_t)(vpx_codec_alg_priv_t *ctx,
typedef vpx_image_t *(*vpx_codec_get_frame_fn_t)(vpx_codec_alg_priv_t *ctx,
vpx_codec_iter_t *iter);
+/*!\brief Pass in external frame buffers for the decoder to use.
+ *
+ * Registers a given function to be called when the current frame to
+ * decode will be bigger than the external frame buffer size. This
+ * function must be called before the first call to decode or libvpx
+ * will assume the default behavior of allocating frame buffers internally.
+ * Frame buffers with a size of 0 are valid.
+ *
+ * \param[in] ctx Pointer to this instance's context
+ * \param[in] fb_list Pointer to array of frame buffers
+ * \param[in] fb_count Number of elements in frame buffer array
+ * \param[in] cb Pointer to the callback function
+ * \param[in] user_priv User's private data
+ *
+ * \retval #VPX_CODEC_OK
+ * External frame buffers will be used by libvpx.
+ * \retval #VPX_CODEC_INVALID_PARAM
+ * fb_count was less than the value needed by the codec.
+ * \retval #VPX_CODEC_ERROR
+ * Decoder context not initialized, or algorithm not capable of
+ * using external frame buffers.
+ *
+ * \note
+ * When decoding VP9, the application must pass in at least 8 external
+ * frame buffers, as VP9 can have up to 8 reference frames.
+ */
+typedef vpx_codec_err_t (*vpx_codec_set_frame_buffers_fn_t)(
+ vpx_codec_alg_priv_t *ctx,
+ vpx_codec_frame_buffer_t *fb_list, int fb_count,
+ vpx_realloc_frame_buffer_cb_fn_t cb, void *user_priv);
/*\brief eXternal Memory Allocation memory map get iterator
*
@@ -305,6 +335,7 @@ struct vpx_codec_iface {
vpx_codec_get_si_fn_t get_si; /**< \copydoc ::vpx_codec_get_si_fn_t */
vpx_codec_decode_fn_t decode; /**< \copydoc ::vpx_codec_decode_fn_t */
vpx_codec_get_frame_fn_t get_frame; /**< \copydoc ::vpx_codec_get_frame_fn_t */
+ vpx_codec_set_frame_buffers_fn_t set_fb; /**< \copydoc ::vpx_codec_set_frame_buffers_fn_t */
} dec;
struct vpx_codec_enc_iface {
vpx_codec_enc_cfg_map_t *cfg_maps; /**< \copydoc ::vpx_codec_enc_cfg_map_t */
diff --git a/vpx/src/vpx_decoder.c b/vpx/src/vpx_decoder.c
index a99e48f88..39fd217ea 100644
--- a/vpx/src/vpx_decoder.c
+++ b/vpx/src/vpx_decoder.c
@@ -226,3 +226,22 @@ vpx_codec_err_t vpx_codec_set_mem_map(vpx_codec_ctx_t *ctx,
return SAVE_STATUS(ctx, res);
}
+
+vpx_codec_err_t vpx_codec_set_frame_buffers(
+ vpx_codec_ctx_t *ctx,
+ vpx_codec_frame_buffer_t *fb_list, int fb_count,
+ vpx_realloc_frame_buffer_cb_fn_t cb, void *user_priv) {
+ vpx_codec_err_t res;
+
+ if (!ctx || !fb_list || fb_count <= 0 || !cb) {
+ res = VPX_CODEC_INVALID_PARAM;
+ } else if (!ctx->iface || !ctx->priv ||
+ !(ctx->iface->caps & VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER)) {
+ res = VPX_CODEC_ERROR;
+ } else {
+ res = ctx->iface->dec.set_fb(ctx->priv->alg_priv, fb_list, fb_count,
+ cb, user_priv);
+ }
+
+ return SAVE_STATUS(ctx, res);
+}
diff --git a/vpx/vp8dx.h b/vpx/vp8dx.h
index b457b9302..218f0b87a 100644
--- a/vpx/vp8dx.h
+++ b/vpx/vp8dx.h
@@ -79,6 +79,13 @@ enum vp8_dec_control_id {
/** For testing. */
VP9_INVERT_TILE_DECODE_ORDER,
+ /** control function to set the vp9 decoder into using the least recently
+ * used frame buffer when a new buffer is requested. Takes an int and if
+ * the value is zero will turn off using lru cache. The value of zero is
+ * the default. If the value is anything besides zero, then that will turn
+ * on lru cache.*/
+ VP9D_SET_FRAME_BUFFER_LRU_CACHE,
+
VP8_DECODER_CTRL_ID_MAX
};
@@ -110,6 +117,7 @@ VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_USED, int *)
VPX_CTRL_USE_TYPE(VP8D_SET_DECRYPTOR, vp8_decrypt_init *)
VPX_CTRL_USE_TYPE(VP9D_GET_DISPLAY_SIZE, int *)
VPX_CTRL_USE_TYPE(VP9_INVERT_TILE_DECODE_ORDER, int)
+VPX_CTRL_USE_TYPE(VP9D_SET_FRAME_BUFFER_LRU_CACHE, int)
/*! @} - end defgroup vp8_decoder */
diff --git a/vpx/vpx_codec.mk b/vpx/vpx_codec.mk
index 549c24908..df3ff6ef1 100644
--- a/vpx/vpx_codec.mk
+++ b/vpx/vpx_codec.mk
@@ -27,6 +27,7 @@ API_DOC_SRCS-yes += vpx_codec.h
API_DOC_SRCS-yes += vpx_decoder.h
API_DOC_SRCS-yes += vpx_encoder.h
API_DOC_SRCS-yes += vpx_image.h
+API_DOC_SRCS-yes += vpx_external_frame_buffer.h
API_SRCS-yes += src/vpx_decoder.c
API_SRCS-yes += vpx_decoder.h
@@ -38,4 +39,5 @@ API_SRCS-yes += src/vpx_image.c
API_SRCS-yes += vpx_codec.h
API_SRCS-yes += vpx_codec.mk
API_SRCS-yes += vpx_image.h
+API_SRCS-yes += vpx_external_frame_buffer.h
API_SRCS-$(BUILD_LIBVPX) += vpx_integer.h
diff --git a/vpx/vpx_decoder.h b/vpx/vpx_decoder.h
index 2dcd024cc..08f7f434e 100644
--- a/vpx/vpx_decoder.h
+++ b/vpx/vpx_decoder.h
@@ -30,6 +30,7 @@ extern "C" {
#endif
#include "vpx_codec.h"
+#include "vpx_external_frame_buffer.h"
/*!\brief Current ABI version number
*
@@ -39,7 +40,7 @@ extern "C" {
* types, removing or reassigning enums, adding/removing/rearranging
* fields to structures
*/
-#define VPX_DECODER_ABI_VERSION (2 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/
+#define VPX_DECODER_ABI_VERSION (3 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/
/*! \brief Decoder capabilities bitfield
*
@@ -66,6 +67,8 @@ extern "C" {
*/
#define VPX_CODEC_CAP_FRAME_THREADING 0x200000 /**< Can support frame-based
multi-threading */
+#define VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER 0x400000 /**< Can support external
+ frame buffers */
#define VPX_CODEC_USE_POSTPROC 0x10000 /**< Postprocess decoded frame */
#define VPX_CODEC_USE_ERROR_CONCEALMENT 0x20000 /**< Conceal errors in decoded
@@ -326,6 +329,49 @@ extern "C" {
/*!@} - end defgroup cap_put_slice*/
+ /*!\defgroup cap_external_frame_buffer External Frame Buffer Functions
+ *
+ * The following section is required to be implemented for all decoders
+ * that advertise the VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER capability.
+ * Calling this function for codecs that don't advertise this capability
+ * will result in an error code being returned, usually VPX_CODEC_ERROR.
+ *
+ * \note
+ * Currently this only works with VP9.
+ * @{
+ */
+
+ /*!\brief Pass in external frame buffers for the decoder to use.
+ *
+ * Registers a given function to be called when the current frame to
+ * decode will be bigger than the external frame buffer size. This
+ * function must be called before the first call to decode or libvpx
+ * will assume the default behavior of allocating frame buffers internally.
+ * Frame buffers with a size of 0 are valid.
+ *
+ * \param[in] ctx Pointer to this instance's context
+ * \param[in] fb_list Pointer to array of frame buffers
+ * \param[in] fb_count Number of elements in frame buffer array
+ * \param[in] cb Pointer to the callback function
+ * \param[in] user_priv User's private data
+ *
+ * \retval #VPX_CODEC_OK
+ * External frame buffers passed into the decoder.
+ * \retval #VPX_CODEC_ERROR
+ * Decoder context not initialized, or algorithm not capable of
+ * using external frame buffers.
+ *
+ * \note
+ * When decoding VP9, the application must pass in at least 8 external
+ * frame buffers, as VP9 can have up to 8 reference frames.
+ */
+ vpx_codec_err_t vpx_codec_set_frame_buffers(
+ vpx_codec_ctx_t *ctx,
+ vpx_codec_frame_buffer_t *fb_list, int fb_count,
+ vpx_realloc_frame_buffer_cb_fn_t cb, void *user_priv);
+
+ /*!@} - end defgroup cap_external_frame_buffer */
+
/*!@} - end defgroup decoder*/
#ifdef __cplusplus
}
diff --git a/vpx/vpx_external_frame_buffer.h b/vpx/vpx_external_frame_buffer.h
new file mode 100644
index 000000000..adf133042
--- /dev/null
+++ b/vpx/vpx_external_frame_buffer.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef VPX_VPX_EXTERNAL_FRAME_BUFFER_H_
+#define VPX_VPX_EXTERNAL_FRAME_BUFFER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "vpx/vpx_integer.h"
+
+/*!\brief External frame buffer
+ *
+ * This structure is used to hold external frame buffers passed into the
+ * decoder by the application.
+ */
+typedef struct vpx_codec_frame_buffer {
+ uint8_t *data; /**< Pointer to the data buffer */
+ size_t size; /**< Size of data in bytes */
+ void *frame_priv; /**< Frame's private data */
+} vpx_codec_frame_buffer_t;
+
+/*!\brief realloc frame buffer callback prototype
+ *
+ * This callback is invoked by the decoder to notify the application one
+ * of the external frame buffers must increase in size, in order for the
+ * decode call to complete. The callback must allocate at least new_size in
+ * bytes and assign it to fb->data. Then the callback must set fb->size to
+ * the allocated size. The application does not need to align the allocated
+ * data. The callback is usually triggered by a frame size change. On success
+ * the callback must return 0. Any failure the callback must return a value
+ * less than 0.
+ *
+ * \param[in] user_priv User's private data
+ * \param[in] new_size Size in bytes needed by the buffer.
+ * \param[in/out] fb Pointer to frame buffer to increase size.
+ */
+typedef int (*vpx_realloc_frame_buffer_cb_fn_t)(
+ void *user_priv, size_t new_size, vpx_codec_frame_buffer_t *fb);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // VPX_VPX_EXTERNAL_FRAME_BUFFER_H_
diff --git a/vpx_scale/generic/yv12config.c b/vpx_scale/generic/yv12config.c
index 7c3f7ece9..a020e19b7 100644
--- a/vpx_scale/generic/yv12config.c
+++ b/vpx_scale/generic/yv12config.c
@@ -19,10 +19,18 @@
/****************************************************************************
*
****************************************************************************/
+
+#define yv12_align_addr(addr, align) \
+ (void*)(((size_t)(addr) + ((align) - 1)) & (size_t)-(align))
+
int
vp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
if (ybf) {
- vpx_free(ybf->buffer_alloc);
+ // If libvpx is using external frame buffers then buffer_alloc_sz must
+ // not be set.
+ if (ybf->buffer_alloc_sz > 0) {
+ vpx_free(ybf->buffer_alloc);
+ }
/* buffer_alloc isn't accessed by most functions. Rather y_buffer,
u_buffer and v_buffer point to buffer_alloc and are used. Clear out
@@ -108,7 +116,9 @@ int vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
int vp9_free_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
if (ybf) {
- vpx_free(ybf->buffer_alloc);
+ if (ybf->buffer_alloc_sz > 0) {
+ vpx_free(ybf->buffer_alloc);
+ }
/* buffer_alloc isn't accessed by most functions. Rather y_buffer,
u_buffer and v_buffer point to buffer_alloc and are used. Clear out
@@ -123,7 +133,10 @@ int vp9_free_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
int vp9_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
int width, int height,
- int ss_x, int ss_y, int border) {
+ int ss_x, int ss_y, int border,
+ vpx_codec_frame_buffer_t *ext_fb,
+ vpx_realloc_frame_buffer_cb_fn_t cb,
+ void *user_priv) {
if (ybf) {
const int aligned_width = (width + 7) & ~7;
const int aligned_height = (height + 7) & ~7;
@@ -148,15 +161,36 @@ int vp9_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
#else
const int frame_size = yplane_size + 2 * uvplane_size;
#endif
- if (frame_size > ybf->buffer_alloc_sz) {
- // Allocation to hold larger frame, or first allocation.
- if (ybf->buffer_alloc)
- vpx_free(ybf->buffer_alloc);
- ybf->buffer_alloc = vpx_memalign(32, frame_size);
- ybf->buffer_alloc_sz = frame_size;
+
+ if (ext_fb != NULL) {
+ const int align_addr_extra_size = 31;
+ const int external_frame_size = frame_size + align_addr_extra_size;
+ if (external_frame_size > ext_fb->size) {
+ // Allocation to hold larger frame, or first allocation.
+ if (cb(user_priv, external_frame_size, ext_fb) < 0) {
+ return -1;
+ }
+
+ if (ext_fb->data == NULL || ext_fb->size < external_frame_size) {
+ return -1;
+ }
+
+ ybf->buffer_alloc = yv12_align_addr(ext_fb->data, 32);
+ }
+ } else {
+ if (frame_size > ybf->buffer_alloc_sz) {
+ // Allocation to hold larger frame, or first allocation.
+ if (ybf->buffer_alloc)
+ vpx_free(ybf->buffer_alloc);
+ ybf->buffer_alloc = vpx_memalign(32, frame_size);
+ ybf->buffer_alloc_sz = frame_size;
+ }
+
+ if (ybf->buffer_alloc_sz < frame_size)
+ return -1;
}
- if (!ybf->buffer_alloc || ybf->buffer_alloc_sz < frame_size)
+ if (!ybf->buffer_alloc)
return -1;
/* Only support allocating buffers that have a border that's a multiple
@@ -206,7 +240,8 @@ int vp9_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
int ss_x, int ss_y, int border) {
if (ybf) {
vp9_free_frame_buffer(ybf);
- return vp9_realloc_frame_buffer(ybf, width, height, ss_x, ss_y, border);
+ return vp9_realloc_frame_buffer(ybf, width, height, ss_x, ss_y, border,
+ NULL, NULL, NULL);
}
return -2;
}
diff --git a/vpx_scale/yv12config.h b/vpx_scale/yv12config.h
index 0e950fb14..f23e1163c 100644
--- a/vpx_scale/yv12config.h
+++ b/vpx_scale/yv12config.h
@@ -15,6 +15,7 @@
extern "C" {
#endif
+#include "vpx/vpx_external_frame_buffer.h"
#include "vpx/vpx_integer.h"
#define VP8BORDERINPIXELS 32
@@ -64,9 +65,20 @@ extern "C" {
int vp9_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
int width, int height, int ss_x, int ss_y,
int border);
+
+ // Updates the yv12 buffer config with the frame buffer. If ext_fb is not
+ // NULL then libvpx is using external frame buffers. The function will
+ // check if the frame buffer is big enough to fit the decoded frame and
+ // try to reallocate the frame buffer. If ext_fb is not NULL and the frame
+ // buffer is not big enough libvpx will call cb with minimum size in bytes.
+ //
+ // Returns 0 on success. Returns < 0 on failure.
int vp9_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
int width, int height, int ss_x, int ss_y,
- int border);
+ int border,
+ vpx_codec_frame_buffer_t *ext_fb,
+ vpx_realloc_frame_buffer_cb_fn_t cb,
+ void *user_priv);
int vp9_free_frame_buffer(YV12_BUFFER_CONFIG *ybf);
#ifdef __cplusplus
diff --git a/vpxdec.c b/vpxdec.c
index 1b9bfd302..91d8faf01 100644
--- a/vpxdec.c
+++ b/vpxdec.c
@@ -89,6 +89,10 @@ static const arg_def_t error_concealment = ARG_DEF(NULL, "error-concealment", 0,
"Enable decoder error-concealment");
static const arg_def_t scalearg = ARG_DEF("S", "scale", 0,
"Scale output frames uniformly");
+static const arg_def_t fb_arg =
+ ARG_DEF(NULL, "frame-buffers", 1, "Number of frame buffers to use");
+static const arg_def_t fb_lru_arg =
+ ARG_DEF(NULL, "frame-buffers-lru", 1, "Turn on/off frame buffer lru");
#if CONFIG_MD5
@@ -98,7 +102,7 @@ static const arg_def_t md5arg = ARG_DEF(NULL, "md5", 0,
static const arg_def_t *all_args[] = {
&codecarg, &use_yv12, &use_i420, &flipuvarg, &noblitarg,
&progressarg, &limitarg, &skiparg, &postprocarg, &summaryarg, &outputfile,
- &threadsarg, &verbosearg, &scalearg,
+ &threadsarg, &verbosearg, &scalearg, &fb_arg, &fb_lru_arg,
#if CONFIG_MD5
&md5arg,
#endif
@@ -314,6 +318,31 @@ void show_progress(int frame_in, int frame_out, unsigned long dx_time) {
(float)frame_out * 1000000.0 / (float)dx_time);
}
+// Called by libvpx if the frame buffer size needs to increase.
+//
+// Parameters:
+// user_priv Data passed into libvpx.
+// new_size Minimum size needed by libvpx to decompress the next frame.
+// fb Pointer to the frame buffer to update.
+//
+// Returns 0 on success. Returns < 0 on failure.
+int realloc_vp9_frame_buffer(void *user_priv, size_t new_size,
+ vpx_codec_frame_buffer_t *fb) {
+ (void)user_priv;
+ if (!fb)
+ return -1;
+
+ free(fb->data);
+ fb->data = (uint8_t*)malloc(new_size);
+ if (!fb->data) {
+ fb->size = 0;
+ return -1;
+ }
+
+ fb->size = new_size;
+ return 0;
+}
+
void generate_filename(const char *pattern, char *out, size_t q_len,
unsigned int d_w, unsigned int d_h,
unsigned int frame_in) {
@@ -428,6 +457,9 @@ int main_loop(int argc, const char **argv_) {
int do_scale = 0;
vpx_image_t *scaled_img = NULL;
int frame_avail, got_data;
+ int num_external_frame_buffers = 0;
+ int fb_lru_cache = 0;
+ vpx_codec_frame_buffer_t *frame_buffers = NULL;
struct VpxDecInputContext input = {0};
struct VpxInputContext vpx_input_ctx = {0};
@@ -487,6 +519,10 @@ int main_loop(int argc, const char **argv_) {
quiet = 0;
else if (arg_match(&arg, &scalearg, argi))
do_scale = 1;
+ else if (arg_match(&arg, &fb_arg, argi))
+ num_external_frame_buffers = arg_parse_uint(&arg);
+ else if (arg_match(&arg, &fb_lru_arg, argi))
+ fb_lru_cache = arg_parse_uint(&arg);
#if CONFIG_VP8_DECODER
else if (arg_match(&arg, &addnoise_level, argi)) {
@@ -704,6 +740,30 @@ int main_loop(int argc, const char **argv_) {
arg_skip--;
}
+ if (num_external_frame_buffers > 0) {
+ // Allocate the frame buffer list, setting all of the values to 0.
+ // Including the size of frame buffers. Libvpx will request the
+ // application to realloc the frame buffer data if the size is too small.
+ frame_buffers = (vpx_codec_frame_buffer_t*)calloc(
+ num_external_frame_buffers, sizeof(*frame_buffers));
+ if (vpx_codec_set_frame_buffers(&decoder, frame_buffers,
+ num_external_frame_buffers,
+ realloc_vp9_frame_buffer,
+ NULL)) {
+ fprintf(stderr, "Failed to configure external frame buffers: %s\n",
+ vpx_codec_error(&decoder));
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (fb_lru_cache > 0 &&
+ vpx_codec_control(&decoder, VP9D_SET_FRAME_BUFFER_LRU_CACHE,
+ fb_lru_cache)) {
+ fprintf(stderr, "Failed to set frame buffer lru cache: %s\n",
+ vpx_codec_error(&decoder));
+ return EXIT_FAILURE;
+ }
+
frame_avail = 1;
got_data = 0;
@@ -878,6 +938,10 @@ fail:
free(buf);
if (scaled_img) vpx_img_free(scaled_img);
+ for (i = 0; i < num_external_frame_buffers; ++i) {
+ free(frame_buffers[i].data);
+ }
+ free(frame_buffers);
fclose(infile);
free(argv);
diff --git a/webmdec.c b/webmdec.c
index 4bf7c7e2b..0c75d7a2c 100644
--- a/webmdec.c
+++ b/webmdec.c
@@ -117,8 +117,10 @@ int webm_read_frame(struct WebmInputContext *webm_ctx,
do {
/* End of this packet, get another. */
- if (webm_ctx->pkt)
+ if (webm_ctx->pkt) {
nestegg_free_packet(webm_ctx->pkt);
+ webm_ctx->pkt = NULL;
+ }
if (nestegg_read_packet(webm_ctx->nestegg_ctx, &webm_ctx->pkt) <= 0 ||
nestegg_packet_track(webm_ctx->pkt, &track)) {
@@ -188,6 +190,9 @@ int webm_guess_framerate(struct WebmInputContext *webm_ctx,
}
void webm_free(struct WebmInputContext *webm_ctx) {
- if (webm_ctx && webm_ctx->nestegg_ctx)
+ if (webm_ctx && webm_ctx->nestegg_ctx) {
+ if (webm_ctx->pkt)
+ nestegg_free_packet(webm_ctx->pkt);
nestegg_destroy(webm_ctx->nestegg_ctx);
+ }
}