vpx/vpx_scale/generic/yv12extend.c

218 lines
7.1 KiB
C
Raw Normal View History

2010-05-18 17:58:33 +02:00
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
2010-05-18 17:58:33 +02:00
*
* 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.
2010-05-18 17:58:33 +02:00
*/
#include <assert.h>
#include "./vpx_config.h"
2010-05-18 17:58:33 +02:00
#include "vpx_scale/yv12config.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_scale/vpx_scale.h"
2010-05-18 17:58:33 +02:00
/****************************************************************************
* Exports
****************************************************************************/
/****************************************************************************
*
****************************************************************************/
static void extend_plane(uint8_t *s, /* source */
int sp, /* source pitch */
int w, /* width */
int h, /* height */
int et, /* extend top border */
int el, /* extend left border */
int eb, /* extend bottom border */
int er) { /* extend right border */
int i;
uint8_t *src_ptr1, *src_ptr2;
uint8_t *dest_ptr1, *dest_ptr2;
int linesize;
/* copy the left and right most columns out */
src_ptr1 = s;
src_ptr2 = s + w - 1;
dest_ptr1 = s - el;
dest_ptr2 = s + w;
for (i = 0; i < h; i++) {
vpx_memset(dest_ptr1, src_ptr1[0], el);
vpx_memset(dest_ptr2, src_ptr2[0], er);
src_ptr1 += sp;
src_ptr2 += sp;
dest_ptr1 += sp;
dest_ptr2 += sp;
}
/* Now copy the top and bottom lines into each line of the respective
* borders
*/
src_ptr1 = s - el;
src_ptr2 = s + sp * (h - 1) - el;
dest_ptr1 = s + sp * (-et) - el;
dest_ptr2 = s + sp * (h) - el;
linesize = el + er + w;
for (i = 0; i < et; i++) {
vpx_memcpy(dest_ptr1, src_ptr1, linesize);
dest_ptr1 += sp;
}
for (i = 0; i < eb; i++) {
vpx_memcpy(dest_ptr2, src_ptr2, linesize);
dest_ptr2 += sp;
}
2010-05-18 17:58:33 +02:00
}
void
vp8_yv12_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf) {
assert(ybf->y_height - ybf->y_crop_height < 16);
assert(ybf->y_width - ybf->y_crop_width < 16);
assert(ybf->y_height - ybf->y_crop_height >= 0);
assert(ybf->y_width - ybf->y_crop_width >= 0);
extend_plane(ybf->y_buffer, ybf->y_stride,
ybf->y_crop_width, ybf->y_crop_height,
ybf->border, ybf->border,
ybf->border + ybf->y_height - ybf->y_crop_height,
ybf->border + ybf->y_width - ybf->y_crop_width);
extend_plane(ybf->u_buffer, ybf->uv_stride,
(ybf->y_crop_width + 1) / 2, (ybf->y_crop_height + 1) / 2,
ybf->border / 2, ybf->border / 2,
(ybf->border + ybf->y_height - ybf->y_crop_height + 1) / 2,
(ybf->border + ybf->y_width - ybf->y_crop_width + 1) / 2);
extend_plane(ybf->v_buffer, ybf->uv_stride,
(ybf->y_crop_width + 1) / 2, (ybf->y_crop_height + 1) / 2,
ybf->border / 2, ybf->border / 2,
(ybf->border + ybf->y_height - ybf->y_crop_height + 1) / 2,
(ybf->border + ybf->y_width - ybf->y_crop_width + 1) / 2);
2010-05-18 17:58:33 +02:00
}
#if CONFIG_VP9
static void extend_frame(YV12_BUFFER_CONFIG *ybf,
int subsampling_x, int subsampling_y,
int ext_size) {
const int c_w = (ybf->y_crop_width + subsampling_x) >> subsampling_x;
const int c_h = (ybf->y_crop_height + subsampling_y) >> subsampling_y;
const int c_et = ext_size >> subsampling_y;
const int c_el = ext_size >> subsampling_x;
const int c_eb = (ext_size + ybf->y_height - ybf->y_crop_height +
subsampling_y) >> subsampling_y;
const int c_er = (ext_size + ybf->y_width - ybf->y_crop_width +
subsampling_x) >> subsampling_x;
assert(ybf->y_height - ybf->y_crop_height < 16);
assert(ybf->y_width - ybf->y_crop_width < 16);
assert(ybf->y_height - ybf->y_crop_height >= 0);
assert(ybf->y_width - ybf->y_crop_width >= 0);
extend_plane(ybf->y_buffer, ybf->y_stride,
ybf->y_crop_width, ybf->y_crop_height,
ext_size, ext_size,
ext_size + ybf->y_height - ybf->y_crop_height,
ext_size + ybf->y_width - ybf->y_crop_width);
extend_plane(ybf->u_buffer, ybf->uv_stride,
c_w, c_h, c_et, c_el, c_eb, c_er);
extend_plane(ybf->v_buffer, ybf->uv_stride,
c_w, c_h, c_et, c_el, c_eb, c_er);
}
void vp9_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf,
int subsampling_x, int subsampling_y) {
extend_frame(ybf, subsampling_x, subsampling_y, ybf->border);
}
void vp9_extend_frame_inner_borders_c(YV12_BUFFER_CONFIG *ybf,
int subsampling_x, int subsampling_y) {
const int inner_bw = ybf->border > VP9INNERBORDERINPIXLES ?
VP9INNERBORDERINPIXLES : ybf->border;
extend_frame(ybf, subsampling_x, subsampling_y, inner_bw);
}
#endif
2010-05-18 17:58:33 +02:00
/****************************************************************************
*
* ROUTINE : vp8_yv12_copy_frame
*
* INPUTS :
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Copies the source image into the destination image and
* updates the destination's UMV borders.
*
* SPECIAL NOTES : The frames are assumed to be identical in size.
*
****************************************************************************/
void
vp8_yv12_copy_frame_c(YV12_BUFFER_CONFIG *src_ybc,
YV12_BUFFER_CONFIG *dst_ybc) {
int row;
unsigned char *source, *dest;
#if 0
/* These assertions are valid in the codec, but the libvpx-tester uses
* this code slightly differently.
*/
assert(src_ybc->y_width == dst_ybc->y_width);
assert(src_ybc->y_height == dst_ybc->y_height);
#endif
source = src_ybc->y_buffer;
dest = dst_ybc->y_buffer;
for (row = 0; row < src_ybc->y_height; row++) {
vpx_memcpy(dest, source, src_ybc->y_width);
source += src_ybc->y_stride;
dest += dst_ybc->y_stride;
}
source = src_ybc->u_buffer;
dest = dst_ybc->u_buffer;
for (row = 0; row < src_ybc->uv_height; row++) {
vpx_memcpy(dest, source, src_ybc->uv_width);
source += src_ybc->uv_stride;
dest += dst_ybc->uv_stride;
}
source = src_ybc->v_buffer;
dest = dst_ybc->v_buffer;
for (row = 0; row < src_ybc->uv_height; row++) {
vpx_memcpy(dest, source, src_ybc->uv_width);
source += src_ybc->uv_stride;
dest += dst_ybc->uv_stride;
}
vp8_yv12_extend_frame_borders_c(dst_ybc);
2010-05-18 17:58:33 +02:00
}
void vp8_yv12_copy_y_c(YV12_BUFFER_CONFIG *src_ybc,
YV12_BUFFER_CONFIG *dst_ybc) {
int row;
unsigned char *source, *dest;
2010-05-18 17:58:33 +02:00
source = src_ybc->y_buffer;
dest = dst_ybc->y_buffer;
2010-05-18 17:58:33 +02:00
for (row = 0; row < src_ybc->y_height; row++) {
vpx_memcpy(dest, source, src_ybc->y_width);
source += src_ybc->y_stride;
dest += dst_ybc->y_stride;
}
2010-05-18 17:58:33 +02:00
}