DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (5b81998bb7ab)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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 63 64 65 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 91 92 93 94 95 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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
diff --git a/media/libvpx/vp8/vp8_dx_iface.c b/media/libvpx/vp8/vp8_dx_iface.c
--- a/media/libvpx/vp8/vp8_dx_iface.c
+++ b/media/libvpx/vp8/vp8_dx_iface.c
@@ -315,16 +315,46 @@ update_error_state(vpx_codec_alg_priv_t 
     if ((res = error->error_code))
         ctx->base.err_detail = error->has_detail
                                ? error->detail
                                : NULL;
 
     return res;
 }
 
+static void yuvconfig2image(vpx_image_t               *img,
+                            const YV12_BUFFER_CONFIG  *yv12,
+                            void                      *user_priv)
+{
+    /** vpx_img_wrap() doesn't allow specifying independent strides for
+      * the Y, U, and V planes, nor other alignment adjustments that
+      * might be representable by a YV12_BUFFER_CONFIG, so we just
+      * initialize all the fields.*/
+    img->fmt = yv12->clrtype == REG_YUV ?
+        VPX_IMG_FMT_I420 : VPX_IMG_FMT_VPXI420;
+    img->w = yv12->y_stride;
+    img->h = (yv12->y_height + 2 * VP8BORDERINPIXELS + 15) & ~15;
+    img->d_w = yv12->y_width;
+    img->d_h = yv12->y_height;
+    img->x_chroma_shift = 1;
+    img->y_chroma_shift = 1;
+    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->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->bps = 12;
+    img->user_priv = user_priv;
+    img->img_data = yv12->buffer_alloc;
+    img->img_data_owner = 0;
+    img->self_allocd = 0;
+}
 
 static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t  *ctx,
                                   const uint8_t         *data,
                                   unsigned int            data_sz,
                                   void                    *user_priv,
                                   long                    deadline)
 {
     vpx_codec_err_t res = VPX_CODEC_OK;
@@ -424,30 +454,18 @@ static vpx_codec_err_t vp8_decode(vpx_co
         if (vp8dx_receive_compressed_data(ctx->pbi, data_sz, data, deadline))
         {
             VP8D_COMP *pbi = (VP8D_COMP *)ctx->pbi;
             res = update_error_state(ctx, &pbi->common.error);
         }
 
         if (!res && 0 == vp8dx_get_raw_frame(ctx->pbi, &sd, &time_stamp, &time_end_stamp, ppdeblocking, ppnoise, ppflag))
         {
-            /* Align width/height */
-            unsigned int a_w = (sd.y_width + 15) & ~15;
-            unsigned int a_h = (sd.y_height + 15) & ~15;
-
-            vpx_img_wrap(&ctx->img, VPX_IMG_FMT_I420,
-                         a_w + 2 * VP8BORDERINPIXELS,
-                         a_h + 2 * VP8BORDERINPIXELS,
-                         1,
-                         sd.buffer_alloc);
-            vpx_img_set_rect(&ctx->img,
-                             VP8BORDERINPIXELS, VP8BORDERINPIXELS,
-                             sd.y_width, sd.y_height);
+            yuvconfig2image(&ctx->img, &sd, user_priv);
             ctx->img_avail = 1;
-
         }
     }
 
     return res;
 }
 
 static vpx_image_t *vp8_get_frame(vpx_codec_alg_priv_t  *ctx,
                                   vpx_codec_iter_t      *iter)
diff --git a/media/libvpx/vpx_scale/generic/yv12config.c b/media/libvpx/vpx_scale/generic/yv12config.c
--- a/media/libvpx/vpx_scale/generic/yv12config.c
+++ b/media/libvpx/vpx_scale/generic/yv12config.c
@@ -42,50 +42,61 @@ vp8_yv12_de_alloc_frame_buffer(YV12_BUFF
 /****************************************************************************
  *
  ****************************************************************************/
 int
 vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, int border)
 {
 /*NOTE:*/
 
-    int yplane_size = (height + 2 * border) * (width + 2 * border);
-    int uvplane_size = ((1 + height) / 2 + border) * ((1 + width) / 2 + border);
-
     if (ybf)
     {
+        int y_stride = ((width + 2 * border) + 31) & ~31;
+        int yplane_size = (height + 2 * border) * y_stride;
+        /** There is currently a bunch of code which assumes
+          *  uv_stride == y_stride/2, so enforce this here. */
+        int uv_width = width >> 1;
+        int uv_height = height >> 1;
+        int uv_stride = y_stride >> 1;
+        int uvplane_size = ((1 + height) / 2 + border) * uv_stride;
+
         vp8_yv12_de_alloc_frame_buffer(ybf);
 
+        /** Only support allocating buffers that have a height and width that
+          *  are multiples of 16, and a border that's a multiple of 32.
+          * The border restriction is required to get 16-byte alignment of the
+          *  start of the chroma rows without intoducing an arbitrary gap
+          *  between planes, which would break the semantics of things like
+          *  vpx_img_set_rect(). */
+        if ((width & 0xf) | (height & 0xf) | (border & 0x1f))
+            return -3;
+
         ybf->y_width  = width;
         ybf->y_height = height;
-        ybf->y_stride = width + 2 * border;
+        ybf->y_stride = y_stride;
 
-        ybf->uv_width = (1 + width) / 2;
-        ybf->uv_height = (1 + height) / 2;
-        ybf->uv_stride = ybf->uv_width + border;
+        ybf->uv_width = uv_width;
+        ybf->uv_height = uv_height;
+        ybf->uv_stride = uv_stride;
 
         ybf->border = border;
         ybf->frame_size = yplane_size + 2 * uvplane_size;
 
         /* Added 2 extra lines to framebuffer so that copy12x12 doesn't fail
          * when we have a large motion vector in V on the last v block.
          * Note : We never use these pixels anyway so this doesn't hurt.
          */
-        ybf->buffer_alloc = (unsigned char *) duck_memalign(32,  ybf->frame_size + (ybf->y_stride * 2) + 32, 0);
+        ybf->buffer_alloc = (unsigned char *) vpx_memalign(32,  ybf->frame_size);
 
         if (ybf->buffer_alloc == NULL)
             return -1;
 
-        ybf->y_buffer = ybf->buffer_alloc + (border * ybf->y_stride) + border;
-
-        if (yplane_size & 0xf)
-            yplane_size += 16 - (yplane_size & 0xf);
-
-        ybf->u_buffer = ybf->buffer_alloc + yplane_size + (border / 2  * ybf->uv_stride) + border / 2;
-        ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size + (border / 2  * ybf->uv_stride) + border / 2;
+        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;
     }
     else
     {
         return -2;
     }
 
     return 0;
 }