Commit 549946cf authored by Austin Yuan's avatar Austin Yuan

vatrace/vafool: refine it

remove va_fool_getframe.c which looks strange
correct some coding style for file va.c
simplify va_fool.c for both decode and encode
refine the surface dump of va_trace.c
Signed-off-by: default avatarAustin Yuan <shengquan.yuan@gmail.com>
parent 1092e4b5
......@@ -35,8 +35,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
va.c \
va_trace.c \
va_fool.c \
va_fool_getframe.c
va_fool.c
LOCAL_CFLAGS += \
-DANDROID \
......@@ -59,7 +58,7 @@ LOCAL_COPY_HEADERS_TO := libva/va
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libva
LOCAL_SHARED_LIBRARIES := libdl libdrm libcutils
LOCAL_SHARED_LIBRARIES := libdl libdrm libcutils liblog
include $(BUILD_SHARED_LIBRARY)
......
......@@ -34,7 +34,6 @@ LDADD = \
libva_source_c = \
va.c \
va_fool.c \
va_fool_getframe.c \
va_trace.c \
$(NULL)
......
......@@ -25,6 +25,8 @@
#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>
......@@ -267,11 +269,6 @@ extern "C" {
);
}
#define VA_TRACE(trace_func,...) \
if (trace_flag) { \
trace_func(__VA_ARGS__); \
}
VAStatus vaPutSurface (
VADisplay dpy,
VASurfaceID surface,
......@@ -300,7 +297,7 @@ VAStatus vaPutSurface (
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
VA_TRACE(va_TracePutSurface, dpy, surface, static_cast<void*>(&draw), srcx, srcy, srcw, srch,
VA_TRACE_LOG(va_TracePutSurface, dpy, surface, static_cast<void*>(&draw), srcx, srcy, srcw, srch,
destx, desty, destw, desth,
cliprects, number_cliprects, flags );
......
......@@ -48,18 +48,6 @@
#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
......@@ -73,7 +61,6 @@ int va_parseConfig(char *env, char *env_value)
char oneline[1024];
FILE *fp=NULL;
if (env == NULL)
return 1;
......@@ -138,8 +125,7 @@ void va_infoMessage(const char *msg, ...)
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;
}
......@@ -148,8 +134,7 @@ static Bool va_checkVtable(void *ptr, char *function)
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;
}
......@@ -158,8 +143,7 @@ static Bool va_checkMaximum(int value, char *variable)
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;
}
......@@ -182,19 +166,14 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
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) +
......@@ -210,25 +189,17 @@ static VAStatus va_openDriver(VADisplay dpy, char *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;
......@@ -242,8 +213,7 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
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);
......@@ -292,15 +262,12 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
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;
}
......@@ -318,7 +285,7 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
{
VADriverContextP ctx;
if( !vaDisplayIsValid(dpy) )
if (!vaDisplayIsValid(dpy))
return NULL;
ctx = CTX(dpy);
......@@ -334,8 +301,7 @@ VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
*/
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:
......@@ -407,21 +373,17 @@ VAStatus vaInitialize (
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);
......@@ -432,7 +394,7 @@ VAStatus vaInitialize (
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;
}
......@@ -463,7 +425,7 @@ VAStatus vaTerminate (
if (VA_STATUS_SUCCESS == vaStatus)
pDisplayContext->vaDestroy(pDisplayContext);
VA_TRACE(va_TraceTerminate, dpy);
VA_TRACE_LOG(va_TraceTerminate, dpy);
va_TraceEnd(dpy);
......@@ -484,7 +446,7 @@ const char *vaQueryVendorString (
VADisplay dpy
)
{
if( !vaDisplayIsValid(dpy) )
if (!vaDisplayIsValid(dpy))
return NULL;
return CTX(dpy)->str_vendor;
......@@ -496,7 +458,7 @@ int vaMaxNumProfiles (
VADisplay dpy
)
{
if( !vaDisplayIsValid(dpy) )
if (!vaDisplayIsValid(dpy))
return 0;
return CTX(dpy)->max_profiles;
......@@ -507,7 +469,7 @@ int vaMaxNumEntrypoints (
VADisplay dpy
)
{
if( !vaDisplayIsValid(dpy) )
if (!vaDisplayIsValid(dpy))
return 0;
return CTX(dpy)->max_entrypoints;
......@@ -519,7 +481,7 @@ int vaMaxNumConfigAttributes (
VADisplay dpy
)
{
if( !vaDisplayIsValid(dpy) )
if (!vaDisplayIsValid(dpy))
return 0;
return CTX(dpy)->max_attributes;
......@@ -583,11 +545,11 @@ VAStatus vaCreateConfig (
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 );
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;
}
......@@ -638,9 +600,7 @@ VAStatus vaCreateSurfaces (
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;
}
......@@ -679,7 +639,8 @@ VAStatus vaCreateContext (
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;
}
......@@ -711,7 +672,7 @@ VAStatus vaCreateBuffer (
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;
......@@ -728,6 +689,8 @@ VAStatus vaBufferSetNumElements (
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
VA_FOOL_RETURN();
return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
}
......@@ -745,14 +708,13 @@ VAStatus vaMapBuffer (
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;
}
......@@ -767,7 +729,7 @@ VAStatus vaUnmapBuffer (
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;
......@@ -783,6 +745,8 @@ VAStatus vaDestroyBuffer (
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
VA_FOOL_RETURN();
return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
}
......@@ -796,9 +760,15 @@ VAStatus vaBufferInfo (
)
{
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 );
}
......@@ -809,18 +779,18 @@ VAStatus vaBeginPicture (
)
{
VADriverContextP ctx;
VAStatus va_status;
int ret = 0;
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
VA_TRACE(va_TraceBeginPicture, dpy, context, render_target);
VA_TRACE_FUNC(va_TraceBeginPicture, dpy, context, render_target);
VA_FOOL_RETURN();
VA_FOOL(va_FoolBeginPicture, dpy, context, render_target);
if (ret)
return VA_STATUS_SUCCESS;
va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
return ctx->vtable->vaBeginPicture( ctx, context, render_target );
return va_status;
}
VAStatus vaRenderPicture (
......@@ -836,11 +806,8 @@ 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 );
}
......@@ -857,15 +824,14 @@ VAStatus vaEndPicture (
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;
}
......@@ -882,12 +848,8 @@ VAStatus vaSyncSurface (
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;
}
......@@ -905,7 +867,7 @@ VAStatus vaQuerySurfaceStatus (
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;
}
......@@ -924,7 +886,7 @@ VAStatus vaQuerySurfaceError (
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;
}
......@@ -934,7 +896,7 @@ int vaMaxNumImageFormats (
VADisplay dpy
)
{
if( !vaDisplayIsValid(dpy) )
if (!vaDisplayIsValid(dpy))
return 0;
return CTX(dpy)->max_image_formats;
......@@ -1100,7 +1062,7 @@ int vaMaxNumSubpictureFormats (
VADisplay dpy
)
{
if( !vaDisplayIsValid(dpy) )
if (!vaDisplayIsValid(dpy))
return 0;
return CTX(dpy)->max_subpic_formats;
......@@ -1126,10 +1088,6 @@ VAStatus vaQuerySubpictureFormats (
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);
}
......@@ -1275,12 +1233,12 @@ int vaMaxNumDisplayAttributes (
{
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;
}
......@@ -1298,14 +1256,13 @@ VAStatus vaQueryDisplayAttributes (
)
{
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;
......@@ -1324,14 +1281,13 @@ VAStatus vaGetDisplayAttributes (
)
{
VADriverContextP ctx;
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
VAStatus va_status;
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
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;
}
......@@ -1349,13 +1305,14 @@ VAStatus vaSetDisplayAttributes (
)
{
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,
......
......@@ -39,6 +39,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
/*
* Do dummy decode/encode, ignore the input data
......@@ -46,41 +47,36 @@
* 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
......@@ -89,18 +85,10 @@ static struct _fool_context {
*/
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; \
......@@ -112,7 +100,6 @@ static struct _fool_context {
if (idx == FOOL_CONTEXT_MAX) \
return 0; /* let driver go */
/* Prototype declarations (functions defined in va.c) */
void va_errorMessage(const char *msg, ...);
......@@ -120,33 +107,6 @@ 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];
......@@ -159,41 +119,30 @@ 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));
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_context[fool_index].frame_buf == NULL)
fool_encode = 0;
if (fool_encode)
va_infoMessage("LIBVA_FOOL_ENCODE is on, dummy encode\n");
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_encode || fool_decode)
if (fool_codec)
fool_context[fool_index].dpy = dpy;
}
......@@ -201,29 +150,23 @@ void va_FoolInit(VADisplay 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].codebuf)
free(fool_context[idx].codebuf);
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);
memset(&fool_context[idx], 0, sizeof(struct _fool_context));
return 0;
}
int va_FoolCodedBuf(VADisplay dpy)
{
/* do nothing */
return 0;
}
......@@ -239,150 +182,26 @@ int va_FoolCreateConfig(
{
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;
}
fool_context[idx].entrypoint = entrypoint;
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
/*
* 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
*/
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]);
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;
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 */
return 0; /* driver continue */
}
VAStatus va_FoolCreateBuffer (
VAStatus va_FoolCreateBuffer(
VADisplay dpy,
VAContextID context, /* in */
VABufferType type, /* in */
......@@ -392,157 +211,146 @@ VAStatus va_FoolCreateBuffer (
VABufferID *buf_id /* out */
)
{
unsigned int new_size = size * num_elements;
unsigned int old_size;
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);
old_size = fool_context[idx].fool_buf_size[type] * fool_context[idx].fool_buf_element[type];
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 */
}
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 = (buffer count << 8) | type
* bufferID = (magic number) | type
*/
fool_context[idx].fool_buf_count[type]++;
*buf_id = (fool_context[idx].fool_buf_count[type] << 8) | type;
*buf_id = FOOL_BUFID_MAGIC | type;
return 1; /* don't call into driver */
}
return 0; /* let driver go ... */
}
VAStatus va_FoolMapBuffer (
VAStatus va_FoolBufferInfo(
VADisplay dpy,
VABufferID buf_id, /* in */
void **pbuf /* out */
VABufferType *type, /* out */
unsigned int *size, /* out */
unsigned int *num_elements /* out */
)
{
VABufferType type;
unsigned int size,frame_size = 0;
unsigned int num_elements;
unsigned int magic = buf_id & FOOL_BUFID_MASK;
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))
if (magic != FOOL_BUFID_MAGIC)
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;
}
return 1; /* don't call into driver */
}
*type = buf_id & 0xff;
*size = fool_context[idx].fool_buf_size[*type];
*num_elements = fool_context[idx].fool_buf_element[*type];;
return 0; /* let driver go ... */
return 1; /* don't call into driver */
}
int va_FoolBeginPicture(
VADisplay dpy,
VAContextID context,
VASurfaceID render_target
)
static int va_FoolFillCodedBufEnc(int idx)
{
DPY2INDEX(dpy);
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;
}
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 */
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_FoolRenderPicture(
VADisplay dpy,
VAContextID context,
VABufferID *buffers,
int num_buffers
)
static int va_FoolFillCodedBufJPG(int idx)
{
DPY2INDEX(dpy);
struct stat file_stat;
VACodedBufferSegment *codedbuf;
int i, fd = -1;
if (FOOL_ENCODE(idx) || FOOL_DECODE(idx))
return 1; /* don't call into driver level */
if ((fd = open(fool_context[idx].fn_jpg, O_RDONLY)) != -1)
fstat(fd, &file_stat);
return 0; /* let driver go ... */
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;
}
int va_FoolEndPicture(
VADisplay dpy,
VAContextID context
)
static int va_FoolFillCodedBuf(int idx)
{
DPY2INDEX(dpy);
/* don't call into driver level */
if (fool_context[idx].entrypoint == VAEntrypointEncSlice)
va_FoolFillCodedBufEnc(idx);
else if (fool_context[idx].entrypoint == VAEntrypointEncPicture)
va_FoolFillCodedBufJPG(idx);
/* 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 ... */
return 0;
}
int va_FoolSyncSurface(
VAStatus va_FoolMapBuffer(
VADisplay dpy,
VASurfaceID render_target
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;
/* 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(
......@@ -550,28 +358,10 @@ VAStatus va_FoolUnmapBuffer(
VABufferID buf_id /* in */
)
{
DPY2INDEX(dpy);
if (FOOL_ENCODE(idx) || FOOL_DECODE(idx))
return 1; /* fool buffer creation */
unsigned int magic = buf_id & FOOL_BUFID_MASK;
if (magic != FOOL_BUFID_MAGIC)
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;
}
......@@ -28,15 +28,28 @@
#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,
......@@ -47,16 +60,8 @@ int va_FoolCreateConfig(
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 */
......@@ -72,41 +77,22 @@ VAStatus va_FoolMapBuffer (
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 (
VAStatus va_FoolUnmapBuffer(
VADisplay dpy,
VABufferID buf_id /* in */
);
VAStatus va_FoolQuerySubpictureFormats (
VADisplay dpy,
VAImageFormat *format_list,
unsigned int *flags,
unsigned int *num_formats
);
int va_FoolSyncSurface(
VAStatus va_FoolBufferInfo (
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
/* 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;
}
......@@ -40,29 +40,25 @@
#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 {
......@@ -70,15 +66,15 @@ 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 */
......@@ -94,7 +90,7 @@ static struct _trace_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; \
......@@ -141,11 +137,22 @@ VAStatus vaUnlockSurface(VADisplay dpy,
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;
......@@ -156,79 +163,59 @@ void va_TraceInit(VADisplay dpy)
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_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);
trace_flag = VA_TRACE_FLAG_LOG;
} else
va_errorMessage("Open file %s failed (%s)\n", env_value, strerror(errno));
}
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);
FILE_NAME_SUFFIX(env_value);
trace_context[trace_index].trace_surface_fn = strdup(env_value);
tmp = fopen(env_value, "w");
va_infoMessage("LIBVA_TRACE_SURFACE is on, save surface into %s\n",
trace_context[trace_index].trace_surface_fn);
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);
/* 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;
......@@ -239,15 +226,24 @@ void va_TraceEnd(VADisplay 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));
}
......@@ -272,9 +268,11 @@ void va_TraceMsg(int idx, const char *msg, ...)
{
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);
......@@ -388,21 +386,14 @@ void va_TraceSurface(VADisplay dpy)
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);
......@@ -412,7 +403,6 @@ void va_TraceSurface(VADisplay dpy)
vaUnlockSurface(dpy, trace_context[idx].trace_rendertarget);
va_TraceMsg(idx, "\tchecksum = 0x%02x\n", check_sum & 0xff);
va_TraceMsg(idx, NULL);
}
......@@ -446,6 +436,7 @@ void va_TraceCreateConfig(
)
{
int i;
int encode, decode, jpeg;
DPY2INDEX(dpy);
TRACE_FUNCNAME(idx);
......@@ -461,6 +452,40 @@ void va_TraceCreateConfig(
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;
}
}
}
......@@ -610,10 +635,10 @@ static void va_TraceVABuffers(
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;
......@@ -1901,7 +1926,7 @@ void va_TraceRenderPicture(
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 */
......@@ -1913,7 +1938,7 @@ void va_TraceRenderPicture(
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:
......@@ -1980,36 +2005,46 @@ void va_TraceRenderPicture(
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);
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 codedbuf, and it is encode */
if (trace_context[idx].trace_fp_codedbuf &&
((trace_context[idx].trace_entrypoint == VAEntrypointEncSlice) ||
(trace_context[idx].trace_entrypoint == VAEntrypointEncPicture))) {
/* 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);
}
......
......@@ -25,6 +25,35 @@
#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);
......@@ -92,7 +121,8 @@ void va_TraceRenderPicture(
void va_TraceEndPicture(
VADisplay dpy,
VAContextID context
VAContextID context,
int endpic_done
);
void va_TraceSyncSurface(
......@@ -155,6 +185,9 @@ void va_TracePutSurface (
unsigned int flags /* de-interlacing flags */
);
#ifdef __cplusplus
}
#endif
#endif /* VA_TRACE_H */
......@@ -26,6 +26,8 @@
#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"
......@@ -208,13 +210,6 @@ VADisplay vaGetDisplay (
#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,
......@@ -258,7 +253,7 @@ VAStatus vaPutSurface (
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
VA_TRACE(va_TracePutSurface, dpy, surface, (void *)draw, srcx, srcy, srcw, srch,
VA_TRACE_FUNC(va_TracePutSurface, dpy, surface, (void *)draw, srcx, srcy, srcw, srch,
destx, desty, destw, desth,
cliprects, number_cliprects, flags );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment