// Common test functionality for all Decoder tests.
class DecoderTest {
public:
- // Main loop.
+ // Main decoding loop
virtual void RunLoop(CompressedVideoSource *video);
// Hook to be called on every decompressed frame.
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
+
#include "vpx_config.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
return match;
}
+void EncoderTest::MismatchHook(const vpx_image_t *img1,
+ const vpx_image_t *img2) {
+ ASSERT_TRUE(0) << "Encode/Decode mismatch found";
+}
+
void EncoderTest::RunLoop(VideoSource *video) {
vpx_codec_dec_cfg_t dec_cfg = {0};
&stats_);
ASSERT_TRUE(encoder != NULL);
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, 0);
- bool has_cxdata = false;
bool again;
for (again = true, video->Begin(); again; video->Next()) {
again = video->img() != NULL;
CxDataIterator iter = encoder->GetCxData();
+ bool has_cxdata = false;
+ bool has_dxdata = false;
while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) {
again = true;
-
switch (pkt->kind) {
case VPX_CODEC_CX_FRAME_PKT:
has_cxdata = true;
- if (decoder)
+ if (decoder && DoDecode()) {
decoder->DecodeFrame((const uint8_t*)pkt->data.frame.buf,
pkt->data.frame.sz);
+ has_dxdata = true;
+ }
ASSERT_GE(pkt->data.frame.pts, last_pts_);
last_pts_ = pkt->data.frame.pts;
FramePktHook(pkt);
}
}
- if (decoder && has_cxdata) {
+ if (has_dxdata && has_cxdata) {
const vpx_image_t *img_enc = encoder->GetPreviewFrame();
DxDataIterator dec_iter = decoder->GetDxData();
const vpx_image_t *img_dec = dec_iter.Next();
- if(img_enc && img_dec) {
+ if (img_enc && img_dec) {
const bool res = compare_img(img_enc, img_dec);
- ASSERT_TRUE(res)<< "Encoder/Decoder mismatch found.";
+ if (!res) { // Mismatch
+ MismatchHook(img_enc, img_dec);
+ }
}
}
-
if (!Continue())
break;
}
break;
}
}
+
} // namespace libvpx_test
*/
#ifndef TEST_ENCODE_TEST_DRIVER_H_
#define TEST_ENCODE_TEST_DRIVER_H_
+
+#include "./vpx_config.h"
#include <string>
#include <vector>
#include "third_party/googletest/src/include/gtest/gtest.h"
// Map the TestMode enum to the deadline_ and passes_ variables.
void SetMode(TestMode mode);
- // Main loop.
+ // Main loop
virtual void RunLoop(VideoSource *video);
// Hook to be called at the beginning of a pass.
virtual bool Continue() const { return !abort_; }
const CodecFactory *codec_;
+ // Hook to determine whether to decode frame after encoding
+ virtual bool DoDecode() const { return 1; }
+
+ // Hook to handle encode/decode mismatch
+ virtual void MismatchHook(const vpx_image_t *img1,
+ const vpx_image_t *img2);
+
bool abort_;
vpx_codec_enc_cfg_t cfg_;
unsigned int passes_;
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"
#include "test/encode_test_driver.h"
namespace {
+const int kMaxErrorFrames = 8;
+const int kMaxDroppableFrames = 8;
+
class ErrorResilienceTest : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected:
- ErrorResilienceTest() : EncoderTest(GET_PARAM(0)), psnr_(0.0), nframes_(0),
- encoding_mode_(GET_PARAM(1)) {}
+ ErrorResilienceTest() : EncoderTest(GET_PARAM(0)),
+ psnr_(0.0),
+ nframes_(0),
+ mismatch_psnr_(0.0),
+ mismatch_nframes_(0),
+ encoding_mode_(GET_PARAM(1)) {
+ Reset();
+ }
virtual ~ErrorResilienceTest() {}
+ void Reset() {
+ error_nframes_ = 0;
+ droppable_nframes_ = 0;
+ }
+
virtual void SetUp() {
InitializeConfig();
SetMode(encoding_mode_);
virtual void BeginPassHook(unsigned int /*pass*/) {
psnr_ = 0.0;
nframes_ = 0;
+ mismatch_psnr_ = 0.0;
+ mismatch_nframes_ = 0;
}
virtual bool Continue() const {
nframes_++;
}
+ virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video) {
+ frame_flags_ &= ~(VP8_EFLAG_NO_UPD_LAST |
+ VP8_EFLAG_NO_UPD_GF |
+ VP8_EFLAG_NO_UPD_ARF);
+ if (droppable_nframes_ > 0 &&
+ (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
+ for (unsigned int i = 0; i < droppable_nframes_; ++i) {
+ if (droppable_frames_[i] == nframes_) {
+ std::cout << " Encoding droppable frame: "
+ << droppable_frames_[i] << "\n";
+ frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST |
+ VP8_EFLAG_NO_UPD_GF |
+ VP8_EFLAG_NO_UPD_ARF);
+ return;
+ }
+ }
+ }
+ }
+
double GetAveragePsnr() const {
if (nframes_)
return psnr_ / nframes_;
return 0.0;
}
+ double GetAverageMismatchPsnr() const {
+ if (mismatch_nframes_)
+ return mismatch_psnr_ / mismatch_nframes_;
+ return 0.0;
+ }
+
+ virtual bool DoDecode() const {
+ if (error_nframes_ > 0 &&
+ (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
+ for (unsigned int i = 0; i < error_nframes_; ++i) {
+ if (error_frames_[i] == nframes_ - 1) {
+ std::cout << " Skipping decoding frame: "
+ << error_frames_[i] << "\n";
+ return 0;
+ }
+ }
+ }
+ return 1;
+ }
+
+ virtual void MismatchHook(const vpx_image_t *img1,
+ const vpx_image_t *img2) {
+ double mismatch_psnr = compute_psnr(img1, img2);
+ mismatch_psnr_ += mismatch_psnr;
+ ++mismatch_nframes_;
+ // std::cout << "Mismatch frame psnr: " << mismatch_psnr << "\n";
+ }
+
+ void SetErrorFrames(int num, unsigned int *list) {
+ if (num > kMaxErrorFrames)
+ num = kMaxErrorFrames;
+ else if (num < 0)
+ num = 0;
+ error_nframes_ = num;
+ for (unsigned int i = 0; i < error_nframes_; ++i)
+ error_frames_[i] = list[i];
+ }
+
+ void SetDroppableFrames(int num, unsigned int *list) {
+ if (num > kMaxDroppableFrames)
+ num = kMaxDroppableFrames;
+ else if (num < 0)
+ num = 0;
+ droppable_nframes_ = num;
+ for (unsigned int i = 0; i < droppable_nframes_; ++i)
+ droppable_frames_[i] = list[i];
+ }
+
+ unsigned int GetMismatchFrames() {
+ return mismatch_nframes_;
+ }
+
private:
double psnr_;
unsigned int nframes_;
+ unsigned int error_nframes_;
+ unsigned int droppable_nframes_;
+ double mismatch_psnr_;
+ unsigned int mismatch_nframes_;
+ unsigned int error_frames_[kMaxErrorFrames];
+ unsigned int droppable_frames_[kMaxDroppableFrames];
libvpx_test::TestMode encoding_mode_;
};
}
}
+TEST_P(ErrorResilienceTest, DropFramesWithoutRecovery) {
+ const vpx_rational timebase = { 33333333, 1000000000 };
+ cfg_.g_timebase = timebase;
+ cfg_.rc_target_bitrate = 2000;
+ cfg_.g_lag_in_frames = 5;
+
+ init_flags_ = VPX_CODEC_USE_PSNR;
+
+ libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
+ timebase.den, timebase.num, 0, 30);
+
+ // Error resilient mode ON.
+ cfg_.g_error_resilient = 1;
+
+ // Set an arbitrary set of error frames same as droppable frames
+ unsigned int num_droppable_frames = 2;
+ unsigned int droppable_frame_list[] = {5, 16};
+ SetDroppableFrames(num_droppable_frames, droppable_frame_list);
+ SetErrorFrames(num_droppable_frames, droppable_frame_list);
+ ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+ // Test that no mismatches have been found
+ std::cout << " Mismatch frames: "
+ << GetMismatchFrames() << "\n";
+ EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
+
+ // reset previously set error/droppable frames
+ Reset();
+
+ // Now set an arbitrary set of error frames that are non-droppable
+ unsigned int num_error_frames = 3;
+ unsigned int error_frame_list[] = {3, 10, 20};
+ SetErrorFrames(num_error_frames, error_frame_list);
+ ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+ // Test that dropping an arbitrary set of inter frames does not hurt too much
+ // Note the Average Mismatch PSNR is the average of the PSNR between
+ // decoded frame and encoder's version of the same frame for all frames
+ // with mismatch.
+ const double psnr_resilience_mismatch = GetAverageMismatchPsnr();
+ std::cout << " Mismatch PSNR: "
+ << psnr_resilience_mismatch << "\n";
+ EXPECT_GT(psnr_resilience_mismatch, 20.0);
+}
+
VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTest, ONE_PASS_TEST_MODES);
+VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTest, ONE_PASS_TEST_MODES);
+
} // namespace
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += config_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += cq_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += datarate_test.cc
+
LIBVPX_TEST_SRCS-yes += encode_test_driver.cc
LIBVPX_TEST_SRCS-yes += encode_test_driver.h
-LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += error_resilience_test.cc
+LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += error_resilience_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += i420_video_source.h
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += keyframe_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += resize_test.cc
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_VP8_DECODER) += test_vector_test.cc
##
## WHITE BOX TESTS
#LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct16x16_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += variance_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct32x32_test.cc
+
endif # VP9
##
## TEST DATA
##
-LIBVPX_TEST_DATA-$(CONFIG_VP8_ENCODER) += hantro_collage_w352h288.yuv
+LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_collage_w352h288.yuv
+
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-001.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-002.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-003.ivf
#ifndef TEST_UTIL_H_
#define TEST_UTIL_H_
+#include <stdio.h>
+#include <math.h>
+#include "third_party/googletest/src/include/gtest/gtest.h"
+#include "vpx/vpx_image.h"
+
// Macros
#define PARAMS(...) ::testing::TestWithParam< std::tr1::tuple< __VA_ARGS__ > >
#define GET_PARAM(k) std::tr1::get< k >(GetParam())
+static double compute_psnr(const vpx_image_t *img1,
+ const vpx_image_t *img2) {
+ assert((img1->fmt == img2->fmt) &&
+ (img1->d_w == img2->d_w) &&
+ (img1->d_h == img2->d_h));
+
+ const unsigned int width_y = img1->d_w;
+ const unsigned int height_y = img1->d_h;
+ unsigned int i, j;
+
+ int64_t sqrerr = 0;
+ for (i = 0; i < height_y; ++i)
+ for (j = 0; j < width_y; ++j) {
+ int64_t d = img1->planes[VPX_PLANE_Y][i * img1->stride[VPX_PLANE_Y] + j] -
+ img2->planes[VPX_PLANE_Y][i * img2->stride[VPX_PLANE_Y] + j];
+ sqrerr += d * d;
+ }
+ double mse = sqrerr / (width_y * height_y);
+ double psnr = 100.0;
+ if (mse > 0.0) {
+ psnr = 10 * log10(255.0 * 255.0 / mse);
+ }
+ return psnr;
+}
+
#endif // TEST_UTIL_H_
return 0;
}
+
void vp9_setup_version(VP9_COMMON *cm) {
if (cm->version & 0x4) {
if (!CONFIG_EXPERIMENTAL)
#include "vp9/common/vp9_onyxc_int.h"
#include "vp9/common/vp9_modecont.h"
+#include "vp9/common/vp9_seg_common.h"
+#include "vp9/common/vp9_alloccommon.h"
#include "vpx_mem/vpx_mem.h"
-
static const unsigned int kf_y_mode_cts[8][VP9_YMODES] = {
/* DC V H D45 135 117 153 D27 D63 TM i8x8 BPRED */
{12, 6, 5, 5, 5, 5, 5, 5, 5, 2, 22, 200},
#if CONFIG_COMP_INTERINTRA_PRED
x->fc.interintra_prob = VP9_DEF_INTERINTRA_PROB;
#endif
+ x->ref_pred_probs[0] = 120;
+ x->ref_pred_probs[1] = 80;
+ x->ref_pred_probs[2] = 40;
}
#define MVREF_COUNT_SAT 20
#define MVREF_MAX_UPDATE_FACTOR 128
-void vp9_update_mode_context(VP9_COMMON *pc) {
+void vp9_adapt_mode_context(VP9_COMMON *pc) {
int i, j;
unsigned int (*mv_ref_ct)[4][2];
int (*mode_context)[4];
}
#endif
}
+
+static void set_default_lf_deltas(MACROBLOCKD *xd) {
+ xd->mode_ref_lf_delta_enabled = 1;
+ xd->mode_ref_lf_delta_update = 1;
+
+ xd->ref_lf_deltas[INTRA_FRAME] = 2;
+ xd->ref_lf_deltas[LAST_FRAME] = 0;
+ xd->ref_lf_deltas[GOLDEN_FRAME] = -2;
+ xd->ref_lf_deltas[ALTREF_FRAME] = -2;
+
+ xd->mode_lf_deltas[0] = 4; // BPRED
+ xd->mode_lf_deltas[1] = -2; // Zero
+ xd->mode_lf_deltas[2] = 2; // New mv
+ xd->mode_lf_deltas[3] = 4; // Split mv
+}
+
+void vp9_setup_past_independence(VP9_COMMON *cm, MACROBLOCKD *xd) {
+ // Reset the segment feature data to the default stats:
+ // Features disabled, 0, with delta coding (Default state).
+ int i;
+ vp9_clearall_segfeatures(xd);
+ xd->mb_segment_abs_delta = SEGMENT_DELTADATA;
+ if (cm->last_frame_seg_map)
+ vpx_memset(cm->last_frame_seg_map, 0, (cm->mb_rows * cm->mb_cols));
+
+ /* reset the mode ref deltas for loop filter */
+ vpx_memset(xd->last_ref_lf_deltas, 0, sizeof(xd->last_ref_lf_deltas));
+ vpx_memset(xd->last_mode_lf_deltas, 0, sizeof(xd->last_mode_lf_deltas));
+ set_default_lf_deltas(xd);
+
+ vp9_default_coef_probs(cm);
+ vp9_init_mbmode_probs(cm);
+ vp9_default_bmode_probs(cm->fc.bmode_prob);
+ vp9_kf_default_bmode_probs(cm->kf_bmode_prob);
+ vp9_init_mv_probs(cm);
+ // To force update of the sharpness
+ cm->last_sharpness_level = -1;
+
+ vp9_init_mode_contexts(cm);
+
+ for (i = 0; i < NUM_FRAME_CONTEXTS; i++) {
+ vpx_memcpy(&cm->frame_contexts[i], &cm->fc, sizeof(cm->fc));
+ }
+
+ vpx_memset(cm->prev_mip, 0,
+ (cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO));
+ vpx_memset(cm->mip, 0,
+ (cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO));
+
+ vp9_update_mode_info_border(cm, cm->mip);
+ vp9_update_mode_info_in_image(cm, cm->mi);
+
+#if CONFIG_NEW_MVREF
+ // Defaults probabilities for encoding the MV ref id signal
+ vpx_memset(xd->mb_mv_ref_probs, VP9_DEFAULT_MV_REF_PROB,
+ sizeof(xd->mb_mv_ref_probs));
+#endif
+ cm->ref_frame_sign_bias[GOLDEN_FRAME] = 0;
+ cm->ref_frame_sign_bias[ALTREF_FRAME] = 0;
+
+ cm->frame_context_idx = 0;
+}
struct VP9Common;
+/* sets up common features to forget past dependence */
+void vp9_setup_past_independence(struct VP9Common *cm, MACROBLOCKD *xd);
+
void vp9_init_mbmode_probs(struct VP9Common *x);
extern void vp9_init_mode_contexts(struct VP9Common *pc);
-extern void vp9_update_mode_context(struct VP9Common *pc);
+extern void vp9_adapt_mode_context(struct VP9Common *pc);
extern void vp9_accum_mv_refs(struct VP9Common *pc,
MB_PREDICTION_MODE m,
int_mv sorted_mvs[MAX_MV_REF_CANDIDATES];
int zero_seen = FALSE;
- // Default all to 0,0 if nothing else available
- nearest->as_int = near->as_int = 0;
- vpx_memset(sorted_mvs, 0, sizeof(sorted_mvs));
+ if (ref_y_buffer) {
- above_src = xd->dst.y_buffer - xd->dst.y_stride * 2;
- above_ref = ref_y_buffer - ref_y_stride * 2;
+ // Default all to 0,0 if nothing else available
+ nearest->as_int = near->as_int = 0;
+ vpx_memset(sorted_mvs, 0, sizeof(sorted_mvs));
+
+ above_src = xd->dst.y_buffer - xd->dst.y_stride * 2;
+ above_ref = ref_y_buffer - ref_y_stride * 2;
#if CONFIG_ABOVESPREFMV
- above_src -= 4;
- above_ref -= 4;
+ above_src -= 4;
+ above_ref -= 4;
#else
- left_src = xd->dst.y_buffer - 2;
- left_ref = ref_y_buffer - 2;
+ left_src = xd->dst.y_buffer - 2;
+ left_ref = ref_y_buffer - 2;
#endif
- // Limit search to the predicted best few candidates
- for(i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
- int_mv this_mv;
- int offset = 0;
- int row_offset, col_offset;
+ // Limit search to the predicted best few candidates
+ for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
+ int_mv this_mv;
+ int offset = 0;
+ int row_offset, col_offset;
- this_mv.as_int = mvlist[i].as_int;
+ this_mv.as_int = mvlist[i].as_int;
- // If we see a 0,0 vector for a second time we have reached the end of
- // the list of valid candidate vectors.
- if (!this_mv.as_int && zero_seen)
- break;
+ // If we see a 0,0 vector for a second time we have reached the end of
+ // the list of valid candidate vectors.
+ if (!this_mv.as_int && zero_seen)
+ break;
- zero_seen = zero_seen || !this_mv.as_int;
+ zero_seen = zero_seen || !this_mv.as_int;
#if !CONFIG_ABOVESPREFMV
- clamp_mv(&this_mv,
- xd->mb_to_left_edge - LEFT_TOP_MARGIN + 24,
- xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
- xd->mb_to_top_edge - LEFT_TOP_MARGIN + 24,
- xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
+ clamp_mv(&this_mv,
+ xd->mb_to_left_edge - LEFT_TOP_MARGIN + 24,
+ xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
+ xd->mb_to_top_edge - LEFT_TOP_MARGIN + 24,
+ xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
#else
- clamp_mv(&this_mv,
- xd->mb_to_left_edge - LEFT_TOP_MARGIN + 32,
- xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
- xd->mb_to_top_edge - LEFT_TOP_MARGIN + 24,
- xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
+ clamp_mv(&this_mv,
+ xd->mb_to_left_edge - LEFT_TOP_MARGIN + 32,
+ xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
+ xd->mb_to_top_edge - LEFT_TOP_MARGIN + 24,
+ xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
#endif
- row_offset = this_mv.as_mv.row >> 3;
- col_offset = this_mv.as_mv.col >> 3;
- offset = ref_y_stride * row_offset + col_offset;
- score = 0;
- if (xd->up_available) {
- vp9_sub_pixel_variance16x2(above_ref + offset, ref_y_stride,
- SP(this_mv.as_mv.col),
- SP(this_mv.as_mv.row),
- above_src, xd->dst.y_stride, &sse);
- score += sse;
- if (xd->mode_info_context->mbmi.sb_type >= BLOCK_SIZE_SB32X32) {
- vp9_sub_pixel_variance16x2(above_ref + offset + 16,
- ref_y_stride,
+ row_offset = this_mv.as_mv.row >> 3;
+ col_offset = this_mv.as_mv.col >> 3;
+ offset = ref_y_stride * row_offset + col_offset;
+ score = 0;
+ if (xd->up_available) {
+ vp9_sub_pixel_variance16x2(above_ref + offset, ref_y_stride,
SP(this_mv.as_mv.col),
SP(this_mv.as_mv.row),
- above_src + 16, xd->dst.y_stride, &sse);
+ above_src, xd->dst.y_stride, &sse);
score += sse;
- }
- if (xd->mode_info_context->mbmi.sb_type >= BLOCK_SIZE_SB64X64) {
- vp9_sub_pixel_variance16x2(above_ref + offset + 32,
- ref_y_stride,
- SP(this_mv.as_mv.col),
- SP(this_mv.as_mv.row),
- above_src + 32, xd->dst.y_stride, &sse);
- score += sse;
- vp9_sub_pixel_variance16x2(above_ref + offset + 48,
- ref_y_stride,
- SP(this_mv.as_mv.col),
- SP(this_mv.as_mv.row),
- above_src + 48, xd->dst.y_stride, &sse);
- score += sse;
- }
- }
-#if !CONFIG_ABOVESPREFMV
- if (xd->left_available) {
- vp9_sub_pixel_variance2x16_c(left_ref + offset, ref_y_stride,
- SP(this_mv.as_mv.col),
- SP(this_mv.as_mv.row),
- left_src, xd->dst.y_stride, &sse);
- score += sse;
- if (xd->mode_info_context->mbmi.sb_type >= BLOCK_SIZE_SB32X32) {
- vp9_sub_pixel_variance2x16_c(left_ref + offset + ref_y_stride * 16,
+ if (xd->mode_info_context->mbmi.sb_type >= BLOCK_SIZE_SB32X32) {
+ vp9_sub_pixel_variance16x2(above_ref + offset + 16,
ref_y_stride,
SP(this_mv.as_mv.col),
SP(this_mv.as_mv.row),
- left_src + xd->dst.y_stride * 16,
- xd->dst.y_stride, &sse);
- score += sse;
- }
- if (xd->mode_info_context->mbmi.sb_type >= BLOCK_SIZE_SB64X64) {
- vp9_sub_pixel_variance2x16_c(left_ref + offset + ref_y_stride * 32,
+ above_src + 16, xd->dst.y_stride, &sse);
+ score += sse;
+ }
+ if (xd->mode_info_context->mbmi.sb_type >= BLOCK_SIZE_SB64X64) {
+ vp9_sub_pixel_variance16x2(above_ref + offset + 32,
ref_y_stride,
SP(this_mv.as_mv.col),
SP(this_mv.as_mv.row),
- left_src + xd->dst.y_stride * 32,
- xd->dst.y_stride, &sse);
- score += sse;
- vp9_sub_pixel_variance2x16_c(left_ref + offset + ref_y_stride * 48,
+ above_src + 32, xd->dst.y_stride, &sse);
+ score += sse;
+ vp9_sub_pixel_variance16x2(above_ref + offset + 48,
ref_y_stride,
SP(this_mv.as_mv.col),
SP(this_mv.as_mv.row),
- left_src + xd->dst.y_stride * 48,
- xd->dst.y_stride, &sse);
+ above_src + 48, xd->dst.y_stride, &sse);
+ score += sse;
+ }
+ }
+#if !CONFIG_ABOVESPREFMV
+ if (xd->left_available) {
+ vp9_sub_pixel_variance2x16_c(left_ref + offset, ref_y_stride,
+ SP(this_mv.as_mv.col),
+ SP(this_mv.as_mv.row),
+ left_src, xd->dst.y_stride, &sse);
score += sse;
+ if (xd->mode_info_context->mbmi.sb_type >= BLOCK_SIZE_SB32X32) {
+ vp9_sub_pixel_variance2x16_c(left_ref + offset + ref_y_stride * 16,
+ ref_y_stride,
+ SP(this_mv.as_mv.col),
+ SP(this_mv.as_mv.row),
+ left_src + xd->dst.y_stride * 16,
+ xd->dst.y_stride, &sse);
+ score += sse;
+ }
+ if (xd->mode_info_context->mbmi.sb_type >= BLOCK_SIZE_SB64X64) {
+ vp9_sub_pixel_variance2x16_c(left_ref + offset + ref_y_stride * 32,
+ ref_y_stride,
+ SP(this_mv.as_mv.col),
+ SP(this_mv.as_mv.row),
+ left_src + xd->dst.y_stride * 32,
+ xd->dst.y_stride, &sse);
+ score += sse;
+ vp9_sub_pixel_variance2x16_c(left_ref + offset + ref_y_stride * 48,
+ ref_y_stride,
+ SP(this_mv.as_mv.col),
+ SP(this_mv.as_mv.row),
+ left_src + xd->dst.y_stride * 48,
+ xd->dst.y_stride, &sse);
+ score += sse;
+ }
}
- }
#endif
- // Add the entry to our list and then resort the list on score.
- ref_scores[i] = score;
- sorted_mvs[i].as_int = this_mv.as_int;
- j = i;
- while (j > 0) {
- if (ref_scores[j] < ref_scores[j-1]) {
- ref_scores[j] = ref_scores[j-1];
- sorted_mvs[j].as_int = sorted_mvs[j-1].as_int;
- ref_scores[j-1] = score;
- sorted_mvs[j-1].as_int = this_mv.as_int;
- j--;
- } else
- break;
+ // Add the entry to our list and then resort the list on score.
+ ref_scores[i] = score;
+ sorted_mvs[i].as_int = this_mv.as_int;
+ j = i;
+ while (j > 0) {
+ if (ref_scores[j] < ref_scores[j-1]) {
+ ref_scores[j] = ref_scores[j-1];
+ sorted_mvs[j].as_int = sorted_mvs[j-1].as_int;
+ ref_scores[j-1] = score;
+ sorted_mvs[j-1].as_int = this_mv.as_int;
+ j--;
+ } else {
+ break;
+ }
+ }
}
+ } else {
+ vpx_memcpy(sorted_mvs, mvlist, sizeof(sorted_mvs));
}
// Make sure all the candidates are properly clamped etc
int_mv *nearest,
int_mv *near);
-static void mv_bias(int refmb_ref_frame_sign_bias, int refframe, int_mv *mvp, const int *ref_frame_sign_bias) {
+static void mv_bias(int refmb_ref_frame_sign_bias, int refframe,
+ int_mv *mvp, const int *ref_frame_sign_bias) {
MV xmv;
xmv = mvp->as_mv;
loop_filter_info_n *lfi = &cm->lf_info;
/* update limits if sharpness has changed */
+ // printf("vp9_loop_filter_frame_init %d\n", default_filt_lvl);
+ // printf("sharpness level: %d [%d]\n",
+ // cm->sharpness_level, cm->last_sharpness_level);
if (cm->last_sharpness_level != cm->sharpness_level) {
vp9_loop_filter_update_sharpness(lfi, cm->sharpness_level);
cm->last_sharpness_level = cm->sharpness_level;
mbmi1->mv[mbmi1->ref_frame].as_int) &&
mbmi0->ref_frame != INTRA_FRAME;
}
+
void vp9_loop_filter_frame(VP9_COMMON *cm,
MACROBLOCKD *xd,
int frame_filter_level,
vp9_loop_filter_bv(y_ptr, u_ptr, v_ptr, post->y_stride,
post->uv_stride, &lfi);
}
-
}
/* don't apply across umv border */
if (mb_row > 0 &&
split_count += (candidate_mi->mbmi.mode == SPLITMV);
}
}
- // Look in the last frame
- candidate_mi = lf_here;
- if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
- clamp_mv(xd, &c_refmv);
- addmv_and_shuffle(candidate_mvs, candidate_scores,
- &index, c_refmv, 18);
+ // Look in the last frame if it exists
+ if (lf_here) {
+ candidate_mi = lf_here;
+ if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
+ clamp_mv(xd, &c_refmv);
+ addmv_and_shuffle(candidate_mvs, candidate_scores,
+ &index, c_refmv, 18);
+ }
}
// More distant neigbours
for (i = 2; (i < MVREF_NEIGHBOURS) &&
}
}
}
- // Look at the last frame
- if (index < (MAX_MV_REF_CANDIDATES - 1)) {
+ // Look at the last frame if it exists
+ if (index < (MAX_MV_REF_CANDIDATES - 1) && lf_here) {
candidate_mi = lf_here;
get_non_matching_candidates(candidate_mi, ref_frame,
&c_ref_frame, &c_refmv,
// 0,0 is always a valid reference.
for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
- if (candidate_mvs[i].as_int == 0)
+ if (candidate_mvs[i].as_int == 0)
break;
}
if (i == MAX_MV_REF_CANDIDATES) {
int encode_breakout; // early breakout encode threshold : for video conf recommend 800
+ /* Bitfield defining the error resiliency features to enable.
+ * Can provide decodable frames after losses in previous
+ * frames and decodable partitions after losses in the same frame.
+ */
+ unsigned int error_resilient_mode;
+
int arnr_max_frames;
int arnr_strength;
int arnr_type;
int use_interintra;
#endif
+ int error_resilient_mode;
} VP9_COMMON;
static int get_free_fb(VP9_COMMON *cm) {
mv->col = read_nmv_component_fp(r, mv->col, ref->col, &mvctx->comps[1],
usehp);
}
- //printf(" %d: %d %d ref: %d %d\n", usehp, mv->row, mv-> col, ref->row, ref->col);
+ /*
+ printf("MV: %d %d REF: %d %d\n", mv->row + ref->row, mv->col + ref->col,
+ ref->row, ref->col);
+ */
}
static void update_nmv(vp9_reader *bc, vp9_prob *const p,
else
mbmi->ref_frame = read_ref_frame(pbi, bc, mbmi->segment_id);
+ /*
+ if (pbi->common.current_video_frame == 1)
+ printf("ref frame: %d [%d %d]\n", mbmi->ref_frame, mb_row, mb_col);
+ */
+
// If reference frame is an Inter frame
if (mbmi->ref_frame) {
int_mv nearest, nearby, best_mv;
printf("%d %d\n", xd->mode_info_context->mbmi.mv[0].as_mv.row,
xd->mode_info_context->mbmi.mv[0].as_mv.col);
#endif
- vp9_find_mv_refs(xd, mi, prev_mi,
+ // if (cm->current_video_frame == 1 && mb_row == 4 && mb_col == 5)
+ // printf("Dello\n");
+ vp9_find_mv_refs(xd, mi, cm->error_resilient_mode ? 0 : prev_mi,
ref_frame, mbmi->ref_mvs[ref_frame],
cm->ref_frame_sign_bias);
vp9_mv_ref_probs(&pbi->common, mv_ref_p,
mbmi->mb_mode_context[ref_frame]);
+ /*
+ if (pbi->common.current_video_frame == 1) {
+ int k = mbmi->mb_mode_context[ref_frame];
+ printf("vp9_mode_contexts: [%d %d %d %d] %d %d %d %d\n",
+ mb_row, mb_col, ref_frame, k,
+ cm->fc.vp9_mode_contexts[k][0],
+ cm->fc.vp9_mode_contexts[k][1],
+ cm->fc.vp9_mode_contexts[k][2],
+ cm->fc.vp9_mode_contexts[k][3]);
+ }
+ */
// Is the segment level mode feature enabled for this segment
if (vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_MODE)) {
if (mbmi->mode != ZEROMV) {
vp9_find_best_ref_mvs(xd,
- xd->pre.y_buffer,
+ pbi->common.error_resilient_mode ?
+ 0 : xd->pre.y_buffer,
recon_y_stride,
mbmi->ref_mvs[ref_frame],
&nearest, &nearby);
xd->second_pre.v_buffer =
cm->yv12_fb[second_ref_fb_idx].v_buffer + recon_uvoffset;
- vp9_find_mv_refs(xd, mi, prev_mi,
+ vp9_find_mv_refs(xd, mi, cm->error_resilient_mode ? 0 : prev_mi,
mbmi->second_ref_frame,
mbmi->ref_mvs[mbmi->second_ref_frame],
cm->ref_frame_sign_bias);
if (mbmi->mode != ZEROMV) {
vp9_find_best_ref_mvs(xd,
- xd->second_pre.y_buffer,
+ pbi->common.error_resilient_mode ?
+ 0 : xd->second_pre.y_buffer,
recon_y_stride,
mbmi->ref_mvs[mbmi->second_ref_frame],
&nearest_second,
pbi->common.fc.uv_mode_counts[mbmi->mode][mbmi->uv_mode]++;
}
}
+ /*
+ if (pbi->common.current_video_frame == 1)
+ printf("mode: %d skip: %d\n", mbmi->mode, mbmi->mb_skip_coeff);
+ */
if (cm->txfm_mode == TX_MODE_SELECT && mbmi->mb_skip_coeff == 0 &&
((mbmi->ref_frame == INTRA_FRAME && mbmi->mode <= I8X8_PRED) ||
mb_mode_mv_init(pbi, bc);
}
+
void vp9_decode_mb_mode_mv(VP9D_COMP* const pbi,
MACROBLOCKD* const xd,
int mb_row,
#include "vp9/decoder/vp9_dboolhuff.h"
#include "vp9/common/vp9_seg_common.h"
-#include "vp9/common/vp9_entropy.h"
#include "vp9_rtcd.h"
#include <assert.h>
MACROBLOCKD *const xd = &pbi->mb;
if (pc->frame_type == KEY_FRAME) {
- int i;
-
- if (pc->last_frame_seg_map)
- vpx_memset(pc->last_frame_seg_map, 0, (pc->mb_rows * pc->mb_cols));
-
- vp9_init_mv_probs(pc);
-
- vp9_init_mbmode_probs(pc);
- vp9_default_bmode_probs(pc->fc.bmode_prob);
-
- vp9_default_coef_probs(pc);
- vp9_kf_default_bmode_probs(pc->kf_bmode_prob);
-
- // Reset the segment feature data to the default stats:
- // Features disabled, 0, with delta coding (Default state).
- vp9_clearall_segfeatures(xd);
-
- xd->mb_segment_abs_delta = SEGMENT_DELTADATA;
-
- /* reset the mode ref deltasa for loop filter */
- vpx_memset(xd->ref_lf_deltas, 0, sizeof(xd->ref_lf_deltas));
- vpx_memset(xd->mode_lf_deltas, 0, sizeof(xd->mode_lf_deltas));
-
+ vp9_setup_past_independence(pc, xd);
/* All buffers are implicitly updated on key frames. */
pbi->refresh_frame_flags = (1 << NUM_REF_FRAMES) - 1;
+ } else if (pc->error_resilient_mode) {
+ vp9_setup_past_independence(pc, xd);
+ }
- /* Note that Golden and Altref modes cannot be used on a key frame so
- * ref_frame_sign_bias[] is undefined and meaningless
- */
- pc->ref_frame_sign_bias[GOLDEN_FRAME] = 0;
- pc->ref_frame_sign_bias[ALTREF_FRAME] = 0;
-
- vp9_init_mode_contexts(&pbi->common);
-
- for (i = 0; i < NUM_FRAME_CONTEXTS; i++)
- vpx_memcpy(&pc->frame_contexts[i], &pc->fc, sizeof(pc->fc));
-
- vpx_memset(pc->prev_mip, 0,
- (pc->mb_cols + 1) * (pc->mb_rows + 1)* sizeof(MODE_INFO));
- vpx_memset(pc->mip, 0,
- (pc->mb_cols + 1) * (pc->mb_rows + 1)* sizeof(MODE_INFO));
-
- vp9_update_mode_info_border(pc, pc->mip);
- vp9_update_mode_info_in_image(pc, pc->mi);
-
-
- } else {
-
+ if (pc->frame_type != KEY_FRAME) {
if (!pc->use_bilinear_mc_filter)
pc->mcomp_filter_type = EIGHTTAP;
else
xd->fullpixel_mask = 0xffffffff;
if (pc->full_pixel)
xd->fullpixel_mask = 0xfffffff8;
-
}
static void read_coef_probs_common(BOOL_DECODER* const bc,
int i, j;
int corrupt_tokens = 0;
+ // printf("Decoding frame %d\n", pc->current_video_frame);
/* start with no corruption of current frame */
xd->corrupted = 0;
pc->yv12_fb[pc->new_fb_idx].corrupted = 0;
}
}
}
-#ifdef DEC_DEBUG
- printf("Decode frame %d\n", pc->current_video_frame);
-#endif
if ((!pbi->decoded_key_frame && pc->frame_type != KEY_FRAME) ||
pc->Width == 0 || pc->Height == 0) {
pc->clamp_type = (CLAMP_TYPE)vp9_read_bit(&header_bc);
}
+ pc->error_resilient_mode = vp9_read_bit(&header_bc);
/* Is segmentation enabled */
xd->segmentation_enabled = (unsigned char)vp9_read_bit(&header_bc);
#if CONFIG_NEW_MVREF
// If Key frame reset mv ref id probabilities to defaults
- if (pc->frame_type == KEY_FRAME) {
- // Defaults probabilities for encoding the MV ref id signal
- vpx_memset(xd->mb_mv_ref_probs, VP9_DEFAULT_MV_REF_PROB,
- sizeof(xd->mb_mv_ref_probs));
- } else {
+ if (pc->frame_type != KEY_FRAME) {
// Read any mv_ref index probability updates
int i, j;
"A stream must start with a complete key frame");
}
- vp9_adapt_coef_probs(pc);
+ if (!pc->error_resilient_mode)
+ vp9_adapt_coef_probs(pc);
if (pc->frame_type != KEY_FRAME) {
- vp9_adapt_mode_probs(pc);
- vp9_adapt_nmv_probs(pc, xd->allow_high_precision_mv);
- vp9_update_mode_context(&pbi->common);
+ if (!pc->error_resilient_mode) {
+ vp9_adapt_mode_probs(pc);
+ vp9_adapt_nmv_probs(pc, xd->allow_high_precision_mv);
+ vp9_adapt_mode_context(&pbi->common);
+ }
}
if (pc->refresh_entropy_probs) {
fclose(f);
}
#endif
- // printf("Frame %d Done\n", frame_count++);
/* Find the end of the coded buffer */
while (residual_bc.count > CHAR_BIT
int old_cost, new_cost;
// Set the prediction probability structures to defaults
- if (cm->frame_type == KEY_FRAME) {
- // Set the prediction probabilities to defaults
- cm->ref_pred_probs[0] = 120;
- cm->ref_pred_probs[1] = 80;
- cm->ref_pred_probs[2] = 40;
-
- vpx_memset(cpi->ref_pred_probs_update, 0,
- sizeof(cpi->ref_pred_probs_update));
- } else {
+ if (cm->frame_type != KEY_FRAME) {
// From the prediction counts set the probabilities for each context
for (i = 0; i < PREDICTION_PROBS; i++) {
new_pred_probs[i] = get_binary_prob(cpi->ref_pred_count[i][0],
cm->ref_pred_probs[i] = new_pred_probs[i];
} else
cpi->ref_pred_probs_update[i] = 0;
-
}
}
}
vp9_sub_mv_ref_encoding_array - LEFT4X4 + m);
}
-static void write_nmv(vp9_writer *bc, const MV *mv, const int_mv *ref,
+static void write_nmv(VP9_COMP *cpi, vp9_writer *bc,
+ const MV *mv, const int_mv *ref,
const nmv_context *nmvc, int usehp) {
MV e;
e.row = mv->row - ref->as_mv.row;
vp9_mv_ref_probs(&cpi->common, mv_ref_p, mi->mb_mode_context[rf]);
- // #ifdef ENTROPY_STATS
#ifdef ENTROPY_STATS
accum_mv_refs(mode, ct);
active_section = 3;
#ifdef ENTROPY_STATS
active_section = 5;
#endif
- write_nmv(bc, &mi->mv[0].as_mv, &mi->best_mv,
+ write_nmv(cpi, bc, &mi->mv[0].as_mv, &mi->best_mv,
(const nmv_context*) nmvc,
xd->allow_high_precision_mv);
if (mi->second_ref_frame > 0) {
- write_nmv(bc, &mi->mv[1].as_mv, &mi->best_second_mv,
+ write_nmv(cpi, bc, &mi->mv[1].as_mv, &mi->best_second_mv,
(const nmv_context*) nmvc,
xd->allow_high_precision_mv);
}
#ifdef ENTROPY_STATS
active_section = 11;
#endif
- write_nmv(bc, &blockmv.as_mv, &mi->best_mv,
+ write_nmv(cpi, bc, &blockmv.as_mv, &mi->best_mv,
(const nmv_context*) nmvc,
xd->allow_high_precision_mv);
if (mi->second_ref_frame > 0) {
- write_nmv(bc,
+ write_nmv(cpi, bc,
&cpi->mb.partition_info->bmi[j].second_mv.as_mv,
&mi->best_second_mv,
(const nmv_context*) nmvc,
vp9_start_encode(&header_bc, cx_data);
}
+ // error resilient mode
+ vp9_write_bit(&header_bc, pc->error_resilient_mode);
+
// Signal whether or not Segmentation is enabled
vp9_write_bit(&header_bc, (xd->segmentation_enabled) ? 1 : 0);
if (pc->mcomp_filter_type == SWITCHABLE)
update_switchable_interp_probs(cpi, &header_bc);
- #if CONFIG_COMP_INTERINTRA_PRED
+#if CONFIG_COMP_INTERINTRA_PRED
if (pc->use_interintra) {
vp9_cond_prob_update(&header_bc,
&pc->fc.interintra_prob,
// if (!cpi->dummy_packing) vp9_zero(cpi->NMVcount);
write_modes(cpi, &residual_bc);
- vp9_update_mode_context(&cpi->common);
+ if (!cpi->common.error_resilient_mode)
+ vp9_adapt_mode_context(&cpi->common);
}
vp9_stop_encode(&residual_bc);
const int idx_map = mb_row * cm->mb_cols + mb_col;
const int idx_str = xd->mode_info_stride * mb_row + mb_col;
+#ifdef ENC_DEBUG
+ enc_debug = (cpi->common.current_video_frame == 2 &&
+ mb_row == 4 && mb_col == 5);
+#endif
// entropy context structures
xd->above_context = cm->above_context + mb_col;
xd->left_context = cm->left_context + (mb_row & 3);
assert(!xd->mode_info_context->mbmi.sb_type);
#ifdef ENC_DEBUG
- enc_debug = (cpi->common.current_video_frame == 46 &&
- mb_row == 5 && mb_col == 2);
+ enc_debug = (cpi->common.current_video_frame == 2 &&
+ mb_row == 5 && mb_col == 18);
if (enc_debug)
printf("Encode MB %d %d output %d\n", mb_row, mb_col, output_enabled);
#endif
}
if (!x->skip) {
-#ifdef ENC_DEBUG
+#if 0 // def ENC_DEBUG
if (enc_debug) {
int i, j;
printf("\n");
if (cpi->oxcf.cpu_used > 5)
cpi->oxcf.cpu_used = 5;
-
break;
case MODE_SECONDPASS_BEST:
for (i = 0; i < MAX_MODES; i++) {
cpi->rd_thresh_mult[i] = 128;
}
+
+ cm->error_resilient_mode = (cpi->oxcf.error_resilient_mode != 0);
}
// Test code for new segment features
}
// Set up entropy depending on frame type.
- if (cm->frame_type == KEY_FRAME)
+ if (cm->frame_type == KEY_FRAME) {
+ /* Choose which entropy context to use. When using a forward reference
+ * frame, it immediately follows the keyframe, and thus benefits from
+ * using the same entropy context established by the keyframe. Otherwise,
+ * use the default context 0.
+ */
+ cm->frame_context_idx = cpi->oxcf.play_alternate;
vp9_setup_key_frame(cpi);
- else
+ } else {
+ /* Choose which entropy context to use. Currently there are only two
+ * contexts used, one for normal frames and one for alt ref frames.
+ */
+ cpi->common.frame_context_idx = cpi->refresh_alt_ref_frame;
vp9_setup_inter_frame(cpi);
+ }
}
// transform / motion compensation build reconstruction frame
vp9_copy(cpi->common.fc.hybrid_coef_counts_16x16,
cpi->hybrid_coef_counts_16x16);
vp9_copy(cpi->common.fc.coef_counts_32x32, cpi->coef_counts_32x32);
- vp9_adapt_coef_probs(&cpi->common);
+ if (!cpi->common.error_resilient_mode)
+ vp9_adapt_coef_probs(&cpi->common);
if (cpi->common.frame_type != KEY_FRAME) {
vp9_copy(cpi->common.fc.sb_ymode_counts, cpi->sb_ymode_count);
vp9_copy(cpi->common.fc.ymode_counts, cpi->ymode_count);
#if CONFIG_COMP_INTERINTRA_PRED
vp9_copy(cpi->common.fc.interintra_counts, cpi->interintra_count);
#endif
- vp9_adapt_mode_probs(&cpi->common);
+ if (!cpi->common.error_resilient_mode)
+ vp9_adapt_mode_probs(&cpi->common);
cpi->common.fc.NMVcount = cpi->NMVcount;
- /*
- printf("2: %d %d %d %d\n", cpi->NMVcount.joints[0], cpi->NMVcount.joints[1],
- cpi->NMVcount.joints[2], cpi->NMVcount.joints[3]);
- */
- vp9_adapt_nmv_probs(&cpi->common, cpi->mb.e_mbd.allow_high_precision_mv);
+ if (!cpi->common.error_resilient_mode)
+ vp9_adapt_nmv_probs(&cpi->common, cpi->mb.e_mbd.allow_high_precision_mv);
}
#if CONFIG_COMP_INTERINTRA_PRED
if (cm->frame_type != KEY_FRAME)
#include "vp9/common/vp9_systemdependent.h"
#include "vp9/encoder/vp9_encodemv.h"
#include "vp9/common/vp9_quant_common.h"
+#include "vp9/common/vp9_seg_common.h"
#define MIN_BPB_FACTOR 0.005
#define MAX_BPB_FACTOR 50
#endif
}
-
void vp9_setup_key_frame(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
- int i;
-
- // Setup for Key frame:
- vp9_default_coef_probs(& cpi->common);
- vp9_kf_default_bmode_probs(cpi->common.kf_bmode_prob);
- vp9_init_mbmode_probs(& cpi->common);
- vp9_default_bmode_probs(cm->fc.bmode_prob);
-
- if(cm->last_frame_seg_map)
- vpx_memset(cm->last_frame_seg_map, 0, (cm->mb_rows * cm->mb_cols));
-
- vp9_init_mv_probs(& cpi->common);
+ MACROBLOCKD *xd = &cpi->mb.e_mbd;
- // cpi->common.filter_level = 0; // Reset every key frame.
- cpi->common.filter_level = cpi->common.base_qindex * 3 / 8;
+ vp9_setup_past_independence(cm, xd);
// interval before next GF
cpi->frames_till_gf_update_due = cpi->baseline_gf_interval;
-
+ /* All buffers are implicitly updated on key frames. */
cpi->refresh_golden_frame = TRUE;
cpi->refresh_alt_ref_frame = TRUE;
-
- vp9_init_mode_contexts(&cpi->common);
-
- for (i = 0; i < NUM_FRAME_CONTEXTS; i++)
- vpx_memcpy(&cpi->common.frame_contexts[i], &cpi->common.fc,
- sizeof(cpi->common.fc));
-
- vpx_memset(cm->prev_mip, 0,
- (cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO));
- vpx_memset(cm->mip, 0,
- (cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO));
-
- vp9_update_mode_info_border(cm, cm->mip);
- vp9_update_mode_info_in_image(cm, cm->mi);
-
-#if CONFIG_NEW_MVREF
- if (1) {
- MACROBLOCKD *xd = &cpi->mb.e_mbd;
-
- // Defaults probabilities for encoding the MV ref id signal
- vpx_memset(xd->mb_mv_ref_probs, VP9_DEFAULT_MV_REF_PROB,
- sizeof(xd->mb_mv_ref_probs));
- }
-#endif
-
- /* Choose which entropy context to use. When using a forward reference
- * frame, it immediately follows the keyframe, and thus benefits from
- * using the same entropy context established by the keyframe. Otherwise,
- * use the default context 0.
- */
- cm->frame_context_idx = cpi->oxcf.play_alternate;
}
void vp9_setup_inter_frame(VP9_COMP *cpi) {
- /* Choose which entropy context to use. Currently there are only two
- * contexts used, one for normal frames and one for alt ref frames.
- */
- cpi->common.frame_context_idx = cpi->refresh_alt_ref_frame;
-
- assert(cpi->common.frame_context_idx < NUM_FRAME_CONTEXTS);
- vpx_memcpy(&cpi->common.fc,
- &cpi->common.frame_contexts[cpi->common.frame_context_idx],
- sizeof(cpi->common.fc));
+ VP9_COMMON *cm = &cpi->common;
+ MACROBLOCKD *xd = &cpi->mb.e_mbd;
+ if (cm->error_resilient_mode) {
+ vp9_setup_past_independence(cm, xd);
+ }
+ assert(cm->frame_context_idx < NUM_FRAME_CONTEXTS);
+ vpx_memcpy(&cm->fc, &cm->frame_contexts[cm->frame_context_idx],
+ sizeof(cm->fc));
}
-
static int estimate_bits_at_q(int frame_kind, int Q, int MBs,
double correction_factor) {
int Bpm = (int)(.5 + correction_factor * vp9_bits_per_mb(frame_kind, Q));
// Gets an initial list of candidate vectors from neighbours and orders them
vp9_find_mv_refs(xd, xd->mode_info_context,
- xd->prev_mode_info_context,
+ cpi->common.error_resilient_mode ?
+ 0 : xd->prev_mode_info_context,
frame_type,
mbmi->ref_mvs[frame_type],
cpi->common.ref_frame_sign_bias);
// Candidate refinement carried out at encoder and decoder
- vp9_find_best_ref_mvs(xd, y_buffer[frame_type],
+ vp9_find_best_ref_mvs(xd,
+ cpi->common.error_resilient_mode ?
+ 0 : y_buffer[frame_type],
yv12->y_stride,
mbmi->ref_mvs[frame_type],
&frame_nearest_mv[frame_type],
&frame_near_mv[frame_type]);
-
// Further refinement that is encode side only to test the top few candidates
// in full and choose the best as the centre point for subsequent searches.
mv_pred(cpi, x, y_buffer[frame_type], yv12->y_stride,
oxcf->lossless = vp8_cfg.lossless;
#endif
+ oxcf->error_resilient_mode = cfg.g_error_resilient;
/*
- printf("Current VP8 Settings: \n");
- printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
- printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity);
- printf("Sharpness: %d\n", oxcf->Sharpness);
- printf("cpu_used: %d\n", oxcf->cpu_used);
- printf("Mode: %d\n", oxcf->Mode);
- printf("delete_first_pass_file: %d\n", oxcf->delete_first_pass_file);
- printf("auto_key: %d\n", oxcf->auto_key);
- printf("key_freq: %d\n", oxcf->key_freq);
- printf("end_usage: %d\n", oxcf->end_usage);
- printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct);
- printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct);
- printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level);
- printf("optimal_buffer_level: %d\n", oxcf->optimal_buffer_level);
- printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size);
- printf("fixed_q: %d\n", oxcf->fixed_q);
- printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q);
- printf("best_allowed_q: %d\n", oxcf->best_allowed_q);
- printf("two_pass_vbrbias: %d\n", oxcf->two_pass_vbrbias);
- printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section);
- printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section);
- printf("allow_lag: %d\n", oxcf->allow_lag);
- printf("lag_in_frames: %d\n", oxcf->lag_in_frames);
- printf("play_alternate: %d\n", oxcf->play_alternate);
- printf("Version: %d\n", oxcf->Version);
- printf("encode_breakout: %d\n", oxcf->encode_breakout);
+ printf("Current VP9 Settings: \n");
+ printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
+ printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity);
+ printf("Sharpness: %d\n", oxcf->Sharpness);
+ printf("cpu_used: %d\n", oxcf->cpu_used);
+ printf("Mode: %d\n", oxcf->Mode);
+ // printf("delete_first_pass_file: %d\n", oxcf->delete_first_pass_file);
+ printf("auto_key: %d\n", oxcf->auto_key);
+ printf("key_freq: %d\n", oxcf->key_freq);
+ printf("end_usage: %d\n", oxcf->end_usage);
+ printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct);
+ printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct);
+ printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level);
+ printf("optimal_buffer_level: %d\n", oxcf->optimal_buffer_level);
+ printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size);
+ printf("fixed_q: %d\n", oxcf->fixed_q);
+ printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q);
+ printf("best_allowed_q: %d\n", oxcf->best_allowed_q);
+ printf("two_pass_vbrbias: %d\n", oxcf->two_pass_vbrbias);
+ printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section);
+ printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section);
+ printf("allow_lag: %d\n", oxcf->allow_lag);
+ printf("lag_in_frames: %d\n", oxcf->lag_in_frames);
+ printf("play_alternate: %d\n", oxcf->play_alternate);
+ printf("Version: %d\n", oxcf->Version);
+ printf("encode_breakout: %d\n", oxcf->encode_breakout);
+ printf("error resilient: %d\n", oxcf->error_resilient_mode);
*/
return VPX_CODEC_OK;
}
long deadline) {
const uint8_t *data_start = data;
const uint8_t *data_end = data + data_sz;
- vpx_codec_err_t res;
+ vpx_codec_err_t res = 0;
do {
res = decode_one(ctx, &data_start, data_sz, user_priv, deadline);
#define mmin(a, b) ((a) < (b) ? (a) : (b))
static void find_mismatch(vpx_image_t *img1, vpx_image_t *img2,
int yloc[2], int uloc[2], int vloc[2]) {
+ static const int bsize = 64;
+ static const int bsize2 = bsize >> 1;
int match = 1;
int i, j;
yloc[0] = yloc[1] = -1;
- for (i = 0, match = 1; match && i < img1->d_h; i+=32) {
- for (j = 0; match && j < img1->d_w; j+=32) {
+ for (i = 0, match = 1; match && i < img1->d_h; i += bsize) {
+ for (j = 0; match && j < img1->d_w; j += bsize) {
int k, l;
- int si = mmin(i + 32, img1->d_h) - i;
- int sj = mmin(j + 32, img1->d_w) - j;
+ int si = mmin(i + bsize, img1->d_h) - i;
+ int sj = mmin(j + bsize, img1->d_w) - j;
for (k = 0; match && k < si; k++)
for (l = 0; match && l < sj; l++) {
if (*(img1->planes[VPX_PLANE_Y] +
}
}
uloc[0] = uloc[1] = -1;
- for (i = 0, match = 1; match && i < (img1->d_h + 1) / 2; i+=16) {
- for (j = 0; j < match && (img1->d_w + 1) / 2; j+=16) {
+ for (i = 0, match = 1; match && i < (img1->d_h + 1) / 2; i += bsize2) {
+ for (j = 0; j < match && (img1->d_w + 1) / 2; j += bsize2) {
int k, l;
- int si = mmin(i + 16, (img1->d_h + 1) / 2) - i;
- int sj = mmin(j + 16, (img1->d_w + 1) / 2) - j;
+ int si = mmin(i + bsize2, (img1->d_h + 1) / 2) - i;
+ int sj = mmin(j + bsize2, (img1->d_w + 1) / 2) - j;
for (k = 0; match && k < si; k++)
for (l = 0; match && l < sj; l++) {
if (*(img1->planes[VPX_PLANE_U] +
}
}
vloc[0] = vloc[1] = -1;
- for (i = 0, match = 1; match && i < (img1->d_h + 1) / 2; i+=16) {
- for (j = 0; j < match && (img1->d_w + 1) / 2; j+=16) {
+ for (i = 0, match = 1; match && i < (img1->d_h + 1) / 2; i += bsize2) {
+ for (j = 0; j < match && (img1->d_w + 1) / 2; j += bsize2) {
int k, l;
- int si = mmin(i + 16, (img1->d_h + 1) / 2) - i;
- int sj = mmin(j + 16, (img1->d_w + 1) / 2) - j;
+ int si = mmin(i + bsize2, (img1->d_h + 1) / 2) - i;
+ int sj = mmin(j + bsize2, (img1->d_w + 1) / 2) - j;
for (k = 0; match && k < si; k++)
for (l = 0; match && l < sj; l++) {
if (*(img1->planes[VPX_PLANE_V] +