summaryrefslogtreecommitdiff
path: root/va/va_fool.c
diff options
context:
space:
mode:
authorAustin Yuan <shengquan.yuan@gmail.com>2010-10-28 07:26:04 +0800
committerAustin Yuan <shengquan.yuan@gmail.com>2010-10-28 07:26:04 +0800
commit7d6bbcfc7709864184a9c56bfbbe4144c4d6c0c2 (patch)
tree2f655eeb28c190c5048948527b9b41df79408388 /va/va_fool.c
parent881b49c5f154ee6603eee4aebb8becae6097a4bd (diff)
downloadlibva-7d6bbcfc7709864184a9c56bfbbe4144c4d6c0c2.tar.gz
Added the missing fileslibva-1.0.6
Diffstat (limited to 'va/va_fool.c')
-rw-r--r--va/va_fool.c545
1 files changed, 545 insertions, 0 deletions
diff --git a/va/va_fool.c b/va/va_fool.c
new file mode 100644
index 0000000..519304d
--- /dev/null
+++ b/va/va_fool.c
@@ -0,0 +1,545 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#define _GNU_SOURCE 1
+#include "va.h"
+#include "va_backend.h"
+#include "va_trace.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <time.h>
+
+#include "va_fool_264.h"
+
+
+/*
+ * Do dummy decode/encode, ignore the input data
+ * In order to debug memory leak or low performance issues, we need to isolate driver problems
+ * We export env "VA_FOOL", with which, we can do fake decode/encode:
+ *
+ * LIBVA_FOOL_DECODE:
+ * . if set, decode does nothing, but fill in some YUV data
+ * LIBVA_FOOL_ENCODE:
+ * . if set, encode does nothing, but fill in a hard-coded 720P clip into coded buffer.
+ * . VA CONTEXT/CONFIG/SURFACE will call into drivers, but VA Buffer creation is done in here
+ * . Bypass all ~SvaBeginPic/vaRenderPic/vaEndPic~T
+ * LIBVA_FOOL_POSTP:
+ * . if set, do nothing for vaPutSurface
+ */
+
+
+/* global settings */
+
+/* LIBVA_FOOL_DECODE/LIBVA_FOOL_ENCODE/LIBVA_FOOL_POSTP */
+static int fool_decode = 0;
+static int fool_encode = 0;
+int fool_postp = 0;
+
+#define FOOL_CONTEXT_MAX 4
+/* per context settings */
+static struct _fool_context {
+ VADisplay dpy; /* should use context as the key */
+
+ VAProfile fool_profile; /* current profile for buffers */
+ VAEntrypoint fool_entrypoint; /* current entrypoint */
+
+ FILE *fool_fp_codedclip; /* load a clip from disk for fooling encode*/
+
+ /* all buffers with same type share one malloc-ed memory
+ * bufferID = (buffer numbers with the same type << 8) || type
+ * the malloc-ed memory can be find by fool_buf[bufferID & 0xff]
+ * the size is ignored here
+ */
+ char *fool_buf[VABufferTypeMax]; /* memory of fool buffers */
+ unsigned int fool_buf_size[VABufferTypeMax]; /* size of memory of fool buffers */
+ unsigned int fool_buf_count[VABufferTypeMax]; /* count of created buffers */
+ VAContextID context;
+} fool_context[FOOL_CONTEXT_MAX] = { {0} }; /* trace five context at the same time */
+
+#define FOOL_DECODE(idx) (fool_decode && (fool_context[idx].fool_entrypoint == VAEntrypointVLD))
+#define FOOL_ENCODE(idx) \
+(fool_encode \
+ && (fool_context[idx].fool_entrypoint == VAEntrypointEncSlice) \
+ && (fool_context[idx].fool_profile >= VAProfileH264Baseline) \
+ && (fool_context[idx].fool_profile <= VAProfileH264High))
+
+
+
+#define DPY2INDEX(dpy) \
+ int idx; \
+ \
+ for (idx = 0; idx < FOOL_CONTEXT_MAX; idx++) \
+ if (fool_context[idx].dpy == dpy) \
+ break; \
+ \
+ if (idx == FOOL_CONTEXT_MAX) \
+ return 0; /* let driver go */ \
+
+/* Prototype declarations (functions defined in va.c) */
+
+void va_errorMessage(const char *msg, ...);
+void va_infoMessage(const char *msg, ...);
+
+int va_parseConfig(char *env, char *env_value);
+
+VAStatus vaBufferInfo(
+ VADisplay dpy,
+ VAContextID context, /* in */
+ VABufferID buf_id, /* in */
+ VABufferType *type, /* out */
+ unsigned int *size, /* out */
+ unsigned int *num_elements /* out */
+);
+
+VAStatus vaLockSurface(VADisplay dpy,
+ VASurfaceID surface,
+ unsigned int *fourcc, /* following are output argument */
+ unsigned int *luma_stride,
+ unsigned int *chroma_u_stride,
+ unsigned int *chroma_v_stride,
+ unsigned int *luma_offset,
+ unsigned int *chroma_u_offset,
+ unsigned int *chroma_v_offset,
+ unsigned int *buffer_name,
+ void **buffer
+);
+
+VAStatus vaUnlockSurface(VADisplay dpy,
+ VASurfaceID surface
+);
+
+
+void va_FoolInit(VADisplay dpy)
+{
+ char env_value[1024];
+ int fool_index = 0;
+
+ for (fool_index = 0; fool_index < FOOL_CONTEXT_MAX; fool_index++)
+ if (fool_context[fool_index].dpy == 0)
+ break;
+
+ if (fool_index == FOOL_CONTEXT_MAX)
+ return;
+
+ if (va_parseConfig("LIBVA_FOOL_POSTP", NULL) == 0) {
+ fool_postp = 1;
+ va_infoMessage("LIBVA_FOOL_POSTP is on, dummy vaPutSurface\n");
+ }
+
+
+ if (va_parseConfig("LIBVA_FOOL_DECODE", NULL) == 0) {
+ fool_decode = 1;
+ va_infoMessage("LIBVA_FOOL_DECODE is on, dummy decode\n");
+ }
+
+
+ if (va_parseConfig("LIBVA_FOOL_ENCODE", &env_value[0]) == 0) {
+ FILE *tmp = fopen(env_value, "r");
+
+ if (tmp)
+ fool_context[fool_index].fool_fp_codedclip = tmp;
+
+ fool_encode = 1;
+
+ va_infoMessage("LIBVA_FOOL_ENCODE is on, dummy encode\n");
+ }
+
+ if (fool_encode || fool_decode)
+ fool_context[fool_index].dpy = dpy;
+}
+
+
+int va_FoolEnd(VADisplay dpy)
+{
+ int i;
+
+ DPY2INDEX(dpy);
+
+ for (i = 0; i < VABufferTypeMax; i++) /* free memory */
+ if (fool_context[idx].fool_buf[i])
+ free(fool_context[idx].fool_buf[i]);
+
+ memset(&fool_context[idx], sizeof(struct _fool_context), 0);
+ return 0;
+}
+
+int va_FoolCodedBuf(VADisplay dpy)
+{
+ /* do nothing */
+ return 0;
+}
+
+
+int va_FoolCreateConfig(
+ VADisplay dpy,
+ VAProfile profile,
+ VAEntrypoint entrypoint,
+ VAConfigAttrib *attrib_list,
+ int num_attribs,
+ VAConfigID *config_id /* out */
+)
+{
+ DPY2INDEX(dpy);
+
+ /* call into driver level to allocate real context/surface/buffers, etc */
+ fool_context[idx].fool_profile = profile;
+ fool_context[idx].fool_entrypoint = entrypoint;
+ return 0;
+}
+
+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;
+}
+
+
+int va_FoolCreateSurfaces(
+ VADisplay dpy,
+ int width,
+ int height,
+ int format,
+ int num_surfaces,
+ VASurfaceID *surfaces /* out */
+)
+{
+ int i;
+ unsigned int fourcc; /* following are output argument */
+ unsigned int luma_stride;
+ unsigned int chroma_u_stride;
+ unsigned int chroma_v_stride;
+ unsigned int luma_offset;
+ unsigned int chroma_u_offset;
+ unsigned int chroma_v_offset;
+ unsigned int buffer_name;
+ void *buffer = NULL;
+ unsigned char *Y_data, *U_data, *V_data;
+
+ int box_width = num_surfaces/2;
+ int row_shift = 0;
+ VAStatus va_status;
+
+ DPY2INDEX(dpy);
+
+ if (FOOL_DECODE(idx)) {
+ /* call into driver level to allocate real context/surface/buffers, etc
+ * fill in the YUV data, will be overwrite if it is encode context
+ */
+ for (i = 0; i < num_surfaces; i++) {
+ /* fool decoder: fill with auto-generated YUV data */
+ va_status = vaLockSurface(dpy, surfaces[i], &fourcc,
+ &luma_stride, &chroma_u_stride, &chroma_v_stride,
+ &luma_offset, &chroma_u_offset, &chroma_v_offset,
+ &buffer_name, &buffer);
+
+ if (va_status != VA_STATUS_SUCCESS)
+ return 0;
+
+ if (!buffer) {
+ vaUnlockSurface(dpy, surfaces[i]);
+ return 0;
+ }
+
+ Y_data = buffer;
+
+ /* UV should be same for NV12 */
+ U_data = buffer + chroma_u_offset;
+ V_data = buffer + chroma_v_offset;
+
+ yuvgen_planar(width, height,
+ Y_data, luma_stride,
+ U_data, chroma_v_stride,
+ V_data, chroma_v_stride,
+ (fourcc==VA_FOURCC_NV12),
+ box_width, row_shift, 0);
+
+ vaUnlockSurface(dpy, surfaces[i]);
+
+ row_shift++;
+ if (row_shift==(2*box_width))
+ row_shift= 0;
+ }
+ return 0; /* the return value is ignored */
+ }
+ return 0; /* the return value is ignored */
+}
+
+VAStatus va_FoolCreateBuffer (
+ VADisplay dpy,
+ VAContextID context, /* in */
+ VABufferType type, /* in */
+ unsigned int size, /* in */
+ unsigned int num_elements, /* in */
+ void *data, /* in */
+ VABufferID *buf_id /* out */
+)
+{
+ DPY2INDEX(dpy);
+
+ if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) { /* fool buffer creation */
+ int new_size = size * num_elements;
+
+ if (type == VAEncCodedBufferType) /* only a VACodedBufferSegment */
+ new_size = sizeof(VACodedBufferSegment);
+
+ if (fool_context[idx].fool_buf_size[type] == 0)
+ fool_context[idx].fool_buf[type] = calloc(1, new_size);
+ else if (fool_context[idx].fool_buf_size[type] <= new_size)
+ fool_context[idx].fool_buf[type] = realloc(fool_context[idx].fool_buf, new_size);
+
+ if (fool_context[idx].fool_buf[type] == NULL) {
+ va_FoolEnd(dpy);
+ return 0; /* let driver go */
+ }
+
+ /* because we ignore the vaRenderPicture,
+ * all buffers with same type share same real memory
+ * bufferID = (buffer count << 8) | type
+ */
+ fool_context[idx].fool_buf_count[type]++;
+ *buf_id = (fool_context[idx].fool_buf_count[type] << 8) | type;
+
+ return 1; /* don't call into driver */
+ }
+
+ return 0; /* let driver go ... */
+}
+
+
+VAStatus va_FoolMapBuffer (
+ VADisplay dpy,
+ VABufferID buf_id, /* in */
+ void **pbuf /* out */
+)
+{
+ VABufferType type;
+ unsigned int size;
+ unsigned int num_elements;
+ DPY2INDEX(dpy);
+
+ if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) { /* fool buffer creation */
+ unsigned int buf_idx = buf_id & 0xff;
+
+ /*Image buffer?*/
+ vaBufferInfo(dpy, fool_context[idx].context, buf_id, &type, &size, &num_elements);
+ if (type == VAImageBufferType && FOOL_ENCODE(idx))
+ return 0;
+
+ /* buf_id is the buffer type */
+ if (fool_context[idx].fool_buf[buf_idx] != NULL)
+ *pbuf = fool_context[idx].fool_buf[buf_idx];
+ else
+ *pbuf = NULL;
+
+ /* expect APP to MapBuffer when get the the coded data */
+ if (*pbuf && (buf_idx == VAEncCodedBufferType)) { /* it is coded buffer */
+ /* should read from a clip, here we use the hardcoded h264_720p_nal */
+ memcpy(*pbuf, &h264_720p_nal[h264_720p_nal_idx], sizeof(VACodedBufferSegment));
+ h264_720p_nal_idx++;
+ if (h264_720p_nal_idx == H264_720P_NAL_NUMBER)
+ h264_720p_nal_idx = 0; /* reset to 0 */
+ }
+
+ return 1; /* don't call into driver */
+ }
+
+ return 0; /* let driver go ... */
+}
+
+
+int va_FoolBeginPicture(
+ VADisplay dpy,
+ VAContextID context,
+ VASurfaceID render_target
+)
+{
+ DPY2INDEX(dpy);
+
+ if (FOOL_ENCODE(idx) || FOOL_DECODE(idx))
+ {
+ if (fool_context[idx].context == 0)
+ fool_context[idx].context = context;
+ return 1; /* don't call into driver level */
+ }
+
+ return 0; /* let driver go ... */
+}
+
+int va_FoolRenderPicture(
+ VADisplay dpy,
+ VAContextID context,
+ VABufferID *buffers,
+ int num_buffers
+)
+{
+ DPY2INDEX(dpy);
+
+ if (FOOL_ENCODE(idx) || FOOL_DECODE(idx))
+ return 1; /* don't call into driver level */
+
+ return 0; /* let driver go ... */
+}
+
+
+int va_FoolEndPicture(
+ VADisplay dpy,
+ VAContextID context
+)
+{
+ DPY2INDEX(dpy);
+
+ /* don't call into driver level */
+
+ /* do real fooling operation here */
+
+ /* only support H264 encoding currently */
+ if (FOOL_ENCODE(idx)) {
+ /* expect vaMapBuffer will handle it
+ * or else, need to save the codedbuf ID,
+ * and fool encode it here
+ */
+ /* va_FoolCodedBuf(dpy); */
+ return 1; /* don't call into driver level */
+ }
+
+ if (FOOL_DECODE(idx))
+ return 1; /* don't call into driver level */
+
+ return 0; /* let driver go ... */
+}
+
+int va_FoolSyncSurface(
+ VADisplay dpy,
+ VASurfaceID render_target)
+{
+ DPY2INDEX(dpy);
+ /*Fill in black and white squares. */
+ if (FOOL_DECODE(idx) || FOOL_DECODE(idx))
+ {
+ return 1;
+ }
+
+ return 0;
+
+}
+
+VAStatus va_FoolUnmapBuffer (
+ VADisplay dpy,
+ VABufferID buf_id /* in */
+)
+{
+ DPY2INDEX(dpy);
+
+ if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) { /* fool buffer creation */
+ return 1;
+ }
+ return 0;
+}
+
+VAStatus va_FoolQuerySubpictureFormats (
+ VADisplay dpy,
+ VAImageFormat *format_list,
+ unsigned int *flags,
+ unsigned int *num_formats
+)
+{
+ DPY2INDEX(dpy);
+
+ if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) {
+ if (num_formats)
+ *num_formats = 0;
+ return 1;
+ }
+ return 0;
+}
+