diff options
48 files changed, 642 insertions, 902 deletions
diff --git a/build/make/Makefile b/build/make/Makefile index dd7fb4a21..0c5ff64f4 100644 --- a/build/make/Makefile +++ b/build/make/Makefile @@ -147,6 +147,15 @@ $(BUILD_PFX)%.cc.o: %.cc $(if $(quiet),@echo " [CXX] $@") $(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $< +$(BUILD_PFX)%.cpp.d: %.cpp + $(if $(quiet),@echo " [DEP] $@") + $(qexec)mkdir -p $(dir $@) + $(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -M $< | $(fmt_deps) > $@ + +$(BUILD_PFX)%.cpp.o: %.cpp + $(if $(quiet),@echo " [CXX] $@") + $(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $< + $(BUILD_PFX)%.asm.d: %.asm $(if $(quiet),@echo " [DEP] $@") $(qexec)mkdir -p $(dir $@) @@ -218,7 +227,7 @@ cond_enabled=$(if $(filter yes,$($(1))), $(call enabled,$(2))) find_file1=$(word 1,$(wildcard $(subst //,/,$(addsuffix /$(1),$(2))))) find_file=$(foreach f,$(1),$(call find_file1,$(strip $(f)),$(strip $(2))) ) -obj_pats=.c=.c.o $(AS_SFX)=$(AS_SFX).o .cc=.cc.o +obj_pats=.c=.c.o $(AS_SFX)=$(AS_SFX).o .cc=.cc.o .cpp=.cpp.o objs=$(addprefix $(BUILD_PFX),$(foreach p,$(obj_pats),$(filter %.o,$(1:$(p))) )) install_map_templates=$(eval $(call install_map_template,$(1),$(2))) @@ -704,13 +704,11 @@ process_toolchain() { enabled postproc || die "postproc_visualizer requires postproc to be enabled" fi - # Enable WebM IO by default. - soft_enable webm_io - # Enable unit tests by default if we have a working C++ compiler. case "$toolchain" in *-vs*) soft_enable unit_tests + soft_enable webm_io ;; *-android-*) # GTestLog must be modified to use Android logging utilities. @@ -726,13 +724,21 @@ process_toolchain() { check_cxx "$@" <<EOF && soft_enable unit_tests int z; EOF + check_cxx "$@" <<EOF && soft_enable webm_io +int z; +EOF ;; *) enabled pthread_h && check_cxx "$@" <<EOF && soft_enable unit_tests int z; EOF + check_cxx "$@" <<EOF && soft_enable webm_io +int z; +EOF ;; esac + # libwebm needs to be linked with C++ standard library + enabled webm_io && LD=${CXX} } diff --git a/examples.mk b/examples.mk index 87be5a8c9..f091c2de4 100644 --- a/examples.mk +++ b/examples.mk @@ -15,6 +15,16 @@ LIBYUV_SRCS += third_party/libyuv/include/libyuv/basic_types.h \ third_party/libyuv/source/scale.c \ third_party/libyuv/source/cpu_id.c +LIBWEBM_MUXER_SRCS += third_party/libwebm/mkvmuxer.cpp \ + third_party/libwebm/mkvmuxerutil.cpp \ + third_party/libwebm/mkvwriter.cpp \ + third_party/libwebm/mkvmuxer.hpp \ + third_party/libwebm/mkvmuxertypes.hpp \ + third_party/libwebm/mkvmuxerutil.hpp \ + third_party/libwebm/mkvparser.hpp \ + third_party/libwebm/mkvwriter.hpp \ + third_party/libwebm/webmids.hpp + # List of examples to build. UTILS are tools meant for distribution # while EXAMPLES demonstrate specific portions of the API. UTILS-$(CONFIG_DECODERS) += vpxdec.c @@ -53,10 +63,8 @@ vpxenc.SRCS += vpx_ports/vpx_timer.h vpxenc.SRCS += vpxstats.c vpxstats.h vpxenc.SRCS += $(LIBYUV_SRCS) ifeq ($(CONFIG_WEBM_IO),yes) - vpxenc.SRCS += third_party/libmkv/EbmlIDs.h - vpxenc.SRCS += third_party/libmkv/EbmlWriter.c - vpxenc.SRCS += third_party/libmkv/EbmlWriter.h - vpxenc.SRCS += webmenc.c webmenc.h + vpxenc.SRCS += $(LIBWEBM_MUXER_SRCS) + vpxenc.SRCS += webmenc.cc webmenc.h endif vpxenc.GUID = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1 vpxenc.DESCRIPTION = Full featured encoder diff --git a/test/android/scrape_gtest_log.py b/test/android/scrape_gtest_log.py new file mode 100644 index 000000000..c159c8938 --- /dev/null +++ b/test/android/scrape_gtest_log.py @@ -0,0 +1,28 @@ +# Copyright (c) 2014 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. + +"""Standalone script which parses a gtest log for json. + +Json is returned returns as an array. This script is used by the libvpx +waterfall to gather json results mixed in with gtest logs. This is +dubious software engineering. +""" + +import json +import re +import sys + + +def main(): + blob = sys.stdin.read() + json_string = '[' + ','.join('{' + x + '}' for x in + re.findall(r'{([^}]*.?)}', blob)) + ']' + print json.dumps(json.loads(json_string), indent=4, sort_keys=True) + +if __name__ == '__main__': + sys.exit(main()) diff --git a/test/datarate_test.cc b/test/datarate_test.cc index 8f7cc7a37..1b921f0a1 100644 --- a/test/datarate_test.cc +++ b/test/datarate_test.cc @@ -580,8 +580,8 @@ VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES); VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large, ::testing::Values(::libvpx_test::kOnePassGood, ::libvpx_test::kRealTime), - ::testing::Range(2, 6)); -// TODO(marpan): Speed 6 and 7 fails on one of these tests, for -// real-time mode. So for now test up to speed 5, and start at 2 + ::testing::Range(2, 5)); +// TODO(marpan): Speed 5 to 7 fails on one of these tests, for +// real-time mode. So for now test up to speed 4, and start at 2 // (since speed 0 and 1 are slow). Enable more speeds when issue is fixed. } // namespace diff --git a/test/test-data.sha1 b/test/test-data.sha1 index 1a6406b59..b8f668a78 100644 --- a/test/test-data.sha1 +++ b/test/test-data.sha1 @@ -589,3 +589,5 @@ b3c48382cf7d0454e83a02497c229d27720f9e20 vp90-2-11-size-351x287.webm.md5 92a756469fa438220524e7fa6ac1d38c89514d17 vp90-2-12-droppable_2.ivf.md5 c21e97e4ba486520118d78b01a5cb6e6dc33e190 vp90-2-12-droppable_3.ivf 601abc9e4176c70f82ac0381365e9b151fdd24cd vp90-2-12-droppable_3.ivf.md5 +61c640dad23cd4f7ad811b867e7b7e3521f4e3ba vp90-2-13-largescaling.webm +bca1b02eebdb088fa3f389fe0e7571e75a71f523 vp90-2-13-largescaling.webm.md5 diff --git a/test/test.mk b/test/test.mk index 31baf059c..4d96bc69d 100644 --- a/test/test.mk +++ b/test/test.mk @@ -694,6 +694,8 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_2.ivf LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_2.ivf.md5 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_3.ivf LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_3.ivf.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-13-largescaling.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-13-largescaling.webm.md5 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yv444.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yv444.webm.md5 diff --git a/test/test_vectors.cc b/test/test_vectors.cc index 175151eaf..8c789ffe7 100644 --- a/test/test_vectors.cc +++ b/test/test_vectors.cc @@ -164,7 +164,7 @@ const char *const kVP9TestVectors[] = { "vp90-2-11-size-351x287.webm", "vp90-2-11-size-351x288.webm", "vp90-2-11-size-352x287.webm", "vp90-2-12-droppable_1.ivf", "vp90-2-12-droppable_2.ivf", "vp90-2-12-droppable_3.ivf", - "vp91-2-04-yv444.webm" + "vp90-2-13-largescaling.webm", "vp91-2-04-yv444.webm" }; const int kNumVP9TestVectors = NELEMENTS(kVP9TestVectors); #endif // CONFIG_VP9_DECODER diff --git a/vp9/common/vp9_alloccommon.c b/vp9/common/vp9_alloccommon.c index 0f26f6e76..f44ada1b9 100644 --- a/vp9/common/vp9_alloccommon.c +++ b/vp9/common/vp9_alloccommon.c @@ -21,17 +21,17 @@ static void clear_mi_border(const VP9_COMMON *cm, MODE_INFO *mi) { int i; // Top border row - vpx_memset(mi, 0, sizeof(*mi) * cm->mode_info_stride); + vpx_memset(mi, 0, sizeof(*mi) * cm->mi_stride); // Left border column for (i = 1; i < cm->mi_rows + 1; ++i) - vpx_memset(&mi[i * cm->mode_info_stride], 0, sizeof(*mi)); + vpx_memset(&mi[i * cm->mi_stride], 0, sizeof(*mi)); } static void set_mb_mi(VP9_COMMON *cm, int aligned_width, int aligned_height) { cm->mi_cols = aligned_width >> MI_SIZE_LOG2; cm->mi_rows = aligned_height >> MI_SIZE_LOG2; - cm->mode_info_stride = cm->mi_cols + MI_BLOCK_SIZE; + cm->mi_stride = cm->mi_cols + MI_BLOCK_SIZE; cm->mb_cols = (cm->mi_cols + 1) >> 1; cm->mb_rows = (cm->mi_rows + 1) >> 1; @@ -39,17 +39,15 @@ static void set_mb_mi(VP9_COMMON *cm, int aligned_width, int aligned_height) { } static void setup_mi(VP9_COMMON *cm) { - cm->mi = cm->mip + cm->mode_info_stride + 1; - cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1; - cm->mi_grid_visible = cm->mi_grid_base + cm->mode_info_stride + 1; - cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mode_info_stride + 1; + cm->mi = cm->mip + cm->mi_stride + 1; + cm->prev_mi = cm->prev_mip + cm->mi_stride + 1; + cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1; + cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1; - vpx_memset(cm->mip, 0, - cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(*cm->mip)); + vpx_memset(cm->mip, 0, cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip)); - vpx_memset(cm->mi_grid_base, 0, - cm->mode_info_stride * (cm->mi_rows + 1) * - sizeof(*cm->mi_grid_base)); + vpx_memset(cm->mi_grid_base, 0, cm->mi_stride * (cm->mi_rows + 1) * + sizeof(*cm->mi_grid_base)); clear_mi_border(cm, cm->prev_mip); } @@ -128,7 +126,7 @@ int vp9_resize_frame_buffers(VP9_COMMON *cm, int width, int height) { set_mb_mi(cm, aligned_width, aligned_height); free_mi(cm); - if (alloc_mi(cm, cm->mode_info_stride * (cm->mi_rows + MI_BLOCK_SIZE))) + if (alloc_mi(cm, cm->mi_stride * (cm->mi_rows + MI_BLOCK_SIZE))) goto fail; setup_mi(cm); @@ -191,7 +189,7 @@ int vp9_alloc_frame_buffers(VP9_COMMON *cm, int width, int height) { set_mb_mi(cm, aligned_width, aligned_height); - if (alloc_mi(cm, cm->mode_info_stride * (cm->mi_rows + MI_BLOCK_SIZE))) + if (alloc_mi(cm, cm->mi_stride * (cm->mi_rows + MI_BLOCK_SIZE))) goto fail; setup_mi(cm); @@ -248,8 +246,8 @@ void vp9_swap_mi_and_prev_mi(VP9_COMMON *cm) { cm->mi_grid_base = temp2; // Update the upper left visible macroblock ptrs. - cm->mi = cm->mip + cm->mode_info_stride + 1; - cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1; - cm->mi_grid_visible = cm->mi_grid_base + cm->mode_info_stride + 1; - cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mode_info_stride + 1; + cm->mi = cm->mip + cm->mi_stride + 1; + cm->prev_mi = cm->prev_mip + cm->mi_stride + 1; + cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1; + cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1; } diff --git a/vp9/common/vp9_blockd.c b/vp9/common/vp9_blockd.c index e1d1318ac..fedfb18d9 100644 --- a/vp9/common/vp9_blockd.c +++ b/vp9/common/vp9_blockd.c @@ -40,7 +40,7 @@ void vp9_foreach_transformed_block_in_plane( const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int plane, foreach_transformed_block_visitor visit, void *arg) { const struct macroblockd_plane *const pd = &xd->plane[plane]; - const MB_MODE_INFO* mbmi = &xd->mi_8x8[0]->mbmi; + const MB_MODE_INFO* mbmi = &xd->mi[0]->mbmi; // block and transform sizes, in number of 4x4 blocks log 2 ("*_b") // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8 // transform size varies per plane, look it up in a common way. diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index 05ff3a786..1f7e6329d 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -204,10 +204,10 @@ typedef struct RefBuffer { typedef struct macroblockd { struct macroblockd_plane plane[MAX_MB_PLANE]; - int mode_info_stride; + int mi_stride; // A NULL indicates that the 8x8 is not part of the image - MODE_INFO **mi_8x8; + MODE_INFO **mi; int up_available; int left_available; @@ -244,13 +244,6 @@ typedef struct macroblockd { PARTITION_CONTEXT left_seg_context[8]; } MACROBLOCKD; -static INLINE void init_macroblockd(MACROBLOCKD *xd) { - int i; - - for (i = 0; i < MAX_MB_PLANE; ++i) - xd->plane[i].dqcoeff = xd->dqcoeff[i]; -} - static INLINE BLOCK_SIZE get_subsize(BLOCK_SIZE bsize, PARTITION_TYPE partition) { const BLOCK_SIZE subsize = subsize_lookup[partition][bsize]; @@ -262,7 +255,7 @@ extern const TX_TYPE intra_mode_to_tx_type_lookup[INTRA_MODES]; static INLINE TX_TYPE get_tx_type(PLANE_TYPE plane_type, const MACROBLOCKD *xd) { - const MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; if (plane_type != PLANE_TYPE_Y || is_inter_block(mbmi)) return DCT_DCT; @@ -271,7 +264,7 @@ static INLINE TX_TYPE get_tx_type(PLANE_TYPE plane_type, static INLINE TX_TYPE get_tx_type_4x4(PLANE_TYPE plane_type, const MACROBLOCKD *xd, int ib) { - const MODE_INFO *const mi = xd->mi_8x8[0]; + const MODE_INFO *const mi = xd->mi[0]; if (plane_type != PLANE_TYPE_Y || xd->lossless || is_inter_block(&mi->mbmi)) return DCT_DCT; diff --git a/vp9/common/vp9_entropy.h b/vp9/common/vp9_entropy.h index 15bf8ebb3..6788eb698 100644 --- a/vp9/common/vp9_entropy.h +++ b/vp9/common/vp9_entropy.h @@ -175,7 +175,7 @@ static INLINE int get_entropy_context(TX_SIZE tx_size, const ENTROPY_CONTEXT *a, static const INLINE scan_order *get_scan(const MACROBLOCKD *xd, TX_SIZE tx_size, PLANE_TYPE type, int block_idx) { - const MODE_INFO *const mi = xd->mi_8x8[0]; + const MODE_INFO *const mi = xd->mi[0]; if (is_inter_block(&mi->mbmi) || type != PLANE_TYPE_Y || xd->lossless) { return &vp9_default_scan_orders[tx_size]; diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c index f2c81bc0a..5b00b0082 100644 --- a/vp9/common/vp9_entropymode.c +++ b/vp9/common/vp9_entropymode.c @@ -465,11 +465,10 @@ void vp9_setup_past_independence(VP9_COMMON *cm) { } if (frame_is_intra_only(cm)) - vpx_memset(cm->prev_mip, 0, - cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO)); + vpx_memset(cm->prev_mip, 0, cm->mi_stride * (cm->mi_rows + 1) * + sizeof(*cm->prev_mip)); - vpx_memset(cm->mip, 0, - cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO)); + vpx_memset(cm->mip, 0, cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip)); vp9_zero(cm->ref_frame_sign_bias); diff --git a/vp9/common/vp9_loopfilter.c b/vp9/common/vp9_loopfilter.c index e48d4178b..3ac5a0577 100644 --- a/vp9/common/vp9_loopfilter.c +++ b/vp9/common/vp9_loopfilter.c @@ -909,7 +909,7 @@ static void filter_block_plane_non420(VP9_COMMON *cm, const int ss_y = plane->subsampling_y; const int row_step = 1 << ss_x; const int col_step = 1 << ss_y; - const int row_step_stride = cm->mode_info_stride * row_step; + const int row_step_stride = cm->mi_stride * row_step; struct buf_2d *const dst = &plane->dst; uint8_t* const dst0 = dst->buf; unsigned int mask_16x16[MI_BLOCK_SIZE] = {0}; @@ -1201,7 +1201,7 @@ void vp9_loop_filter_rows(const YV12_BUFFER_CONFIG *frame_buffer, xd->plane[1].subsampling_x == 1); for (mi_row = start; mi_row < stop; mi_row += MI_BLOCK_SIZE) { - MODE_INFO **mi_8x8 = cm->mi_grid_visible + mi_row * cm->mode_info_stride; + MODE_INFO **mi_8x8 = cm->mi_grid_visible + mi_row * cm->mi_stride; for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MI_BLOCK_SIZE) { int plane; @@ -1210,8 +1210,8 @@ void vp9_loop_filter_rows(const YV12_BUFFER_CONFIG *frame_buffer, // TODO(JBB): Make setup_mask work for non 420. if (use_420) - vp9_setup_mask(cm, mi_row, mi_col, mi_8x8 + mi_col, - cm->mode_info_stride, &lfm); + vp9_setup_mask(cm, mi_row, mi_col, mi_8x8 + mi_col, cm->mi_stride, + &lfm); for (plane = 0; plane < num_planes; ++plane) { if (use_420) diff --git a/vp9/common/vp9_mvref_common.c b/vp9/common/vp9_mvref_common.c index c043e6c5b..9d3380801 100644 --- a/vp9/common/vp9_mvref_common.c +++ b/vp9/common/vp9_mvref_common.c @@ -194,7 +194,7 @@ static void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, const int *ref_sign_bias = cm->ref_frame_sign_bias; int i, refmv_count = 0; const MODE_INFO *prev_mi = cm->coding_use_prev_mi && cm->prev_mi - ? cm->prev_mi_grid_visible[mi_row * xd->mode_info_stride + mi_col] + ? cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col] : NULL; const MB_MODE_INFO *const prev_mbmi = prev_mi ? &prev_mi->mbmi : NULL; @@ -213,8 +213,8 @@ static void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, for (i = 0; i < 2; ++i) { const POSITION *const mv_ref = &mv_ref_search[i]; if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { - const MODE_INFO *const candidate_mi = xd->mi_8x8[mv_ref->col + mv_ref->row - * xd->mode_info_stride]; + const MODE_INFO *const candidate_mi = xd->mi[mv_ref->col + mv_ref->row * + xd->mi_stride]; const MB_MODE_INFO *const candidate = &candidate_mi->mbmi; // Keep counts for entropy encoding. context_counter += mode_2_counter[candidate->mode]; @@ -233,9 +233,8 @@ static void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, for (; i < MVREF_NEIGHBOURS; ++i) { const POSITION *const mv_ref = &mv_ref_search[i]; if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { - const MB_MODE_INFO *const candidate = &xd->mi_8x8[mv_ref->col + - mv_ref->row - * xd->mode_info_stride]->mbmi; + const MB_MODE_INFO *const candidate = &xd->mi[mv_ref->col + mv_ref->row * + xd->mi_stride]->mbmi; different_ref_found = 1; if (candidate->ref_frame[0] == ref_frame) @@ -260,9 +259,8 @@ static void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, for (i = 0; i < MVREF_NEIGHBOURS; ++i) { const POSITION *mv_ref = &mv_ref_search[i]; if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { - const MB_MODE_INFO *const candidate = &xd->mi_8x8[mv_ref->col + - mv_ref->row - * xd->mode_info_stride]->mbmi; + const MB_MODE_INFO *const candidate = &xd->mi[mv_ref->col + mv_ref->row + * xd->mi_stride]->mbmi; // If the candidate is INTRA we don't want to consider its mv. if (is_inter_block(candidate)) @@ -321,7 +319,7 @@ void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd, 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]; + MODE_INFO *const mi = xd->mi[0]; b_mode_info *bmi = mi->bmi; int n; diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index f564afb9e..ea1b8856e 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h @@ -126,7 +126,7 @@ typedef struct VP9Common { int MBs; int mb_rows, mi_rows; int mb_cols, mi_cols; - int mode_info_stride; + int mi_stride; /* profile settings */ TX_MODE tx_mode; @@ -237,24 +237,33 @@ static INLINE int mi_cols_aligned_to_sb(int n_mis) { return ALIGN_POWER_OF_TWO(n_mis, MI_BLOCK_SIZE_LOG2); } +static INLINE void init_macroblockd(VP9_COMMON *cm, MACROBLOCKD *xd) { + int i; + + for (i = 0; i < MAX_MB_PLANE; ++i) { + xd->plane[i].dqcoeff = xd->dqcoeff[i]; + xd->above_context[i] = cm->above_context + + i * sizeof(*cm->above_context) * 2 * mi_cols_aligned_to_sb(cm->mi_cols); + } + + xd->above_seg_context = cm->above_seg_context; + xd->mi_stride = cm->mi_stride; +} + static INLINE const vp9_prob* get_partition_probs(const VP9_COMMON *cm, int ctx) { return cm->frame_type == KEY_FRAME ? vp9_kf_partition_probs[ctx] : cm->fc.partition_prob[ctx]; } -static INLINE void set_skip_context( - MACROBLOCKD *xd, - ENTROPY_CONTEXT *above_context[MAX_MB_PLANE], - ENTROPY_CONTEXT left_context[MAX_MB_PLANE][16], - int mi_row, int mi_col) { +static INLINE void set_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col) { const int above_idx = mi_col * 2; const int left_idx = (mi_row * 2) & 15; int i; - for (i = 0; i < MAX_MB_PLANE; i++) { + for (i = 0; i < MAX_MB_PLANE; ++i) { struct macroblockd_plane *const pd = &xd->plane[i]; - pd->above_context = above_context[i] + (above_idx >> pd->subsampling_x); - pd->left_context = left_context[i] + (left_idx >> pd->subsampling_y); + pd->above_context = &xd->above_context[i][above_idx >> pd->subsampling_x]; + pd->left_context = &xd->left_context[i][left_idx >> pd->subsampling_y]; } } @@ -280,7 +289,7 @@ static INLINE void set_prev_mi(VP9_COMMON *cm) { // Special case: set prev_mi to NULL when the previous mode info // context cannot be used. cm->prev_mi = use_prev_in_find_mv_refs ? - cm->prev_mip + cm->mode_info_stride + 1 : NULL; + cm->prev_mip + cm->mi_stride + 1 : NULL; } static INLINE int frame_is_intra_only(const VP9_COMMON *const cm) { diff --git a/vp9/common/vp9_pred_common.c b/vp9/common/vp9_pred_common.c index 197bcb643..bc9d6ef5e 100644 --- a/vp9/common/vp9_pred_common.c +++ b/vp9/common/vp9_pred_common.c @@ -348,7 +348,7 @@ int vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) { // left of the entries corresponding to real blocks. // The prediction flags in these dummy entries are initialized to 0. int vp9_get_tx_size_context(const MACROBLOCKD *xd) { - const int max_tx_size = max_txsize_lookup[xd->mi_8x8[0]->mbmi.sb_type]; + const int max_tx_size = max_txsize_lookup[xd->mi[0]->mbmi.sb_type]; const MB_MODE_INFO *const above_mbmi = get_mbmi(get_above_mi(xd)); const MB_MODE_INFO *const left_mbmi = get_mbmi(get_left_mi(xd)); const int has_above = above_mbmi != NULL; diff --git a/vp9/common/vp9_pred_common.h b/vp9/common/vp9_pred_common.h index 6c7a0d383..1a7ba86e4 100644 --- a/vp9/common/vp9_pred_common.h +++ b/vp9/common/vp9_pred_common.h @@ -19,11 +19,11 @@ extern "C" { #endif static INLINE const MODE_INFO *get_above_mi(const MACROBLOCKD *const xd) { - return xd->up_available ? xd->mi_8x8[-xd->mode_info_stride] : NULL; + return xd->up_available ? xd->mi[-xd->mi_stride] : NULL; } static INLINE const MODE_INFO *get_left_mi(const MACROBLOCKD *const xd) { - return xd->left_available ? xd->mi_8x8[-1] : NULL; + return xd->left_available ? xd->mi[-1] : NULL; } int vp9_get_segment_id(VP9_COMMON *cm, const uint8_t *segment_ids, diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c index 0a4c33962..0ab50d456 100644 --- a/vp9/common/vp9_reconinter.c +++ b/vp9/common/vp9_reconinter.c @@ -144,7 +144,7 @@ static void build_inter_predictors(MACROBLOCKD *xd, int plane, int block, int x, int y, int w, int h, int mi_x, int mi_y) { struct macroblockd_plane *const pd = &xd->plane[plane]; - const MODE_INFO *mi = xd->mi_8x8[0]; + const MODE_INFO *mi = xd->mi[0]; const int is_compound = has_second_ref(&mi->mbmi); int ref; @@ -212,7 +212,7 @@ static void build_inter_predictors_for_planes(MACROBLOCKD *xd, BLOCK_SIZE bsize, const int bw = 4 * num_4x4_w; const int bh = 4 * num_4x4_h; - if (xd->mi_8x8[0]->mbmi.sb_type < BLOCK_8X8) { + if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8) { int i = 0, x, y; assert(bsize == BLOCK_8X8); for (y = 0; y < num_4x4_h; ++y) @@ -248,7 +248,7 @@ static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block, int x, int y, int w, int h, int mi_x, int mi_y) { struct macroblockd_plane *const pd = &xd->plane[plane]; - const MODE_INFO *mi = xd->mi_8x8[0]; + const MODE_INFO *mi = xd->mi[0]; const int is_compound = has_second_ref(&mi->mbmi); int ref; @@ -394,7 +394,7 @@ void vp9_dec_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col, const int bw = 4 * num_4x4_w; const int bh = 4 * num_4x4_h; - if (xd->mi_8x8[0]->mbmi.sb_type < BLOCK_8X8) { + if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8) { int i = 0, x, y; assert(bsize == BLOCK_8X8); for (y = 0; y < num_4x4_h; ++y) diff --git a/vp9/common/vp9_scale.c b/vp9/common/vp9_scale.c index e0f1e3410..d3405fcdb 100644 --- a/vp9/common/vp9_scale.c +++ b/vp9/common/vp9_scale.c @@ -13,11 +13,11 @@ #include "vp9/common/vp9_scale.h" static INLINE int scaled_x(int val, const struct scale_factors *sf) { - return val * sf->x_scale_fp >> REF_SCALE_SHIFT; + return (int)((int64_t)val * sf->x_scale_fp >> REF_SCALE_SHIFT); } static INLINE int scaled_y(int val, const struct scale_factors *sf) { - return val * sf->y_scale_fp >> REF_SCALE_SHIFT; + return (int)((int64_t)val * sf->y_scale_fp >> REF_SCALE_SHIFT); } static int unscaled_value(int val, const struct scale_factors *sf) { diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c index 2f15bfb52..53f94f848 100644 --- a/vp9/decoder/vp9_decodeframe.c +++ b/vp9/decoder/vp9_decodeframe.c @@ -245,7 +245,7 @@ static void predict_and_reconstruct_intra_block(int plane, int block, VP9_COMMON *const cm = args->cm; MACROBLOCKD *const xd = args->xd; struct macroblockd_plane *const pd = &xd->plane[plane]; - MODE_INFO *const mi = xd->mi_8x8[0]; + MODE_INFO *const mi = xd->mi[0]; const MB_PREDICTION_MODE mode = (plane == 0) ? get_y_mode(mi, block) : mi->mbmi.uv_mode; int x, y; @@ -291,35 +291,36 @@ static void reconstruct_inter_block(int plane, int block, *args->eobtotal += eob; } -static void set_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd, - const TileInfo *const tile, - BLOCK_SIZE bsize, int mi_row, int mi_col) { +static MB_MODE_INFO *set_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd, + const TileInfo *const tile, + BLOCK_SIZE bsize, int mi_row, int mi_col) { 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 offset = mi_row * cm->mi_stride + mi_col; int x, y; - xd->mi_8x8 = cm->mi_grid_visible + offset; - xd->mi_8x8[0] = &cm->mi[offset]; - xd->mi_8x8[0]->mbmi.sb_type = bsize; + xd->mi = cm->mi_grid_visible + offset; + xd->mi[0] = &cm->mi[offset]; + xd->mi[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]; + xd->mi[y * cm->mi_stride + x] = xd->mi[0]; - set_skip_context(xd, xd->above_context, xd->left_context, mi_row, mi_col); + set_skip_context(xd, mi_row, mi_col); // Distance of Mb to the various image edges. These are specified to 8th pel // as they are always compared to values that are in 1/8th pel units set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); vp9_setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col); + return &xd->mi[0]->mbmi; } static void set_ref(VP9_COMMON *const cm, MACROBLOCKD *const xd, int idx, int mi_row, int mi_col) { - MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; RefBuffer *ref_buffer = &cm->frame_refs[mbmi->ref_frame[idx] - LAST_FRAME]; xd->block_refs[idx] = ref_buffer; if (!vp9_is_valid_scale(&ref_buffer->sf)) @@ -335,17 +336,12 @@ static void decode_block(VP9_COMMON *const cm, MACROBLOCKD *const xd, int mi_row, int mi_col, vp9_reader *r, BLOCK_SIZE bsize) { const int less8x8 = bsize < BLOCK_8X8; - MB_MODE_INFO *mbmi; - - set_offsets(cm, xd, tile, bsize, mi_row, mi_col); + MB_MODE_INFO *mbmi = set_offsets(cm, xd, tile, bsize, mi_row, mi_col); vp9_read_mode_info(cm, xd, tile, mi_row, mi_col, r); if (less8x8) bsize = BLOCK_8X8; - // Has to be called after set_offsets - mbmi = &xd->mi_8x8[0]->mbmi; - if (mbmi->skip) { reset_skip_context(xd, bsize); } else { @@ -677,17 +673,6 @@ static void setup_frame_size_with_refs(VP9_COMMON *cm, setup_display_size(cm, rb); } -static void setup_tile_context(VP9_COMMON *cm, MACROBLOCKD *const xd, - int tile_row, int tile_col) { - int i; - - for (i = 0; i < MAX_MB_PLANE; ++i) - xd->above_context[i] = cm->above_context + - i * sizeof(*cm->above_context) * 2 * mi_cols_aligned_to_sb(cm->mi_cols); - - xd->above_seg_context = cm->above_seg_context; -} - static void decode_tile(VP9D_COMP *pbi, const TileInfo *const tile, vp9_reader *r) { const int num_threads = pbi->oxcf.max_threads; @@ -797,7 +782,6 @@ static const uint8_t *decode_tiles(VP9D_COMP *pbi, const uint8_t *data, const uint8_t *data_end) { VP9_COMMON *const cm = &pbi->common; - MACROBLOCKD *const xd = &pbi->mb; const int aligned_cols = mi_cols_aligned_to_sb(cm->mi_cols); const int tile_cols = 1 << cm->log2_tile_cols; const int tile_rows = 1 << cm->log2_tile_rows; @@ -842,7 +826,6 @@ static const uint8_t *decode_tiles(VP9D_COMP *pbi, vp9_tile_init(&tile, cm, tile_row, col); setup_token_decoder(buf->data, data_end, buf->size, &cm->error, &r); - setup_tile_context(cm, xd, tile_row, col); decode_tile(pbi, &tile, &r); if (last_tile) @@ -976,12 +959,9 @@ static const uint8_t *decode_tiles_mt(VP9D_COMP *pbi, tile_data->xd = pbi->mb; tile_data->xd.corrupted = 0; vp9_tile_init(tile, tile_data->cm, 0, buf->col); - setup_token_decoder(buf->data, data_end, buf->size, &cm->error, &tile_data->bit_reader); - - setup_tile_context(cm, &tile_data->xd, 0, buf->col); - init_macroblockd(&tile_data->xd); + init_macroblockd(cm, &tile_data->xd); vp9_zero(tile_data->xd.dqcoeff); worker->had_error = 0; @@ -1309,7 +1289,8 @@ int vp9_decode_frame(VP9D_COMP *pbi, } } - xd->mode_info_stride = cm->mode_info_stride; + init_macroblockd(cm, &pbi->mb); + if (cm->coding_use_prev_mi) set_prev_mi(cm); else diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index bade2b17b..3618f12d0 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -104,7 +104,7 @@ static int read_intra_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd, int mi_row, int mi_col, vp9_reader *r) { struct segmentation *const seg = &cm->seg; - const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type; + const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; int segment_id; if (!seg->enabled) @@ -121,7 +121,7 @@ static int read_intra_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd, static int read_inter_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd, int mi_row, int mi_col, vp9_reader *r) { struct segmentation *const seg = &cm->seg; - MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; const BLOCK_SIZE bsize = mbmi->sb_type; int predicted_segment_id, segment_id; @@ -161,10 +161,10 @@ static int read_skip(VP9_COMMON *cm, const MACROBLOCKD *xd, static void read_intra_frame_mode_info(VP9_COMMON *const cm, MACROBLOCKD *const xd, int mi_row, int mi_col, vp9_reader *r) { - MODE_INFO *const mi = xd->mi_8x8[0]; + MODE_INFO *const mi = xd->mi[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 MODE_INFO *above_mi = xd->mi[-cm->mi_stride]; + const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1] : NULL; const BLOCK_SIZE bsize = mbmi->sb_type; int i; @@ -515,7 +515,7 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm, MACROBLOCKD *const xd, const TileInfo *const tile, int mi_row, int mi_col, vp9_reader *r) { - MODE_INFO *const mi = xd->mi_8x8[0]; + MODE_INFO *const mi = xd->mi[0]; MB_MODE_INFO *const mbmi = &mi->mbmi; int inter_block; diff --git a/vp9/decoder/vp9_decoder.c b/vp9/decoder/vp9_decoder.c index 17b8c98c8..c954a5d0e 100644 --- a/vp9/decoder/vp9_decoder.c +++ b/vp9/decoder/vp9_decoder.c @@ -147,8 +147,6 @@ VP9D_COMP *vp9_create_decompressor(const VP9D_CONFIG *oxcf) { cm->error.setjmp = 0; pbi->decoded_key_frame = 0; - init_macroblockd(&pbi->mb); - vp9_worker_init(&pbi->lf_worker); return pbi; diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c index 52e78cd90..860da532a 100644 --- a/vp9/decoder/vp9_detokenize.c +++ b/vp9/decoder/vp9_detokenize.c @@ -86,7 +86,7 @@ static int decode_coefs(VP9_COMMON *cm, const MACROBLOCKD *xd, PLANE_TYPE type, const int max_eob = 16 << (tx_size << 1); const FRAME_CONTEXT *const fc = &cm->fc; FRAME_COUNTS *const counts = &cm->counts; - const int ref = is_inter_block(&xd->mi_8x8[0]->mbmi); + const int ref = is_inter_block(&xd->mi[0]->mbmi); int band, c = 0; const vp9_prob (*coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] = fc->coef_probs[tx_size][type][ref]; diff --git a/vp9/decoder/vp9_dthread.c b/vp9/decoder/vp9_dthread.c index 4df85094b..163936021 100644 --- a/vp9/decoder/vp9_dthread.c +++ b/vp9/decoder/vp9_dthread.c @@ -99,7 +99,7 @@ static void loop_filter_rows_mt(const YV12_BUFFER_CONFIG *const frame_buffer, for (r = start; r < stop; r += num_lf_workers) { const int mi_row = r << MI_BLOCK_SIZE_LOG2; - MODE_INFO **mi_8x8 = cm->mi_grid_visible + mi_row * cm->mode_info_stride; + MODE_INFO **mi_8x8 = cm->mi_grid_visible + mi_row * cm->mi_stride; for (c = 0; c < sb_cols; ++c) { const int mi_col = c << MI_BLOCK_SIZE_LOG2; @@ -108,8 +108,7 @@ static void loop_filter_rows_mt(const YV12_BUFFER_CONFIG *const frame_buffer, sync_read(lf_sync, r, c); vp9_setup_dst_planes(xd, frame_buffer, mi_row, mi_col); - vp9_setup_mask(cm, mi_row, mi_col, mi_8x8 + mi_col, cm->mode_info_stride, - &lfm); + vp9_setup_mask(cm, mi_row, mi_col, mi_8x8 + mi_col, cm->mi_stride, &lfm); for (plane = 0; plane < num_planes; ++plane) { vp9_filter_block_plane(cm, &xd->plane[plane], mi_row, &lfm); diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index a1db097bd..544a27dc9 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -192,7 +192,7 @@ static void write_segment_id(vp9_writer *w, const struct segmentation *seg, static void write_ref_frames(const VP9_COMP *cpi, vp9_writer *w) { const VP9_COMMON *const cm = &cpi->common; const MACROBLOCKD *const xd = &cpi->mb.e_mbd; - const MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; const int is_compound = has_second_ref(mbmi); const int segment_id = mbmi->segment_id; @@ -336,7 +336,7 @@ static void write_mb_modes_kf(const VP9_COMP *cpi, MODE_INFO **mi_8x8, const MACROBLOCKD *const xd = &cpi->mb.e_mbd; const struct segmentation *const seg = &cm->seg; const MODE_INFO *const mi = mi_8x8[0]; - const MODE_INFO *const above_mi = mi_8x8[-xd->mode_info_stride]; + const MODE_INFO *const above_mi = mi_8x8[-xd->mi_stride]; const MODE_INFO *const left_mi = xd->left_available ? mi_8x8[-1] : NULL; const MB_MODE_INFO *const mbmi = &mi->mbmi; const BLOCK_SIZE bsize = mbmi->sb_type; @@ -375,15 +375,15 @@ static void write_modes_b(VP9_COMP *cpi, const TileInfo *const tile, MACROBLOCKD *const xd = &cpi->mb.e_mbd; MODE_INFO *m; - xd->mi_8x8 = cm->mi_grid_visible + (mi_row * cm->mode_info_stride + mi_col); - m = xd->mi_8x8[0]; + xd->mi = cm->mi_grid_visible + (mi_row * cm->mi_stride + mi_col); + m = xd->mi[0]; set_mi_row_col(xd, tile, mi_row, num_8x8_blocks_high_lookup[m->mbmi.sb_type], mi_col, num_8x8_blocks_wide_lookup[m->mbmi.sb_type], cm->mi_rows, cm->mi_cols); if (frame_is_intra_only(cm)) { - write_mb_modes_kf(cpi, xd->mi_8x8, w); + write_mb_modes_kf(cpi, xd->mi, w); } else { pack_inter_mode_mvs(cpi, m, w); } @@ -424,7 +424,7 @@ static void write_modes_sb(VP9_COMP *cpi, const int bs = (1 << bsl) / 4; PARTITION_TYPE partition; BLOCK_SIZE subsize; - MODE_INFO *m = cm->mi_grid_visible[mi_row * cm->mode_info_stride + mi_col]; + MODE_INFO *m = cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col]; if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 1e5890cda..cdca93a20 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -163,14 +163,14 @@ static INLINE void set_modeinfo_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd, int mi_row, int mi_col) { - const int idx_str = xd->mode_info_stride * mi_row + mi_col; - xd->mi_8x8 = cm->mi_grid_visible + idx_str; - xd->mi_8x8[0] = cm->mi + idx_str; + const int idx_str = xd->mi_stride * mi_row + mi_col; + xd->mi = cm->mi_grid_visible + idx_str; + xd->mi[0] = cm->mi + idx_str; } -static int is_block_in_mb_map(VP9_COMP *cpi, int mi_row, int mi_col, +static int is_block_in_mb_map(const VP9_COMP *cpi, int mi_row, int mi_col, BLOCK_SIZE bsize) { - VP9_COMMON *const cm = &cpi->common; + const VP9_COMMON *const cm = &cpi->common; const int mb_rows = cm->mb_rows; const int mb_cols = cm->mb_cols; const int mb_row = mi_row >> 1; @@ -194,6 +194,16 @@ static int is_block_in_mb_map(VP9_COMP *cpi, int mi_row, int mi_col, return 0; } +static int check_active_map(const VP9_COMP *cpi, const MACROBLOCK *x, + int mi_row, int mi_col, + BLOCK_SIZE bsize) { + if (cpi->active_map_enabled && !x->e_mbd.lossless) { + return is_block_in_mb_map(cpi, mi_row, mi_col, bsize); + } else { + return 1; + } +} + static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile, int mi_row, int mi_col, BLOCK_SIZE bsize) { MACROBLOCK *const x = &cpi->mb; @@ -207,20 +217,15 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile, const int idx_map = mb_row * cm->mb_cols + mb_col; const struct segmentation *const seg = &cm->seg; - set_skip_context(xd, xd->above_context, xd->left_context, mi_row, mi_col); + set_skip_context(xd, mi_row, mi_col); // Activity map pointer x->mb_activity_ptr = &cpi->mb_activity_map[idx_map]; - - if (cpi->active_map_enabled && !x->e_mbd.lossless) { - x->in_active_map = is_block_in_mb_map(cpi, mi_row, mi_col, bsize); - } else { - x->in_active_map = 1; - } + x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize); set_modeinfo_offsets(cm, xd, mi_row, mi_col); - mbmi = &xd->mi_8x8[0]->mbmi; + mbmi = &xd->mi[0]->mbmi; // Set up destination pointers. vp9_setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col); @@ -283,12 +288,11 @@ static void duplicate_mode_info_in_sb(VP9_COMMON * const cm, BLOCK_SIZE bsize) { const int block_width = num_8x8_blocks_wide_lookup[bsize]; const int block_height = num_8x8_blocks_high_lookup[bsize]; - const int mis = xd->mode_info_stride; int i, j; for (j = 0; j < block_height; ++j) for (i = 0; i < block_width; ++i) { if (mi_row + j < cm->mi_rows && mi_col + i < cm->mi_cols) - xd->mi_8x8[j * mis + i] = xd->mi_8x8[0]; + xd->mi[j * xd->mi_stride + i] = xd->mi[0]; } } @@ -299,7 +303,7 @@ static void set_block_size(VP9_COMP * const cpi, if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) { MACROBLOCKD *const xd = &cpi->mb.e_mbd; set_modeinfo_offsets(&cpi->common, xd, mi_row, mi_col); - xd->mi_8x8[0]->mbmi.sb_type = bsize; + xd->mi[0]->mbmi.sb_type = bsize; duplicate_mode_info_in_sb(&cpi->common, xd, mi_row, mi_col, bsize); } } @@ -496,13 +500,13 @@ static void choose_partitioning(VP9_COMP *cpi, if (cm->frame_type != KEY_FRAME) { vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col, sf); - xd->mi_8x8[0]->mbmi.ref_frame[0] = LAST_FRAME; - xd->mi_8x8[0]->mbmi.sb_type = BLOCK_64X64; + xd->mi[0]->mbmi.ref_frame[0] = LAST_FRAME; + xd->mi[0]->mbmi.sb_type = BLOCK_64X64; vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, - xd->mi_8x8[0]->mbmi.ref_mvs[LAST_FRAME], + xd->mi[0]->mbmi.ref_mvs[LAST_FRAME], &nearest_mv, &near_mv); - xd->mi_8x8[0]->mbmi.mv[0] = nearest_mv; + xd->mi[0]->mbmi.mv[0] = nearest_mv; vp9_build_inter_predictors_sby(xd, mi_row, mi_col, BLOCK_64X64); d = xd->plane[0].dst.buf; @@ -839,11 +843,11 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, struct macroblock_plane *const p = x->plane; struct macroblockd_plane *const pd = xd->plane; MODE_INFO *mi = &ctx->mic; - MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; - MODE_INFO *mi_addr = xd->mi_8x8[0]; + MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; + MODE_INFO *mi_addr = xd->mi[0]; const struct segmentation *const seg = &cm->seg; - const int mis = cm->mode_info_stride; + const int mis = cm->mi_stride; const int mi_width = num_8x8_blocks_wide_lookup[bsize]; const int mi_height = num_8x8_blocks_high_lookup[bsize]; int max_plane; @@ -856,7 +860,7 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, // the cyclic refresh map. if ((cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) && seg->enabled && output_enabled) { - vp9_cyclic_refresh_update_segment(cpi, &xd->mi_8x8[0]->mbmi, + vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col, bsize, 1); vp9_init_plane_quantizers(cpi, x); } @@ -882,7 +886,7 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, for (x_idx = 0; x_idx < mi_width; x_idx++) if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) { - xd->mi_8x8[x_idx + y * mis] = mi_addr; + xd->mi[x_idx + y * mis] = mi_addr; } if (cpi->oxcf.aq_mode) @@ -1001,7 +1005,7 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile, } set_offsets(cpi, tile, mi_row, mi_col, bsize); - mbmi = &xd->mi_8x8[0]->mbmi; + mbmi = &xd->mi[0]->mbmi; mbmi->sb_type = bsize; for (i = 0; i < MAX_MB_PLANE; ++i) { @@ -1089,7 +1093,7 @@ static void update_stats(VP9_COMP *cpi) { VP9_COMMON *const cm = &cpi->common; const MACROBLOCK *const x = &cpi->mb; const MACROBLOCKD *const xd = &x->e_mbd; - const MODE_INFO *const mi = xd->mi_8x8[0]; + const MODE_INFO *const mi = xd->mi[0]; const MB_MODE_INFO *const mbmi = &mi->mbmi; if (!frame_is_intra_only(cm)) { @@ -1332,7 +1336,7 @@ static void set_fixed_partitioning(VP9_COMP *cpi, const TileInfo *const tile, MODE_INFO **mi_8x8, int mi_row, int mi_col, BLOCK_SIZE bsize) { VP9_COMMON *const cm = &cpi->common; - const int mis = cm->mode_info_stride; + const int mis = cm->mi_stride; int row8x8_remaining = tile->mi_row_end - mi_row; int col8x8_remaining = tile->mi_col_end - mi_col; int block_row, block_col; @@ -1370,13 +1374,14 @@ static void set_fixed_partitioning(VP9_COMP *cpi, const TileInfo *const tile, static void copy_partitioning(VP9_COMMON *cm, MODE_INFO **mi_8x8, MODE_INFO **prev_mi_8x8) { - const int mis = cm->mode_info_stride; + const int mis = cm->mi_stride; int block_row, block_col; for (block_row = 0; block_row < 8; ++block_row) { for (block_col = 0; block_col < 8; ++block_col) { MODE_INFO *const prev_mi = prev_mi_8x8[block_row * mis + block_col]; const BLOCK_SIZE sb_type = prev_mi ? prev_mi->mbmi.sb_type : 0; + if (prev_mi) { const ptrdiff_t offset = prev_mi - cm->prev_mi; mi_8x8[block_row * mis + block_col] = cm->mi + offset; @@ -1387,7 +1392,7 @@ static void copy_partitioning(VP9_COMMON *cm, MODE_INFO **mi_8x8, } static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) { - const int mis = cm->mode_info_stride; + const int mis = cm->mi_stride; int block_row, block_col; if (cm->prev_mi) { @@ -1410,15 +1415,15 @@ static void update_state_rt(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, VP9_COMMON *const cm = &cpi->common; MACROBLOCK *const x = &cpi->mb; MACROBLOCKD *const xd = &x->e_mbd; - MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; const struct segmentation *const seg = &cm->seg; - *(xd->mi_8x8[0]) = ctx->mic; + *(xd->mi[0]) = ctx->mic; // For in frame adaptive Q, check for reseting the segment_id and updating // the cyclic refresh map. if ((cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) && seg->enabled) { - vp9_cyclic_refresh_update_segment(cpi, &xd->mi_8x8[0]->mbmi, + vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col, bsize, 1); vp9_init_plane_quantizers(cpi, x); } @@ -1431,6 +1436,8 @@ static void update_state_rt(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, ++cm->counts.switchable_interp[pred_ctx][mbmi->interp_filter]; } } + + x->skip = ctx->skip; } static void encode_b_rt(VP9_COMP *cpi, const TileInfo *const tile, @@ -1472,7 +1479,7 @@ static void encode_sb_rt(VP9_COMP *cpi, const TileInfo *const tile, if (bsize >= BLOCK_8X8) { MACROBLOCKD *const xd = &cpi->mb.e_mbd; - const int idx_str = xd->mode_info_stride * mi_row + mi_col; + const int idx_str = xd->mi_stride * mi_row + mi_col; MODE_INFO ** mi_8x8 = cm->mi_grid_visible + idx_str; ctx = partition_plane_context(xd, mi_row, mi_col, bsize); subsize = mi_8x8[0]->mbmi.sb_type; @@ -1545,7 +1552,7 @@ static void rd_use_partition(VP9_COMP *cpi, VP9_COMMON *const cm = &cpi->common; MACROBLOCK *const x = &cpi->mb; MACROBLOCKD *const xd = &x->e_mbd; - const int mis = cm->mode_info_stride; + const int mis = cm->mi_stride; const int bsl = b_width_log2(bsize); const int mi_step = num_4x4_blocks_wide_lookup[bsize] / 2; const int bss = (1 << bsl) / 4; @@ -1590,9 +1597,11 @@ static void rd_use_partition(VP9_COMP *cpi, } save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); - set_offsets(cpi, tile, mi_row, mi_col, bsize); if (bsize == BLOCK_16X16) { + set_offsets(cpi, tile, mi_row, mi_col, bsize); x->mb_energy = vp9_block_energy(cpi, x, bsize); + } else { + x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize); } if (!x->in_active_map) { @@ -1883,7 +1892,7 @@ static void get_sb_partition_size_range(VP9_COMP *cpi, MODE_INFO ** mi_8x8, *min_block_size = MIN(*min_block_size, sb_type); *max_block_size = MAX(*max_block_size, sb_type); } - index += xd->mode_info_stride; + index += xd->mi_stride; } } @@ -1904,10 +1913,10 @@ static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile, BLOCK_SIZE *max_block_size) { VP9_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &cpi->mb.e_mbd; - MODE_INFO **mi_8x8 = xd->mi_8x8; + MODE_INFO **mi_8x8 = xd->mi; const int left_in_image = xd->left_available && mi_8x8[-1]; const int above_in_image = xd->up_available && - mi_8x8[-xd->mode_info_stride]; + mi_8x8[-xd->mi_stride]; MODE_INFO **above_sb64_mi_8x8; MODE_INFO **left_sb64_mi_8x8; @@ -1927,7 +1936,7 @@ static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile, // Find the min and max partition used in previous frame at this location if (cm->frame_type != KEY_FRAME) { MODE_INFO **const prev_mi = - &cm->prev_mi_grid_visible[mi_row * xd->mode_info_stride + mi_col]; + &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col]; get_sb_partition_size_range(cpi, prev_mi, &min_size, &max_size); } // Find the min and max partition sizes used in the left SB64 @@ -1938,7 +1947,7 @@ static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile, } // Find the min and max partition sizes used in the above SB64. if (above_in_image) { - above_sb64_mi_8x8 = &mi_8x8[-xd->mode_info_stride * MI_BLOCK_SIZE]; + above_sb64_mi_8x8 = &mi_8x8[-xd->mi_stride * MI_BLOCK_SIZE]; get_sb_partition_size_range(cpi, above_sb64_mi_8x8, &min_size, &max_size); } @@ -2024,6 +2033,8 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile, if (bsize == BLOCK_16X16) { set_offsets(cpi, tile, mi_row, mi_col, bsize); x->mb_energy = vp9_block_energy(cpi, x, bsize); + } else { + x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize); } // Determine partition types in search according to the speed features. @@ -2326,7 +2337,7 @@ static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile, cpi->sf.use_lastframe_partitioning) || cpi->sf.partition_search_type == FIXED_PARTITION || cpi->sf.partition_search_type == VAR_BASED_FIXED_PARTITION) { - const int idx_str = cm->mode_info_stride * mi_row + mi_col; + const int idx_str = cm->mi_stride * mi_row + mi_col; MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str; MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str; cpi->mb.source_variance = UINT_MAX; @@ -2395,8 +2406,6 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) { x->act_zbin_adj = 0; cpi->seg0_idx = 0; - xd->mode_info_stride = cm->mode_info_stride; - // Copy data over into macro block data structures. vp9_setup_src_planes(x, cpi->Source, 0, 0); @@ -2407,19 +2416,8 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) { vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y); - xd->mi_8x8[0]->mbmi.mode = DC_PRED; - xd->mi_8x8[0]->mbmi.uv_mode = DC_PRED; - - vp9_zero(cm->counts.y_mode); - vp9_zero(cm->counts.uv_mode); - vp9_zero(cm->counts.inter_mode); - vp9_zero(cm->counts.partition); - vp9_zero(cm->counts.intra_inter); - vp9_zero(cm->counts.comp_inter); - vp9_zero(cm->counts.single_ref); - vp9_zero(cm->counts.comp_ref); - vp9_zero(cm->counts.tx); - vp9_zero(cm->counts.skip); + xd->mi[0]->mbmi.mode = DC_PRED; + xd->mi[0]->mbmi.uv_mode = DC_PRED; // Note: this memset assumes above_context[0], [1] and [2] // are allocated as part of the same buffer. @@ -2472,7 +2470,7 @@ static int get_skip_flag(MODE_INFO **mi_8x8, int mis, int ymbs, int xmbs) { static void reset_skip_txfm_size(VP9_COMMON *cm, TX_SIZE txfm_max) { int mi_row, mi_col; - const int mis = cm->mode_info_stride; + const int mis = cm->mi_stride; MODE_INFO **mi_ptr = cm->mi_grid_visible; for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) { @@ -2557,14 +2555,14 @@ static void nonrd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile, MACROBLOCK *const x = &cpi->mb; MACROBLOCKD *const xd = &x->e_mbd; set_offsets(cpi, tile, mi_row, mi_col, bsize); - xd->mi_8x8[0]->mbmi.sb_type = bsize; + xd->mi[0]->mbmi.sb_type = bsize; if (!frame_is_intra_only(cm)) { vp9_pick_inter_mode(cpi, x, tile, mi_row, mi_col, rate, dist, bsize); } else { MB_PREDICTION_MODE intramode = DC_PRED; - set_mode_info(&xd->mi_8x8[0]->mbmi, bsize, intramode); + set_mode_info(&xd->mi[0]->mbmi, bsize, intramode); } duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize); } @@ -2584,31 +2582,31 @@ static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x, switch (partition) { case PARTITION_NONE: set_modeinfo_offsets(cm, xd, mi_row, mi_col); - *(xd->mi_8x8[0]) = (get_block_context(x, subsize))->mic; + *(xd->mi[0]) = get_block_context(x, subsize)->mic; duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize); break; case PARTITION_VERT: *get_sb_index(x, subsize) = 0; set_modeinfo_offsets(cm, xd, mi_row, mi_col); - *(xd->mi_8x8[0]) = (get_block_context(x, subsize))->mic; + *(xd->mi[0]) = get_block_context(x, subsize)->mic; duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize); if (mi_col + hbs < cm->mi_cols) { *get_sb_index(x, subsize) = 1; set_modeinfo_offsets(cm, xd, mi_row, mi_col + hbs); - *(xd->mi_8x8[0]) = (get_block_context(x, subsize))->mic; + *(xd->mi[0]) = get_block_context(x, subsize)->mic; duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col + hbs, bsize); } break; case PARTITION_HORZ: *get_sb_index(x, subsize) = 0; set_modeinfo_offsets(cm, xd, mi_row, mi_col); - *(xd->mi_8x8[0]) = (get_block_context(x, subsize))->mic; + *(xd->mi[0]) = get_block_context(x, subsize)->mic; duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize); if (mi_row + hbs < cm->mi_rows) { *get_sb_index(x, subsize) = 1; set_modeinfo_offsets(cm, xd, mi_row + hbs, mi_col); - *(xd->mi_8x8[0]) = (get_block_context(x, subsize))->mic; + *(xd->mi[0]) = get_block_context(x, subsize)->mic; duplicate_mode_info_in_sb(cm, xd, mi_row + hbs, mi_col, bsize); } break; @@ -2674,6 +2672,8 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile, assert(num_8x8_blocks_wide_lookup[bsize] == num_8x8_blocks_high_lookup[bsize]); + x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize); + // Determine partition types in search according to the speed features. // The threshold set here has to be of square block size. if (cpi->sf.auto_min_max_partition_size) { @@ -2699,7 +2699,7 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile, if (partition_none_allowed) { nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, &this_rate, &this_dist, bsize); - ctx->mic.mbmi = xd->mi_8x8[0]->mbmi; + ctx->mic.mbmi = xd->mi[0]->mbmi; if (this_rate != INT_MAX) { int pl = partition_plane_context(xd, mi_row, mi_col, bsize); @@ -2789,7 +2789,7 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile, nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, &this_rate, &this_dist, subsize); - (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi; + get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); @@ -2801,7 +2801,7 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile, nonrd_pick_sb_modes(cpi, tile, mi_row + ms, mi_col, &this_rate, &this_dist, subsize); - (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi; + get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; if (this_rate == INT_MAX) { sum_rd = INT64_MAX; @@ -2831,7 +2831,7 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile, nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, &this_rate, &this_dist, subsize); - (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi; + get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); if (sum_rd < best_rd && mi_col + ms < cm->mi_cols) { *get_sb_index(x, subsize) = 1; @@ -2841,7 +2841,7 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile, nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + ms, &this_rate, &this_dist, subsize); - (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi; + get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; if (this_rate == INT_MAX) { sum_rd = INT64_MAX; @@ -2909,7 +2909,7 @@ static void nonrd_use_partition(VP9_COMP *cpi, MACROBLOCK *const x = &cpi->mb; MACROBLOCKD *const xd = &x->e_mbd; const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4; - const int mis = cm->mode_info_stride; + const int mis = cm->mi_stride; PARTITION_TYPE partition; BLOCK_SIZE subsize; int rate = INT_MAX; @@ -2929,17 +2929,17 @@ static void nonrd_use_partition(VP9_COMP *cpi, switch (partition) { case PARTITION_NONE: nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize); - (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi; + get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; break; case PARTITION_VERT: *get_sb_index(x, subsize) = 0; nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize); - (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi; + get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; if (mi_col + hbs < cm->mi_cols) { *get_sb_index(x, subsize) = 1; nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + hbs, &rate, &dist, subsize); - (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi; + get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; if (rate != INT_MAX && dist != INT64_MAX && *totrate != INT_MAX && *totdist != INT64_MAX) { *totrate += rate; @@ -2950,12 +2950,12 @@ static void nonrd_use_partition(VP9_COMP *cpi, case PARTITION_HORZ: *get_sb_index(x, subsize) = 0; nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize); - (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi; + get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; if (mi_row + hbs < cm->mi_rows) { *get_sb_index(x, subsize) = 1; nonrd_pick_sb_modes(cpi, tile, mi_row + hbs, mi_col, &rate, &dist, subsize); - (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi; + get_block_context(x, subsize)->mic.mbmi = mi_8x8[0]->mbmi; if (rate != INT_MAX && dist != INT64_MAX && *totrate != INT_MAX && *totdist != INT64_MAX) { *totrate += rate; @@ -3023,7 +3023,7 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile, mi_col += MI_BLOCK_SIZE) { int dummy_rate = 0; int64_t dummy_dist = 0; - const int idx_str = cm->mode_info_stride * mi_row + mi_col; + const int idx_str = cm->mi_stride * mi_row + mi_col; MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str; MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str; @@ -3074,16 +3074,12 @@ static void encode_frame_internal(VP9_COMP *cpi) { // cpi->common.current_video_frame, cpi->common.show_frame, // cm->frame_type); - vp9_zero(cm->counts.switchable_interp); - vp9_zero(cpi->tx_stepdown_count); - - xd->mi_8x8 = cm->mi_grid_visible; - // required for vp9_frame_init_quantizer - xd->mi_8x8[0] = cm->mi; + xd->mi = cm->mi_grid_visible; + xd->mi[0] = cm->mi; - vp9_zero(cm->counts.mv); + vp9_zero(cm->counts); vp9_zero(cpi->coef_counts); - vp9_zero(cm->counts.eob_branch); + vp9_zero(cpi->tx_stepdown_count); // Set frame level transform size use case cm->tx_mode = select_tx_mode(cpi); @@ -3403,12 +3399,12 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled, VP9_COMMON *const cm = &cpi->common; MACROBLOCK *const x = &cpi->mb; MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO **mi_8x8 = xd->mi_8x8; + MODE_INFO **mi_8x8 = xd->mi; MODE_INFO *mi = mi_8x8[0]; MB_MODE_INFO *mbmi = &mi->mbmi; PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize); unsigned int segment_id = mbmi->segment_id; - const int mis = cm->mode_info_stride; + const int mis = cm->mi_stride; const int mi_width = num_8x8_blocks_wide_lookup[bsize]; const int mi_height = num_8x8_blocks_high_lookup[bsize]; diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c index fae03bf55..5e98e4e3f 100644 --- a/vp9/encoder/vp9_encodemb.c +++ b/vp9/encoder/vp9_encodemb.c @@ -111,7 +111,7 @@ static void optimize_b(int plane, int block, BLOCK_SIZE plane_bsize, MACROBLOCKD *const xd = &mb->e_mbd; struct macroblock_plane *p = &mb->plane[plane]; struct macroblockd_plane *pd = &xd->plane[plane]; - const int ref = is_inter_block(&xd->mi_8x8[0]->mbmi); + const int ref = is_inter_block(&xd->mi[0]->mbmi); vp9_token_state tokens[1025][2]; unsigned best_index[1025][2]; const int16_t *coeff = BLOCK_OFFSET(mb->plane[plane].coeff, block); @@ -139,7 +139,7 @@ static void optimize_b(int plane, int block, BLOCK_SIZE plane_bsize, /* Now set up a Viterbi trellis to evaluate alternative roundings. */ rdmult = mb->rdmult * err_mult; - if (!is_inter_block(&mb->e_mbd.mi_8x8[0]->mbmi)) + if (!is_inter_block(&mb->e_mbd.mi[0]->mbmi)) rdmult = (rdmult * 9) >> 4; rddiv = mb->rddiv; /* Initialize the sentinel node of the trellis. */ @@ -452,7 +452,7 @@ void vp9_encode_sby_pass1(MACROBLOCK *x, BLOCK_SIZE bsize) { void vp9_encode_sb(MACROBLOCK *x, BLOCK_SIZE bsize) { MACROBLOCKD *const xd = &x->e_mbd; struct optimize_ctx ctx; - MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; struct encode_b_args arg = {x, &ctx, &mbmi->skip}; int plane; @@ -477,7 +477,7 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, struct encode_b_args* const args = arg; MACROBLOCK *const x = args->x; MACROBLOCKD *const xd = &x->e_mbd; - MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; struct macroblock_plane *const p = &x->plane[plane]; struct macroblockd_plane *const pd = &xd->plane[plane]; int16_t *coeff = BLOCK_OFFSET(p->coeff, block); @@ -562,7 +562,7 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, case TX_4X4: tx_type = get_tx_type_4x4(pd->plane_type, xd, block); scan_order = &vp9_scan_orders[TX_4X4][tx_type]; - mode = plane == 0 ? get_y_mode(xd->mi_8x8[0], block) : mbmi->uv_mode; + mode = plane == 0 ? get_y_mode(xd->mi[0], block) : mbmi->uv_mode; vp9_predict_intra_block(xd, block, bwl, TX_4X4, mode, x->skip_encode ? src : dst, x->skip_encode ? src_stride : dst_stride, @@ -608,14 +608,14 @@ void vp9_encode_block_intra(MACROBLOCK *x, int plane, int block, void vp9_encode_intra_block_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) { const MACROBLOCKD *const xd = &x->e_mbd; - struct encode_b_args arg = {x, NULL, &xd->mi_8x8[0]->mbmi.skip}; + struct encode_b_args arg = {x, NULL, &xd->mi[0]->mbmi.skip}; vp9_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block_intra, &arg); } int vp9_encode_intra(MACROBLOCK *x, int use_16x16_pred) { - MB_MODE_INFO * mbmi = &x->e_mbd.mi_8x8[0]->mbmi; + MB_MODE_INFO * mbmi = &x->e_mbd.mi[0]->mbmi; x->skip_encode = 0; mbmi->mode = DC_PRED; mbmi->ref_frame[0] = INTRA_FRAME; diff --git a/vp9/encoder/vp9_encodemv.c b/vp9/encoder/vp9_encodemv.c index 2a10bbfde..9d4486511 100644 --- a/vp9/encoder/vp9_encodemv.c +++ b/vp9/encoder/vp9_encodemv.c @@ -242,7 +242,7 @@ static void inc_mvs(const MB_MODE_INFO *mbmi, const int_mv mvs[2], } void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd) { - const MODE_INFO *mi = xd->mi_8x8[0]; + const MODE_INFO *mi = xd->mi[0]; const MB_MODE_INFO *const mbmi = &mi->mbmi; if (mbmi->sb_type < BLOCK_8X8) { diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 6d36b7cf5..cf0f8054a 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -384,7 +384,7 @@ static unsigned int zz_motion_search(const MACROBLOCK *x) { const uint8_t *const ref = xd->plane[0].pre[0].buf; const int ref_stride = xd->plane[0].pre[0].stride; unsigned int sse; - vp9_variance_fn_t fn = get_block_variance_fn(xd->mi_8x8[0]->mbmi.sb_type); + vp9_variance_fn_t fn = get_block_variance_fn(xd->mi[0]->mbmi.sb_type); fn(src, src_stride, ref, ref_stride, &sse); return sse; } @@ -398,7 +398,7 @@ static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x, int num00, tmp_err, n, sr = 0; int step_param = 3; int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; - const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type; + const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize]; int new_mv_mode_penalty = 256; const int quart_frm = MIN(cpi->common.width, cpi->common.height); @@ -542,8 +542,8 @@ void vp9_first_pass(VP9_COMP *cpi) { vp9_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL); vp9_setup_dst_planes(xd, new_yv12, 0, 0); - xd->mi_8x8 = cm->mi_grid_visible; - xd->mi_8x8[0] = cm->mi; + xd->mi = cm->mi_grid_visible; + xd->mi[0] = cm->mi; vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y); @@ -591,8 +591,8 @@ void vp9_first_pass(VP9_COMP *cpi) { xd->plane[1].dst.buf = new_yv12->u_buffer + recon_uvoffset; xd->plane[2].dst.buf = new_yv12->v_buffer + recon_uvoffset; xd->left_available = (mb_col != 0); - xd->mi_8x8[0]->mbmi.sb_type = bsize; - xd->mi_8x8[0]->mbmi.ref_frame[0] = INTRA_FRAME; + xd->mi[0]->mbmi.sb_type = bsize; + xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME; set_mi_row_col(xd, &tile, mb_row << 1, num_8x8_blocks_high_lookup[bsize], mb_col << 1, num_8x8_blocks_wide_lookup[bsize], @@ -711,11 +711,11 @@ void vp9_first_pass(VP9_COMP *cpi) { mv.as_mv.row *= 8; mv.as_mv.col *= 8; this_error = motion_error; - xd->mi_8x8[0]->mbmi.mode = NEWMV; - xd->mi_8x8[0]->mbmi.mv[0] = mv; - 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; + xd->mi[0]->mbmi.mode = NEWMV; + xd->mi[0]->mbmi.mv[0] = mv; + xd->mi[0]->mbmi.tx_size = TX_4X4; + xd->mi[0]->mbmi.ref_frame[0] = LAST_FRAME; + xd->mi[0]->mbmi.ref_frame[1] = NONE; vp9_build_inter_predictors_sby(xd, mb_row << 1, mb_col << 1, bsize); vp9_encode_sby_pass1(x, bsize); sum_mvr += mv.as_mv.row; @@ -911,6 +911,7 @@ int vp9_twopass_worst_quality(VP9_COMP *cpi, FIRSTPASS_STATS *fpstats, const double section_err = fpstats->coded_error / fpstats->count; const double err_per_mb = section_err / num_mbs; + const double speed_term = 1.0 + ((double)cpi->speed * 0.04); if (section_target_bandwitdh <= 0) return rc->worst_quality; // Highest value allowed @@ -924,8 +925,8 @@ int vp9_twopass_worst_quality(VP9_COMP *cpi, FIRSTPASS_STATS *fpstats, for (q = rc->best_quality; q < rc->worst_quality; ++q) { const double err_correction_factor = calc_correction_factor(err_per_mb, ERR_DIVISOR, 0.5, 0.90, q); - const int bits_per_mb_at_this_q = vp9_rc_bits_per_mb(INTER_FRAME, q, - err_correction_factor); + const int bits_per_mb_at_this_q = + vp9_rc_bits_per_mb(INTER_FRAME, q, (err_correction_factor * speed_term)); if (bits_per_mb_at_this_q <= target_norm_bits_per_mb) break; } diff --git a/vp9/encoder/vp9_lookahead.c b/vp9/encoder/vp9_lookahead.c index a88d5ecf8..cf03e0142 100644 --- a/vp9/encoder/vp9_lookahead.c +++ b/vp9/encoder/vp9_lookahead.c @@ -28,8 +28,8 @@ struct lookahead_ctx { /* Return the buffer at the given absolute index and increment the index */ -static struct lookahead_entry * pop(struct lookahead_ctx *ctx, - unsigned int *idx) { +static struct lookahead_entry *pop(struct lookahead_ctx *ctx, + unsigned int *idx) { unsigned int index = *idx; struct lookahead_entry *buf = ctx->buf + index; @@ -55,16 +55,19 @@ void vp9_lookahead_destroy(struct lookahead_ctx *ctx) { } -struct lookahead_ctx * vp9_lookahead_init(unsigned int width, - unsigned int height, - unsigned int subsampling_x, - unsigned int subsampling_y, - unsigned int depth) { +struct lookahead_ctx *vp9_lookahead_init(unsigned int width, + unsigned int height, + unsigned int subsampling_x, + unsigned int subsampling_y, + unsigned int depth) { struct lookahead_ctx *ctx = NULL; // Clamp the lookahead queue depth depth = clamp(depth, 1, MAX_LAG_BUFFERS); + // Allocate memory to keep previous source frames available. + depth += MAX_PRE_FRAMES; + // Allocate the lookahead structures ctx = calloc(1, sizeof(*ctx)); if (ctx) { @@ -96,7 +99,7 @@ int vp9_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src, int mb_cols = (src->y_width + 15) >> 4; #endif - if (ctx->sz + 1 > ctx->max_sz) + if (ctx->sz + 1 + MAX_PRE_FRAMES > ctx->max_sz) return 1; ctx->sz++; buf = pop(ctx, &ctx->write_idx); @@ -159,11 +162,11 @@ int vp9_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src, } -struct lookahead_entry * vp9_lookahead_pop(struct lookahead_ctx *ctx, - int drain) { +struct lookahead_entry *vp9_lookahead_pop(struct lookahead_ctx *ctx, + int drain) { struct lookahead_entry *buf = NULL; - if (ctx->sz && (drain || ctx->sz == ctx->max_sz)) { + if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) { buf = pop(ctx, &ctx->read_idx); ctx->sz--; } @@ -171,16 +174,28 @@ struct lookahead_entry * vp9_lookahead_pop(struct lookahead_ctx *ctx, } -struct lookahead_entry * vp9_lookahead_peek(struct lookahead_ctx *ctx, - int index) { +struct lookahead_entry *vp9_lookahead_peek(struct lookahead_ctx *ctx, + int index) { struct lookahead_entry *buf = NULL; - if (index < (int)ctx->sz) { - index += ctx->read_idx; - if (index >= (int)ctx->max_sz) - index -= ctx->max_sz; - buf = ctx->buf + index; + if (index >= 0) { + // Forward peek + if (index < (int)ctx->sz) { + index += ctx->read_idx; + if (index >= (int)ctx->max_sz) + index -= ctx->max_sz; + buf = ctx->buf + index; + } + } else if (index < 0) { + // Backward peek + if (-index <= MAX_PRE_FRAMES) { + index += ctx->read_idx; + if (index < 0) + index += ctx->max_sz; + buf = ctx->buf + index; + } } + return buf; } diff --git a/vp9/encoder/vp9_lookahead.h b/vp9/encoder/vp9_lookahead.h index ff63c0d0d..046c533cc 100644 --- a/vp9/encoder/vp9_lookahead.h +++ b/vp9/encoder/vp9_lookahead.h @@ -20,6 +20,9 @@ extern "C" { #define MAX_LAG_BUFFERS 25 +// The max of past frames we want to keep in the queue. +#define MAX_PRE_FRAMES 1 + struct lookahead_entry { YV12_BUFFER_CONFIG img; int64_t ts_start; diff --git a/vp9/encoder/vp9_mbgraph.c b/vp9/encoder/vp9_mbgraph.c index 652038950..650b06ed0 100644 --- a/vp9/encoder/vp9_mbgraph.c +++ b/vp9/encoder/vp9_mbgraph.c @@ -61,8 +61,8 @@ static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi, &sse); } - xd->mi_8x8[0]->mbmi.mode = NEWMV; - xd->mi_8x8[0]->mbmi.mv[0].as_mv = *dst_mv; + xd->mi[0]->mbmi.mode = NEWMV; + xd->mi[0]->mbmi.mv[0].as_mv = *dst_mv; vp9_build_inter_predictors_sby(xd, mb_row, mb_col, BLOCK_16X16); @@ -145,7 +145,7 @@ static int find_best_16x16_intra(VP9_COMP *cpi, for (mode = DC_PRED; mode <= TM_PRED; mode++) { unsigned int err; - xd->mi_8x8[0]->mbmi.mode = mode; + xd->mi[0]->mbmi.mode = mode; vp9_predict_intra_block(xd, 0, 2, TX_16X16, mode, x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].dst.buf, xd->plane[0].dst.stride, @@ -252,7 +252,7 @@ static void update_mbgraph_frame_stats(VP9_COMP *cpi, xd->plane[0].dst.stride = buf->y_stride; xd->plane[0].pre[0].stride = buf->y_stride; xd->plane[1].dst.stride = buf->uv_stride; - xd->mi_8x8[0] = &mi_local; + xd->mi[0] = &mi_local; mi_local.mbmi.sb_type = BLOCK_16X16; mi_local.mbmi.ref_frame[0] = LAST_FRAME; mi_local.mbmi.ref_frame[1] = NONE; diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index ef5349733..1f83f6b76 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -40,6 +40,7 @@ #include "vp9/encoder/vp9_ratectrl.h" #include "vp9/encoder/vp9_rdopt.h" #include "vp9/encoder/vp9_segmentation.h" +#include "vp9/encoder/vp9_speed_features.h" #include "vp9/encoder/vp9_temporal_filter.h" #include "vp9/encoder/vp9_resize.h" #include "vp9/encoder/vp9_svc_layercontext.h" @@ -188,6 +189,7 @@ static void dealloc_compressor_data(VP9_COMP *cpi) { vp9_free_frame_buffer(&cpi->last_frame_uf); vp9_free_frame_buffer(&cpi->scaled_source); + vp9_free_frame_buffer(&cpi->scaled_last_source); vp9_free_frame_buffer(&cpi->alt_ref_buffer); vp9_lookahead_destroy(cpi->lookahead); @@ -235,27 +237,27 @@ int vp9_compute_qdelta(const VP9_COMP *cpi, double qstart, double qtarget) { // Computes a q delta (in "q index" terms) to get from a starting q value // to a value that should equate to the given rate ratio. -int vp9_compute_qdelta_by_rate(VP9_COMP *cpi, int base_q_index, +int vp9_compute_qdelta_by_rate(VP9_COMP *cpi, int qindex, double rate_target_ratio) { + const FRAME_TYPE frame_type = cpi->common.frame_type; + const RATE_CONTROL *const rc = &cpi->rc; + int target_index = rc->worst_quality; int i; - int target_index = cpi->rc.worst_quality; // Look up the current projected bits per block for the base index - const int base_bits_per_mb = vp9_rc_bits_per_mb(cpi->common.frame_type, - base_q_index, 1.0); + const int base_bits_per_mb = vp9_rc_bits_per_mb(frame_type, qindex, 1.0); // Find the target bits per mb based on the base value and given ratio. const int target_bits_per_mb = (int)(rate_target_ratio * base_bits_per_mb); // Convert the q target to an index - for (i = cpi->rc.best_quality; i < cpi->rc.worst_quality; ++i) { + for (i = rc->best_quality; i < rc->worst_quality; ++i) { target_index = i; - if (vp9_rc_bits_per_mb(cpi->common.frame_type, i, 1.0) <= - target_bits_per_mb ) + if (vp9_rc_bits_per_mb(frame_type, i, 1.0) <= target_bits_per_mb ) break; } - return target_index - base_q_index; + return target_index - qindex; } static void configure_static_seg_features(VP9_COMP *cpi) { @@ -412,7 +414,7 @@ static void update_reference_segmentation_map(VP9_COMP *cpi) { uint8_t *cache = cache_ptr; for (col = 0; col < cm->mi_cols; col++, mi_8x8++, cache++) cache[0] = mi_8x8[0]->mbmi.segment_id; - mi_8x8_ptr += cm->mode_info_stride; + mi_8x8_ptr += cm->mi_stride; cache_ptr += cm->mi_cols; } } @@ -594,6 +596,13 @@ void vp9_alloc_compressor_data(VP9_COMP *cpi) { vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, "Failed to allocate scaled source buffer"); + if (vp9_alloc_frame_buffer(&cpi->scaled_last_source, + cm->width, cm->height, + cm->subsampling_x, cm->subsampling_y, + VP9_ENC_BORDER_IN_PIXELS)) + vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, + "Failed to allocate scaled last source buffer"); + vpx_free(cpi->tok); { @@ -635,6 +644,13 @@ static void update_frame_size(VP9_COMP *cpi) { vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, "Failed to reallocate scaled source buffer"); + if (vp9_realloc_frame_buffer(&cpi->scaled_last_source, + cm->width, cm->height, + cm->subsampling_x, cm->subsampling_y, + VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL)) + vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, + "Failed to reallocate scaled last source buffer"); + { int y_stride = cpi->scaled_source.y_stride; @@ -645,15 +661,7 @@ static void update_frame_size(VP9_COMP *cpi) { } } - { - int i; - - for (i = 0; i < MAX_MB_PLANE; ++i) - xd->above_context[i] = cm->above_context + - i * sizeof(*cm->above_context) * 2 * mi_cols_aligned_to_sb(cm->mi_cols); - } - - xd->above_seg_context = cpi->common.above_seg_context; + init_macroblockd(cm, xd); } // Table that converts 0-63 Q range values passed in outside to the Qindex @@ -821,6 +829,7 @@ static void init_config(struct VP9_COMP *cpi, VP9_CONFIG *oxcf) { void vp9_change_config(struct VP9_COMP *cpi, const VP9_CONFIG *oxcf) { VP9_COMMON *const cm = &cpi->common; + RATE_CONTROL *const rc = &cpi->rc; if (cm->version != oxcf->version) cm->version = oxcf->version; @@ -873,7 +882,7 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9_CONFIG *oxcf) { } else { cpi->mb.e_mbd.itxm_add = vp9_idct4x4_add; } - cpi->rc.baseline_gf_interval = DEFAULT_GF_INTERVAL; + rc->baseline_gf_interval = DEFAULT_GF_INTERVAL; cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG; cpi->refresh_golden_frame = 0; @@ -922,17 +931,15 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9_CONFIG *oxcf) { cpi->oxcf.target_bandwidth, 1000); // Under a configuration change, where maximum_buffer_size may change, // keep buffer level clipped to the maximum allowed buffer size. - cpi->rc.bits_off_target = MIN(cpi->rc.bits_off_target, - cpi->oxcf.maximum_buffer_size); - cpi->rc.buffer_level = MIN(cpi->rc.buffer_level, - cpi->oxcf.maximum_buffer_size); + rc->bits_off_target = MIN(rc->bits_off_target, cpi->oxcf.maximum_buffer_size); + rc->buffer_level = MIN(rc->buffer_level, cpi->oxcf.maximum_buffer_size); // Set up frame rate and related parameters rate control values. vp9_new_framerate(cpi, cpi->oxcf.framerate); // Set absolute upper and lower quality limits - cpi->rc.worst_quality = cpi->oxcf.worst_allowed_q; - cpi->rc.best_quality = cpi->oxcf.best_allowed_q; + rc->worst_quality = cpi->oxcf.worst_allowed_q; + rc->best_quality = cpi->oxcf.best_allowed_q; // active values should only be modified if out of new range @@ -975,7 +982,7 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9_CONFIG *oxcf) { #else cpi->alt_ref_source = NULL; #endif - cpi->rc.is_src_frame_alt_ref = 0; + rc->is_src_frame_alt_ref = 0; #if 0 // Experimental RD Code @@ -2234,7 +2241,7 @@ static void encode_without_recode_loop(VP9_COMP *cpi, int q) { VP9_COMMON *const cm = &cpi->common; vp9_clear_system_state(); - vp9_set_quantizer(cpi, q); + vp9_set_quantizer(cm, q); // Set up entropy context depending on frame type. The decoder mandates // the use of the default context, index 0, for keyframes and inter @@ -2245,7 +2252,7 @@ static void encode_without_recode_loop(VP9_COMP *cpi, setup_key_frame(cpi); } else { if (!cm->intra_only && !cm->error_resilient_mode && !cpi->use_svc) - cpi->common.frame_context_idx = cpi->refresh_alt_ref_frame; + cm->frame_context_idx = cpi->refresh_alt_ref_frame; setup_inter_frame(cm); } @@ -2291,7 +2298,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi, do { vp9_clear_system_state(); - vp9_set_quantizer(cpi, q); + vp9_set_quantizer(cm, q); if (loop_count == 0) { // Set up entropy context depending on frame type. The decoder mandates @@ -2553,6 +2560,19 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, } else { cpi->Source = cpi->un_scaled_source; } + + // Scale the last source buffer, if required. + if (cpi->unscaled_last_source != NULL) { + if (cm->mi_cols * MI_SIZE != cpi->unscaled_last_source->y_width || + cm->mi_rows * MI_SIZE != cpi->unscaled_last_source->y_height) { + scale_and_extend_frame_nonnormative(cpi->unscaled_last_source, + &cpi->scaled_last_source); + cpi->Last_Source = &cpi->scaled_last_source; + } else { + cpi->Last_Source = cpi->unscaled_last_source; + } + } + vp9_scale_references(cpi); vp9_clear_system_state(); @@ -2672,6 +2692,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, vp9_write_yuv_frame(cpi->Source); #endif + set_speed_features(cpi); + // Decide q and q bounds. q = vp9_rc_pick_q_and_bounds(cpi, &bottom_index, &top_index); @@ -2681,8 +2703,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, set_high_precision_mv(cpi, q < HIGH_PRECISION_MV_QTHRESH); } - set_speed_features(cpi); - if (cpi->sf.recode_loop == DISALLOW_RECODE) { encode_without_recode_loop(cpi, size, dest, q); } else { @@ -2825,8 +2845,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, } // restore prev_mi - cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1; - cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mode_info_stride + 1; + cm->prev_mi = cm->prev_mip + cm->mi_stride + 1; + cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1; } static void SvcEncode(VP9_COMP *cpi, size_t *size, uint8_t *dest, @@ -2852,7 +2872,7 @@ static void Pass1Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, (void) frame_flags; vp9_rc_get_first_pass_params(cpi); - vp9_set_quantizer(cpi, find_fp_qindex()); + vp9_set_quantizer(&cpi->common, find_fp_qindex()); vp9_first_pass(cpi); } @@ -2968,8 +2988,9 @@ void adjust_frame_rate(VP9_COMP *cpi) { int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, size_t *size, uint8_t *dest, int64_t *time_stamp, int64_t *time_end, int flush) { - VP9_COMMON *cm = &cpi->common; - MACROBLOCKD *xd = &cpi->mb.e_mbd; + VP9_COMMON *const cm = &cpi->common; + MACROBLOCKD *const xd = &cpi->mb.e_mbd; + RATE_CONTROL *const rc = &cpi->rc; struct vpx_usec_timer cmptimer; YV12_BUFFER_CONFIG *force_src_buffer = NULL; MV_REFERENCE_FRAME ref_frame; @@ -2984,6 +3005,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, vpx_usec_timer_start(&cmptimer); cpi->source = NULL; + cpi->last_source = NULL; set_high_precision_mv(cpi, ALTREF_HIGH_PRECISION_MV); @@ -2995,7 +3017,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, cpi->refresh_alt_ref_frame = 0; // Should we code an alternate reference frame. - if (cpi->oxcf.play_alternate && cpi->rc.source_alt_ref_pending) { + if (cpi->oxcf.play_alternate && rc->source_alt_ref_pending) { int frames_to_arf; #if CONFIG_MULTIPLE_ARF @@ -3007,9 +3029,9 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, - cpi->next_frame_in_order; else #endif - frames_to_arf = cpi->rc.frames_till_gf_update_due; + frames_to_arf = rc->frames_till_gf_update_due; - assert(frames_to_arf <= cpi->rc.frames_to_key); + assert(frames_to_arf <= rc->frames_to_key); if ((cpi->source = vp9_lookahead_peek(cpi->lookahead, frames_to_arf))) { #if CONFIG_MULTIPLE_ARF @@ -3021,7 +3043,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, if (cpi->oxcf.arnr_max_frames > 0) { // Produce the filtered ARF frame. // TODO(agrange) merge these two functions. - vp9_configure_arnr_filter(cpi, frames_to_arf, cpi->rc.gfu_boost); + vp9_configure_arnr_filter(cpi, frames_to_arf, rc->gfu_boost); vp9_temporal_filter_prepare(cpi, frames_to_arf); vp9_extend_frame_borders(&cpi->alt_ref_buffer); force_src_buffer = &cpi->alt_ref_buffer; @@ -3031,14 +3053,14 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, cpi->refresh_alt_ref_frame = 1; cpi->refresh_golden_frame = 0; cpi->refresh_last_frame = 0; - cpi->rc.is_src_frame_alt_ref = 0; + rc->is_src_frame_alt_ref = 0; #if CONFIG_MULTIPLE_ARF if (!cpi->multi_arf_enabled) #endif - cpi->rc.source_alt_ref_pending = 0; + rc->source_alt_ref_pending = 0; } else { - cpi->rc.source_alt_ref_pending = 0; + rc->source_alt_ref_pending = 0; } } @@ -3046,25 +3068,32 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, #if CONFIG_MULTIPLE_ARF int i; #endif + + // Get last frame source. + if (cm->current_video_frame > 0) { + if ((cpi->last_source = vp9_lookahead_peek(cpi->lookahead, -1)) == NULL) + return -1; + } + if ((cpi->source = vp9_lookahead_pop(cpi->lookahead, flush))) { cm->show_frame = 1; cm->intra_only = 0; #if CONFIG_MULTIPLE_ARF // Is this frame the ARF overlay. - cpi->rc.is_src_frame_alt_ref = 0; + rc->is_src_frame_alt_ref = 0; for (i = 0; i < cpi->arf_buffered; ++i) { if (cpi->source == cpi->alt_ref_source[i]) { - cpi->rc.is_src_frame_alt_ref = 1; + rc->is_src_frame_alt_ref = 1; cpi->refresh_golden_frame = 1; break; } } #else - cpi->rc.is_src_frame_alt_ref = cpi->alt_ref_source - && (cpi->source == cpi->alt_ref_source); + rc->is_src_frame_alt_ref = cpi->alt_ref_source && + (cpi->source == cpi->alt_ref_source); #endif - if (cpi->rc.is_src_frame_alt_ref) { + if (rc->is_src_frame_alt_ref) { // Current frame is an ARF overlay frame. #if CONFIG_MULTIPLE_ARF cpi->alt_ref_source[i] = NULL; @@ -3084,13 +3113,20 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, if (cpi->source) { cpi->un_scaled_source = cpi->Source = force_src_buffer ? force_src_buffer : &cpi->source->img; + + if (cpi->last_source != NULL) { + cpi->unscaled_last_source = &cpi->last_source->img; + } else { + cpi->unscaled_last_source = NULL; + } + *time_stamp = cpi->source->ts_start; *time_end = cpi->source->ts_end; *frame_flags = cpi->source->flags; #if CONFIG_MULTIPLE_ARF - if ((cm->frame_type != KEY_FRAME) && (cpi->pass == 2)) - cpi->rc.source_alt_ref_pending = is_next_frame_arf(cpi); + if (cm->frame_type != KEY_FRAME && cpi->pass == 2) + rc->source_alt_ref_pending = is_next_frame_arf(cpi); #endif } else { *size = 0; diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index 6dbe4d474..535bdaacb 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -280,23 +280,7 @@ typedef struct { } VP9_CONFIG; typedef struct VP9_COMP { - DECLARE_ALIGNED(16, int16_t, y_quant[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, y_quant_shift[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, y_zbin[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, y_round[QINDEX_RANGE][8]); - - DECLARE_ALIGNED(16, int16_t, uv_quant[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, uv_quant_shift[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, uv_zbin[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, uv_round[QINDEX_RANGE][8]); - -#if CONFIG_ALPHA - DECLARE_ALIGNED(16, int16_t, a_quant[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, a_quant_shift[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, a_zbin[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, a_round[QINDEX_RANGE][8]); -#endif - + QUANTS quants; MACROBLOCK mb; VP9_COMMON common; VP9_CONFIG oxcf; @@ -307,10 +291,14 @@ typedef struct VP9_COMP { #else struct lookahead_entry *alt_ref_source; #endif + struct lookahead_entry *last_source; YV12_BUFFER_CONFIG *Source; + YV12_BUFFER_CONFIG *Last_Source; // NULL for first frame and alt_ref frames YV12_BUFFER_CONFIG *un_scaled_source; YV12_BUFFER_CONFIG scaled_source; + YV12_BUFFER_CONFIG *unscaled_last_source; + YV12_BUFFER_CONFIG scaled_last_source; int key_frame_frequency; diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index c500a0163..b517d6cfe 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c @@ -31,7 +31,7 @@ static void full_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mi_row, int mi_col, int_mv *tmp_mv) { MACROBLOCKD *xd = &x->e_mbd; - MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}}; int step_param; int sadpb = x->sadperbit16; @@ -135,7 +135,7 @@ static void sub_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mi_row, int mi_col, MV *tmp_mv, int *rate_mv) { MACROBLOCKD *xd = &x->e_mbd; - MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}}; int ref = mbmi->ref_frame[0]; MV ref_mv = mbmi->ref_mvs[ref][0].as_mv; @@ -209,7 +209,7 @@ int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, int64_t *returndistortion, BLOCK_SIZE bsize) { MACROBLOCKD *xd = &x->e_mbd; - MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; struct macroblock_plane *const p = &x->plane[0]; struct macroblockd_plane *const pd = &xd->plane[0]; const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]); @@ -343,7 +343,7 @@ int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, mbmi->mode = best_mode; mbmi->ref_frame[0] = best_ref_frame; mbmi->mv[0].as_int = frame_mv[best_mode][best_ref_frame].as_int; - xd->mi_8x8[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int; + xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int; // Perform intra prediction search, if the best SAD is above a certain // threshold. diff --git a/vp9/encoder/vp9_quantize.c b/vp9/encoder/vp9_quantize.c index 4ab8995e3..c092ee41f 100644 --- a/vp9/encoder/vp9_quantize.c +++ b/vp9/encoder/vp9_quantize.c @@ -153,6 +153,7 @@ static void invert_quant(int16_t *quant, int16_t *shift, int d) { void vp9_init_quantizer(VP9_COMP *cpi) { VP9_COMMON *const cm = &cpi->common; + QUANTS *const quants = &cpi->quants; int i, q, quant; for (q = 0; q < QINDEX_RANGE; q++) { @@ -163,48 +164,49 @@ void vp9_init_quantizer(VP9_COMP *cpi) { // y quant = i == 0 ? vp9_dc_quant(q, cm->y_dc_delta_q) : vp9_ac_quant(q, 0); - invert_quant(&cpi->y_quant[q][i], &cpi->y_quant_shift[q][i], quant); - cpi->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7); - cpi->y_round[q][i] = (qrounding_factor * quant) >> 7; + invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i], quant); + quants->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7); + quants->y_round[q][i] = (qrounding_factor * quant) >> 7; cm->y_dequant[q][i] = quant; // uv quant = i == 0 ? vp9_dc_quant(q, cm->uv_dc_delta_q) : vp9_ac_quant(q, cm->uv_ac_delta_q); - invert_quant(&cpi->uv_quant[q][i], &cpi->uv_quant_shift[q][i], quant); - cpi->uv_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7); - cpi->uv_round[q][i] = (qrounding_factor * quant) >> 7; + invert_quant(&quants->uv_quant[q][i], + &quants->uv_quant_shift[q][i], quant); + quants->uv_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7); + quants->uv_round[q][i] = (qrounding_factor * quant) >> 7; cm->uv_dequant[q][i] = quant; #if CONFIG_ALPHA // alpha quant = i == 0 ? vp9_dc_quant(q, cm->a_dc_delta_q) : vp9_ac_quant(q, cm->a_ac_delta_q); - invert_quant(&cpi->a_quant[q][i], &cpi->a_quant_shift[q][i], quant); - cpi->a_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7); - cpi->a_round[q][i] = (qrounding_factor * quant) >> 7; + invert_quant(&quants->a_quant[q][i], &quants->a_quant_shift[q][i], quant); + quants->a_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7); + quants->a_round[q][i] = (qrounding_factor * quant) >> 7; cm->a_dequant[q][i] = quant; #endif } for (i = 2; i < 8; i++) { - cpi->y_quant[q][i] = cpi->y_quant[q][1]; - cpi->y_quant_shift[q][i] = cpi->y_quant_shift[q][1]; - cpi->y_zbin[q][i] = cpi->y_zbin[q][1]; - cpi->y_round[q][i] = cpi->y_round[q][1]; + quants->y_quant[q][i] = quants->y_quant[q][1]; + quants->y_quant_shift[q][i] = quants->y_quant_shift[q][1]; + quants->y_zbin[q][i] = quants->y_zbin[q][1]; + quants->y_round[q][i] = quants->y_round[q][1]; cm->y_dequant[q][i] = cm->y_dequant[q][1]; - cpi->uv_quant[q][i] = cpi->uv_quant[q][1]; - cpi->uv_quant_shift[q][i] = cpi->uv_quant_shift[q][1]; - cpi->uv_zbin[q][i] = cpi->uv_zbin[q][1]; - cpi->uv_round[q][i] = cpi->uv_round[q][1]; + quants->uv_quant[q][i] = quants->uv_quant[q][1]; + quants->uv_quant_shift[q][i] = quants->uv_quant_shift[q][1]; + quants->uv_zbin[q][i] = quants->uv_zbin[q][1]; + quants->uv_round[q][i] = quants->uv_round[q][1]; cm->uv_dequant[q][i] = cm->uv_dequant[q][1]; #if CONFIG_ALPHA - cpi->a_quant[q][i] = cpi->a_quant[q][1]; - cpi->a_quant_shift[q][i] = cpi->a_quant_shift[q][1]; - cpi->a_zbin[q][i] = cpi->a_zbin[q][1]; - cpi->a_round[q][i] = cpi->a_round[q][1]; + quants->a_quant[q][i] = quants->a_quant[q][1]; + quants->a_quant_shift[q][i] = quants->a_quant_shift[q][1]; + quants->a_zbin[q][i] = quants->a_zbin[q][1]; + quants->a_round[q][i] = quants->a_round[q][1]; cm->a_dequant[q][i] = cm->a_dequant[q][1]; #endif } @@ -213,27 +215,28 @@ void vp9_init_quantizer(VP9_COMP *cpi) { void vp9_init_plane_quantizers(VP9_COMP *cpi, MACROBLOCK *x) { const VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *xd = &x->e_mbd; - const int segment_id = xd->mi_8x8[0]->mbmi.segment_id; + MACROBLOCKD *const xd = &x->e_mbd; + QUANTS *const quants = &cpi->quants; + const int segment_id = xd->mi[0]->mbmi.segment_id; const int qindex = vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex); const int rdmult = vp9_compute_rd_mult(cpi, qindex + cm->y_dc_delta_q); const int zbin = cpi->zbin_mode_boost + x->act_zbin_adj; int i; // Y - x->plane[0].quant = cpi->y_quant[qindex]; - x->plane[0].quant_shift = cpi->y_quant_shift[qindex]; - x->plane[0].zbin = cpi->y_zbin[qindex]; - x->plane[0].round = cpi->y_round[qindex]; + x->plane[0].quant = quants->y_quant[qindex]; + x->plane[0].quant_shift = quants->y_quant_shift[qindex]; + x->plane[0].zbin = quants->y_zbin[qindex]; + x->plane[0].round = quants->y_round[qindex]; x->plane[0].zbin_extra = (int16_t)((cm->y_dequant[qindex][1] * zbin) >> 7); xd->plane[0].dequant = cm->y_dequant[qindex]; // UV for (i = 1; i < 3; i++) { - x->plane[i].quant = cpi->uv_quant[qindex]; - x->plane[i].quant_shift = cpi->uv_quant_shift[qindex]; - x->plane[i].zbin = cpi->uv_zbin[qindex]; - x->plane[i].round = cpi->uv_round[qindex]; + x->plane[i].quant = quants->uv_quant[qindex]; + x->plane[i].quant_shift = quants->uv_quant_shift[qindex]; + x->plane[i].zbin = quants->uv_zbin[qindex]; + x->plane[i].round = quants->uv_round[qindex]; x->plane[i].zbin_extra = (int16_t)((cm->uv_dequant[qindex][1] * zbin) >> 7); xd->plane[i].dequant = cm->uv_dequant[qindex]; } @@ -273,9 +276,7 @@ void vp9_frame_init_quantizer(VP9_COMP *cpi) { vp9_init_plane_quantizers(cpi, &cpi->mb); } -void vp9_set_quantizer(struct VP9_COMP *cpi, int q) { - VP9_COMMON *const cm = &cpi->common; - +void vp9_set_quantizer(VP9_COMMON *cm, int q) { // quantizer has to be reinitialized with vp9_init_quantizer() if any // delta_q changes. cm->base_qindex = q; diff --git a/vp9/encoder/vp9_quantize.h b/vp9/encoder/vp9_quantize.h index f356b125c..7d231dfd3 100644 --- a/vp9/encoder/vp9_quantize.h +++ b/vp9/encoder/vp9_quantize.h @@ -17,12 +17,30 @@ extern "C" { #endif +typedef struct { + DECLARE_ALIGNED(16, int16_t, y_quant[QINDEX_RANGE][8]); + DECLARE_ALIGNED(16, int16_t, y_quant_shift[QINDEX_RANGE][8]); + DECLARE_ALIGNED(16, int16_t, y_zbin[QINDEX_RANGE][8]); + DECLARE_ALIGNED(16, int16_t, y_round[QINDEX_RANGE][8]); + + DECLARE_ALIGNED(16, int16_t, uv_quant[QINDEX_RANGE][8]); + DECLARE_ALIGNED(16, int16_t, uv_quant_shift[QINDEX_RANGE][8]); + DECLARE_ALIGNED(16, int16_t, uv_zbin[QINDEX_RANGE][8]); + DECLARE_ALIGNED(16, int16_t, uv_round[QINDEX_RANGE][8]); + +#if CONFIG_ALPHA + DECLARE_ALIGNED(16, int16_t, a_quant[QINDEX_RANGE][8]); + DECLARE_ALIGNED(16, int16_t, a_quant_shift[QINDEX_RANGE][8]); + DECLARE_ALIGNED(16, int16_t, a_zbin[QINDEX_RANGE][8]); + DECLARE_ALIGNED(16, int16_t, a_round[QINDEX_RANGE][8]); +#endif +} QUANTS; + void vp9_regular_quantize_b_4x4(MACROBLOCK *x, int plane, int block, const int16_t *scan, const int16_t *iscan); struct VP9_COMP; - -void vp9_set_quantizer(struct VP9_COMP *cpi, int q); +struct VP9Common; void vp9_frame_init_quantizer(struct VP9_COMP *cpi); @@ -32,6 +50,8 @@ void vp9_init_plane_quantizers(struct VP9_COMP *cpi, MACROBLOCK *x); void vp9_init_quantizer(struct VP9_COMP *cpi); +void vp9_set_quantizer(struct VP9Common *cm, int q); + #ifdef __cplusplus } // extern "C" #endif diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index c62d31293..9ee58185c 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -977,14 +977,14 @@ int vp9_rc_pick_q_and_bounds(const VP9_COMP *cpi, q = rc_pick_q_and_bounds_two_pass(cpi, bottom_index, top_index); } - // JBB : This is realtime mode. In real time mode the first frame - // should be larger. Q of 0 is disabled because we force tx size to be + // Q of 0 is disabled because we force tx size to be // 16x16... if (cpi->sf.use_nonrd_pick_mode) { - if (cpi->common.current_video_frame == 0) - q /= 3; if (q == 0) q++; + if (cpi->sf.partition_check == 1) + q -= 10; + if (q < *bottom_index) *bottom_index = q; else if (q > *top_index) @@ -1010,7 +1010,7 @@ void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi, *frame_over_shoot_limit = this_frame_target * 9 / 8; *frame_under_shoot_limit = this_frame_target * 7 / 8; } else { - // Stron overshoot limit for constrained quality + // Strong overshoot limit for constrained quality if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { *frame_over_shoot_limit = this_frame_target * 11 / 8; *frame_under_shoot_limit = this_frame_target * 2 / 8; @@ -1188,15 +1188,15 @@ static int test_for_kf_one_pass(VP9_COMP *cpi) { static int calc_pframe_target_size_one_pass_vbr(const VP9_COMP *const cpi) { static const int af_ratio = 10; - const RATE_CONTROL *rc = &cpi->rc; + const RATE_CONTROL *const rc = &cpi->rc; int target; #if USE_ALTREF_FOR_ONE_PASS target = (!rc->is_src_frame_alt_ref && (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) ? - (rc->av_per_frame_bandwidth * cpi->rc.baseline_gf_interval * af_ratio) / - (cpi->rc.baseline_gf_interval + af_ratio - 1) : - (rc->av_per_frame_bandwidth * cpi->rc.baseline_gf_interval) / - (cpi->rc.baseline_gf_interval + af_ratio - 1); + (rc->av_per_frame_bandwidth * rc->baseline_gf_interval * af_ratio) / + (rc->baseline_gf_interval + af_ratio - 1) : + (rc->av_per_frame_bandwidth * rc->baseline_gf_interval) / + (rc->baseline_gf_interval + af_ratio - 1); #else target = rc->av_per_frame_bandwidth; #endif @@ -1296,13 +1296,14 @@ static int calc_iframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { void vp9_rc_get_svc_params(VP9_COMP *cpi) { VP9_COMMON *const cm = &cpi->common; - int target = cpi->rc.av_per_frame_bandwidth; + RATE_CONTROL *const rc = &cpi->rc; + int target = rc->av_per_frame_bandwidth; if ((cm->current_video_frame == 0) || (cm->frame_flags & FRAMEFLAGS_KEY) || - (cpi->oxcf.auto_key && (cpi->rc.frames_since_key % + (cpi->oxcf.auto_key && (rc->frames_since_key % cpi->key_frame_frequency == 0))) { cm->frame_type = KEY_FRAME; - cpi->rc.source_alt_ref_active = 0; + rc->source_alt_ref_active = 0; if (cpi->pass == 0 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { target = calc_iframe_target_size_one_pass_cbr(cpi); } @@ -1313,8 +1314,8 @@ void vp9_rc_get_svc_params(VP9_COMP *cpi) { } } vp9_rc_set_frame_target(cpi, target); - cpi->rc.frames_till_gf_update_due = INT_MAX; - cpi->rc.baseline_gf_interval = INT_MAX; + rc->frames_till_gf_update_due = INT_MAX; + rc->baseline_gf_interval = INT_MAX; } void vp9_rc_get_one_pass_cbr_params(VP9_COMP *cpi) { diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index ba7d4db12..d758d3bf5 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -432,7 +432,7 @@ static void model_rd_for_sb(VP9_COMP *cpi, BLOCK_SIZE bsize, int i; int64_t rate_sum = 0; int64_t dist_sum = 0; - const int ref = xd->mi_8x8[0]->mbmi.ref_frame[0]; + const int ref = xd->mi[0]->mbmi.ref_frame[0]; unsigned int sse; for (i = 0; i < MAX_MB_PLANE; ++i) { @@ -556,7 +556,7 @@ static INLINE int cost_coeffs(MACROBLOCK *x, const int16_t *scan, const int16_t *nb, int use_fast_coef_costing) { MACROBLOCKD *const xd = &x->e_mbd; - MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; const struct macroblock_plane *p = &x->plane[plane]; const struct macroblockd_plane *pd = &xd->plane[plane]; const PLANE_TYPE type = pd->plane_type; @@ -638,7 +638,7 @@ static void dist_block(int plane, int block, TX_SIZE tx_size, &this_sse) >> shift; args->sse = this_sse >> shift; - if (x->skip_encode && !is_inter_block(&xd->mi_8x8[0]->mbmi)) { + if (x->skip_encode && !is_inter_block(&xd->mi[0]->mbmi)) { // TODO(jingning): tune the model to better capture the distortion. int64_t p = (pd->dequant[1] * pd->dequant[1] * (1 << ss_txfrm_size)) >> (shift + 2); @@ -663,7 +663,7 @@ static void block_rd_txfm(int plane, int block, BLOCK_SIZE plane_bsize, struct rdcost_block_args *args = arg; MACROBLOCK *const x = args->x; MACROBLOCKD *const xd = &x->e_mbd; - MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; int64_t rd1, rd2, rd; if (args->skip) @@ -749,7 +749,7 @@ static void txfm_rd_in_plane(MACROBLOCK *x, args.use_fast_coef_costing = use_fast_coef_casting; if (plane == 0) - xd->mi_8x8[0]->mbmi.tx_size = tx_size; + xd->mi[0]->mbmi.tx_size = tx_size; vp9_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left); @@ -779,7 +779,7 @@ static void choose_largest_txfm_size(VP9_COMP *cpi, MACROBLOCK *x, VP9_COMMON *const cm = &cpi->common; const TX_SIZE largest_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode]; MACROBLOCKD *const xd = &x->e_mbd; - MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; mbmi->tx_size = MIN(max_tx_size, largest_tx_size); @@ -798,7 +798,7 @@ static void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x, const TX_SIZE max_tx_size = max_txsize_lookup[bs]; VP9_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &x->e_mbd; - MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; vp9_prob skip_prob = vp9_get_skip_prob(cm, xd); int64_t rd[TX_SIZES][2] = {{INT64_MAX, INT64_MAX}, {INT64_MAX, INT64_MAX}, @@ -881,7 +881,7 @@ static void choose_txfm_size_from_modelrd(VP9_COMP *cpi, MACROBLOCK *x, const TX_SIZE max_tx_size = max_txsize_lookup[bs]; VP9_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &x->e_mbd; - MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; vp9_prob skip_prob = vp9_get_skip_prob(cm, xd); int64_t rd[TX_SIZES][2] = {{INT64_MAX, INT64_MAX}, {INT64_MAX, INT64_MAX}, @@ -951,7 +951,7 @@ static void inter_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate, int r[TX_SIZES][2], s[TX_SIZES]; int64_t d[TX_SIZES], sse[TX_SIZES]; MACROBLOCKD *xd = &x->e_mbd; - MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; const TX_SIZE max_tx_size = max_txsize_lookup[bs]; TX_SIZE tx_size; @@ -994,7 +994,7 @@ static void intra_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate, int64_t ref_best_rd) { int64_t sse[TX_SIZES]; MACROBLOCKD *xd = &x->e_mbd; - MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; assert(bs == mbmi->sb_type); if (cpi->sf.tx_size_search_method != USE_FULL_RD) { @@ -1070,7 +1070,7 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib, vpx_memcpy(ta, a, sizeof(ta)); vpx_memcpy(tl, l, sizeof(tl)); - xd->mi_8x8[0]->mbmi.tx_size = TX_4X4; + xd->mi[0]->mbmi.tx_size = TX_4X4; for (mode = DC_PRED; mode <= TM_PRED; ++mode) { int64_t this_rd; @@ -1099,7 +1099,7 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib, int16_t *const src_diff = raster_block_offset_int16(BLOCK_8X8, block, p->src_diff); int16_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block); - xd->mi_8x8[0]->bmi[block].as_mode = mode; + xd->mi[0]->bmi[block].as_mode = mode; vp9_predict_intra_block(xd, block, 1, TX_4X4, mode, x->skip_encode ? src : dst, @@ -1172,10 +1172,10 @@ static int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP *cpi, MACROBLOCK *mb, int64_t best_rd) { int i, j; const MACROBLOCKD *const xd = &mb->e_mbd; - MODE_INFO *const mic = xd->mi_8x8[0]; - const MODE_INFO *above_mi = xd->mi_8x8[-xd->mode_info_stride]; - const MODE_INFO *left_mi = xd->left_available ? xd->mi_8x8[-1] : NULL; - const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type; + MODE_INFO *const mic = xd->mi[0]; + const MODE_INFO *above_mi = xd->mi[-xd->mi_stride]; + const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1] : NULL; + const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; int idx, idy; @@ -1242,7 +1242,7 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x, MB_PREDICTION_MODE mode; MB_PREDICTION_MODE mode_selected = DC_PRED; MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mic = xd->mi_8x8[0]; + MODE_INFO *const mic = xd->mi[0]; int this_rate, this_rate_tokenonly, s; int64_t this_distortion, this_rd; TX_SIZE best_tx = TX_4X4; @@ -1256,8 +1256,8 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x, /* Y Search for intra prediction mode */ for (mode = DC_PRED; mode <= TM_PRED; mode++) { int64_t local_tx_cache[TX_MODES]; - MODE_INFO *above_mi = xd->mi_8x8[-xd->mode_info_stride]; - MODE_INFO *left_mi = xd->left_available ? xd->mi_8x8[-1] : NULL; + MODE_INFO *above_mi = xd->mi[-xd->mi_stride]; + MODE_INFO *left_mi = xd->left_available ? xd->mi[-1] : NULL; if (!(cpi->sf.intra_y_mode_mask[max_txsize_lookup[bsize]] & (1 << mode))) continue; @@ -1311,7 +1311,7 @@ static void super_block_uvrd(const VP9_COMP *cpi, MACROBLOCK *x, int64_t *sse, BLOCK_SIZE bsize, int64_t ref_best_rd) { MACROBLOCKD *const xd = &x->e_mbd; - MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; TX_SIZE uv_txfm_size = get_uv_tx_size(mbmi); int plane; int pnrate = 0, pnskip = 1; @@ -1368,7 +1368,7 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x, if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode))) continue; - xd->mi_8x8[0]->mbmi.uv_mode = mode; + xd->mi[0]->mbmi.uv_mode = mode; super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, &this_sse, bsize, best_rd); @@ -1409,7 +1409,7 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x, } } - xd->mi_8x8[0]->mbmi.uv_mode = mode_selected; + xd->mi[0]->mbmi.uv_mode = mode_selected; return best_rd; } @@ -1420,7 +1420,7 @@ static int64_t rd_sbuv_dcpred(const VP9_COMP *cpi, MACROBLOCK *x, const VP9_COMMON *cm = &cpi->common; int64_t unused; - x->e_mbd.mi_8x8[0]->mbmi.uv_mode = DC_PRED; + x->e_mbd.mi[0]->mbmi.uv_mode = DC_PRED; super_block_uvrd(cpi, x, rate_tokenonly, distortion, skippable, &unused, bsize, INT64_MAX); *rate = *rate_tokenonly + x->intra_uv_mode_cost[cm->frame_type][DC_PRED]; @@ -1446,13 +1446,13 @@ static void choose_intra_uv_mode(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv, bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size); } - *mode_uv = x->e_mbd.mi_8x8[0]->mbmi.uv_mode; + *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode; } static int cost_mv_ref(const VP9_COMP *cpi, MB_PREDICTION_MODE mode, int mode_context) { const MACROBLOCK *const x = &cpi->mb; - const int segment_id = x->e_mbd.mi_8x8[0]->mbmi.segment_id; + const int segment_id = x->e_mbd.mi[0]->mbmi.segment_id; // Don't account for mode here if segment skip is enabled. if (!vp9_segfeature_active(&cpi->common.seg, segment_id, SEG_LVL_SKIP)) { @@ -1477,7 +1477,7 @@ static int labels2mode(VP9_COMP *cpi, MACROBLOCKD *xd, int i, int_mv seg_mvs[MAX_REF_FRAMES], int_mv *best_ref_mv[2], const int *mvjcost, int *mvcost[2]) { - MODE_INFO *const mic = xd->mi_8x8[0]; + MODE_INFO *const mic = xd->mi[0]; const MB_MODE_INFO *const mbmi = &mic->mbmi; int thismvcost = 0; int idx, idy; @@ -1545,7 +1545,7 @@ static int64_t encode_inter_mb_segment(VP9_COMP *cpi, MACROBLOCKD *xd = &x->e_mbd; struct macroblockd_plane *const pd = &xd->plane[0]; struct macroblock_plane *const p = &x->plane[0]; - MODE_INFO *const mi = xd->mi_8x8[0]; + MODE_INFO *const mi = xd->mi[0]; const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd); const int width = 4 * num_4x4_blocks_wide_lookup[plane_bsize]; const int height = 4 * num_4x4_blocks_high_lookup[plane_bsize]; @@ -1642,7 +1642,7 @@ static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) { } static INLINE void mi_buf_shift(MACROBLOCK *x, int i) { - MB_MODE_INFO *const mbmi = &x->e_mbd.mi_8x8[0]->mbmi; + MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi; struct macroblock_plane *const p = &x->plane[0]; struct macroblockd_plane *const pd = &x->e_mbd.plane[0]; @@ -1657,7 +1657,7 @@ static INLINE void mi_buf_shift(MACROBLOCK *x, int i) { static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src, struct buf_2d orig_pre[2]) { - MB_MODE_INFO *mbmi = &x->e_mbd.mi_8x8[0]->mbmi; + MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi; x->plane[0].src = orig_src; x->e_mbd.plane[0].pre[0] = orig_pre[0]; if (has_second_ref(mbmi)) @@ -1717,7 +1717,7 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, MB_PREDICTION_MODE this_mode; MACROBLOCKD *xd = &x->e_mbd; VP9_COMMON *cm = &cpi->common; - MODE_INFO *mi = xd->mi_8x8[0]; + MODE_INFO *mi = xd->mi[0]; MB_MODE_INFO *const mbmi = &mi->mbmi; struct macroblock_plane *const p = &x->plane[0]; struct macroblockd_plane *const pd = &xd->plane[0]; @@ -2096,7 +2096,7 @@ static int64_t rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x, int i; BEST_SEG_INFO *bsi = bsi_buf + filter_idx; MACROBLOCKD *xd = &x->e_mbd; - MODE_INFO *mi = xd->mi_8x8[0]; + MODE_INFO *mi = xd->mi[0]; MB_MODE_INFO *mbmi = &mi->mbmi; int mode_idx; @@ -2143,7 +2143,7 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x, uint8_t *ref_y_buffer, int ref_y_stride, int ref_frame, BLOCK_SIZE block_size ) { MACROBLOCKD *xd = &x->e_mbd; - MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; int_mv this_mv; int i; int zero_seen = 0; @@ -2273,7 +2273,7 @@ static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx, // restored if we decide to encode this way ctx->skip = x->skip; ctx->best_mode_index = mode_index; - ctx->mic = *xd->mi_8x8[0]; + ctx->mic = *xd->mi[0]; ctx->best_ref_mv[0].as_int = ref_mv->as_int; ctx->best_ref_mv[1].as_int = second_ref_mv->as_int; @@ -2324,7 +2324,7 @@ void vp9_setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x, const VP9_COMMON *cm = &cpi->common; const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame); MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi_8x8[0]; + MODE_INFO *const mi = xd->mi[0]; int_mv *const candidates = mi->mbmi.ref_mvs[ref_frame]; const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf; @@ -2358,7 +2358,7 @@ const YV12_BUFFER_CONFIG *vp9_get_scaled_ref_frame(const VP9_COMP *cpi, static INLINE int get_switchable_rate(const MACROBLOCK *x) { const MACROBLOCKD *const xd = &x->e_mbd; - const MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; const int ctx = vp9_get_pred_context_switchable_interp(xd); return SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs[ctx][mbmi->interp_filter]; @@ -2371,7 +2371,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, int_mv *tmp_mv, int *rate_mv) { MACROBLOCKD *xd = &x->e_mbd; VP9_COMMON *cm = &cpi->common; - MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}}; int bestsme = INT_MAX; int further_steps, step_param; @@ -2537,7 +2537,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, const int pw = 4 * num_4x4_blocks_wide_lookup[bsize]; const int ph = 4 * num_4x4_blocks_high_lookup[bsize]; MACROBLOCKD *xd = &x->e_mbd; - MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; const int refs[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] }; int_mv ref_mv[2]; @@ -2698,7 +2698,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, const int64_t ref_best_rd) { VP9_COMMON *cm = &cpi->common; MACROBLOCKD *xd = &x->e_mbd; - MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; const int is_comp_pred = has_second_ref(mbmi); const int num_refs = is_comp_pred ? 2 : 1; const int this_mode = mbmi->mode; @@ -2750,7 +2750,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, return INT64_MAX; *rate2 += rate_mv; frame_mv[refs[0]].as_int = - xd->mi_8x8[0]->bmi[0].as_mv[0].as_int = tmp_mv.as_int; + xd->mi[0]->bmi[0].as_mv[0].as_int = tmp_mv.as_int; single_newmv[refs[0]].as_int = tmp_mv.as_int; } } @@ -3072,7 +3072,7 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, TX_SIZE max_uv_tx_size; x->skip_encode = 0; ctx->skip = 0; - xd->mi_8x8[0]->mbmi.ref_frame[0] = INTRA_FRAME; + xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME; if (bsize >= BLOCK_8X8) { if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, @@ -3081,7 +3081,7 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, *returnrate = INT_MAX; return; } - max_uv_tx_size = get_uv_tx_size_impl(xd->mi_8x8[0]->mbmi.tx_size, bsize); + max_uv_tx_size = get_uv_tx_size_impl(xd->mi[0]->mbmi.tx_size, bsize); rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly, &dist_uv, &uv_skip, bsize, max_uv_tx_size); } else { @@ -3091,7 +3091,7 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, *returnrate = INT_MAX; return; } - max_uv_tx_size = get_uv_tx_size_impl(xd->mi_8x8[0]->mbmi.tx_size, bsize); + max_uv_tx_size = get_uv_tx_size_impl(xd->mi[0]->mbmi.tx_size, bsize); rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly, &dist_uv, &uv_skip, BLOCK_8X8, max_uv_tx_size); } @@ -3114,7 +3114,7 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, } } - ctx->mic = *xd->mi_8x8[0]; + ctx->mic = *xd->mi[0]; } int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, @@ -3127,7 +3127,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, int64_t best_rd_so_far) { VP9_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &x->e_mbd; - MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; const struct segmentation *const seg = &cm->seg; MB_PREDICTION_MODE this_mode; MV_REFERENCE_FRAME ref_frame, second_ref_frame; @@ -3759,7 +3759,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, int64_t best_rd_so_far) { VP9_COMMON *cm = &cpi->common; MACROBLOCKD *xd = &x->e_mbd; - MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; const struct segmentation *seg = &cm->seg; MV_REFERENCE_FRAME ref_frame, second_ref_frame; unsigned char segment_id = mbmi->segment_id; @@ -4037,7 +4037,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, cpi->rd_thresh_sub8x8[segment_id][bsize][THR_ALTR]; this_rd_thresh = (ref_frame == GOLDEN_FRAME) ? cpi->rd_thresh_sub8x8[segment_id][bsize][THR_GOLD] : this_rd_thresh; - xd->mi_8x8[0]->mbmi.tx_size = TX_4X4; + xd->mi[0]->mbmi.tx_size = TX_4X4; cpi->mask_filter_rd = 0; for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) @@ -4101,7 +4101,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, tmp_best_skippable = skippable; tmp_best_mbmode = *mbmi; for (i = 0; i < 4; i++) { - tmp_best_bmodes[i] = xd->mi_8x8[0]->bmi[i]; + tmp_best_bmodes[i] = xd->mi[0]->bmi[i]; x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i]; } pred_exists = 1; @@ -4149,7 +4149,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, skippable = tmp_best_skippable; *mbmi = tmp_best_mbmode; for (i = 0; i < 4; i++) - xd->mi_8x8[0]->bmi[i] = tmp_best_bmodes[i]; + xd->mi[0]->bmi[i] = tmp_best_bmodes[i]; } rate2 += rate; @@ -4233,8 +4233,8 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, } // Keep record of best inter rd with single reference - if (is_inter_block(&xd->mi_8x8[0]->mbmi) && - !has_second_ref(&xd->mi_8x8[0]->mbmi) && + if (is_inter_block(&xd->mi[0]->mbmi) && + !has_second_ref(&xd->mi[0]->mbmi) && !mode_excluded && this_rd < best_inter_rd) { best_inter_rd = this_rd; @@ -4274,7 +4274,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, sizeof(uint8_t) * ctx->num_4x4_blk); for (i = 0; i < 4; i++) - best_bmodes[i] = xd->mi_8x8[0]->bmi[i]; + best_bmodes[i] = xd->mi[0]->bmi[i]; // TODO(debargha): enhance this test with a better distortion prediction // based on qp, activity mask and history @@ -4423,13 +4423,13 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, x->skip |= best_skip2; if (!is_inter_block(&best_mbmode)) { for (i = 0; i < 4; i++) - xd->mi_8x8[0]->bmi[i].as_mode = best_bmodes[i].as_mode; + xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode; } else { for (i = 0; i < 4; ++i) - vpx_memcpy(&xd->mi_8x8[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info)); + vpx_memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info)); - mbmi->mv[0].as_int = xd->mi_8x8[0]->bmi[3].as_mv[0].as_int; - mbmi->mv[1].as_int = xd->mi_8x8[0]->bmi[3].as_mv[1].as_int; + mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int; + mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int; } for (i = 0; i < REFERENCE_MODES; ++i) { diff --git a/vp9/encoder/vp9_segmentation.c b/vp9/encoder/vp9_segmentation.c index fd8fa53f5..9d3e6dc12 100644 --- a/vp9/encoder/vp9_segmentation.c +++ b/vp9/encoder/vp9_segmentation.c @@ -133,8 +133,8 @@ static void count_segs(VP9_COMP *cpi, const TileInfo *const tile, if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - xd->mi_8x8 = mi_8x8; - segment_id = xd->mi_8x8[0]->mbmi.segment_id; + xd->mi = mi_8x8; + segment_id = xd->mi[0]->mbmi.segment_id; set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); @@ -152,7 +152,7 @@ static void count_segs(VP9_COMP *cpi, const TileInfo *const tile, // Store the prediction status for this mb and update counts // as appropriate - xd->mi_8x8[0]->mbmi.seg_id_predicted = pred_flag; + xd->mi[0]->mbmi.seg_id_predicted = pred_flag; temporal_predictor_count[pred_context][pred_flag]++; if (!pred_flag) @@ -169,7 +169,7 @@ static void count_segs_sb(VP9_COMP *cpi, const TileInfo *const tile, int mi_row, int mi_col, BLOCK_SIZE bsize) { const VP9_COMMON *const cm = &cpi->common; - const int mis = cm->mode_info_stride; + const int mis = cm->mi_stride; int bw, bh; const int bs = num_8x8_blocks_wide_lookup[bsize], hbs = bs / 2; @@ -229,7 +229,7 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) { vp9_prob t_pred_tree[SEG_TREE_PROBS]; vp9_prob t_nopred_prob[PREDICTION_PROBS]; - const int mis = cm->mode_info_stride; + const int mis = cm->mi_stride; MODE_INFO **mi_ptr, **mi; // Set default state for the segment tree probabilities and the diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index fd89d3304..f09035077 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -207,15 +207,6 @@ static void set_rt_speed_feature(VP9_COMMON *cm, } if (speed >= 3) { sf->use_square_partition_only = 1; - if (MIN(cm->width, cm->height) >= 720) - sf->disable_split_mask = DISABLE_ALL_SPLIT; - else - sf->disable_split_mask = DISABLE_ALL_INTER_SPLIT; - - sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH - | FLAG_SKIP_INTRA_BESTINTER | FLAG_SKIP_COMP_BESTINTRA - | FLAG_SKIP_INTRA_LOWVAR; - sf->disable_filter_search_var_thresh = 100; sf->use_lastframe_partitioning = LAST_FRAME_PARTITION_ALL; sf->use_uv_intra_rd_estimate = 1; @@ -224,16 +215,13 @@ static void set_rt_speed_feature(VP9_COMMON *cm, sf->use_fast_coef_updates = 2; sf->adaptive_rd_thresh = 4; sf->mode_skip_start = 6; - sf->encode_breakout_thresh = 400; sf->allow_skip_recode = 0; - } - if (speed >= 4) { sf->optimize_coefficients = 0; sf->disable_split_mask = DISABLE_ALL_SPLIT; sf->lpf_pick = LPF_PICK_FROM_Q; sf->encode_breakout_thresh = 700; } - if (speed >= 5) { + if (speed >= 4) { int i; sf->last_partitioning_redo_frequency = 4; sf->adaptive_rd_thresh = 5; @@ -258,7 +246,7 @@ static void set_rt_speed_feature(VP9_COMMON *cm, sf->max_intra_bsize = BLOCK_32X32; sf->allow_skip_recode = 1; } - if (speed >= 6) { + if (speed >= 5) { sf->max_partition_size = BLOCK_32X32; sf->min_partition_size = BLOCK_8X8; sf->partition_check = @@ -268,12 +256,12 @@ static void set_rt_speed_feature(VP9_COMMON *cm, sf->search_method = FAST_DIAMOND; sf->allow_skip_recode = 0; } - if (speed >= 7) { + if (speed >= 6) { sf->partition_search_type = VAR_BASED_FIXED_PARTITION; sf->use_nonrd_pick_mode = 1; sf->search_method = FAST_DIAMOND; } - if (speed >= 8) { + if (speed >= 7) { int i; for (i = 0; i < BLOCK_SIZES; ++i) sf->disable_inter_mode_mask[i] = 14; // only search NEARESTMV (0) diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c index 623311659..f8a641513 100644 --- a/vp9/encoder/vp9_temporal_filter.c +++ b/vp9/encoder/vp9_temporal_filter.c @@ -133,7 +133,7 @@ static int temporal_filter_find_matching_mb_c(VP9_COMP *cpi, MV best_ref_mv1 = {0, 0}; MV best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */ - MV *ref_mv = &x->e_mbd.mi_8x8[0]->bmi[0].as_mv[0].as_mv; + MV *ref_mv = &x->e_mbd.mi[0]->bmi[0].as_mv[0].as_mv; // Save input state struct buf_2d src = x->plane[0].src; @@ -250,8 +250,8 @@ static void temporal_filter_iterate_c(VP9_COMP *cpi, if (cpi->frames[frame] == NULL) continue; - mbd->mi_8x8[0]->bmi[0].as_mv[0].as_mv.row = 0; - mbd->mi_8x8[0]->bmi[0].as_mv[0].as_mv.col = 0; + mbd->mi[0]->bmi[0].as_mv[0].as_mv.row = 0; + mbd->mi[0]->bmi[0].as_mv[0].as_mv.col = 0; if (frame == alt_ref_index) { filter_weight = 2; @@ -284,8 +284,8 @@ static void temporal_filter_iterate_c(VP9_COMP *cpi, cpi->frames[frame]->v_buffer + mb_uv_offset, cpi->frames[frame]->y_stride, mb_uv_height, - mbd->mi_8x8[0]->bmi[0].as_mv[0].as_mv.row, - mbd->mi_8x8[0]->bmi[0].as_mv[0].as_mv.col, + mbd->mi[0]->bmi[0].as_mv[0].as_mv.row, + mbd->mi[0]->bmi[0].as_mv[0].as_mv.col, predictor, scale, mb_col * 16, mb_row * 16); diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c index b6211e5fa..291ccb37e 100644 --- a/vp9/encoder/vp9_tokenize.c +++ b/vp9/encoder/vp9_tokenize.c @@ -215,7 +215,7 @@ static void tokenize_b(int plane, int block, BLOCK_SIZE plane_bsize, uint8_t token_cache[32 * 32]; struct macroblock_plane *p = &cpi->mb.plane[plane]; struct macroblockd_plane *pd = &xd->plane[plane]; - MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; int pt; /* near block/prev token context index */ int c; TOKENEXTRA *t = *tp; /* store tokens starting here */ @@ -309,7 +309,7 @@ void vp9_tokenize_sb(VP9_COMP *cpi, TOKENEXTRA **t, int dry_run, BLOCK_SIZE bsize) { VP9_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &cpi->mb.e_mbd; - MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; + MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; TOKENEXTRA *t_backup = *t; const int ctx = vp9_get_skip_context(xd); const int skip_inc = !vp9_segfeature_active(&cm->seg, mbmi->segment_id, @@ -123,55 +123,6 @@ int fourcc_is_ivf(const char detect[4]) { return 0; } -#if CONFIG_WEBM_IO -/* Murmur hash derived from public domain reference implementation at - * http:// sites.google.com/site/murmurhash/ - */ -static unsigned int murmur(const void *key, int len, unsigned int seed) { - const unsigned int m = 0x5bd1e995; - const int r = 24; - - unsigned int h = seed ^ len; - - const unsigned char *data = (const unsigned char *)key; - - while (len >= 4) { - unsigned int k; - - k = (unsigned int)data[0]; - k |= (unsigned int)data[1] << 8; - k |= (unsigned int)data[2] << 16; - k |= (unsigned int)data[3] << 24; - - k *= m; - k ^= k >> r; - k *= m; - - h *= m; - h ^= k; - - data += 4; - len -= 4; - } - - switch (len) { - case 3: - h ^= data[2] << 16; - case 2: - h ^= data[1] << 8; - case 1: - h ^= data[0]; - h *= m; - }; - - h ^= h >> 13; - h *= m; - h ^= h >> 15; - - return h; -} -#endif // CONFIG_WEBM_IO - static const arg_def_t debugmode = ARG_DEF("D", "debug", 0, "Debug mode (makes output deterministic)"); static const arg_def_t outputfile = ARG_DEF("o", "output", 1, @@ -614,7 +565,6 @@ struct stream_state { FILE *file; struct rate_hist *rate_hist; struct EbmlGlobal ebml; - uint32_t hash; uint64_t psnr_sse_total; uint64_t psnr_samples_total; double psnr_totals[4]; @@ -836,7 +786,9 @@ static struct stream_state *new_stream(struct VpxEncoderConfig *global, stream->config.stereo_fmt = STEREO_FORMAT_MONO; stream->config.write_webm = 1; #if CONFIG_WEBM_IO - stream->ebml.last_pts_ms = -1; + stream->ebml.last_pts_ns = -1; + stream->ebml.writer = NULL; + stream->ebml.segment = NULL; #endif /* Allows removal of the application version from the EBML tags */ @@ -1171,9 +1123,7 @@ static void close_output_file(struct stream_state *stream, #if CONFIG_WEBM_IO if (stream->config.write_webm) { - write_webm_file_footer(&stream->ebml, stream->hash); - free(stream->ebml.cue_list); - stream->ebml.cue_list = NULL; + write_webm_file_footer(&stream->ebml); } #endif @@ -1329,12 +1279,6 @@ static void get_cx_data(struct stream_state *stream, update_rate_histogram(stream->rate_hist, cfg, pkt); #if CONFIG_WEBM_IO if (stream->config.write_webm) { - /* Update the hash */ - if (!stream->ebml.debug) - stream->hash = murmur(pkt->data.frame.buf, - (int)pkt->data.frame.sz, - stream->hash); - write_webm_block(&stream->ebml, cfg, pkt); } #endif diff --git a/webmenc.c b/webmenc.c deleted file mode 100644 index 17bbeec78..000000000 --- a/webmenc.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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 "webmenc.h" - -#include <limits.h> -#include <string.h> - -#include "third_party/libmkv/EbmlWriter.h" -#include "third_party/libmkv/EbmlIDs.h" - -void Ebml_Write(struct EbmlGlobal *glob, - const void *buffer_in, - unsigned long len) { - (void) fwrite(buffer_in, 1, len, glob->stream); -} - -#define WRITE_BUFFER(s) \ -for (i = len - 1; i >= 0; i--) { \ - x = (char)(*(const s *)buffer_in >> (i * CHAR_BIT)); \ - Ebml_Write(glob, &x, 1); \ -} - -void Ebml_Serialize(struct EbmlGlobal *glob, - const void *buffer_in, - int buffer_size, - unsigned long len) { - char x; - int i; - - /* buffer_size: - * 1 - int8_t; - * 2 - int16_t; - * 3 - int32_t; - * 4 - int64_t; - */ - switch (buffer_size) { - case 1: - WRITE_BUFFER(int8_t) - break; - case 2: - WRITE_BUFFER(int16_t) - break; - case 4: - WRITE_BUFFER(int32_t) - break; - case 8: - WRITE_BUFFER(int64_t) - break; - default: - break; - } -} -#undef WRITE_BUFFER - -/* Need a fixed size serializer for the track ID. libmkv provides a 64 bit - * one, but not a 32 bit one. - */ -static void Ebml_SerializeUnsigned32(struct EbmlGlobal *glob, - unsigned int class_id, - uint64_t ui) { - const unsigned char sizeSerialized = 4 | 0x80; - Ebml_WriteID(glob, class_id); - Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1); - Ebml_Serialize(glob, &ui, sizeof(ui), 4); -} - -static void Ebml_StartSubElement(struct EbmlGlobal *glob, - EbmlLoc *ebmlLoc, - unsigned int class_id) { - const uint64_t kEbmlUnknownLength = LITERALU64(0x01FFFFFF, 0xFFFFFFFF); - Ebml_WriteID(glob, class_id); - *ebmlLoc = ftello(glob->stream); - Ebml_Serialize(glob, &kEbmlUnknownLength, sizeof(kEbmlUnknownLength), 8); -} - -static void Ebml_EndSubElement(struct EbmlGlobal *glob, EbmlLoc *ebmlLoc) { - off_t pos; - uint64_t size; - - /* Save the current stream pointer. */ - pos = ftello(glob->stream); - - /* Calculate the size of this element. */ - size = pos - *ebmlLoc - 8; - size |= LITERALU64(0x01000000, 0x00000000); - - /* Seek back to the beginning of the element and write the new size. */ - fseeko(glob->stream, *ebmlLoc, SEEK_SET); - Ebml_Serialize(glob, &size, sizeof(size), 8); - - /* Reset the stream pointer. */ - fseeko(glob->stream, pos, SEEK_SET); -} - -void write_webm_seek_element(struct EbmlGlobal *ebml, - unsigned int id, - off_t pos) { - uint64_t offset = pos - ebml->position_reference; - EbmlLoc start; - Ebml_StartSubElement(ebml, &start, Seek); - Ebml_SerializeBinary(ebml, SeekID, id); - Ebml_SerializeUnsigned64(ebml, SeekPosition, offset); - Ebml_EndSubElement(ebml, &start); -} - -void write_webm_seek_info(struct EbmlGlobal *ebml) { - off_t pos; - EbmlLoc start; - EbmlLoc startInfo; - uint64_t frame_time; - char version_string[64]; - - /* Save the current stream pointer. */ - pos = ftello(ebml->stream); - - if (ebml->seek_info_pos) - fseeko(ebml->stream, ebml->seek_info_pos, SEEK_SET); - else - ebml->seek_info_pos = pos; - - Ebml_StartSubElement(ebml, &start, SeekHead); - write_webm_seek_element(ebml, Tracks, ebml->track_pos); - write_webm_seek_element(ebml, Cues, ebml->cue_pos); - write_webm_seek_element(ebml, Info, ebml->segment_info_pos); - Ebml_EndSubElement(ebml, &start); - - /* Create and write the Segment Info. */ - if (ebml->debug) { - strcpy(version_string, "vpxenc"); - } else { - strcpy(version_string, "vpxenc "); - strncat(version_string, - vpx_codec_version_str(), - sizeof(version_string) - 1 - strlen(version_string)); - } - - frame_time = (uint64_t)1000 * ebml->framerate.den - / ebml->framerate.num; - ebml->segment_info_pos = ftello(ebml->stream); - Ebml_StartSubElement(ebml, &startInfo, Info); - Ebml_SerializeUnsigned(ebml, TimecodeScale, 1000000); - Ebml_SerializeFloat(ebml, Segment_Duration, - (double)(ebml->last_pts_ms + frame_time)); - Ebml_SerializeString(ebml, 0x4D80, version_string); - Ebml_SerializeString(ebml, 0x5741, version_string); - Ebml_EndSubElement(ebml, &startInfo); -} - -void write_webm_file_header(struct EbmlGlobal *glob, - const vpx_codec_enc_cfg_t *cfg, - const struct vpx_rational *fps, - stereo_format_t stereo_fmt, - unsigned int fourcc) { - EbmlLoc start; - EbmlLoc trackStart; - EbmlLoc videoStart; - unsigned int trackNumber = 1; - uint64_t trackID = 0; - unsigned int pixelWidth = cfg->g_w; - unsigned int pixelHeight = cfg->g_h; - - /* Write the EBML header. */ - Ebml_StartSubElement(glob, &start, EBML); - Ebml_SerializeUnsigned(glob, EBMLVersion, 1); - Ebml_SerializeUnsigned(glob, EBMLReadVersion, 1); - Ebml_SerializeUnsigned(glob, EBMLMaxIDLength, 4); - Ebml_SerializeUnsigned(glob, EBMLMaxSizeLength, 8); - Ebml_SerializeString(glob, DocType, "webm"); - Ebml_SerializeUnsigned(glob, DocTypeVersion, 2); - Ebml_SerializeUnsigned(glob, DocTypeReadVersion, 2); - Ebml_EndSubElement(glob, &start); - - /* Open and begin writing the segment element. */ - Ebml_StartSubElement(glob, &glob->startSegment, Segment); - glob->position_reference = ftello(glob->stream); - glob->framerate = *fps; - write_webm_seek_info(glob); - - /* Open and write the Tracks element. */ - glob->track_pos = ftello(glob->stream); - Ebml_StartSubElement(glob, &trackStart, Tracks); - - /* Open and write the Track entry. */ - Ebml_StartSubElement(glob, &start, TrackEntry); - Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber); - glob->track_id_pos = ftello(glob->stream); - Ebml_SerializeUnsigned32(glob, TrackUID, trackID); - Ebml_SerializeUnsigned(glob, TrackType, 1); - Ebml_SerializeString(glob, CodecID, - fourcc == VP8_FOURCC ? "V_VP8" : "V_VP9"); - Ebml_StartSubElement(glob, &videoStart, Video); - Ebml_SerializeUnsigned(glob, PixelWidth, pixelWidth); - Ebml_SerializeUnsigned(glob, PixelHeight, pixelHeight); - Ebml_SerializeUnsigned(glob, StereoMode, stereo_fmt); - Ebml_EndSubElement(glob, &videoStart); - - /* Close Track entry. */ - Ebml_EndSubElement(glob, &start); - - /* Close Tracks element. */ - Ebml_EndSubElement(glob, &trackStart); - - /* Segment element remains open. */ -} - -void write_webm_block(struct EbmlGlobal *glob, - const vpx_codec_enc_cfg_t *cfg, - const vpx_codec_cx_pkt_t *pkt) { - unsigned int block_length; - unsigned char track_number; - uint16_t block_timecode = 0; - unsigned char flags; - int64_t pts_ms; - int start_cluster = 0, is_keyframe; - - /* Calculate the PTS of this frame in milliseconds. */ - pts_ms = pkt->data.frame.pts * 1000 - * (uint64_t)cfg->g_timebase.num / (uint64_t)cfg->g_timebase.den; - - if (pts_ms <= glob->last_pts_ms) - pts_ms = glob->last_pts_ms + 1; - - glob->last_pts_ms = pts_ms; - - /* Calculate the relative time of this block. */ - if (pts_ms - glob->cluster_timecode > SHRT_MAX) - start_cluster = 1; - else - block_timecode = (uint16_t)pts_ms - glob->cluster_timecode; - - is_keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY); - if (start_cluster || is_keyframe) { - if (glob->cluster_open) - Ebml_EndSubElement(glob, &glob->startCluster); - - /* Open the new cluster. */ - block_timecode = 0; - glob->cluster_open = 1; - glob->cluster_timecode = (uint32_t)pts_ms; - glob->cluster_pos = ftello(glob->stream); - Ebml_StartSubElement(glob, &glob->startCluster, Cluster); - Ebml_SerializeUnsigned(glob, Timecode, glob->cluster_timecode); - - /* Save a cue point if this is a keyframe. */ - if (is_keyframe) { - struct cue_entry *cue, *new_cue_list; - - new_cue_list = realloc(glob->cue_list, - (glob->cues + 1) * sizeof(struct cue_entry)); - if (new_cue_list) - glob->cue_list = new_cue_list; - else - fatal("Failed to realloc cue list."); - - cue = &glob->cue_list[glob->cues]; - cue->time = glob->cluster_timecode; - cue->loc = glob->cluster_pos; - glob->cues++; - } - } - - /* Write the Simple Block. */ - Ebml_WriteID(glob, SimpleBlock); - - block_length = (unsigned int)pkt->data.frame.sz + 4; - block_length |= 0x10000000; - Ebml_Serialize(glob, &block_length, sizeof(block_length), 4); - - track_number = 1; - track_number |= 0x80; - Ebml_Write(glob, &track_number, 1); - - Ebml_Serialize(glob, &block_timecode, sizeof(block_timecode), 2); - - flags = 0; - if (is_keyframe) - flags |= 0x80; - if (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) - flags |= 0x08; - Ebml_Write(glob, &flags, 1); - - Ebml_Write(glob, pkt->data.frame.buf, (unsigned int)pkt->data.frame.sz); -} - -void write_webm_file_footer(struct EbmlGlobal *glob, int hash) { - EbmlLoc start_cues; - EbmlLoc start_cue_point; - EbmlLoc start_cue_tracks; - unsigned int i; - - if (glob->cluster_open) - Ebml_EndSubElement(glob, &glob->startCluster); - - glob->cue_pos = ftello(glob->stream); - Ebml_StartSubElement(glob, &start_cues, Cues); - - for (i = 0; i < glob->cues; i++) { - struct cue_entry *cue = &glob->cue_list[i]; - Ebml_StartSubElement(glob, &start_cue_point, CuePoint); - Ebml_SerializeUnsigned(glob, CueTime, cue->time); - - Ebml_StartSubElement(glob, &start_cue_tracks, CueTrackPositions); - Ebml_SerializeUnsigned(glob, CueTrack, 1); - Ebml_SerializeUnsigned64(glob, CueClusterPosition, - cue->loc - glob->position_reference); - Ebml_EndSubElement(glob, &start_cue_tracks); - - Ebml_EndSubElement(glob, &start_cue_point); - } - - Ebml_EndSubElement(glob, &start_cues); - - /* Close the Segment. */ - Ebml_EndSubElement(glob, &glob->startSegment); - - /* Patch up the seek info block. */ - write_webm_seek_info(glob); - - /* Patch up the track id. */ - fseeko(glob->stream, glob->track_id_pos, SEEK_SET); - Ebml_SerializeUnsigned32(glob, TrackUID, glob->debug ? 0xDEADBEEF : hash); - - fseeko(glob->stream, 0, SEEK_END); -} diff --git a/webmenc.cc b/webmenc.cc new file mode 100644 index 000000000..6a3374d02 --- /dev/null +++ b/webmenc.cc @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014 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 "./webmenc.h" + +#include <string> + +#include "third_party/libwebm/mkvmuxer.hpp" +#include "third_party/libwebm/mkvmuxerutil.hpp" +#include "third_party/libwebm/mkvwriter.hpp" + +namespace { +const uint64_t kDebugTrackUid = 0xDEADBEEF; +const int kVideoTrackNumber = 1; +} // namespace + +void write_webm_file_header(struct EbmlGlobal *glob, + const vpx_codec_enc_cfg_t *cfg, + const struct vpx_rational *fps, + stereo_format_t stereo_fmt, + unsigned int fourcc) { + mkvmuxer::MkvWriter *const writer = new mkvmuxer::MkvWriter(glob->stream); + mkvmuxer::Segment *const segment = new mkvmuxer::Segment(); + segment->Init(writer); + segment->set_mode(mkvmuxer::Segment::kFile); + segment->OutputCues(true); + + mkvmuxer::SegmentInfo *const info = segment->GetSegmentInfo(); + const uint64_t kTimecodeScale = 1000000; + info->set_timecode_scale(kTimecodeScale); + std::string version = "vpxenc"; + if (!glob->debug) { + version.append(std::string(" ") + vpx_codec_version_str()); + } + info->set_writing_app(version.c_str()); + + const int video_track_id = segment->AddVideoTrack(static_cast<int>(cfg->g_w), + static_cast<int>(cfg->g_h), + kVideoTrackNumber); + mkvmuxer::VideoTrack* const video_track = + static_cast<mkvmuxer::VideoTrack*>( + segment->GetTrackByNumber(video_track_id)); + video_track->SetStereoMode(stereo_fmt); + video_track->set_codec_id(fourcc == VP8_FOURCC ? "V_VP8" : "V_VP9"); + if (glob->debug) { + video_track->set_uid(kDebugTrackUid); + } + glob->writer = writer; + glob->segment = segment; +} + +void write_webm_block(struct EbmlGlobal *glob, + const vpx_codec_enc_cfg_t *cfg, + const vpx_codec_cx_pkt_t *pkt) { + mkvmuxer::Segment *const segment = + reinterpret_cast<mkvmuxer::Segment*>(glob->segment); + int64_t pts_ns = pkt->data.frame.pts * 1000000000ll * + cfg->g_timebase.num / cfg->g_timebase.den; + if (pts_ns <= glob->last_pts_ns) + pts_ns = glob->last_pts_ns + 1000000; + glob->last_pts_ns = pts_ns; + + segment->AddFrame(static_cast<uint8_t*>(pkt->data.frame.buf), + pkt->data.frame.sz, + kVideoTrackNumber, + pts_ns, + pkt->data.frame.flags & VPX_FRAME_IS_KEY); +} + +void write_webm_file_footer(struct EbmlGlobal *glob) { + mkvmuxer::MkvWriter *const writer = + reinterpret_cast<mkvmuxer::MkvWriter*>(glob->writer); + mkvmuxer::Segment *const segment = + reinterpret_cast<mkvmuxer::Segment*>(glob->segment); + segment->Finalize(); + delete segment; + delete writer; + glob->writer = NULL; + glob->segment = NULL; +} @@ -13,13 +13,6 @@ #include <stdio.h> #include <stdlib.h> -#if defined(_MSC_VER) -/* MSVS doesn't define off_t */ -typedef __int64 off_t; -#else -#include <stdint.h> -#endif - #include "tools_common.h" #include "vpx/vpx_encoder.h" @@ -27,40 +20,13 @@ typedef __int64 off_t; extern "C" { #endif -typedef off_t EbmlLoc; - -struct cue_entry { - unsigned int time; - uint64_t loc; -}; - +/* TODO(vigneshv): Rename this struct */ struct EbmlGlobal { int debug; - FILE *stream; - int64_t last_pts_ms; - vpx_rational_t framerate; - - /* These pointers are to the start of an element */ - off_t position_reference; - off_t seek_info_pos; - off_t segment_info_pos; - off_t track_pos; - off_t cue_pos; - off_t cluster_pos; - - /* This pointer is to a specific element to be serialized */ - off_t track_id_pos; - - /* These pointers are to the size field of the element */ - EbmlLoc startSegment; - EbmlLoc startCluster; - - uint32_t cluster_timecode; - int cluster_open; - - struct cue_entry *cue_list; - unsigned int cues; + int64_t last_pts_ns; + void *writer; + void *segment; }; /* Stereo 3D packed frame format */ @@ -72,10 +38,6 @@ typedef enum stereo_format { STEREO_FORMAT_RIGHT_LEFT = 11 } stereo_format_t; -void write_webm_seek_element(struct EbmlGlobal *ebml, - unsigned int id, - off_t pos); - void write_webm_file_header(struct EbmlGlobal *glob, const vpx_codec_enc_cfg_t *cfg, const struct vpx_rational *fps, @@ -86,7 +48,7 @@ void write_webm_block(struct EbmlGlobal *glob, const vpx_codec_enc_cfg_t *cfg, const vpx_codec_cx_pkt_t *pkt); -void write_webm_file_footer(struct EbmlGlobal *glob, int hash); +void write_webm_file_footer(struct EbmlGlobal *glob); #ifdef __cplusplus } // extern "C" |