vp9_extend.c 5.47 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5 6
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
9 10
 */

11
#include "vp9/common/vp9_extend.h"
John Koleszar's avatar
John Koleszar committed
12 13
#include "vpx_mem/vpx_mem.h"

14 15 16 17 18 19 20 21 22 23
static void copy_and_extend_plane(unsigned char *s, /* source */
                                  int sp,           /* source pitch */
                                  unsigned char *d, /* destination */
                                  int dp,           /* destination pitch */
                                  int h,            /* height */
                                  int w,            /* width */
                                  int et,           /* extend top border */
                                  int el,           /* extend left border */
                                  int eb,           /* extend bottom border */
                                  int er) {         /* extend right border */
John Koleszar's avatar
John Koleszar committed
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
  int i;
  unsigned char *src_ptr1, *src_ptr2;
  unsigned char *dest_ptr1, *dest_ptr2;
  int linesize;

  /* copy the left and right most columns out */
  src_ptr1 = s;
  src_ptr2 = s + w - 1;
  dest_ptr1 = d - el;
  dest_ptr2 = d + w;

  for (i = 0; i < h; i++) {
    vpx_memset(dest_ptr1, src_ptr1[0], el);
    vpx_memcpy(dest_ptr1 + el, src_ptr1, w);
    vpx_memset(dest_ptr2, src_ptr2[0], er);
    src_ptr1  += sp;
    src_ptr2  += sp;
    dest_ptr1 += dp;
    dest_ptr2 += dp;
  }

  /* Now copy the top and bottom lines into each line of the respective
   * borders
   */
  src_ptr1 = d - el;
  src_ptr2 = d + dp * (h - 1) - el;
  dest_ptr1 = d + dp * (-et) - el;
  dest_ptr2 = d + dp * (h) - el;
  linesize = el + er + w;

  for (i = 0; i < et; i++) {
    vpx_memcpy(dest_ptr1, src_ptr1, linesize);
    dest_ptr1 += dp;
  }

  for (i = 0; i < eb; i++) {
    vpx_memcpy(dest_ptr2, src_ptr2, linesize);
    dest_ptr2 += dp;
  }
John Koleszar's avatar
John Koleszar committed
63 64
}

65
void vp9_copy_and_extend_frame(YV12_BUFFER_CONFIG *src,
John Koleszar's avatar
John Koleszar committed
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
                               YV12_BUFFER_CONFIG *dst) {
  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;

  copy_and_extend_plane(src->y_buffer, src->y_stride,
                        dst->y_buffer, dst->y_stride,
                        src->y_height, src->y_width,
                        et, el, eb, er);

  et = dst->border >> 1;
  el = dst->border >> 1;
  eb = (dst->border >> 1) + dst->uv_height - src->uv_height;
  er = (dst->border >> 1) + dst->uv_width - src->uv_width;

  copy_and_extend_plane(src->u_buffer, src->uv_stride,
                        dst->u_buffer, dst->uv_stride,
                        src->uv_height, src->uv_width,
                        et, el, eb, er);

  copy_and_extend_plane(src->v_buffer, src->uv_stride,
                        dst->v_buffer, dst->uv_stride,
                        src->uv_height, src->uv_width,
                        et, el, eb, er);
John Koleszar's avatar
John Koleszar committed
91 92
}

93
void vp9_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src,
94 95
                                         YV12_BUFFER_CONFIG *dst,
                                         int srcy, int srcx,
John Koleszar's avatar
John Koleszar committed
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
                                         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);
143 144
}

145
/* note the extension is only for the last row, for intra prediction purpose */
146 147
void vp9_extend_mb_row(YV12_BUFFER_CONFIG *ybf, unsigned char *YPtr,
                       unsigned char *UPtr, unsigned char *VPtr) {
John Koleszar's avatar
John Koleszar committed
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
  int i;

  YPtr += ybf->y_stride * 14;
  UPtr += ybf->uv_stride * 6;
  VPtr += ybf->uv_stride * 6;

  for (i = 0; i < 4; i++) {
    YPtr[i] = YPtr[-1];
    UPtr[i] = UPtr[-1];
    VPtr[i] = VPtr[-1];
  }

  YPtr += ybf->y_stride;
  UPtr += ybf->uv_stride;
  VPtr += ybf->uv_stride;

  for (i = 0; i < 4; i++) {
    YPtr[i] = YPtr[-1];
    UPtr[i] = UPtr[-1];
    VPtr[i] = VPtr[-1];
  }
John Koleszar's avatar
John Koleszar committed
169
}