diff options
-rw-r--r-- | README | 16 | ||||
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | docs.mk | 6 | ||||
-rwxr-xr-x | test/resize_util.sh | 66 | ||||
-rw-r--r-- | vp8/vp8_cx_iface.c | 2 | ||||
-rw-r--r-- | vp9/common/vp9_convolve.c | 20 | ||||
-rw-r--r-- | vp9/common/vp9_loopfilter.c | 5 | ||||
-rw-r--r-- | vp9/common/vp9_loopfilter.h | 3 | ||||
-rw-r--r-- | vp9/decoder/vp9_decodeframe.c | 118 | ||||
-rw-r--r-- | vp9/decoder/vp9_decoder.c | 10 | ||||
-rw-r--r-- | vp9/decoder/vp9_decoder.h | 1 | ||||
-rw-r--r-- | vp9/decoder/vp9_dthread.c | 6 | ||||
-rw-r--r-- | vp9/decoder/vp9_dthread.h | 3 | ||||
-rw-r--r-- | vp9/encoder/vp9_encoder.c | 38 | ||||
-rw-r--r-- | vp9/encoder/vp9_mcomp.c | 2 | ||||
-rw-r--r-- | vp9/encoder/vp9_mcomp.h | 3 | ||||
-rw-r--r-- | vp9/encoder/vp9_picklpf.c | 3 | ||||
-rw-r--r-- | vp9/encoder/vp9_rdopt.c | 3 | ||||
-rw-r--r-- | vp9/vp9_cx_iface.c | 2 | ||||
-rw-r--r-- | vpxdec.c | 6 | ||||
-rw-r--r-- | vpxenc.c | 19 |
21 files changed, 211 insertions, 123 deletions
@@ -12,22 +12,20 @@ COMPILING THE APPLICATIONS/LIBRARIES: * All x86 targets require the Yasm[1] assembler be installed. * All Windows builds require that Cygwin[2] be installed. - * Building the documentation requires PHP[3] and Doxygen[4]. If you do not - have these packages, you must pass --disable-install-docs to the - configure script. - * Downloading the data for the unit tests requires curl[5] and sha1sum. + * Building the documentation requires Doxygen[3]. If you do not + have this package, the install-docs option will be disabled. + * Downloading the data for the unit tests requires curl[4] and sha1sum. sha1sum is provided via the GNU coreutils, installed by default on many *nix platforms, as well as MinGW and Cygwin. If coreutils is not available, a compatible version of sha1sum can be built from - source[6]. These requirements are optional if not running the unit + source[5]. These requirements are optional if not running the unit tests. [1]: http://www.tortall.net/projects/yasm [2]: http://www.cygwin.com - [3]: http://php.net - [4]: http://www.doxygen.org - [5]: http://curl.haxx.se - [6]: http://www.microbrew.org/tools/md5sha1sum/ + [3]: http://www.doxygen.org + [4]: http://curl.haxx.se + [5]: http://www.microbrew.org/tools/md5sha1sum/ 2. Out-of-tree builds Out of tree builds are a supported method of building the application. For @@ -189,7 +189,7 @@ fi # install everything except the sources, by default. sources will have # to be enabled when doing dist builds, since that's no longer a common # case. -enabled doxygen && php -v >/dev/null 2>&1 && enable_feature install_docs +enabled doxygen && enable_feature install_docs enable_feature install_bins enable_feature install_libs @@ -23,12 +23,6 @@ CODEC_DOX := mainpage.dox \ # Other doxy files sourced in Markdown TXT_DOX = $(call enabled,TXT_DOX) -%.dox: %.txt - @echo " [DOXY] $@" - @$(SRC_PATH_BARE)/examples/gen_example_doxy.php \ - $(@:.dox=) "$($@.DESC)" > $@ < $< - - EXAMPLE_PATH += $(SRC_PATH_BARE) #for CHANGELOG, README, etc EXAMPLE_PATH += $(SRC_PATH_BARE)/examples diff --git a/test/resize_util.sh b/test/resize_util.sh new file mode 100755 index 000000000..2a8e3fb7c --- /dev/null +++ b/test/resize_util.sh @@ -0,0 +1,66 @@ +#!/bin/sh +## +## 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. +## +## This file tests the libvpx resize_util example code. To add new tests to +## this file, do the following: +## 1. Write a shell function (this is your test). +## 2. Add the function to resize_util_tests (on a new line). +## +. $(dirname $0)/tools_common.sh + +# Environment check: $YUV_RAW_INPUT is required. +resize_util_verify_environment() { + if [ ! -e "${YUV_RAW_INPUT}" ]; then + echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH." + return 1 + fi +} + +# Resizes $YUV_RAW_INPUT using the resize_util example. $1 is the output +# dimensions that will be passed to resize_util. +resize_util() { + local resizer="${LIBVPX_BIN_PATH}/resize_util${VPX_TEST_EXE_SUFFIX}" + local output_file="${VPX_TEST_OUTPUT_DIR}/resize_util.raw" + local frames_to_resize="10" + local target_dimensions="$1" + + # resize_util is available only when CONFIG_SHARED is disabled. + if [ -z "$(vpx_config_option_enabled CONFIG_SHARED)" ]; then + [ -x "${resizer}" ] || return 1 + + eval "${resizer}" "${YUV_RAW_INPUT}" \ + "${YUV_RAW_INPUT_WIDTH}x${YUV_RAW_INPUT_HEIGHT}" \ + "${target_dimensions}" "${output_file}" ${frames_to_resize} \ + ${devnull} + + [ -e "${output_file}" ] || return 1 + fi +} + +# Halves each dimension of $YUV_RAW_INPUT using resize_util(). +resize_down() { + local target_width=$((${YUV_RAW_INPUT_WIDTH} / 2)) + local target_height=$((${YUV_RAW_INPUT_HEIGHT} / 2)) + + resize_util "${target_width}x${target_height}" +} + +# Doubles each dimension of $YUV_RAW_INPUT using resize_util(). +resize_up() { + local target_width=$((${YUV_RAW_INPUT_WIDTH} * 2)) + local target_height=$((${YUV_RAW_INPUT_HEIGHT} * 2)) + + resize_util "${target_width}x${target_height}" +} + +resize_util_tests="resize_down + resize_up" + +run_tests resize_util_verify_environment "${resize_util_tests}" diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c index 6ca6087b2..501dd3eb4 100644 --- a/vp8/vp8_cx_iface.c +++ b/vp8/vp8_cx_iface.c @@ -886,7 +886,7 @@ static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t *ctx, VP8_COMP *cpi = (VP8_COMP *)ctx->cpi; /* Add the frame packet to the list of returned packets. */ - round = (vpx_codec_pts_t)1000000 + round = (vpx_codec_pts_t)10000000 * ctx->cfg.g_timebase.num / 2 - 1; delta = (dst_end_time_stamp - dst_time_stamp); pkt.kind = VPX_CODEC_CX_FRAME_PKT; diff --git a/vp9/common/vp9_convolve.c b/vp9/common/vp9_convolve.c index d30e0b488..1a8c49d52 100644 --- a/vp9/common/vp9_convolve.c +++ b/vp9/common/vp9_convolve.c @@ -156,6 +156,9 @@ void vp9_convolve8_horiz_c(const uint8_t *src, ptrdiff_t src_stride, const InterpKernel *const filters_x = get_filter_base(filter_x); const int x0_q4 = get_filter_offset(filter_x, filters_x); + (void)filter_y; + (void)y_step_q4; + convolve_horiz(src, src_stride, dst, dst_stride, filters_x, x0_q4, x_step_q4, w, h); } @@ -168,6 +171,9 @@ void vp9_convolve8_avg_horiz_c(const uint8_t *src, ptrdiff_t src_stride, const InterpKernel *const filters_x = get_filter_base(filter_x); const int x0_q4 = get_filter_offset(filter_x, filters_x); + (void)filter_y; + (void)y_step_q4; + convolve_avg_horiz(src, src_stride, dst, dst_stride, filters_x, x0_q4, x_step_q4, w, h); } @@ -179,6 +185,10 @@ void vp9_convolve8_vert_c(const uint8_t *src, ptrdiff_t src_stride, int w, int h) { const InterpKernel *const filters_y = get_filter_base(filter_y); const int y0_q4 = get_filter_offset(filter_y, filters_y); + + (void)filter_x; + (void)x_step_q4; + convolve_vert(src, src_stride, dst, dst_stride, filters_y, y0_q4, y_step_q4, w, h); } @@ -190,6 +200,10 @@ void vp9_convolve8_avg_vert_c(const uint8_t *src, ptrdiff_t src_stride, int w, int h) { const InterpKernel *const filters_y = get_filter_base(filter_y); const int y0_q4 = get_filter_offset(filter_y, filters_y); + + (void)filter_x; + (void)x_step_q4; + convolve_avg_vert(src, src_stride, dst, dst_stride, filters_y, y0_q4, y_step_q4, w, h); } @@ -232,6 +246,9 @@ void vp9_convolve_copy_c(const uint8_t *src, ptrdiff_t src_stride, int w, int h) { int r; + (void)filter_x; (void)filter_x_stride; + (void)filter_y; (void)filter_y_stride; + for (r = h; r > 0; --r) { vpx_memcpy(dst, src, w); src += src_stride; @@ -246,6 +263,9 @@ void vp9_convolve_avg_c(const uint8_t *src, ptrdiff_t src_stride, int w, int h) { int x, y; + (void)filter_x; (void)filter_x_stride; + (void)filter_y; (void)filter_y_stride; + for (y = 0; y < h; ++y) { for (x = 0; x < w; ++x) dst[x] = ROUND_POWER_OF_TWO(dst[x] + src[x], 1); diff --git a/vp9/common/vp9_loopfilter.c b/vp9/common/vp9_loopfilter.c index 3ac5a0577..5b43e233b 100644 --- a/vp9/common/vp9_loopfilter.c +++ b/vp9/common/vp9_loopfilter.c @@ -1224,7 +1224,8 @@ void vp9_loop_filter_rows(const YV12_BUFFER_CONFIG *frame_buffer, } } -void vp9_loop_filter_frame(VP9_COMMON *cm, MACROBLOCKD *xd, +void vp9_loop_filter_frame(YV12_BUFFER_CONFIG *frame, + VP9_COMMON *cm, MACROBLOCKD *xd, int frame_filter_level, int y_only, int partial_frame) { int start_mi_row, end_mi_row, mi_rows_to_filter; @@ -1238,7 +1239,7 @@ void vp9_loop_filter_frame(VP9_COMMON *cm, MACROBLOCKD *xd, } end_mi_row = start_mi_row + mi_rows_to_filter; vp9_loop_filter_frame_init(cm, frame_filter_level); - vp9_loop_filter_rows(cm->frame_to_show, cm, xd, + vp9_loop_filter_rows(frame, cm, xd, start_mi_row, end_mi_row, y_only); } diff --git a/vp9/common/vp9_loopfilter.h b/vp9/common/vp9_loopfilter.h index 97ae9d22d..83463c544 100644 --- a/vp9/common/vp9_loopfilter.h +++ b/vp9/common/vp9_loopfilter.h @@ -104,7 +104,8 @@ void vp9_loop_filter_init(struct VP9Common *cm); // calls this function directly. void vp9_loop_filter_frame_init(struct VP9Common *cm, int default_filt_lvl); -void vp9_loop_filter_frame(struct VP9Common *cm, +void vp9_loop_filter_frame(YV12_BUFFER_CONFIG *frame, + struct VP9Common *cm, struct macroblockd *mbd, int filter_level, int y_only, int partial_frame); diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c index 9dd0c4415..9dc0cf1a3 100644 --- a/vp9/decoder/vp9_decodeframe.c +++ b/vp9/decoder/vp9_decodeframe.c @@ -676,13 +676,13 @@ static void setup_frame_size_with_refs(VP9_COMMON *cm, } static void decode_tile(VP9Decoder *pbi, const TileInfo *const tile, - vp9_reader *r) { + int do_loopfilter_inline, vp9_reader *r) { const int num_threads = pbi->max_threads; VP9_COMMON *const cm = &pbi->common; int mi_row, mi_col; MACROBLOCKD *xd = &pbi->mb; - if (pbi->do_loopfilter_inline) { + if (do_loopfilter_inline) { LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1; lf_data->frame_buffer = get_frame_new_buffer(cm); lf_data->cm = cm; @@ -702,7 +702,7 @@ static void decode_tile(VP9Decoder *pbi, const TileInfo *const tile, decode_partition(cm, xd, tile, mi_row, mi_col, r, BLOCK_64X64); } - if (pbi->do_loopfilter_inline) { + if (do_loopfilter_inline) { const int lf_start = mi_row - MI_BLOCK_SIZE; LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1; @@ -723,7 +723,7 @@ static void decode_tile(VP9Decoder *pbi, const TileInfo *const tile, } } - if (pbi->do_loopfilter_inline) { + if (do_loopfilter_inline) { LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1; vp9_worker_sync(&pbi->lf_worker); @@ -749,14 +749,20 @@ static void setup_tile_info(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) { cm->log2_tile_rows += vp9_rb_read_bit(rb); } +typedef struct TileBuffer { + const uint8_t *data; + size_t size; + int col; // only used with multi-threaded decoding +} TileBuffer; + // Reads the next tile returning its size and adjusting '*data' accordingly // based on 'is_last'. -static size_t get_tile(const uint8_t *const data_end, - int is_last, - struct vpx_internal_error_info *error_info, - const uint8_t **data, - vpx_decrypt_cb decrypt_cb, - void *decrypt_state) { +static void get_tile_buffer(const uint8_t *const data_end, + int is_last, + struct vpx_internal_error_info *error_info, + const uint8_t **data, + vpx_decrypt_cb decrypt_cb, void *decrypt_state, + TileBuffer *buf) { size_t size; if (!is_last) { @@ -779,18 +785,34 @@ static size_t get_tile(const uint8_t *const data_end, } else { size = data_end - *data; } - return size; + + buf->data = *data; + buf->size = size; + + *data += size; } -typedef struct TileBuffer { - const uint8_t *data; - size_t size; - int col; // only used with multi-threaded decoding -} TileBuffer; +static void get_tile_buffers(VP9Decoder *pbi, + const uint8_t *data, const uint8_t *data_end, + int tile_cols, int tile_rows, + TileBuffer (*tile_buffers)[1 << 6]) { + int r, c; + + for (r = 0; r < tile_rows; ++r) { + for (c = 0; c < tile_cols; ++c) { + const int is_last = (r == tile_rows - 1) && (c == tile_cols - 1); + TileBuffer *const buf = &tile_buffers[r][c]; + buf->col = c; + get_tile_buffer(data_end, is_last, &pbi->common.error, &data, + pbi->decrypt_cb, pbi->decrypt_state, buf); + } + } +} static const uint8_t *decode_tiles(VP9Decoder *pbi, const uint8_t *data, - const uint8_t *data_end) { + const uint8_t *data_end, + int do_loopfilter_inline) { VP9_COMMON *const cm = &pbi->common; const int aligned_cols = mi_cols_aligned_to_sb(cm->mi_cols); const int tile_cols = 1 << cm->log2_tile_cols; @@ -811,19 +833,7 @@ static const uint8_t *decode_tiles(VP9Decoder *pbi, vpx_memset(cm->above_seg_context, 0, sizeof(*cm->above_seg_context) * aligned_cols); - // Load tile data into tile_buffers - for (tile_row = 0; tile_row < tile_rows; ++tile_row) { - for (tile_col = 0; tile_col < tile_cols; ++tile_col) { - const int last_tile = tile_row == tile_rows - 1 && - tile_col == tile_cols - 1; - const size_t size = get_tile(data_end, last_tile, &cm->error, &data, - pbi->decrypt_cb, pbi->decrypt_state); - TileBuffer *const buf = &tile_buffers[tile_row][tile_col]; - buf->data = data; - buf->size = size; - data += size; - } - } + get_tile_buffers(pbi, data, data_end, tile_cols, tile_rows, tile_buffers); // Decode tiles using data from tile_buffers for (tile_row = 0; tile_row < tile_rows; ++tile_row) { @@ -837,7 +847,7 @@ static const uint8_t *decode_tiles(VP9Decoder *pbi, vp9_tile_init(&tile, cm, tile_row, col); setup_token_decoder(buf->data, data_end, buf->size, &cm->error, &r, pbi->decrypt_cb, pbi->decrypt_state); - decode_tile(pbi, &tile, &r); + decode_tile(pbi, &tile, do_loopfilter_inline, &r); if (last_tile) end = vp9_reader_find_end(&r); @@ -887,7 +897,7 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi, const int tile_cols = 1 << cm->log2_tile_cols; const int tile_rows = 1 << cm->log2_tile_rows; const int num_workers = MIN(pbi->max_threads & ~1, tile_cols); - TileBuffer tile_buffers[1 << 6]; + TileBuffer tile_buffers[1][1 << 6]; int n; int final_worker = -1; @@ -932,19 +942,11 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi, sizeof(*cm->above_seg_context) * aligned_mi_cols); // Load tile data into tile_buffers - for (n = 0; n < tile_cols; ++n) { - const size_t size = - get_tile(data_end, n == tile_cols - 1, &cm->error, &data, - pbi->decrypt_cb, pbi->decrypt_state); - TileBuffer *const buf = &tile_buffers[n]; - buf->data = data; - buf->size = size; - buf->col = n; - data += size; - } + get_tile_buffers(pbi, data, data_end, tile_cols, tile_rows, tile_buffers); // Sort the buffers based on size in descending order. - qsort(tile_buffers, tile_cols, sizeof(tile_buffers[0]), compare_tile_buffers); + qsort(tile_buffers[0], tile_cols, sizeof(tile_buffers[0][0]), + compare_tile_buffers); // Rearrange the tile buffers such that per-tile group the largest, and // presumably the most difficult, tile will be decoded in the main thread. @@ -953,11 +955,11 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi, { int group_start = 0; while (group_start < tile_cols) { - const TileBuffer largest = tile_buffers[group_start]; + const TileBuffer largest = tile_buffers[0][group_start]; const int group_end = MIN(group_start + num_workers, tile_cols) - 1; - memmove(tile_buffers + group_start, tile_buffers + group_start + 1, - (group_end - group_start) * sizeof(tile_buffers[0])); - tile_buffers[group_end] = largest; + memmove(tile_buffers[0] + group_start, tile_buffers[0] + group_start + 1, + (group_end - group_start) * sizeof(tile_buffers[0][0])); + tile_buffers[0][group_end] = largest; group_start = group_end + 1; } } @@ -969,7 +971,7 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi, VP9Worker *const worker = &pbi->tile_workers[i]; TileWorkerData *const tile_data = (TileWorkerData*)worker->data1; TileInfo *const tile = (TileInfo*)worker->data2; - TileBuffer *const buf = &tile_buffers[n]; + TileBuffer *const buf = &tile_buffers[0][n]; tile_data->cm = cm; tile_data->xd = pbi->mb; @@ -1305,6 +1307,8 @@ int vp9_decode_frame(VP9Decoder *pbi, const int tile_rows = 1 << cm->log2_tile_rows; const int tile_cols = 1 << cm->log2_tile_cols; YV12_BUFFER_CONFIG *const new_fb = get_frame_new_buffer(cm); + const int do_loopfilter_inline = tile_rows == 1 && tile_cols == 1 && + cm->lf.filter_level; xd->cur_buf = new_fb; if (!first_partition_size) { @@ -1321,9 +1325,7 @@ int vp9_decode_frame(VP9Decoder *pbi, vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet or corrupt header length"); - pbi->do_loopfilter_inline = - (cm->log2_tile_rows | cm->log2_tile_cols) == 0 && cm->lf.filter_level; - if (pbi->do_loopfilter_inline && pbi->lf_worker.data1 == NULL) { + if (do_loopfilter_inline && pbi->lf_worker.data1 == NULL) { CHECK_MEM_ERROR(cm, pbi->lf_worker.data1, vpx_memalign(32, sizeof(LFWorkerData))); pbi->lf_worker.hook = (VP9WorkerHook)vp9_loop_filter_worker; @@ -1356,7 +1358,8 @@ int vp9_decode_frame(VP9Decoder *pbi, cm->frame_parallel_decoding_mode) { *p_data_end = decode_tiles_mt(pbi, data + first_partition_size, data_end); } else { - *p_data_end = decode_tiles(pbi, data + first_partition_size, data_end); + *p_data_end = decode_tiles(pbi, data + first_partition_size, data_end, + do_loopfilter_inline); } new_fb->corrupted |= xd->corrupted; @@ -1385,5 +1388,16 @@ int vp9_decode_frame(VP9Decoder *pbi, if (cm->refresh_frame_context) cm->frame_contexts[cm->frame_context_idx] = cm->fc; + // Loopfilter + if (!do_loopfilter_inline) { + // If multiple threads are used to decode tiles, then we use those threads + // to do parallel loopfiltering. + if (pbi->num_tile_workers) { + vp9_loop_filter_frame_mt(new_fb, pbi, cm, cm->lf.filter_level, 0, 0); + } else { + vp9_loop_filter_frame(new_fb, cm, &pbi->mb, cm->lf.filter_level, 0, 0); + } + } + return 0; } diff --git a/vp9/decoder/vp9_decoder.c b/vp9/decoder/vp9_decoder.c index 8f72aa48f..6f310c765 100644 --- a/vp9/decoder/vp9_decoder.c +++ b/vp9/decoder/vp9_decoder.c @@ -279,16 +279,6 @@ int vp9_receive_compressed_data(VP9Decoder *pbi, swap_frame_buffers(pbi); - if (!pbi->do_loopfilter_inline) { - // If multiple threads are used to decode tiles, then we use those threads - // to do parallel loopfiltering. - if (pbi->num_tile_workers) { - vp9_loop_filter_frame_mt(pbi, cm, cm->lf.filter_level, 0, 0); - } else { - vp9_loop_filter_frame(cm, &pbi->mb, cm->lf.filter_level, 0, 0); - } - } - vp9_clear_system_state(); cm->last_width = cm->width; diff --git a/vp9/decoder/vp9_decoder.h b/vp9/decoder/vp9_decoder.h index 66b0f15f9..d6110c47e 100644 --- a/vp9/decoder/vp9_decoder.h +++ b/vp9/decoder/vp9_decoder.h @@ -39,7 +39,6 @@ typedef struct VP9Decoder { int decoded_key_frame; - int do_loopfilter_inline; // apply loopfilter to available rows immediately VP9Worker lf_worker; VP9Worker *tile_workers; diff --git a/vp9/decoder/vp9_dthread.c b/vp9/decoder/vp9_dthread.c index 019b0ffe8..5fe5ed79a 100644 --- a/vp9/decoder/vp9_dthread.c +++ b/vp9/decoder/vp9_dthread.c @@ -132,8 +132,8 @@ static int loop_filter_row_worker(void *arg1, void *arg2) { // VP9 decoder: Implement multi-threaded loopfilter that uses the tile // threads. -void vp9_loop_filter_frame_mt(VP9Decoder *pbi, - VP9_COMMON *cm, +void vp9_loop_filter_frame_mt(YV12_BUFFER_CONFIG *frame, + VP9Decoder *pbi, VP9_COMMON *cm, int frame_filter_level, int y_only, int partial_frame) { VP9LfSync *const lf_sync = &pbi->lf_row_sync; @@ -184,7 +184,7 @@ void vp9_loop_filter_frame_mt(VP9Decoder *pbi, worker->hook = (VP9WorkerHook)loop_filter_row_worker; // Loopfilter data - lf_data->frame_buffer = get_frame_new_buffer(cm); + lf_data->frame_buffer = frame; lf_data->cm = cm; lf_data->xd = pbi->mb; lf_data->start = i; diff --git a/vp9/decoder/vp9_dthread.h b/vp9/decoder/vp9_dthread.h index 8738ceebd..c3b7a293b 100644 --- a/vp9/decoder/vp9_dthread.h +++ b/vp9/decoder/vp9_dthread.h @@ -48,7 +48,8 @@ void vp9_loop_filter_alloc(struct VP9Common *cm, VP9LfSync *lf_sync, void vp9_loop_filter_dealloc(VP9LfSync *lf_sync, int rows); // Multi-threaded loopfilter that uses the tile threads. -void vp9_loop_filter_frame_mt(struct VP9Decoder *pbi, +void vp9_loop_filter_frame_mt(YV12_BUFFER_CONFIG *frame, + struct VP9Decoder *pbi, struct VP9Common *cm, int frame_filter_level, int y_only, int partial_frame); diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 2756bf0fa..2ae26d943 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -115,22 +115,6 @@ static void set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv) { } } -static void setup_key_frame(VP9_COMP *cpi) { - vp9_setup_past_independence(&cpi->common); - - // All buffers are implicitly updated on key frames. - cpi->refresh_golden_frame = 1; - cpi->refresh_alt_ref_frame = 1; -} - -static void setup_inter_frame(VP9_COMMON *cm) { - if (cm->error_resilient_mode || cm->intra_only) - vp9_setup_past_independence(cm); - - assert(cm->frame_context_idx < FRAME_CONTEXTS); - cm->fc = cm->frame_contexts[cm->frame_context_idx]; -} - static void setup_frame(VP9_COMP *cpi) { VP9_COMMON *const cm = &cpi->common; // Set up entropy context depending on frame type. The decoder mandates @@ -138,17 +122,21 @@ static void setup_frame(VP9_COMP *cpi) { // frames where the error_resilient_mode or intra_only flag is set. For // other inter-frames the encoder currently uses only two contexts; // context 1 for ALTREF frames and context 0 for the others. + if (frame_is_intra_only(cm) || cm->error_resilient_mode) { + vp9_setup_past_independence(cm); + } else { + if (!cpi->use_svc) + cm->frame_context_idx = cpi->refresh_alt_ref_frame; + } + if (cm->frame_type == KEY_FRAME) { - setup_key_frame(cpi); + cpi->refresh_golden_frame = 1; + cpi->refresh_alt_ref_frame = 1; } else { - if (!cm->intra_only && !cm->error_resilient_mode && !cpi->use_svc) - cm->frame_context_idx = cpi->refresh_alt_ref_frame; - setup_inter_frame(cm); + cm->fc = cm->frame_contexts[cm->frame_context_idx]; } } - - void vp9_initialize_enc() { static int init_done = 0; @@ -1617,7 +1605,7 @@ static void loopfilter_frame(VP9_COMP *cpi, VP9_COMMON *cm) { } if (lf->filter_level > 0) { - vp9_loop_filter_frame(cm, xd, lf->filter_level, 0, 0); + vp9_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level, 0, 0); } vp9_extend_frame_inner_borders(cm->frame_to_show); @@ -1737,8 +1725,6 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) { #endif static void encode_without_recode_loop(VP9_COMP *cpi, - size_t *size, - uint8_t *dest, int q) { VP9_COMMON *const cm = &cpi->common; vp9_clear_system_state(); @@ -2174,7 +2160,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, } if (cpi->sf.recode_loop == DISALLOW_RECODE) { - encode_without_recode_loop(cpi, size, dest, q); + encode_without_recode_loop(cpi, q); } else { encode_with_recode_loop(cpi, size, dest, q, bottom_index, top_index); } diff --git a/vp9/encoder/vp9_mcomp.c b/vp9/encoder/vp9_mcomp.c index 43c8ab868..7e5f35bbf 100644 --- a/vp9/encoder/vp9_mcomp.c +++ b/vp9/encoder/vp9_mcomp.c @@ -1551,7 +1551,7 @@ int vp9_refining_search_8p_c(const MACROBLOCK *x, int search_range, const vp9_variance_fn_ptr_t *fn_ptr, const MV *center_mv, - const uint8_t *second_pred, int w, int h) { + const uint8_t *second_pred) { const MV neighbors[8] = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}, {-1, -1}, {1, -1}, {-1, 1}, {1, 1}}; const MACROBLOCKD *const xd = &x->e_mbd; diff --git a/vp9/encoder/vp9_mcomp.h b/vp9/encoder/vp9_mcomp.h index 827957d62..873edf376 100644 --- a/vp9/encoder/vp9_mcomp.h +++ b/vp9/encoder/vp9_mcomp.h @@ -144,8 +144,7 @@ int vp9_refining_search_8p_c(const MACROBLOCK *x, MV *ref_mv, int error_per_bit, int search_range, const vp9_variance_fn_ptr_t *fn_ptr, - const MV *center_mv, const uint8_t *second_pred, - int w, int h); + const MV *center_mv, const uint8_t *second_pred); #ifdef __cplusplus } // extern "C" #endif diff --git a/vp9/encoder/vp9_picklpf.c b/vp9/encoder/vp9_picklpf.c index a4b280c53..53284656e 100644 --- a/vp9/encoder/vp9_picklpf.c +++ b/vp9/encoder/vp9_picklpf.c @@ -38,7 +38,8 @@ static int try_filter_frame(const YV12_BUFFER_CONFIG *sd, VP9_COMP *const cpi, VP9_COMMON *const cm = &cpi->common; int filt_err; - vp9_loop_filter_frame(cm, &cpi->mb.e_mbd, filt_level, 1, partial_frame); + vp9_loop_filter_frame(cm->frame_to_show, cm, &cpi->mb.e_mbd, filt_level, 1, + partial_frame); filt_err = vp9_get_y_sse(sd, cm->frame_to_show); // Re-instate the unfiltered frame diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 22e19feee..0f1e9a04c 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -2514,8 +2514,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, bestsme = vp9_refining_search_8p_c(x, &tmp_mv, sadpb, search_range, &cpi->fn_ptr[bsize], - &ref_mv[id].as_mv, second_pred, - pw, ph); + &ref_mv[id].as_mv, second_pred); if (bestsme < INT_MAX) bestsme = vp9_get_mvpred_av_var(x, &tmp_mv, &ref_mv[id].as_mv, second_pred, &cpi->fn_ptr[bsize], 1); diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index 6ef52eda9..c4058bb78 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -824,7 +824,7 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, } // Add the frame packet to the list of returned packets. - round = (vpx_codec_pts_t)1000000 * ctx->cfg.g_timebase.num / 2 - 1; + round = (vpx_codec_pts_t)10000000 * ctx->cfg.g_timebase.num / 2 - 1; delta = (dst_end_time_stamp - dst_time_stamp); pkt.kind = VPX_CODEC_CX_FRAME_PKT; pkt.data.frame.pts = @@ -33,7 +33,9 @@ #include "./md5_utils.h" #include "./tools_common.h" +#if CONFIG_WEBM_IO #include "./webmdec.h" +#endif #include "./y4menc.h" static const char *exec_name; @@ -528,9 +530,11 @@ int main_loop(int argc, const char **argv_) { struct VpxDecInputContext input = {0}; struct VpxInputContext vpx_input_ctx = {0}; +#if CONFIG_WEBM_IO struct WebmInputContext webm_ctx = {0}; - input.vpx_input_ctx = &vpx_input_ctx; input.webm_ctx = &webm_ctx; +#endif + input.vpx_input_ctx = &vpx_input_ctx; /* Parse command line */ exec_name = argv_[0]; @@ -42,7 +42,9 @@ #include "./rate_hist.h" #include "./vpxstats.h" #include "./warnings.h" +#if CONFIG_WEBM_IO #include "./webmenc.h" +#endif #include "./y4minput.h" /* Swallow warnings about unused results of fread/fwrite */ @@ -207,6 +209,7 @@ static const arg_def_t width = ARG_DEF("w", "width", 1, "Frame width"); static const arg_def_t height = ARG_DEF("h", "height", 1, "Frame height"); +#if CONFIG_WEBM_IO static const struct arg_enum_list stereo_mode_enum[] = { {"mono", STEREO_FORMAT_MONO}, {"left-right", STEREO_FORMAT_LEFT_RIGHT}, @@ -217,6 +220,7 @@ static const struct arg_enum_list stereo_mode_enum[] = { }; static const arg_def_t stereo_mode = ARG_DEF_ENUM(NULL, "stereo-mode", 1, "Stereo 3D video format", stereo_mode_enum); +#endif static const arg_def_t timebase = ARG_DEF(NULL, "timebase", 1, "Output timestamp precision (fractional seconds)"); static const arg_def_t error_resilient = ARG_DEF(NULL, "error-resilient", 1, @@ -226,7 +230,11 @@ static const arg_def_t lag_in_frames = ARG_DEF(NULL, "lag-in-frames", 1, static const arg_def_t *global_args[] = { &use_yv12, &use_i420, &usage, &threads, &profile, - &width, &height, &stereo_mode, &timebase, &framerate, + &width, &height, +#if CONFIG_WEBM_IO + &stereo_mode, +#endif + &timebase, &framerate, &error_resilient, &lag_in_frames, NULL }; @@ -554,6 +562,11 @@ static int compare_img(const vpx_image_t *const img1, NELEMENTS(vp9_arg_ctrl_map)) #endif +#if !CONFIG_WEBM_IO +typedef int stereo_format_t; +struct EbmlGlobal { int debug; }; +#endif + /* Per-stream configuration */ struct stream_config { struct vpx_codec_enc_cfg cfg; @@ -792,9 +805,9 @@ static struct stream_state *new_stream(struct VpxEncoderConfig *global, stream->config.cfg.g_h = 0; /* Initialize remaining stream parameters */ - stream->config.stereo_fmt = STEREO_FORMAT_MONO; stream->config.write_webm = 1; #if CONFIG_WEBM_IO + stream->config.stereo_fmt = STEREO_FORMAT_MONO; stream->ebml.last_pts_ns = -1; stream->ebml.writer = NULL; stream->ebml.segment = NULL; @@ -869,8 +882,10 @@ static int parse_stream_params(struct VpxEncoderConfig *global, config->cfg.g_w = arg_parse_uint(&arg); } else if (arg_match(&arg, &height, argi)) { config->cfg.g_h = arg_parse_uint(&arg); +#if CONFIG_WEBM_IO } else if (arg_match(&arg, &stereo_mode, argi)) { config->stereo_fmt = arg_parse_enum_or_int(&arg); +#endif } else if (arg_match(&arg, &timebase, argi)) { config->cfg.g_timebase = arg_parse_rational(&arg); validate_positive_rational(arg.name, &config->cfg.g_timebase); |