Merge "Fix the transform type selection in 4x4 partition" into experimental
diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c
index e521a69..e7303f1 100644
--- a/vp9/common/vp9_reconinter.c
+++ b/vp9/common/vp9_reconinter.c
@@ -492,3 +492,18 @@
vp9_build_inter_predictors_sbuv(xd, mb_row, mb_col,
BLOCK_SIZE_MB16X16);
}
+
+// TODO(dkovalev: find better place for this function)
+void vp9_setup_scale_factors(VP9_COMMON *cm, int i) {
+ const int ref = cm->active_ref_idx[i];
+ struct scale_factors *const sf = &cm->active_ref_scale[i];
+ if (ref >= NUM_YV12_BUFFERS) {
+ memset(sf, 0, sizeof(*sf));
+ } else {
+ YV12_BUFFER_CONFIG *const fb = &cm->yv12_fb[ref];
+ vp9_setup_scale_factors_for_frame(sf,
+ fb->y_crop_width, fb->y_crop_height,
+ cm->width, cm->height);
+ }
+}
+
diff --git a/vp9/common/vp9_reconinter.h b/vp9/common/vp9_reconinter.h
index 885e1de..8f76195 100644
--- a/vp9/common/vp9_reconinter.h
+++ b/vp9/common/vp9_reconinter.h
@@ -122,4 +122,6 @@
xd->scale_factor_uv[1] = xd->scale_factor[1];
}
+void vp9_setup_scale_factors(VP9_COMMON *cm, int i);
+
#endif // VP9_COMMON_VP9_RECONINTER_H_
diff --git a/vp9/common/vp9_reconintra.c b/vp9/common/vp9_reconintra.c
index 9e580c7..ea4805f 100644
--- a/vp9/common/vp9_reconintra.c
+++ b/vp9/common/vp9_reconintra.c
@@ -378,19 +378,21 @@
void vp9_build_intra_predictors_sbuv_s(MACROBLOCKD *xd,
BLOCK_SIZE_TYPE bsize) {
- const int bwl = b_width_log2(bsize), bw = 2 << bwl;
- const int bhl = b_height_log2(bsize), bh = 2 << bhl;
+ int p;
- vp9_build_intra_predictors(xd->plane[1].dst.buf, xd->plane[1].dst.stride,
- xd->plane[1].dst.buf, xd->plane[1].dst.stride,
- xd->mode_info_context->mbmi.uv_mode,
- bw, bh, xd->up_available,
- xd->left_available, 0 /*xd->right_available*/);
- vp9_build_intra_predictors(xd->plane[2].dst.buf, xd->plane[1].dst.stride,
- xd->plane[2].dst.buf, xd->plane[1].dst.stride,
- xd->mode_info_context->mbmi.uv_mode,
- bw, bh, xd->up_available,
- xd->left_available, 0 /*xd->right_available*/);
+ for (p = 1; p < MAX_MB_PLANE; p++) {
+ const struct macroblockd_plane* const pd = &xd->plane[p];
+ const int bwl = b_width_log2(bsize) - pd->subsampling_x;
+ const int bw = 4 << bwl;
+ const int bhl = b_height_log2(bsize) - pd->subsampling_y;
+ const int bh = 4 << bhl;
+
+ vp9_build_intra_predictors(pd->dst.buf, pd->dst.stride,
+ pd->dst.buf, pd->dst.stride,
+ xd->mode_info_context->mbmi.uv_mode,
+ bw, bh, xd->up_available,
+ xd->left_available, 0 /*xd->right_available*/);
+ }
}
void vp9_intra4x4_predict(MACROBLOCKD *xd,
diff --git a/vp9/common/vp9_seg_common.c b/vp9/common/vp9_seg_common.c
index 02b7053..e5511a1 100644
--- a/vp9/common/vp9_seg_common.c
+++ b/vp9/common/vp9_seg_common.c
@@ -89,7 +89,7 @@
#if CONFIG_IMPLICIT_SEGMENTATION
// This function defines an implicit segmentation for the next frame based
// on predcition and transform decisions in the current frame.
-// For test purposes at the moment only TX size is used.
+// For test purposes at the moment it uses ref frame and prediction size
void vp9_implicit_segment_map_update(VP9_COMMON * cm) {
int row, col;
MODE_INFO *mi, *mi_ptr = cm->mi;
@@ -97,9 +97,66 @@
for (row = 0; row < cm->mb_rows; row++) {
mi = mi_ptr;
- // Experimental use of tx size to define implicit segmentation
+
for (col = 0; col < cm->mb_cols; ++col, ++mi) {
- map_ptr[col] = 1 + mi->mbmi.txfm_size;
+ // Inter prediction
+ if (mi->mbmi.ref_frame != INTRA_FRAME) {
+ // Zero motion and prediction block size >= 16
+ if ((mi->mbmi.sb_type >= BLOCK_SIZE_MB16X16) &&
+ (mi->mbmi.mv[0].as_int == 0))
+ map_ptr[col] = 1;
+ else if (mi->mbmi.sb_type >= BLOCK_SIZE_SB32X32)
+ map_ptr[col] = 2;
+ else if (mi->mbmi.sb_type >= BLOCK_SIZE_MB16X16)
+ map_ptr[col] = 3;
+ else
+ map_ptr[col] = 6;
+
+ // Intra prediction
+ } else {
+ if (mi->mbmi.sb_type >= BLOCK_SIZE_SB32X32)
+ map_ptr[col] = 4;
+ else if (mi->mbmi.sb_type >= BLOCK_SIZE_MB16X16)
+ map_ptr[col] = 5;
+ else
+ map_ptr[col] = 7;
+ }
+ }
+ mi_ptr += cm->mode_info_stride;
+ map_ptr += cm->mb_cols;
+ }
+}
+
+// This function defines an implicit segmentation for the next frame based
+// on predcition and transform decisions in the current frame.
+// For test purposes at the moment only TX size is used.
+void vp9_implicit_segment_map_update_tx(VP9_COMMON * cm) {
+ int row, col;
+ MODE_INFO *mi, *mi_ptr = cm->mi;
+ unsigned char * map_ptr = cm->last_frame_seg_map;
+
+ for (row = 0; row < cm->mb_rows; row++) {
+ mi = mi_ptr;
+ for (col = 0; col < cm->mb_cols; ++col, ++mi) {
+ // Intra modes
+ if (mi->mbmi.ref_frame == INTRA_FRAME) {
+ if (mi->mbmi.txfm_size == TX_4X4)
+ map_ptr[col] = 7;
+ else if (mi->mbmi.txfm_size <= TX_16X16)
+ map_ptr[col] = 5;
+ else
+ map_ptr[col] = 4;
+ } else {
+ // Inter Modes
+ if (mi->mbmi.txfm_size == TX_4X4)
+ map_ptr[col] = 6;
+ else if (mi->mbmi.txfm_size == TX_8X8)
+ map_ptr[col] = 3;
+ else if (mi->mbmi.txfm_size == TX_16X16)
+ map_ptr[col] = 2;
+ else
+ map_ptr[col] = 1;
+ }
}
mi_ptr += cm->mode_info_stride;
map_ptr += cm->mb_cols;
@@ -107,6 +164,7 @@
}
#endif
+
const vp9_tree_index vp9_segment_tree[14] = {
2, 4, 6, 8, 10, 12,
0, -1, -2, -3, -4, -5, -6, -7
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c
index 6a79c6c..2e233c3 100644
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -1021,23 +1021,13 @@
// Select active reference frames and calculate scaling factors
for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
const int ref = vp9_read_literal(&header_bc, NUM_REF_FRAMES_LG2);
- const int mapped_ref = pc->ref_frame_map[ref];
- YV12_BUFFER_CONFIG *const fb = &pc->yv12_fb[mapped_ref];
- struct scale_factors *const sf = &pc->active_ref_scale[i];
-
- pc->active_ref_idx[i] = mapped_ref;
- if (mapped_ref >= NUM_YV12_BUFFERS)
- memset(sf, 0, sizeof(*sf));
- else
- vp9_setup_scale_factors_for_frame(sf,
- fb->y_crop_width, fb->y_crop_height,
- pc->width, pc->height);
+ pc->active_ref_idx[i] = pc->ref_frame_map[ref];
+ vp9_setup_scale_factors(pc, i);
}
// Read the sign bias for each reference frame buffer.
- for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
+ for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i)
pc->ref_frame_sign_bias[i + 1] = vp9_read_bit(&header_bc);
- }
xd->allow_high_precision_mv = vp9_read_bit(&header_bc);
pc->mcomp_filter_type = read_mcomp_filter_type(&header_bc);
diff --git a/vp9/decoder/vp9_onyxd_if.c b/vp9/decoder/vp9_onyxd_if.c
index c0ce311..6a55e8f 100644
--- a/vp9/decoder/vp9_onyxd_if.c
+++ b/vp9/decoder/vp9_onyxd_if.c
@@ -352,7 +352,8 @@
vp9_loop_filter_frame(cm, &pbi->mb, cm->filter_level, 0,
cm->dering_enabled);
}
- vp8_yv12_extend_frame_borders(cm->frame_to_show);
+ vp9_extend_frame_borders(cm->frame_to_show,
+ cm->subsampling_x, cm->subsampling_y);
}
#if WRITE_RECON_BUFFER == 1
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index ddcf849..367ebec 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -522,6 +522,8 @@
xd->plane[2].dst.buf = new_yv12->v_buffer + recon_uvoffset;
xd->left_available = (mb_col != 0);
+ xd->mode_info_context->mbmi.sb_type = BLOCK_SIZE_MB16X16;
+
// do intra 16x16 prediction
this_error = vp9_encode_intra(cpi, x, use_dc_pred);
@@ -768,7 +770,7 @@
// swap frame pointers so last frame refers to the frame we just compressed
swap_yv12(lst_yv12, new_yv12);
- vp8_yv12_extend_frame_borders(lst_yv12);
+ vp9_extend_frame_borders(lst_yv12, cm->subsampling_x, cm->subsampling_y);
// Special case for the first frame. Copy into the GF buffer as a second reference.
if (cm->current_video_frame == 0)
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index d78373f..67d1b67 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -487,12 +487,14 @@
}
#if CONFIG_IMPLICIT_SEGMENTATION
-static void configure_implicit_segmentation(VP9_COMP *cpi) {
+static double implict_seg_q_modifiers[MAX_MB_SEGMENTS] =
+ {1.0, 0.95, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
+static void configure_implicit_segmentation(VP9_COMP *cpi, int frame_qindex) {
VP9_COMMON *cm = &cpi->common;
MACROBLOCKD *xd = &cpi->mb.e_mbd;
int i;
int qi_delta;
- double q_target = cpi->active_worst_quality * 1.10;
+ double q_baseline = vp9_convert_qindex_to_q(frame_qindex);
// Set the flags to allow implicit segment update but disallow explicit update
xd->segmentation_enabled = 1;
@@ -507,13 +509,19 @@
// Clear down the segment features.
vp9_clearall_segfeatures(xd);
+ xd->update_mb_segmentation_data = 0;
+
+ // Update the segment data if it is an arf or non overlay gf.
+ } else if (cpi->refresh_alt_ref_frame ||
+ (cpi->refresh_golden_frame && !cpi->is_src_frame_alt_ref)) {
xd->update_mb_segmentation_data = 1;
// Enable use of q deltas on segments 1 and up
+ // Segment 0 is treated as a neutral segment with no changes
for (i = 1; i < MAX_MB_SEGMENTS; ++i) {
- qi_delta = compute_qdelta(cpi, cpi->active_worst_quality, q_target);
+ qi_delta = compute_qdelta(cpi, q_baseline,
+ implict_seg_q_modifiers[i] * q_baseline);
vp9_set_segdata(xd, i, SEG_LVL_ALT_Q, qi_delta);
- q_target *= 0.95;
vp9_enable_segfeature(xd, i, SEG_LVL_ALT_Q);
}
@@ -728,7 +736,7 @@
#if CONFIG_IMPLICIT_SEGMENTATION
sf->static_segmentation = 0;
#else
- sf->static_segmentation = 1;
+ sf->static_segmentation = 0;
#endif
#endif
sf->splitmode_breakout = 0;
@@ -747,7 +755,7 @@
#if CONFIG_IMPLICIT_SEGMENTATION
sf->static_segmentation = 0;
#else
- sf->static_segmentation = 1;
+ sf->static_segmentation = 0;
#endif
#endif
sf->splitmode_breakout = 1;
@@ -2439,7 +2447,8 @@
cm->dering_enabled);
}
- vp8_yv12_extend_frame_borders(cm->frame_to_show);
+ vp9_extend_frame_borders(cm->frame_to_show,
+ cm->subsampling_x, cm->subsampling_y);
}
@@ -2944,13 +2953,13 @@
cpi->common.frame_context_idx = cpi->refresh_alt_ref_frame;
vp9_setup_inter_frame(cpi);
}
+ }
#if CONFIG_IMPLICIT_SEGMENTATION
- if (!cm->error_resilient_mode && !cpi->sf.static_segmentation) {
- configure_implicit_segmentation(cpi);
- }
-#endif
+ if (!cm->error_resilient_mode && !cpi->sf.static_segmentation) {
+ configure_implicit_segmentation(cpi, q);
}
+#endif
// transform / motion compensation build reconstruction frame
#if CONFIG_MODELCOEFPROB
@@ -3860,16 +3869,8 @@
VP9BORDERINPIXELS);
// Calculate scaling factors for each of the 3 available references
- for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
- if (cm->active_ref_idx[i] >= NUM_YV12_BUFFERS) {
- memset(&cm->active_ref_scale[i], 0, sizeof(cm->active_ref_scale[i]));
- } else {
- YV12_BUFFER_CONFIG *fb = &cm->yv12_fb[cm->active_ref_idx[i]];
- vp9_setup_scale_factors_for_frame(&cm->active_ref_scale[i],
- fb->y_crop_width, fb->y_crop_height,
- cm->width, cm->height);
- }
- }
+ for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i)
+ vp9_setup_scale_factors(cm, i);
vp9_setup_interp_filters(&cpi->mb.e_mbd, DEFAULT_INTERP_FILTER, cm);
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index 45609da..9326165 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -543,31 +543,6 @@
return VPX_CODEC_OK;
}
-static vpx_codec_err_t image2yuvconfig(const vpx_image_t *img,
- YV12_BUFFER_CONFIG *yv12) {
- vpx_codec_err_t res = VPX_CODEC_OK;
- yv12->y_buffer = img->planes[VPX_PLANE_Y];
- yv12->u_buffer = img->planes[VPX_PLANE_U];
- yv12->v_buffer = img->planes[VPX_PLANE_V];
-
- yv12->y_crop_width = img->d_w;
- yv12->y_crop_height = img->d_h;
- yv12->y_width = img->d_w;
- yv12->y_height = img->d_h;
-
- yv12->uv_width = img->x_chroma_shift == 1 ? (1 + yv12->y_width) / 2
- : yv12->y_width;
- yv12->uv_height = img->y_chroma_shift == 1 ? (1 + yv12->y_height) / 2
- : yv12->y_height;
-
- yv12->y_stride = img->stride[VPX_PLANE_Y];
- yv12->uv_stride = img->stride[VPX_PLANE_U];
-
- yv12->border = (img->stride[VPX_PLANE_Y] - img->w) / 2;
- yv12->clrtype = REG_YUV;
- return res;
-}
-
static void pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx,
unsigned long duration,
unsigned long deadline) {
diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c
index 85022c9..811cea7 100644
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -578,30 +578,6 @@
return res;
}
-static vpx_codec_err_t image2yuvconfig(const vpx_image_t *img,
- YV12_BUFFER_CONFIG *yv12) {
- vpx_codec_err_t res = VPX_CODEC_OK;
- yv12->y_buffer = img->planes[VPX_PLANE_Y];
- yv12->u_buffer = img->planes[VPX_PLANE_U];
- yv12->v_buffer = img->planes[VPX_PLANE_V];
-
- yv12->y_crop_width = img->d_w;
- yv12->y_crop_height = img->d_h;
- yv12->y_width = img->d_w;
- yv12->y_height = img->d_h;
- yv12->uv_width = yv12->y_width / 2;
- yv12->uv_height = yv12->y_height / 2;
-
- yv12->y_stride = img->stride[VPX_PLANE_Y];
- yv12->uv_stride = img->stride[VPX_PLANE_U];
-
- yv12->border = (img->stride[VPX_PLANE_Y] - img->d_w) / 2;
- yv12->clrtype = (img->fmt == VPX_IMG_FMT_VPXI420 ||
- img->fmt == VPX_IMG_FMT_VPXYV12);
-
- return res;
-}
-
static vpx_codec_err_t vp9_set_reference(vpx_codec_alg_priv_t *ctx,
int ctr_id,
diff --git a/vp9/vp9_iface_common.h b/vp9/vp9_iface_common.h
index 96de5f5..84b4d39 100644
--- a/vp9/vp9_iface_common.h
+++ b/vp9/vp9_iface_common.h
@@ -37,11 +37,11 @@
img->planes[VPX_PLANE_Y] = yv12->y_buffer;
img->planes[VPX_PLANE_U] = yv12->u_buffer;
img->planes[VPX_PLANE_V] = yv12->v_buffer;
- img->planes[VPX_PLANE_ALPHA] = NULL;
+ img->planes[VPX_PLANE_ALPHA] = yv12->alpha_buffer;
img->stride[VPX_PLANE_Y] = yv12->y_stride;
img->stride[VPX_PLANE_U] = yv12->uv_stride;
img->stride[VPX_PLANE_V] = yv12->uv_stride;
- img->stride[VPX_PLANE_ALPHA] = yv12->y_stride;
+ img->stride[VPX_PLANE_ALPHA] = yv12->alpha_stride;
img->bps = bps;
img->user_priv = user_priv;
img->img_data = yv12->buffer_alloc;
@@ -49,4 +49,34 @@
img->self_allocd = 0;
}
+static vpx_codec_err_t image2yuvconfig(const vpx_image_t *img,
+ YV12_BUFFER_CONFIG *yv12) {
+ yv12->y_buffer = img->planes[VPX_PLANE_Y];
+ yv12->u_buffer = img->planes[VPX_PLANE_U];
+ yv12->v_buffer = img->planes[VPX_PLANE_V];
+ yv12->alpha_buffer = img->planes[VPX_PLANE_ALPHA];
+
+ yv12->y_crop_width = img->d_w;
+ yv12->y_crop_height = img->d_h;
+ yv12->y_width = img->d_w;
+ yv12->y_height = img->d_h;
+
+ yv12->uv_width = img->x_chroma_shift == 1 ? (1 + yv12->y_width) / 2
+ : yv12->y_width;
+ yv12->uv_height = img->y_chroma_shift == 1 ? (1 + yv12->y_height) / 2
+ : yv12->y_height;
+
+ yv12->alpha_width = yv12->alpha_buffer ? img->d_w : 0;
+ yv12->alpha_height = yv12->alpha_buffer ? img->d_h : 0;
+
+ yv12->y_stride = img->stride[VPX_PLANE_Y];
+ yv12->uv_stride = img->stride[VPX_PLANE_U];
+ yv12->alpha_stride = yv12->alpha_buffer ? img->stride[VPX_PLANE_ALPHA] : 0;
+
+ yv12->border = (img->stride[VPX_PLANE_Y] - img->w) / 2;
+ yv12->clrtype = REG_YUV;
+
+ return VPX_CODEC_OK;
+}
+
#endif // VP9_VP9_IFACE_COMMON_H_
diff --git a/vpx_scale/generic/yv12config.c b/vpx_scale/generic/yv12config.c
index cd66f00..99e3543 100644
--- a/vpx_scale/generic/yv12config.c
+++ b/vpx_scale/generic/yv12config.c
@@ -76,12 +76,17 @@
ybf->uv_height = uv_height;
ybf->uv_stride = uv_stride;
+ ybf->alpha_width = 0;
+ ybf->alpha_height = 0;
+ ybf->alpha_stride = 0;
+
ybf->border = border;
ybf->frame_size = frame_size;
ybf->y_buffer = ybf->buffer_alloc + (border * y_stride) + border;
ybf->u_buffer = ybf->buffer_alloc + yplane_size + (border / 2 * uv_stride) + border / 2;
ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size + (border / 2 * uv_stride) + border / 2;
+ ybf->alpha_buffer = NULL;
ybf->corrupted = 0; /* assume not currupted by errors */
return 0;
diff --git a/vpx_scale/generic/yv12extend.c b/vpx_scale/generic/yv12extend.c
index a322e0a..c38fb80 100644
--- a/vpx_scale/generic/yv12extend.c
+++ b/vpx_scale/generic/yv12extend.c
@@ -9,6 +9,7 @@
*/
#include <assert.h>
+#include "./vpx_config.h"
#include "vpx_scale/yv12config.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_scale/vpx_scale.h"
@@ -94,6 +95,36 @@
(ybf->border + ybf->y_width - ybf->y_crop_width + 1) / 2);
}
+#if CONFIG_VP9
+void vp9_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf,
+ int subsampling_x, int subsampling_y) {
+ 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 = ybf->border >> subsampling_y;
+ const int c_el = ybf->border >> subsampling_x;
+ const int c_eb = (ybf->border + ybf->y_height - ybf->y_crop_height +
+ subsampling_y) >> subsampling_y;
+ const int c_er = (ybf->border + 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,
+ 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,
+ 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);
+}
+#endif
/****************************************************************************
*
diff --git a/vpx_scale/vpx_scale_rtcd.sh b/vpx_scale/vpx_scale_rtcd.sh
index e2bade0..b4f8907 100644
--- a/vpx_scale/vpx_scale_rtcd.sh
+++ b/vpx_scale/vpx_scale_rtcd.sh
@@ -24,3 +24,8 @@
prototype void vp8_yv12_copy_y "struct yv12_buffer_config *src_ybc, struct yv12_buffer_config *dst_ybc"
specialize vp8_yv12_copy_y neon
+
+if [ "$CONFIG_VP9" = "yes" ]; then
+ prototype void vp9_extend_frame_borders "struct yv12_buffer_config *ybf, int subsampling_x, int subsampling_y"
+ specialize vp9_extend_frame_borders
+fi
diff --git a/vpx_scale/yv12config.h b/vpx_scale/yv12config.h
index 85396c0..7b8bd85 100644
--- a/vpx_scale/yv12config.h
+++ b/vpx_scale/yv12config.h
@@ -52,9 +52,14 @@
int uv_stride;
/* int uvinternal_width; */
+ int alpha_width;
+ int alpha_height;
+ int alpha_stride;
+
uint8_t *y_buffer;
uint8_t *u_buffer;
uint8_t *v_buffer;
+ uint8_t *alpha_buffer;
uint8_t *buffer_alloc;
int buffer_alloc_sz;