From 4e8d35a461e7a45f5134715b010ed38be986fb00 Mon Sep 17 00:00:00 2001 From: Alpha Lam Date: Tue, 9 Aug 2011 20:59:45 +0100 Subject: Copy less when active map is in use When active map is specified and the current frame is not a key frame, golden frame nor a altref frame then copy only those active regions. This significantly reduces encoding time by as much as 19% on the test system where realtime encoding is used. This is particularly useful when the frame size is large (e.g. 2560x1600) and there's only a few action macroblocks. Change-Id: If394a813ec2df5a0201745d1348dbde4278f7ad4 --- vp8/common/extend.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++ vp8/common/extend.h | 4 ++++ vp8/encoder/lookahead.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++-- vp8/encoder/lookahead.h | 17 +++++++++------ vp8/encoder/onyx_if.c | 2 +- 5 files changed, 125 insertions(+), 9 deletions(-) (limited to 'vp8') diff --git a/vp8/common/extend.c b/vp8/common/extend.c index a2d325332..9089e1629 100644 --- a/vp8/common/extend.c +++ b/vp8/common/extend.c @@ -102,6 +102,60 @@ void vp8_copy_and_extend_frame(YV12_BUFFER_CONFIG *src, } +void vp8_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src, + YV12_BUFFER_CONFIG *dst, + int srcy, int srcx, + int srch, int srcw) +{ + int et = dst->border; + int el = dst->border; + int eb = dst->border + dst->y_height - src->y_height; + int er = dst->border + dst->y_width - src->y_width; + int src_y_offset = srcy * src->y_stride + srcx; + int dst_y_offset = srcy * dst->y_stride + srcx; + int src_uv_offset = ((srcy * src->uv_stride) >> 1) + (srcx >> 1); + int dst_uv_offset = ((srcy * dst->uv_stride) >> 1) + (srcx >> 1); + + // If the side is not touching the bounder then don't extend. + if (srcy) + et = 0; + if (srcx) + el = 0; + if (srcy + srch != src->y_height) + eb = 0; + if (srcx + srcw != src->y_width) + er = 0; + + copy_and_extend_plane(src->y_buffer + src_y_offset, + src->y_stride, + dst->y_buffer + dst_y_offset, + dst->y_stride, + srch, srcw, + et, el, eb, er); + + et = (et + 1) >> 1; + el = (el + 1) >> 1; + eb = (eb + 1) >> 1; + er = (er + 1) >> 1; + srch = (srch + 1) >> 1; + srcw = (srcw + 1) >> 1; + + copy_and_extend_plane(src->u_buffer + src_uv_offset, + src->uv_stride, + dst->u_buffer + dst_uv_offset, + dst->uv_stride, + srch, srcw, + et, el, eb, er); + + copy_and_extend_plane(src->v_buffer + src_uv_offset, + src->uv_stride, + dst->v_buffer + dst_uv_offset, + dst->uv_stride, + srch, srcw, + et, el, eb, er); +} + + /* note the extension is only for the last row, for intra prediction purpose */ void vp8_extend_mb_row(YV12_BUFFER_CONFIG *ybf, unsigned char *YPtr, unsigned char *UPtr, unsigned char *VPtr) { diff --git a/vp8/common/extend.h b/vp8/common/extend.h index 9e0be4e06..74a0b177d 100644 --- a/vp8/common/extend.h +++ b/vp8/common/extend.h @@ -17,5 +17,9 @@ void vp8_extend_mb_row(YV12_BUFFER_CONFIG *ybf, unsigned char *YPtr, unsigned char *UPtr, unsigned char *VPtr); void vp8_copy_and_extend_frame(YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst); +void vp8_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src, + YV12_BUFFER_CONFIG *dst, + int srcy, int srcx, + int srch, int srcw); #endif diff --git a/vp8/encoder/lookahead.c b/vp8/encoder/lookahead.c index d7f85cba1..b92e82bdf 100644 --- a/vp8/encoder/lookahead.c +++ b/vp8/encoder/lookahead.c @@ -102,15 +102,68 @@ vp8_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src, int64_t ts_start, int64_t ts_end, - unsigned int flags) + unsigned int flags, + unsigned char *active_map) { struct lookahead_entry* buf; + int row, col, active_end; + int mb_rows = (src->y_height + 15) >> 4; + int mb_cols = (src->y_width + 15) >> 4; if(ctx->sz + 1 > ctx->max_sz) return 1; ctx->sz++; buf = pop(ctx, &ctx->write_idx); - vp8_copy_and_extend_frame(src, &buf->img); + + // Only do this partial copy if the following conditions are all met: + // 1. Lookahead queue has has size of 1. + // 2. Active map is provided. + // 3. This is not a key frame, golden nor altref frame. + if (ctx->max_sz == 1 && active_map && !flags) + { + for (row = 0; row < mb_rows; ++row) + { + col = 0; + + while (1) + { + // Find the first active macroblock in this row. + for (; col < mb_cols; ++col) + { + if (active_map[col]) + break; + } + + // No more active macroblock in this row. + if (col == mb_cols) + break; + + // Find the end of active region in this row. + active_end = col; + + for (; active_end < mb_cols; ++active_end) + { + if (!active_map[active_end]) + break; + } + + // Only copy this active region. + vp8_copy_and_extend_frame_with_rect(src, &buf->img, + row << 4, + col << 4, 16, + (active_end - col) << 4); + + // Start again from the end of this active region. + col = active_end; + } + + active_map += mb_cols; + } + } + else + { + vp8_copy_and_extend_frame(src, &buf->img); + } buf->ts_start = ts_start; buf->ts_end = ts_end; buf->flags = flags; diff --git a/vp8/encoder/lookahead.h b/vp8/encoder/lookahead.h index a483d7e0b..afb3fd4a9 100644 --- a/vp8/encoder/lookahead.h +++ b/vp8/encoder/lookahead.h @@ -47,18 +47,23 @@ void vp8_lookahead_destroy(struct lookahead_ctx *ctx); * This function will copy the source image into a new framebuffer with * the expected stride/border. * - * \param[in] ctx Pointer to the lookahead context - * \param[in] src Pointer to the image to enqueue - * \param[in] ts_start Timestamp for the start of this frame - * \param[in] ts_end Timestamp for the end of this frame - * \param[in] flags Flags set on this frame + * If active_map is non-NULL and there is only one frame in the queue, then copy + * only active macroblocks. + * + * \param[in] ctx Pointer to the lookahead context + * \param[in] src Pointer to the image to enqueue + * \param[in] ts_start Timestamp for the start of this frame + * \param[in] ts_end Timestamp for the end of this frame + * \param[in] flags Flags set on this frame + * \param[in] active_map Map that specifies which macroblock is active */ int vp8_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src, int64_t ts_start, int64_t ts_end, - unsigned int flags); + unsigned int flags, + unsigned char *active_map); /**\brief Get the next source buffer to encode diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 36a186521..3f7b86854 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -4676,7 +4676,7 @@ int vp8_receive_raw_frame(VP8_PTR ptr, unsigned int frame_flags, YV12_BUFFER_CON vpx_usec_timer_start(&timer); if(vp8_lookahead_push(cpi->lookahead, sd, time_stamp, end_time, - frame_flags)) + frame_flags, cpi->active_map_enabled ? cpi->active_map : NULL)) res = -1; cm->clr_type = sd->clrtype; vpx_usec_timer_mark(&timer); -- cgit v1.2.3