LOCAL_SRC_FILES := \
va.c \
va_trace.c \
- va_fool.c \
- va_fool_getframe.c
+ va_fool.c
LOCAL_CFLAGS += \
-DANDROID \
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libva
-LOCAL_SHARED_LIBRARIES := libdl libdrm libcutils
+LOCAL_SHARED_LIBRARIES := libdl libdrm libcutils liblog
include $(BUILD_SHARED_LIBRARY)
libva_source_c = \
va.c \
va_fool.c \
- va_fool_getframe.c \
va_trace.c \
$(NULL)
#define _GNU_SOURCE 1
#include "va.h"
#include "va_backend.h"
+#include "va_trace.h"
+#include "va_fool.h"
#include "va_android.h"
#include "va_dricommon.h" /* needs some helper functions from this file */
#include <stdio.h>
);
}
-#define VA_TRACE(trace_func,...) \
- if (trace_flag) { \
- trace_func(__VA_ARGS__); \
- }
-
VAStatus vaPutSurface (
VADisplay dpy,
VASurfaceID surface,
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
- VA_TRACE(va_TracePutSurface, dpy, surface, static_cast<void*>(&draw), srcx, srcy, srcw, srch,
- destx, desty, destw, desth,
- cliprects, number_cliprects, flags );
+ VA_TRACE_LOG(va_TracePutSurface, dpy, surface, static_cast<void*>(&draw), srcx, srcy, srcw, srch,
+ destx, desty, destw, desth,
+ cliprects, number_cliprects, flags );
return ctx->vtable->vaPutSurface( ctx, surface, static_cast<void*>(&draw), srcx, srcy, srcw, srch,
destx, desty, destw, desth,
#define CHECK_MAXIMUM(s, ctx, var) if (!va_checkMaximum(ctx->max_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
#define CHECK_STRING(s, ctx, var) if (!va_checkString(ctx->str_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
-extern int trace_flag;
-#define VA_TRACE(trace_func,...) \
- if (trace_flag) { \
- trace_func(__VA_ARGS__); \
- }
-
-extern int fool_decode;
-extern int fool_encode;
-#define VA_FOOL(fool_func,...) \
- if (fool_decode || fool_encode) { \
- ret = fool_func(__VA_ARGS__); \
- }
/*
* read a config "env" for libva.conf or from environment setting
char oneline[1024];
FILE *fp=NULL;
-
if (env == NULL)
return 1;
static Bool va_checkVtable(void *ptr, char *function)
{
- if (!ptr)
- {
+ if (!ptr) {
va_errorMessage("No valid vtable entry for va%s\n", function);
return False;
}
static Bool va_checkMaximum(int value, char *variable)
{
- if (!value)
- {
+ if (!value) {
va_errorMessage("Failed to define max_%s in init\n", variable);
return False;
}
static Bool va_checkString(const char* value, char *variable)
{
- if (!value)
- {
+ if (!value) {
va_errorMessage("Failed to define str_%s in init\n", variable);
return False;
}
char *driver_dir;
if (geteuid() == getuid())
- {
/* don't allow setuid apps to use LIBVA_DRIVERS_PATH */
search_path = getenv("LIBVA_DRIVERS_PATH");
- }
if (!search_path)
- {
search_path = VA_DRIVERS_PATH;
- }
search_path = strdup((const char *)search_path);
- driver_dir = strtok_r((const char *)search_path, ":", &saveptr);
- while(driver_dir)
- {
+ driver_dir = strtok_r(search_path, ":", &saveptr);
+ while (driver_dir) {
void *handle = NULL;
char *driver_path = (char *) malloc( strlen(driver_dir) +
strlen(driver_name) +
#else
handle = dlopen( driver_path, RTLD_NOW| RTLD_GLOBAL);
#endif
- if (!handle)
- {
+ if (!handle) {
/* Don't give errors for non-existing files */
if (0 == access( driver_path, F_OK))
- {
va_errorMessage("dlopen of %s failed: %s\n", driver_path, dlerror());
- }
- }
- else
- {
+ } else {
VADriverInit init_func;
init_func = (VADriverInit) dlsym(handle, VA_DRIVER_INIT_FUNC_S);
- if (!init_func)
- {
+ if (!init_func) {
va_errorMessage("%s has no function %s\n", driver_path, VA_DRIVER_INIT_FUNC_S);
dlclose(handle);
- }
- else
- {
+ } else {
struct VADriverVTable *vtable = ctx->vtable;
vaStatus = VA_STATUS_SUCCESS;
if (VA_STATUS_SUCCESS == vaStatus)
vaStatus = (*init_func)(ctx);
- if (VA_STATUS_SUCCESS == vaStatus)
- {
+ if (VA_STATUS_SUCCESS == vaStatus) {
CHECK_MAXIMUM(vaStatus, ctx, profiles);
CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
CHECK_MAXIMUM(vaStatus, ctx, attributes);
CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
}
- if (VA_STATUS_SUCCESS != vaStatus)
- {
+ if (VA_STATUS_SUCCESS != vaStatus) {
va_errorMessage("%s init failed\n", driver_path);
dlclose(handle);
}
if (VA_STATUS_SUCCESS == vaStatus)
- {
ctx->handle = handle;
- }
free(driver_path);
break;
}
VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
{
VADriverContextP ctx;
- if( !vaDisplayIsValid(dpy) )
+ if (!vaDisplayIsValid(dpy))
return NULL;
ctx = CTX(dpy);
*/
const char *vaErrorStr(VAStatus error_status)
{
- switch(error_status)
- {
+ switch(error_status) {
case VA_STATUS_SUCCESS:
return "success (no error)";
case VA_STATUS_ERROR_OPERATION_FAILED:
va_infoMessage("libva version %s\n", VA_VERSION_S);
driver_name_env = getenv("LIBVA_DRIVER_NAME");
- if (driver_name_env && geteuid() == getuid())
- {
+ if (driver_name_env && geteuid() == getuid()) {
/* Don't allow setuid apps to use LIBVA_DRIVER_NAME */
driver_name = strdup(driver_name_env);
vaStatus = VA_STATUS_SUCCESS;
va_infoMessage("User requested driver '%s'\n", driver_name);
- }
- else
- {
+ } else {
vaStatus = va_getDriverName(dpy, &driver_name);
va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
}
- if (VA_STATUS_SUCCESS == vaStatus)
- {
+ if (VA_STATUS_SUCCESS == vaStatus) {
vaStatus = va_openDriver(dpy, driver_name);
va_infoMessage("va_openDriver() returns %d\n", vaStatus);
if (driver_name)
free(driver_name);
- VA_TRACE(va_TraceInitialize, dpy, major_version, minor_version);
+ VA_TRACE_LOG(va_TraceInitialize, dpy, major_version, minor_version);
return vaStatus;
}
if (VA_STATUS_SUCCESS == vaStatus)
pDisplayContext->vaDestroy(pDisplayContext);
- VA_TRACE(va_TraceTerminate, dpy);
+ VA_TRACE_LOG(va_TraceTerminate, dpy);
va_TraceEnd(dpy);
VADisplay dpy
)
{
- if( !vaDisplayIsValid(dpy) )
+ if (!vaDisplayIsValid(dpy))
return NULL;
return CTX(dpy)->str_vendor;
VADisplay dpy
)
{
- if( !vaDisplayIsValid(dpy) )
+ if (!vaDisplayIsValid(dpy))
return 0;
return CTX(dpy)->max_profiles;
VADisplay dpy
)
{
- if( !vaDisplayIsValid(dpy) )
+ if (!vaDisplayIsValid(dpy))
return 0;
return CTX(dpy)->max_entrypoints;
VADisplay dpy
)
{
- if( !vaDisplayIsValid(dpy) )
+ if (!vaDisplayIsValid(dpy))
return 0;
return CTX(dpy)->max_attributes;
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
- VA_FOOL(va_FoolCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
+ vaStatus = ctx->vtable->vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
- vaStatus = ctx->vtable->vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
-
- VA_TRACE(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
+ /* record the current entrypoint for further trace/fool determination */
+ VA_TRACE_FUNC(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
+ VA_FOOL_FUNC(va_FoolCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
return vaStatus;
}
vaStatus = ctx->vtable->vaCreateSurfaces( ctx, width, height, format, num_surfaces, surfaces );
- VA_TRACE(va_TraceCreateSurface, dpy, width, height, format, num_surfaces, surfaces);
-
- VA_FOOL(va_FoolCreateSurfaces, dpy, width, height, format, num_surfaces, surfaces);
+ VA_TRACE_LOG(va_TraceCreateSurface, dpy, width, height, format, num_surfaces, surfaces);
return vaStatus;
}
vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height,
flag, render_targets, num_render_targets, context );
- VA_TRACE(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
+ /* keep current encode/decode resoluton */
+ VA_TRACE_FUNC(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
return vaStatus;
}
ctx = CTX(dpy);
int ret = 0;
- VA_FOOL(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
+ VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
if (ret)
return VA_STATUS_SUCCESS;
VADriverContextP ctx;
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
-
+
+ VA_FOOL_RETURN();
+
return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
}
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
-
- VA_FOOL(va_FoolMapBuffer, dpy, buf_id, pbuf);
+
+ VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
if (ret)
return VA_STATUS_SUCCESS;
-
+
va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
- if (va_status == VA_STATUS_SUCCESS)
- VA_TRACE(va_TraceMapBuffer, dpy, buf_id, pbuf);
+ VA_TRACE_LOG(va_TraceMapBuffer, dpy, buf_id, pbuf);
return va_status;
}
ctx = CTX(dpy);
int ret = 0;
- VA_FOOL(va_FoolUnmapBuffer, dpy, buf_id);
+ VA_FOOL_FUNC(va_FoolUnmapBuffer, dpy, buf_id);
if (ret)
return VA_STATUS_SUCCESS;
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
+ VA_FOOL_RETURN();
+
return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
}
)
{
VADriverContextP ctx;
+ int ret = 0;
+
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
+ VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
+ if (ret)
+ return VA_STATUS_SUCCESS;
+
return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
}
)
{
VADriverContextP ctx;
+ VAStatus va_status;
int ret = 0;
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
- VA_TRACE(va_TraceBeginPicture, dpy, context, render_target);
-
- VA_FOOL(va_FoolBeginPicture, dpy, context, render_target);
- if (ret)
- return VA_STATUS_SUCCESS;
-
- return ctx->vtable->vaBeginPicture( ctx, context, render_target );
+ VA_TRACE_FUNC(va_TraceBeginPicture, dpy, context, render_target);
+ VA_FOOL_RETURN();
+
+ va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
+
+ return va_status;
}
VAStatus vaRenderPicture (
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
- VA_FOOL(va_FoolRenderPicture, dpy, context, buffers, num_buffers);
- if (ret)
- return VA_STATUS_SUCCESS;
-
- VA_TRACE(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
+ VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
+ VA_FOOL_RETURN();
return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
}
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
- VA_FOOL(va_FoolEndPicture, dpy, context);
- if (ret) {
- VA_TRACE(va_TraceEndPicture, dpy, context);
- return VA_STATUS_SUCCESS;
- }
+ /* dump encode source surface */
+ VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 0);
+ /* return directly if do dummy operation */
+ VA_FOOL_RETURN();
va_status = ctx->vtable->vaEndPicture( ctx, context );
-
- VA_TRACE(va_TraceEndPicture, dpy, context);
+ /* dump decode dest surface */
+ VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 1);
return va_status;
}
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
- VA_FOOL(va_FoolSyncSurface, dpy, render_target);
- if (ret)
- return VA_STATUS_SUCCESS;
-
va_status = ctx->vtable->vaSyncSurface( ctx, render_target );
- VA_TRACE(va_TraceSyncSurface, dpy, render_target);
+ VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
return va_status;
}
va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status );
- VA_TRACE(va_TraceQuerySurfaceStatus, dpy, render_target, status);
+ VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
return va_status;
}
va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info );
- VA_TRACE(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
+ VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
return va_status;
}
VADisplay dpy
)
{
- if( !vaDisplayIsValid(dpy) )
+ if (!vaDisplayIsValid(dpy))
return 0;
return CTX(dpy)->max_image_formats;
VADisplay dpy
)
{
- if( !vaDisplayIsValid(dpy) )
+ if (!vaDisplayIsValid(dpy))
return 0;
return CTX(dpy)->max_subpic_formats;
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
- VA_FOOL(va_FoolQuerySubpictureFormats, dpy, format_list, flags, num_formats);
- if (ret)
- return VA_STATUS_SUCCESS;
-
return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
}
{
int tmp;
- if( !vaDisplayIsValid(dpy) )
+ if (!vaDisplayIsValid(dpy))
return 0;
tmp = CTX(dpy)->max_display_attributes;
- VA_TRACE(va_TraceMaxNumDisplayAttributes, dpy, tmp);
+ VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
return tmp;
}
)
{
VADriverContextP ctx;
- CHECK_DISPLAY(dpy);
- ctx = CTX(dpy);
-
VAStatus va_status;
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
- VA_TRACE(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
+ VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
return va_status;
)
{
VADriverContextP ctx;
+ VAStatus va_status;
+
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
-
- VAStatus va_status;
-
va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
- VA_TRACE(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
+ VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
return va_status;
}
)
{
VADriverContextP ctx;
+ VAStatus va_status;
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
- VA_TRACE(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
-
+ va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
+ VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
- return ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
+ return va_status;
}
VAStatus vaLockSurface(VADisplay dpy,
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
+#include <fcntl.h>
/*
* Do dummy decode/encode, ignore the input data
* 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=<clip name>:
- * . if set, encode does nothing, but fill in the coded buffer from a H264 clip.
- * . VA CONTEXT/CONFIG/SURFACE will call into drivers, but VA Buffer creation is done in here
- * . Bypass all "vaBeginPic/vaRenderPic/vaEndPic"
+ * . if set, decode does nothing
+ * LIBVA_FOOL_ENCODE=<framename>:
+ * . if set, encode does nothing, but fill in the coded buffer from the content of files with
+ * name framename.0,framename.1,framename.2, ..., framename.N, framename.N,framename.N,...
+ * LIBVA_FOOL_JPEG=<framename>:fill the content of filename to codedbuf for jpeg encoding
* LIBVA_FOOL_POSTP:
* . if set, do nothing for vaPutSurface
*/
/* global settings */
-
-/* LIBVA_FOOL_DECODE/LIBVA_FOOL_ENCODE/LIBVA_FOOL_POSTP */
-int fool_decode = 0;
-int fool_encode = 0;
+int fool_codec = 0;
int fool_postp = 0;
-
-
-#define NAL_BUF_SIZE 65536 // maximum NAL unit size
-#define RING_BUF_SIZE 8192 // input ring buffer size, MUST be a power of two!
-#define MAX_FRAME 16
-#define SLICE_NUM 4
-
#define FOOL_CONTEXT_MAX 4
+
+#define FOOL_BUFID_MAGIC 0x12345600
+#define FOOL_BUFID_MASK 0xffffff00
/* 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 */
+ char *fn_enc;/* file pattern with codedbuf content for encode */
+ char *segbuf_enc; /* the segment buffer of coded buffer, load frome fn_enc */
+ int file_count;
- FILE *fool_fp_codedclip; /* load a clip from disk for fooling encode*/
- char *frame_buf;
- VACodedBufferSegment *codebuf;
+ char *fn_jpg;/* file name of JPEG fool with codedbuf content */
+ char *segbuf_jpg; /* the segment buffer of coded buffer, load frome fn_jpg */
+ VAEntrypoint entrypoint; /* current entrypoint */
+
/* 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]
*/
char *fool_buf[VABufferTypeMax]; /* memory of fool buffers */
unsigned int fool_buf_size[VABufferTypeMax]; /* size of memory of fool buffers */
+ unsigned int fool_buf_element[VABufferTypeMax]; /* element count of created 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))
-
-
+} fool_context[FOOL_CONTEXT_MAX]; /* trace five context at the same time */
#define DPY2INDEX(dpy) \
int idx; \
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
-);
-
+int va_parseConfig(char *env, char *env_value);
void va_FoolInit(VADisplay dpy)
{
if (fool_index == FOOL_CONTEXT_MAX)
return;
+ memset(&fool_context[fool_index], 0, sizeof(struct _fool_context));
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;
+ fool_codec |= VA_FOOL_FLAG_DECODE;
va_infoMessage("LIBVA_FOOL_DECODE is on, dummy decode\n");
}
-
-
if (va_parseConfig("LIBVA_FOOL_ENCODE", &env_value[0]) == 0) {
- fool_context[fool_index].fool_fp_codedclip = fopen(env_value, "r");
-
- if (fool_context[fool_index].fool_fp_codedclip) {
- fool_encode = 1;
- } else
- fool_encode = 0;
-
- if (fool_encode) /* malloc the buffer for fake clip */
- {
- fool_context[fool_index].frame_buf = malloc(MAX_FRAME*SLICE_NUM*NAL_BUF_SIZE*sizeof(char));
- fool_context[fool_index].codebuf = malloc(sizeof(VACodedBufferSegment));
- }
-
- if (fool_context[fool_index].frame_buf == NULL)
- fool_encode = 0;
-
- if (fool_encode)
- va_infoMessage("LIBVA_FOOL_ENCODE is on, dummy encode\n");
-
+ fool_codec |= VA_FOOL_FLAG_ENCODE;
+ fool_context[fool_index].fn_enc = strdup(env_value);
+ va_infoMessage("LIBVA_FOOL_ENCODE is on, load encode data from file with patten %s\n",
+ fool_context[fool_index].fn_enc);
}
-
- if (fool_encode || fool_decode)
+ if (va_parseConfig("LIBVA_FOOL_JPEG", &env_value[0]) == 0) {
+ fool_codec |= VA_FOOL_FLAG_JPEG;
+ fool_context[fool_index].fn_jpg = strdup(env_value);
+ va_infoMessage("LIBVA_FOOL_JPEG is on, load encode data from file with patten %s\n",
+ fool_context[fool_index].fn_jpg);
+ }
+
+ if (fool_codec)
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]);
}
- if (fool_context[idx].fool_fp_codedclip)
- fclose(fool_context[idx].fool_fp_codedclip);
-
- if (fool_context[idx].frame_buf)
- free(fool_context[idx].frame_buf);
+ if (fool_context[idx].segbuf_enc)
+ free(fool_context[idx].segbuf_enc);
+ if (fool_context[idx].segbuf_jpg)
+ free(fool_context[idx].segbuf_jpg);
+ if (fool_context[idx].fn_enc)
+ free(fool_context[idx].fn_enc);
+ if (fool_context[idx].fn_jpg)
+ free(fool_context[idx].fn_jpg);
- if (fool_context[idx].codebuf)
- free(fool_context[idx].codebuf);
-
memset(&fool_context[idx], 0, sizeof(struct _fool_context));
- return 0;
-}
-
-int va_FoolCodedBuf(VADisplay dpy)
-{
- /* do nothing */
+
return 0;
}
{
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;
+ fool_context[idx].entrypoint = entrypoint;
+
+ /*
+ * check fool_codec to align with current context
+ * e.g. fool_codec = decode then for encode, the
+ * vaBegin/vaRender/vaEnd also run into fool path
+ * which is not desired
+ */
+ if (((fool_codec & VA_FOOL_FLAG_DECODE) && (entrypoint == VAEntrypointVLD)) ||
+ ((fool_codec & VA_FOOL_FLAG_ENCODE) && (entrypoint == VAEntrypointEncSlice)) ||
+ ((fool_codec & VA_FOOL_FLAG_JPEG) && (entrypoint == VAEntrypointEncPicture)))
+ ; /* the fool_codec is meaningful */
+ else
+ fool_codec = 0;
+
+ return 0; /* driver continue */
}
-int va_FoolCreateSurfaces(
- VADisplay dpy,
- int width,
- int height,
- int format,
- int num_surfaces,
- VASurfaceID *surfaces /* out */
+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 */
)
{
- 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;
-
+ unsigned int new_size = size * num_elements;
+ unsigned int old_size;
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 */
+ old_size = fool_context[idx].fool_buf_size[type] * fool_context[idx].fool_buf_element[type];
+
+ if (old_size < new_size)
+ fool_context[idx].fool_buf[type] = realloc(fool_context[idx].fool_buf[type], new_size);
+
+ fool_context[idx].fool_buf_size[type] = size;
+ fool_context[idx].fool_buf_element[type] = num_elements;
+ fool_context[idx].fool_buf_count[type]++;
+ /* because we ignore the vaRenderPicture,
+ * all buffers with same type share same real memory
+ * bufferID = (magic number) | type
+ */
+ *buf_id = FOOL_BUFID_MAGIC | type;
+
+ return 1; /* don't call into driver */
}
-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 */
+VAStatus va_FoolBufferInfo(
+ VADisplay dpy,
+ VABufferID buf_id, /* in */
+ VABufferType *type, /* out */
+ unsigned int *size, /* out */
+ unsigned int *num_elements /* out */
)
{
+ unsigned int magic = buf_id & FOOL_BUFID_MASK;
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 */
- }
+ if (magic != FOOL_BUFID_MAGIC)
+ return 0;
- return 0; /* let driver go ... */
+ *type = buf_id & 0xff;
+ *size = fool_context[idx].fool_buf_size[*type];
+ *num_elements = fool_context[idx].fool_buf_element[*type];;
+
+ return 1; /* don't call into driver */
}
-VAStatus va_FoolMapBuffer (
- VADisplay dpy,
- VABufferID buf_id, /* in */
- void **pbuf /* out */
-)
+static int va_FoolFillCodedBufEnc(int idx)
{
- VABufferType type;
- unsigned int size,frame_size = 0;
- 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 */
- /* read from a clip */
- frame_size = va_FoolGetFrame(fool_context[idx].fool_fp_codedclip,
- fool_context[idx].frame_buf);
-
- memset(fool_context[idx].codebuf,0,sizeof(VACodedBufferSegment));
- fool_context[idx].codebuf->size = frame_size;
- fool_context[idx].codebuf->bit_offset = 0;
- fool_context[idx].codebuf->status = 0;
- fool_context[idx].codebuf->reserved = 0;
- fool_context[idx].codebuf->buf = fool_context[idx].frame_buf;
- fool_context[idx].codebuf->next = NULL;
- *pbuf = fool_context[idx].codebuf;
+ char file_name[1024];
+ struct stat file_stat;
+ VACodedBufferSegment *codedbuf;
+ int i, fd = -1;
+
+ /* try file_name.file_count, if fail, try file_name.file_count-- */
+ for (i=0; i<=1; i++) {
+ sprintf(file_name, "%s.%d",
+ fool_context[idx].fn_enc,
+ fool_context[idx].file_count);
+
+ if ((fd = open(file_name, O_RDONLY)) != -1) {
+ fstat(fd, &file_stat);
+ fool_context[idx].file_count++; /* open next file */
+ break;
}
- return 1; /* don't call into driver */
+
+ fool_context[idx].file_count--; /* fall back to previous file */
+ if (fool_context[idx].file_count < 0)
+ fool_context[idx].file_count = 0;
}
+ if (fd != -1) {
+ fool_context[idx].segbuf_enc = realloc(fool_context[idx].segbuf_enc, file_stat.st_size);
+ read(fd, fool_context[idx].segbuf_enc, file_stat.st_size);
+ close(fd);
+ }
+ codedbuf = (VACodedBufferSegment *)fool_context[idx].fool_buf[VAEncCodedBufferType];
+ codedbuf->size = file_stat.st_size;
+ codedbuf->bit_offset = 0;
+ codedbuf->status = 0;
+ codedbuf->reserved = 0;
+ codedbuf->buf = fool_context[idx].segbuf_enc;
+ codedbuf->next = NULL;
- return 0; /* let driver go ... */
+ return 0;
}
-int va_FoolBeginPicture(
- VADisplay dpy,
- VAContextID context,
- VASurfaceID render_target
-)
+static int va_FoolFillCodedBufJPG(int idx)
{
- 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 */
+ struct stat file_stat;
+ VACodedBufferSegment *codedbuf;
+ int i, fd = -1;
+
+ if ((fd = open(fool_context[idx].fn_jpg, O_RDONLY)) != -1)
+ fstat(fd, &file_stat);
+
+ if (fd != -1) {
+ fool_context[idx].segbuf_jpg = realloc(fool_context[idx].segbuf_jpg, file_stat.st_size);
+ read(fd, fool_context[idx].segbuf_jpg, file_stat.st_size);
+ close(fd);
}
+ codedbuf = (VACodedBufferSegment *)fool_context[idx].fool_buf[VAEncCodedBufferType];
+ codedbuf->size = file_stat.st_size;
+ codedbuf->bit_offset = 0;
+ codedbuf->status = 0;
+ codedbuf->reserved = 0;
+ codedbuf->buf = fool_context[idx].segbuf_jpg;
+ codedbuf->next = NULL;
- 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 ... */
+ return 0;
}
-int va_FoolEndPicture(
- VADisplay dpy,
- VAContextID context
-)
+static int va_FoolFillCodedBuf(int idx)
{
- 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 ... */
+ if (fool_context[idx].entrypoint == VAEntrypointEncSlice)
+ va_FoolFillCodedBufEnc(idx);
+ else if (fool_context[idx].entrypoint == VAEntrypointEncPicture)
+ va_FoolFillCodedBufJPG(idx);
+
+ return 0;
}
-int va_FoolSyncSurface(
- VADisplay dpy,
- VASurfaceID render_target
+
+VAStatus va_FoolMapBuffer(
+ VADisplay dpy,
+ VABufferID buf_id, /* in */
+ void **pbuf /* out */
)
{
+ unsigned int buftype = buf_id & 0xff;
+ unsigned int magic = buf_id & FOOL_BUFID_MASK;
DPY2INDEX(dpy);
- /*Fill in black and white squares. */
- if (FOOL_DECODE(idx) || FOOL_DECODE(idx))
- return 1;
+ if (magic != FOOL_BUFID_MAGIC)
+ return 0;
- return 0;
+ /* buf_id is the buffer type */
+ *pbuf = fool_context[idx].fool_buf[buftype];
+ /* it is coded buffer, fill the fake segment buf from file */
+ if (*pbuf && (buftype == VAEncCodedBufferType))
+ va_FoolFillCodedBuf(idx);
+
+ return 1; /* don't call into driver */
}
VAStatus va_FoolUnmapBuffer(
VABufferID buf_id /* in */
)
{
- DPY2INDEX(dpy);
+ unsigned int magic = buf_id & FOOL_BUFID_MASK;
- if (FOOL_ENCODE(idx) || FOOL_DECODE(idx))
- return 1; /* fool buffer creation */
+ if (magic != FOOL_BUFID_MAGIC)
+ return 0;
- return 0;
+ return 1;
}
-
-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;
-}
-
#include <stdio.h>
-void va_FoolInit(VADisplay dpy);
-
-int va_FoolEnd(VADisplay dpy);
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int fool_codec;
+extern int fool_postp;
-int va_FoolGetFrame(FILE *input_fp, char *frame_buf);
+#define VA_FOOL_FLAG_DECODE 0x1
+#define VA_FOOL_FLAG_ENCODE 0x2
+#define VA_FOOL_FLAG_JPEG 0x4
-int va_FoolCodedBuf(VADisplay dpy);
+#define VA_FOOL_FUNC(fool_func,...) \
+ if (fool_codec) { \
+ ret = fool_func(__VA_ARGS__); \
+ }
+#define VA_FOOL_RETURN() \
+ if (fool_codec) { \
+ return VA_STATUS_SUCCESS; \
+ }
+void va_FoolInit(VADisplay dpy);
+int va_FoolEnd(VADisplay dpy);
int va_FoolCreateConfig(
- VADisplay dpy,
- VAProfile profile,
- VAEntrypoint entrypoint,
- VAConfigAttrib *attrib_list,
- int num_attribs,
- VAConfigID *config_id /* out */
+ VADisplay dpy,
+ VAProfile profile,
+ VAEntrypoint entrypoint,
+ VAConfigAttrib *attrib_list,
+ int num_attribs,
+ VAConfigID *config_id /* out */
);
-int va_FoolCreateSurfaces(
- VADisplay dpy,
- int width,
- int height,
- int format,
- int num_surfaces,
- VASurfaceID *surfaces /* out */
-);
-VAStatus va_FoolCreateBuffer (
+VAStatus va_FoolCreateBuffer(
VADisplay dpy,
VAContextID context, /* in */
VABufferType type, /* in */
void **pbuf /* out */
);
-int va_FoolBeginPicture(
- VADisplay dpy,
- VAContextID context,
- VASurfaceID render_target
-);
-
-int va_FoolRenderPicture(
- VADisplay dpy,
- VAContextID context,
- VABufferID *buffers,
- int num_buffers
-);
-
-int va_FoolEndPicture(
- VADisplay dpy,
- VAContextID context
-);
-
-VAStatus va_FoolUnmapBuffer (
- VADisplay dpy,
- VABufferID buf_id /* in */
+VAStatus va_FoolUnmapBuffer(
+ VADisplay dpy,
+ VABufferID buf_id /* in */
);
-
-VAStatus va_FoolQuerySubpictureFormats (
+VAStatus va_FoolBufferInfo (
VADisplay dpy,
- VAImageFormat *format_list,
- unsigned int *flags,
- unsigned int *num_formats
-);
-int va_FoolSyncSurface(
- VADisplay dpy,
- VASurfaceID render_target
+ VABufferID buf_id, /* in */
+ VABufferType *type, /* out */
+ unsigned int *size, /* out */
+ unsigned int *num_elements /* out */
);
-
-
+
+
+#ifdef __cplusplus
+}
+#endif
#endif
+++ /dev/null
-/* The code refers to
- * http://keyj.s2000.at/files/projects/h264-src.tar.gz
- */
-#include <string.h>
-#include <stdio.h>
-
-#define SLICE_NUM 4
-#define NAL_BUF_SIZE 65536 // maximum NAL unit size
-#define RING_BUF_SIZE 8192 // input ring buffer size, MUST be a power of two!
-
-typedef struct _nal_unit {
- int NumBytesInNALunit;
- int forbidden_zero_bit;
- int nal_ref_idc;
- int nal_unit_type;
- unsigned char *last_rbsp_byte;
-} nal_unit;
-
- typedef struct _slice_header {
- int first_mb_in_slice;
-} slice_header;
-
-static int get_next_nal_unit(FILE *input_fp, nal_unit *nalu);
-static int get_unsigned_exp_golomb();
-static void decode_slice_header(slice_header *sh);
-static void input_read(FILE *input_fp, unsigned char *dest, int size);
-static int input_get_bits(int bit_count);
-
-
-static unsigned char nal_buf[NAL_BUF_SIZE];
-static unsigned char ring_buf[RING_BUF_SIZE];
-static int input_remain = 0;
-static int ring_pos = 0;
-static int nal_pos;
-static int nal_bit;
-static int frame_no = 0;
-
-#define RING_MOD ((RING_BUF_SIZE)-1)
-#define HALF_RING ((RING_BUF_SIZE)/2)
-
-#define gnn_advance() do { \
- ring_pos = (ring_pos+1)&RING_MOD; \
- --input_remain; \
- if (ring_pos==0) input_read(input_fp, &ring_buf[HALF_RING],HALF_RING); \
- if (ring_pos==HALF_RING) input_read(input_fp, &ring_buf[0],HALF_RING); \
-} while(0)
-
-#define gnn_add_segment(end) do { \
- int size = end-segment_start; \
- if (size>0) { \
- memcpy(&nal_buf[nalu_size],&ring_buf[segment_start],size); \
- nalu_size += size; \
- } \
- segment_start = end&RING_MOD; \
-} while(0)
-
-static int input_get_bits(int bit_count)
-{
- int res = 0;
- register unsigned int x =
- (nal_buf[nal_pos]<<24)|
- (nal_buf[nal_pos+1]<<16)|
- (nal_buf[nal_pos+2]<<8)|
- nal_buf[nal_pos+3];
-
- res = (x>>(32-bit_count-nal_bit))&((1<<bit_count)-1);
- nal_bit += bit_count;
- nal_pos += nal_bit>>3;
- nal_bit &= 7;
-
- return res;
-}
-
-static int input_get_one_bit()
-{
- int res = (nal_buf[nal_pos]>>(7-nal_bit))&1;
-
- if (++nal_bit>7) {
- ++nal_pos;
- nal_bit = 0;
- }
- return res;
-}
-
-static int get_unsigned_exp_golomb()
-{
- int exp;
-
- for(exp = 0; !input_get_one_bit(); ++exp);
-
- if (exp)
- return (1<<exp) - 1 + input_get_bits(exp);
- else
- return 0;
-}
-
-static void decode_slice_header(slice_header *sh )
-{
- memset((void*)sh,0,sizeof(slice_header));
- sh->first_mb_in_slice = get_unsigned_exp_golomb();
-}
-
-static void input_read(FILE *input_fp, unsigned char *dest, int size)
-{
- int count = fread(dest, 1, size, input_fp);
-
- input_remain += count;
-}
-
-static int get_next_nal_unit(FILE *input_fp, nal_unit *nalu)
-{
- int i,segment_start;
- int nalu_size = 0;
- int NumBytesInRbsp = 0;
-
- /* search for the next NALU start
- * here is the sync that the start of the NALU is 0x00000001
- */
- for (;;) {
- if (input_remain<= 4) {
- /* clip restart */
- memset(ring_buf,0,sizeof(char)*RING_BUF_SIZE);
- memset(nal_buf,0,sizeof(char)*NAL_BUF_SIZE);
-
- fseek(input_fp,0,SEEK_SET);
- input_remain = 0;
- input_read(input_fp, ring_buf, RING_BUF_SIZE);
- ring_pos = 0;
- return 1;
- }
- if ((!ring_buf[ring_pos]) &&
- (!ring_buf[(ring_pos+1)&RING_MOD]) &&
- (!ring_buf[(ring_pos+2)&RING_MOD]) &&
- ( ring_buf[(ring_pos+3)&RING_MOD]==1))
- break;
- gnn_advance();
- }
-
- for(i=0;i<4;++i)
- gnn_advance();
-
- /* add bytes to the NALU until the end is found */
- segment_start = ring_pos;
- while (input_remain) {
- if ((!ring_buf[ring_pos]) &&
- (!ring_buf[(ring_pos+1)&RING_MOD]) &&
- (!ring_buf[(ring_pos+2)&RING_MOD]))
- break;
- ring_pos = (ring_pos+1)&RING_MOD;
- --input_remain;
-
- if (ring_pos==0) {
- gnn_add_segment(RING_BUF_SIZE);
- input_read(input_fp, &ring_buf[HALF_RING],HALF_RING);
- }
-
- if (ring_pos==HALF_RING) {
- gnn_add_segment(HALF_RING);
- input_read(input_fp, &ring_buf[0], HALF_RING);
- }
- }
-
- gnn_add_segment(ring_pos);
-
- /* read the NAL unit */
- nal_pos = 0; nal_bit = 0;
- nalu->forbidden_zero_bit = input_get_bits(1);
- nalu->nal_ref_idc = input_get_bits(2);
- nalu->nal_unit_type = input_get_bits(5);
- nalu->last_rbsp_byte = &nal_buf[nalu_size-1];
- nalu->NumBytesInNALunit = nalu_size;
-
- return 1;
-}
-
-int va_FoolGetFrame(FILE *input_fp, char *frame_buf)
-{
- int i = 0, frame_pos = 0;
- static slice_header sh;
- static nal_unit nalu;
- char nal_head[4] = {0x00,0x00,0x00,0x01};
-
- /* read the clip , here is the first frame,
- * &let the clip go on frame by frame
- */
- if (!frame_no)
- input_read(input_fp, ring_buf,RING_BUF_SIZE);
-
- while (get_next_nal_unit(input_fp, &nalu)) {
- if (nalu.nal_unit_type == 7 || nalu.nal_unit_type == 8) {
- memcpy(frame_buf+frame_pos, nal_head, sizeof(char)*4);
- frame_pos = frame_pos + 4;
- memcpy(frame_buf+frame_pos, nal_buf, sizeof(char)*(nalu.NumBytesInNALunit));
- frame_pos += nalu.NumBytesInNALunit;
- }
- else if (nalu.nal_unit_type == 1 || nalu.nal_unit_type == 5) {
- decode_slice_header(&sh);
- if (0 == sh.first_mb_in_slice) {
- ++frame_no;
- }
- memcpy(frame_buf+frame_pos, nal_head, sizeof(char)*4);
- frame_pos = frame_pos + 4;
- memcpy(frame_buf+frame_pos, nal_buf, sizeof(char)*(nalu.NumBytesInNALunit));
- frame_pos += nalu.NumBytesInNALunit;
- break;
- }
- }
-
- return frame_pos;
-}
#include <time.h>
#include <errno.h>
-
/*
* Env. to debug some issue, e.g. the decode/encode issue in a video conference scenerio:
* .LIBVA_TRACE=log_file: general VA parameters saved into log_file
* .LIBVA_TRACE_BUFDATA: dump VA buffer data into log_file (if not set, just calculate a checksum)
* .LIBVA_TRACE_CODEDBUF=coded_clip_file: save the coded clip into file coded_clip_file
- * .LIBVA_TRACE_SURFACE=decoded_yuv_file: save the decoded YUV file decoded_yuv_file
+ * .LIBVA_TRACE_SURFACE=yuv_file: save surface YUV into file yuv_file. Use file name to determine
+ * decode/encode or jpeg surfaces
* .LIBVA_TRACE_LOGSIZE=numeric number: truncate the log_file or coded_clip_file, or decoded_yuv_file
* when the size is bigger than the number
*/
-
/* global settings */
/* LIBVA_TRACE */
-unsigned int trace_flag = 0;
+int trace_flag = 0;
/* LIBVA_TRACE_LOGSIZE */
static unsigned int trace_logsize = 0xffffffff; /* truncate the log when the size is bigger than it */
-/* LIBVA_TRACE_BUFDATA */
-static unsigned int trace_buffer_data; /* dump buffer data or not */
-
#define TRACE_CONTEXT_MAX 4
/* per context settings */
static struct _trace_context {
/* LIBVA_TRACE */
FILE *trace_fp_log; /* save the log into a file */
- char trace_log_fn[1024]; /* file name */
+ char *trace_log_fn; /* file name */
/* LIBVA_TRACE_CODEDBUF */
FILE *trace_fp_codedbuf; /* save the encode result into a file */
- char trace_codedbuf_fn[1024]; /* file name */
+ char *trace_codedbuf_fn; /* file name */
/* LIBVA_TRACE_SURFACE */
FILE *trace_fp_surface; /* save the surface YUV into a file */
- char trace_surface_fn[1024]; /* file name */
+ char *trace_surface_fn; /* file name */
VAContextID trace_context; /* current context */
unsigned int trace_frame_width; /* current frame width */
unsigned int trace_frame_height; /* current frame height */
unsigned int trace_sequence_start; /* get a new sequence for encoding or not */
-} trace_context[TRACE_CONTEXT_MAX] = { {0} }; /* trace five context at the same time */
+} trace_context[TRACE_CONTEXT_MAX]; /* trace five context at the same time */
#define DPY2INDEX(dpy) \
int idx; \
VASurfaceID surface
);
+#define FILE_NAME_SUFFIX(env_value) \
+do { \
+ int tmp = strnlen(env_value, sizeof(env_value)); \
+ int left = sizeof(env_value) - tmp; \
+ \
+ snprintf(env_value+tmp, \
+ left, \
+ ".%04d.%05d", \
+ trace_index, \
+ suffix); \
+} while (0)
void va_TraceInit(VADisplay dpy)
{
char env_value[1024];
- unsigned int suffix = 0xffff & ((unsigned int)time(NULL));
+ unsigned short suffix = 0xffff & ((unsigned int)time(NULL));
int trace_index = 0;
FILE *tmp;
if (trace_index == TRACE_CONTEXT_MAX)
return;
+ memset(&trace_context[trace_index], 0, sizeof(struct _trace_context));
if (va_parseConfig("LIBVA_TRACE", &env_value[0]) == 0) {
- trace_flag = 1;
-
- /*Check if there is still room for suffix .%d.%d*/
- if (strnlen(env_value, 1024) < (1024 - 8))
- snprintf(env_value+strnlen(env_value, 1024),
- (1025 - 8 - strnlen(env_value, 1024)),
- ".%d.%d", trace_index, suffix);
-
+ FILE_NAME_SUFFIX(env_value);
+ trace_context[trace_index].trace_log_fn = strdup(env_value);
+
tmp = fopen(env_value, "w");
if (tmp) {
trace_context[trace_index].trace_fp_log = tmp;
- strcpy(trace_context[trace_index].trace_log_fn, env_value);
- } else {
+ va_infoMessage("LIBVA_TRACE is on, save log into %s\n", trace_context[trace_index].trace_log_fn);
+ trace_flag = VA_TRACE_FLAG_LOG;
+ } else
va_errorMessage("Open file %s failed (%s)\n", env_value, strerror(errno));
- trace_context[trace_index].trace_fp_log = stderr;
- strcpy(trace_context[trace_index].trace_codedbuf_fn, "/dev/stderr");
- }
- va_infoMessage("LIBVA_TRACE is on, save log into %s\n", trace_context[trace_index].trace_log_fn);
}
- if (trace_flag == 0)
- return;
-
/* may re-get the global settings for multiple context */
if (va_parseConfig("LIBVA_TRACE_LOGSIZE", &env_value[0]) == 0) {
trace_logsize = atoi(env_value);
va_infoMessage("LIBVA_TRACE_LOGSIZE is on, size is %d\n", trace_logsize);
}
-
- if (va_parseConfig("LIBVA_TRACE_BUFDATA", NULL) == 0) {
- trace_buffer_data = 1; /* dump buffer data */
+ if ((trace_flag & VA_TRACE_FLAG_LOG) && (va_parseConfig("LIBVA_TRACE_BUFDATA", NULL) == 0)) {
+ trace_flag |= VA_TRACE_FLAG_BUFDATA;
va_infoMessage("LIBVA_TRACE_BUFDATA is on, dump buffer into log file\n");
}
-
/* per-context setting */
if (va_parseConfig("LIBVA_TRACE_CODEDBUF", &env_value[0]) == 0) {
- if (strnlen(env_value, 1024) < (1024 - 8))
- snprintf(env_value+strnlen(env_value, 1024),
- (1025 - 8 - strnlen(env_value, 1024)),
- ".%d.%d", trace_index, suffix);
-
- tmp = fopen(env_value, "w");
-
- if (tmp) {
- trace_context[trace_index].trace_fp_codedbuf = tmp;
- strcpy(trace_context[trace_index].trace_codedbuf_fn, env_value);
- } else {
- va_errorMessage("Open file %s failed (%s)\n", env_value, strerror(errno));
- trace_context[trace_index].trace_fp_codedbuf = stderr;
- strcpy(trace_context[trace_index].trace_codedbuf_fn, "/dev/stderr");
- }
-
- va_infoMessage("LIBVA_TRACE_CODEDBUF is on, save coded clip into %s\n", trace_context[trace_index].trace_codedbuf_fn);
+ FILE_NAME_SUFFIX(env_value);
+ trace_context[trace_index].trace_codedbuf_fn = strdup(env_value);
+ va_infoMessage("LIBVA_TRACE_CODEDBUF is on, save codedbuf into log file %s\n",
+ trace_context[trace_index].trace_codedbuf_fn);
+ trace_flag |= VA_TRACE_FLAG_CODEDBUF;
}
if (va_parseConfig("LIBVA_TRACE_SURFACE", &env_value[0]) == 0) {
- sprintf(env_value+strnlen(env_value, 1024), ".%d.%d", trace_index, suffix);
-
- tmp = fopen(env_value, "w");
+ FILE_NAME_SUFFIX(env_value);
+ trace_context[trace_index].trace_surface_fn = strdup(env_value);
- if (tmp) {
- trace_context[trace_index].trace_fp_surface = tmp;
- strcpy(trace_context[trace_index].trace_surface_fn, env_value);
- } else {
- va_errorMessage("Open file %s failed (%s)\n", env_value, strerror(errno));
- trace_context[trace_index].trace_fp_surface = stderr;
- strcpy(trace_context[trace_index].trace_surface_fn, "/dev/stderr");
- }
-
- va_infoMessage("LIBVA_TRACE_SURFACE is on, save coded clip into %s\n", trace_context[trace_index].trace_surface_fn);
+ va_infoMessage("LIBVA_TRACE_SURFACE is on, save surface into %s\n",
+ trace_context[trace_index].trace_surface_fn);
+
+ /* for surface data dump, it is time-consume, and may
+ * cause some side-effect, so only trace the needed surfaces
+ * to trace encode surface, set the trace file name to sth like *enc*
+ * to trace decode surface, set the trace file name to sth like *dec*
+ * if no dec/enc in file name, set both
+ */
+ if (strstr(env_value, "dec"))
+ trace_flag |= VA_TRACE_FLAG_SURFACE_DECODE;
+ if (strstr(env_value, "enc"))
+ trace_flag |= VA_TRACE_FLAG_SURFACE_ENCODE;
+ if (strstr(env_value, "jpeg") || strstr(env_value, "jpg"))
+ trace_flag |= VA_TRACE_FLAG_SURFACE_JPEG;
}
trace_context[trace_index].dpy = dpy;
{
DPY2INDEX(dpy);
- if (trace_context[idx].trace_fp_log && (trace_context[idx].trace_fp_log != stderr))
+ if (trace_context[idx].trace_fp_log)
fclose(trace_context[idx].trace_fp_log);
- if (trace_context[idx].trace_fp_codedbuf && (trace_context[idx].trace_fp_codedbuf != stderr))
+ if (trace_context[idx].trace_fp_codedbuf)
fclose(trace_context[idx].trace_fp_codedbuf);
- if (trace_context[idx].trace_fp_surface && (trace_context[idx].trace_fp_surface != stderr))
+ if (trace_context[idx].trace_fp_surface)
fclose(trace_context[idx].trace_fp_surface);
+ if (trace_context[idx].trace_log_fn)
+ free(trace_context[idx].trace_log_fn);
+
+ if (trace_context[idx].trace_codedbuf_fn)
+ free(trace_context[idx].trace_codedbuf_fn);
+
+ if (trace_context[idx].trace_surface_fn)
+ free(trace_context[idx].trace_surface_fn);
+
memset(&trace_context[idx], 0, sizeof(struct _trace_context));
}
{
va_list args;
+ if (!(trace_flag & VA_TRACE_FLAG_LOG))
+ return;
+
if (file_size(trace_context[idx].trace_fp_log) >= trace_logsize)
truncate_file(trace_context[idx].trace_fp_log);
-
if (msg) {
va_start(args, msg);
vfprintf(trace_context[idx].trace_fp_log, msg, args);
VAStatus va_status;
unsigned char check_sum = 0;
DPY2INDEX(dpy);
-
+
va_TraceMsg(idx, "==========dump surface data in file %s\n", trace_context[idx].trace_surface_fn);
if ((file_size(trace_context[idx].trace_fp_surface) >= trace_logsize)) {
tmp = Y_data;
for (i=0; i<trace_context[idx].trace_frame_height; i++) {
- for (j=0; j<trace_context[idx].trace_frame_width; j++)
- check_sum ^= tmp[j];
-
if (trace_context[idx].trace_fp_surface)
fwrite(tmp, trace_context[idx].trace_frame_width, 1, trace_context[idx].trace_fp_surface);
tmp = Y_data + i * luma_stride;
}
-
tmp = UV_data;
if (fourcc == VA_FOURCC_NV12) {
for (i=0; i<trace_context[idx].trace_frame_height/2; i++) {
- for (j=0; j<trace_context[idx].trace_frame_width; j++)
- check_sum ^= tmp[j];
-
if (trace_context[idx].trace_fp_surface)
fwrite(tmp, trace_context[idx].trace_frame_width, 1, trace_context[idx].trace_fp_surface);
vaUnlockSurface(dpy, trace_context[idx].trace_rendertarget);
- va_TraceMsg(idx, "\tchecksum = 0x%02x\n", check_sum & 0xff);
va_TraceMsg(idx, NULL);
}
)
{
int i;
+ int encode, decode, jpeg;
DPY2INDEX(dpy);
TRACE_FUNCNAME(idx);
trace_context[idx].trace_profile = profile;
trace_context[idx].trace_entrypoint = entrypoint;
+
+ /* avoid to create so many empty files */
+ encode = (trace_context[idx].trace_entrypoint == VAEntrypointEncSlice);
+ decode = (trace_context[idx].trace_entrypoint == VAEntrypointVLD);
+ jpeg = (trace_context[idx].trace_entrypoint == VAEntrypointEncPicture);
+ if ((encode && (trace_flag & VA_TRACE_FLAG_SURFACE_ENCODE)) ||
+ (decode && (trace_flag & VA_TRACE_FLAG_SURFACE_DECODE)) ||
+ (jpeg && (trace_flag & VA_TRACE_FLAG_SURFACE_JPEG))) {
+ FILE *tmp = fopen(trace_context[idx].trace_surface_fn, "w");
+
+ if (tmp)
+ trace_context[idx].trace_fp_surface = tmp;
+ else {
+ va_errorMessage("Open file %s failed (%s)\n",
+ trace_context[idx].trace_surface_fn,
+ strerror(errno));
+ trace_context[idx].trace_fp_surface = NULL;
+ trace_flag &= ~(VA_TRACE_FLAG_SURFACE);
+ }
+ }
+
+ if (encode && (trace_flag & VA_TRACE_FLAG_CODEDBUF)) {
+ FILE *tmp = fopen(trace_context[idx].trace_codedbuf_fn, "w");
+
+ if (tmp)
+ trace_context[idx].trace_fp_codedbuf = tmp;
+ else {
+ va_errorMessage("Open file %s failed (%s)\n",
+ trace_context[idx].trace_codedbuf_fn,
+ strerror(errno));
+ trace_context[idx].trace_fp_codedbuf = NULL;
+ trace_flag &= ~VA_TRACE_FLAG_CODEDBUF;
+ }
+ }
}
for (i=0; i<size; i++) {
unsigned char value = p[i];
- if ((trace_buffer_data) && ((i%16) == 0))
+ if ((trace_flag & VA_TRACE_FLAG_BUFDATA) && ((i%16) == 0))
va_TraceMsg(idx, "\n0x%08x:", i);
- if (trace_buffer_data)
+ if (trace_flag & VA_TRACE_FLAG_BUFDATA)
va_TraceMsg(idx, " %02x", value);
check_sum ^= value;
va_TraceMsg(idx, "\tcontext = 0x%08x\n", context);
va_TraceMsg(idx, "\tnum_buffers = %d\n", num_buffers);
for (i = 0; i < num_buffers; i++) {
- void *pbuf;
+ unsigned char *pbuf;
unsigned int j;
/* get buffer type information */
va_TraceMsg(idx, "\t size = %d\n", size);
va_TraceMsg(idx, "\t num_elements = %d\n", num_elements);
- vaMapBuffer(dpy, buffers[i], &pbuf);
+ vaMapBuffer(dpy, buffers[i], (void **)&pbuf);
switch (trace_context[idx].trace_profile) {
case VAProfileMPEG2Simple:
va_TraceMsg(idx, NULL);
}
-
void va_TraceEndPicture(
VADisplay dpy,
- VAContextID context
+ VAContextID context,
+ int endpic_done
)
{
+ int encode, decode, jpeg;
DPY2INDEX(dpy);
TRACE_FUNCNAME(idx);
-
- va_TraceMsg(idx, "\tcontext = 0x%08x\n", context);
- va_TraceMsg(idx, "\trender_targets = 0x%08x\n", trace_context[idx].trace_rendertarget);
- /* want to trace codedbuf, and it is encode */
- if (trace_context[idx].trace_fp_codedbuf &&
- ((trace_context[idx].trace_entrypoint == VAEntrypointEncSlice) ||
- (trace_context[idx].trace_entrypoint == VAEntrypointEncPicture))) {
+ if (endpic_done == 0) {
+ va_TraceMsg(idx, "\tcontext = 0x%08x\n", context);
+ va_TraceMsg(idx, "\trender_targets = 0x%08x\n", trace_context[idx].trace_rendertarget);
+ }
+
+ encode = (trace_context[idx].trace_entrypoint == VAEntrypointEncSlice) &&
+ (trace_flag & VA_TRACE_FLAG_SURFACE_ENCODE);
+ decode = (trace_context[idx].trace_entrypoint == VAEntrypointVLD) &&
+ (trace_flag & VA_TRACE_FLAG_SURFACE_DECODE);
+ jpeg = (trace_context[idx].trace_entrypoint == VAEntrypointEncPicture) &&
+ (trace_flag & VA_TRACE_FLAG_SURFACE_JPEG);
+
+ /* want to trace encode source surface, do it before vaEndPicture */
+ if ((encode || jpeg) && (endpic_done == 0))
+ va_TraceSurface(dpy);
+
+ /* want to trace encoode codedbuf, do it after vaEndPicture */
+ if ((encode || jpeg) && (endpic_done == 1)) {
/* force the pipleline finish rendering */
vaSyncSurface(dpy, trace_context[idx].trace_rendertarget);
va_TraceCodedBuf(dpy);
}
- /* trace decoded surface for decoding, or the source sourface for encoding */
- if (trace_context[idx].trace_fp_surface) {
+ /* want to trace decode dest surface, do it after vaEndPicture */
+ if (decode && (endpic_done == 1)) {
/* force the pipleline finish rendering */
vaSyncSurface(dpy, trace_context[idx].trace_rendertarget);
-
va_TraceSurface(dpy);
}
-
va_TraceMsg(idx, NULL);
}
#ifndef VA_TRACE_H
#define VA_TRACE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int trace_flag;
+
+#define VA_TRACE_FLAG_LOG 0x1
+#define VA_TRACE_FLAG_BUFDATA 0x2
+#define VA_TRACE_FLAG_CODEDBUF 0x4
+#define VA_TRACE_FLAG_SURFACE_DECODE 0x8
+#define VA_TRACE_FLAG_SURFACE_ENCODE 0x10
+#define VA_TRACE_FLAG_SURFACE_JPEG 0x20
+#define VA_TRACE_FLAG_SURFACE (VA_TRACE_FLAG_SURFACE_DECODE | \
+ VA_TRACE_FLAG_SURFACE_ENCODE | \
+ VA_TRACE_FLAG_SURFACE_JPEG)
+
+#define VA_TRACE_FUNC(trace_func,...) \
+ if (trace_flag) { \
+ trace_func(__VA_ARGS__); \
+ }
+#define VA_TRACE_LOG(trace_func,...) \
+ if (trace_flag & VA_TRACE_FLAG_LOG) { \
+ trace_func(__VA_ARGS__); \
+ }
+#define VA_TRACE_SURFACE(trace_func,...) \
+ if (trace_flag & (VA_TRACE_FLAG_SURFACE | VA_TRACE_FLAG_CODEDBUF)) { \
+ trace_func(__VA_ARGS__); \
+ }
+
void va_TraceInit(VADisplay dpy);
void va_TraceEnd(VADisplay dpy);
void va_TraceEndPicture(
VADisplay dpy,
- VAContextID context
+ VAContextID context,
+ int endpic_done
);
void va_TraceSyncSurface(
unsigned int flags /* de-interlacing flags */
);
-
+#ifdef __cplusplus
+}
+#endif
+
#endif /* VA_TRACE_H */
#include "sysdeps.h"
#include "va.h"
#include "va_backend.h"
+#include "va_trace.h"
+#include "va_fool.h"
#include "va_x11.h"
#include "va_dri.h"
#include "va_dri2.h"
#define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
#define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
-extern int fool_postp; /* do nothing for vaPutSurface if set */
-extern int trace_flag; /* trace vaPutSurface parameters */
-#define VA_TRACE(trace_func,...) \
- if (trace_flag) { \
- trace_func(__VA_ARGS__); \
- }
-
void va_TracePutSurface (
VADisplay dpy,
VASurfaceID surface,
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
- VA_TRACE(va_TracePutSurface, dpy, surface, (void *)draw, srcx, srcy, srcw, srch,
- destx, desty, destw, desth,
+ VA_TRACE_FUNC(va_TracePutSurface, dpy, surface, (void *)draw, srcx, srcy, srcw, srch,
+ destx, desty, destw, desth,
cliprects, number_cliprects, flags );
return ctx->vtable->vaPutSurface( ctx, surface, (void *)draw, srcx, srcy, srcw, srch,