| /* |
| * Copyright (c) 2008-2009 Intel Corporation. All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the |
| * "Software"), to deal in the Software without restriction, including |
| * without limitation the rights to use, copy, modify, merge, publish, |
| * distribute, sub license, and/or sell copies of the Software, and to |
| * permit persons to whom the Software is furnished to do so, subject to |
| * the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the |
| * next paragraph) shall be included in all copies or substantial portions |
| * of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
| * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR |
| * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| |
| |
| static int yuvgen_planar(int width, int height, |
| unsigned char *Y_start, int Y_pitch, |
| unsigned char *U_start, int U_pitch, |
| unsigned char *V_start, int V_pitch, |
| int UV_interleave, int box_width, int row_shift, |
| int field) |
| { |
| int row; |
| |
| /* copy Y plane */ |
| for (row=0;row<height;row++) { |
| unsigned char *Y_row = Y_start + row * Y_pitch; |
| int jj, xpos, ypos; |
| |
| ypos = (row / box_width) & 0x1; |
| |
| /* fill garbage data into the other field */ |
| if (((field == VA_TOP_FIELD) && (row &1)) |
| || ((field == VA_BOTTOM_FIELD) && ((row &1)==0))) { |
| memset(Y_row, 0xff, width); |
| continue; |
| } |
| |
| for (jj=0; jj<width; jj++) { |
| xpos = ((row_shift + jj) / box_width) & 0x1; |
| |
| if ((xpos == 0) && (ypos == 0)) |
| Y_row[jj] = 0xeb; |
| if ((xpos == 1) && (ypos == 1)) |
| Y_row[jj] = 0xeb; |
| |
| if ((xpos == 1) && (ypos == 0)) |
| Y_row[jj] = 0x10; |
| if ((xpos == 0) && (ypos == 1)) |
| Y_row[jj] = 0x10; |
| } |
| } |
| |
| /* copy UV data */ |
| for( row =0; row < height/2; row++) { |
| unsigned short value = 0x80; |
| |
| /* fill garbage data into the other field */ |
| if (((field == VA_TOP_FIELD) && (row &1)) |
| || ((field == VA_BOTTOM_FIELD) && ((row &1)==0))) { |
| value = 0xff; |
| } |
| |
| if (UV_interleave) { |
| unsigned short *UV_row = (unsigned short *)(U_start + row * U_pitch); |
| |
| memset(UV_row, value, width); |
| } else { |
| unsigned char *U_row = U_start + row * U_pitch; |
| unsigned char *V_row = V_start + row * V_pitch; |
| |
| memset (U_row,value,width/2); |
| memset (V_row,value,width/2); |
| } |
| } |
| |
| return 0; |
| } |
| |
| static int upload_surface(VADisplay va_dpy, VASurfaceID surface_id, |
| int box_width, int row_shift, |
| int field) |
| { |
| VAImage surface_image; |
| void *surface_p=NULL, *U_start,*V_start; |
| VAStatus va_status; |
| |
| va_status = vaDeriveImage(va_dpy,surface_id,&surface_image); |
| CHECK_VASTATUS(va_status,"vaDeriveImage"); |
| |
| vaMapBuffer(va_dpy,surface_image.buf,&surface_p); |
| assert(VA_STATUS_SUCCESS == va_status); |
| |
| U_start = surface_p + surface_image.offsets[1]; |
| V_start = surface_p + surface_image.offsets[2]; |
| |
| /* assume surface is planar format */ |
| yuvgen_planar(surface_image.width, surface_image.height, |
| surface_p, surface_image.pitches[0], |
| U_start, surface_image.pitches[1], |
| V_start, surface_image.pitches[2], |
| (surface_image.format.fourcc==VA_FOURCC_NV12), |
| box_width, row_shift, field); |
| |
| vaUnmapBuffer(va_dpy,surface_image.buf); |
| |
| vaDestroyImage(va_dpy,surface_image.image_id); |
| |
| return 0; |
| } |