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) ...@@ -35,8 +35,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
va.c \ va.c \
va_trace.c \ va_trace.c \
va_fool.c \ va_fool.c
va_fool_getframe.c
LOCAL_CFLAGS += \ LOCAL_CFLAGS += \
-DANDROID \ -DANDROID \
...@@ -59,7 +58,7 @@ LOCAL_COPY_HEADERS_TO := libva/va ...@@ -59,7 +58,7 @@ LOCAL_COPY_HEADERS_TO := libva/va
LOCAL_MODULE_TAGS := optional LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libva LOCAL_MODULE := libva
LOCAL_SHARED_LIBRARIES := libdl libdrm libcutils LOCAL_SHARED_LIBRARIES := libdl libdrm libcutils liblog
include $(BUILD_SHARED_LIBRARY) include $(BUILD_SHARED_LIBRARY)
......
...@@ -34,7 +34,6 @@ LDADD = \ ...@@ -34,7 +34,6 @@ LDADD = \
libva_source_c = \ libva_source_c = \
va.c \ va.c \
va_fool.c \ va_fool.c \
va_fool_getframe.c \
va_trace.c \ va_trace.c \
$(NULL) $(NULL)
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#define _GNU_SOURCE 1 #define _GNU_SOURCE 1
#include "va.h" #include "va.h"
#include "va_backend.h" #include "va_backend.h"
#include "va_trace.h"
#include "va_fool.h"
#include "va_android.h" #include "va_android.h"
#include "va_dricommon.h" /* needs some helper functions from this file */ #include "va_dricommon.h" /* needs some helper functions from this file */
#include <stdio.h> #include <stdio.h>
...@@ -267,11 +269,6 @@ extern "C" { ...@@ -267,11 +269,6 @@ extern "C" {
); );
} }
#define VA_TRACE(trace_func,...) \
if (trace_flag) { \
trace_func(__VA_ARGS__); \
}
VAStatus vaPutSurface ( VAStatus vaPutSurface (
VADisplay dpy, VADisplay dpy,
VASurfaceID surface, VASurfaceID surface,
...@@ -300,9 +297,9 @@ VAStatus vaPutSurface ( ...@@ -300,9 +297,9 @@ VAStatus vaPutSurface (
CHECK_DISPLAY(dpy); CHECK_DISPLAY(dpy);
ctx = CTX(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, destx, desty, destw, desth,
cliprects, number_cliprects, flags ); cliprects, number_cliprects, flags );
return ctx->vtable->vaPutSurface( ctx, surface, static_cast<void*>(&draw), srcx, srcy, srcw, srch, return ctx->vtable->vaPutSurface( ctx, surface, static_cast<void*>(&draw), srcx, srcy, srcw, srch,
destx, desty, destw, desth, destx, desty, destw, desth,
......
...@@ -48,18 +48,6 @@ ...@@ -48,18 +48,6 @@
#define CHECK_MAXIMUM(s, ctx, var) if (!va_checkMaximum(ctx->max_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN; #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; #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 * read a config "env" for libva.conf or from environment setting
...@@ -73,7 +61,6 @@ int va_parseConfig(char *env, char *env_value) ...@@ -73,7 +61,6 @@ int va_parseConfig(char *env, char *env_value)
char oneline[1024]; char oneline[1024];
FILE *fp=NULL; FILE *fp=NULL;
if (env == NULL) if (env == NULL)
return 1; return 1;
...@@ -138,8 +125,7 @@ void va_infoMessage(const char *msg, ...) ...@@ -138,8 +125,7 @@ void va_infoMessage(const char *msg, ...)
static Bool va_checkVtable(void *ptr, char *function) static Bool va_checkVtable(void *ptr, char *function)
{ {
if (!ptr) if (!ptr) {
{
va_errorMessage("No valid vtable entry for va%s\n", function); va_errorMessage("No valid vtable entry for va%s\n", function);
return False; return False;
} }
...@@ -148,8 +134,7 @@ static Bool va_checkVtable(void *ptr, char *function) ...@@ -148,8 +134,7 @@ static Bool va_checkVtable(void *ptr, char *function)
static Bool va_checkMaximum(int value, char *variable) static Bool va_checkMaximum(int value, char *variable)
{ {
if (!value) if (!value) {
{
va_errorMessage("Failed to define max_%s in init\n", variable); va_errorMessage("Failed to define max_%s in init\n", variable);
return False; return False;
} }
...@@ -158,8 +143,7 @@ static Bool va_checkMaximum(int value, char *variable) ...@@ -158,8 +143,7 @@ static Bool va_checkMaximum(int value, char *variable)
static Bool va_checkString(const char* 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); va_errorMessage("Failed to define str_%s in init\n", variable);
return False; return False;
} }
...@@ -182,19 +166,14 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name) ...@@ -182,19 +166,14 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
char *driver_dir; char *driver_dir;
if (geteuid() == getuid()) if (geteuid() == getuid())
{
/* don't allow setuid apps to use LIBVA_DRIVERS_PATH */ /* don't allow setuid apps to use LIBVA_DRIVERS_PATH */
search_path = getenv("LIBVA_DRIVERS_PATH"); search_path = getenv("LIBVA_DRIVERS_PATH");
}
if (!search_path) if (!search_path)
{
search_path = VA_DRIVERS_PATH; search_path = VA_DRIVERS_PATH;
}
search_path = strdup((const char *)search_path); search_path = strdup((const char *)search_path);
driver_dir = strtok_r((const char *)search_path, ":", &saveptr); driver_dir = strtok_r(search_path, ":", &saveptr);
while(driver_dir) while (driver_dir) {
{
void *handle = NULL; void *handle = NULL;
char *driver_path = (char *) malloc( strlen(driver_dir) + char *driver_path = (char *) malloc( strlen(driver_dir) +
strlen(driver_name) + strlen(driver_name) +
...@@ -210,25 +189,17 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name) ...@@ -210,25 +189,17 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
#else #else
handle = dlopen( driver_path, RTLD_NOW| RTLD_GLOBAL); handle = dlopen( driver_path, RTLD_NOW| RTLD_GLOBAL);
#endif #endif
if (!handle) if (!handle) {
{
/* Don't give errors for non-existing files */ /* Don't give errors for non-existing files */
if (0 == access( driver_path, F_OK)) if (0 == access( driver_path, F_OK))
{
va_errorMessage("dlopen of %s failed: %s\n", driver_path, dlerror()); va_errorMessage("dlopen of %s failed: %s\n", driver_path, dlerror());
} } else {
}
else
{
VADriverInit init_func; VADriverInit init_func;
init_func = (VADriverInit) dlsym(handle, VA_DRIVER_INIT_FUNC_S); 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); va_errorMessage("%s has no function %s\n", driver_path, VA_DRIVER_INIT_FUNC_S);
dlclose(handle); dlclose(handle);
} } else {
else
{
struct VADriverVTable *vtable = ctx->vtable; struct VADriverVTable *vtable = ctx->vtable;
vaStatus = VA_STATUS_SUCCESS; vaStatus = VA_STATUS_SUCCESS;
...@@ -242,8 +213,7 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name) ...@@ -242,8 +213,7 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
if (VA_STATUS_SUCCESS == vaStatus) if (VA_STATUS_SUCCESS == vaStatus)
vaStatus = (*init_func)(ctx); vaStatus = (*init_func)(ctx);
if (VA_STATUS_SUCCESS == vaStatus) if (VA_STATUS_SUCCESS == vaStatus) {
{
CHECK_MAXIMUM(vaStatus, ctx, profiles); CHECK_MAXIMUM(vaStatus, ctx, profiles);
CHECK_MAXIMUM(vaStatus, ctx, entrypoints); CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
CHECK_MAXIMUM(vaStatus, ctx, attributes); CHECK_MAXIMUM(vaStatus, ctx, attributes);
...@@ -292,15 +262,12 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name) ...@@ -292,15 +262,12 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes); CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes); CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
} }
if (VA_STATUS_SUCCESS != vaStatus) if (VA_STATUS_SUCCESS != vaStatus) {
{
va_errorMessage("%s init failed\n", driver_path); va_errorMessage("%s init failed\n", driver_path);
dlclose(handle); dlclose(handle);
} }
if (VA_STATUS_SUCCESS == vaStatus) if (VA_STATUS_SUCCESS == vaStatus)
{
ctx->handle = handle; ctx->handle = handle;
}
free(driver_path); free(driver_path);
break; break;
} }
...@@ -318,7 +285,7 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name) ...@@ -318,7 +285,7 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func) VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
{ {
VADriverContextP ctx; VADriverContextP ctx;
if( !vaDisplayIsValid(dpy) ) if (!vaDisplayIsValid(dpy))
return NULL; return NULL;
ctx = CTX(dpy); ctx = CTX(dpy);
...@@ -334,8 +301,7 @@ VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func) ...@@ -334,8 +301,7 @@ VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
*/ */
const char *vaErrorStr(VAStatus error_status) const char *vaErrorStr(VAStatus error_status)
{ {
switch(error_status) switch(error_status) {
{
case VA_STATUS_SUCCESS: case VA_STATUS_SUCCESS:
return "success (no error)"; return "success (no error)";
case VA_STATUS_ERROR_OPERATION_FAILED: case VA_STATUS_ERROR_OPERATION_FAILED:
...@@ -407,21 +373,17 @@ VAStatus vaInitialize ( ...@@ -407,21 +373,17 @@ VAStatus vaInitialize (
va_infoMessage("libva version %s\n", VA_VERSION_S); va_infoMessage("libva version %s\n", VA_VERSION_S);
driver_name_env = getenv("LIBVA_DRIVER_NAME"); 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 */ /* Don't allow setuid apps to use LIBVA_DRIVER_NAME */
driver_name = strdup(driver_name_env); driver_name = strdup(driver_name_env);
vaStatus = VA_STATUS_SUCCESS; vaStatus = VA_STATUS_SUCCESS;
va_infoMessage("User requested driver '%s'\n", driver_name); va_infoMessage("User requested driver '%s'\n", driver_name);
} } else {
else
{
vaStatus = va_getDriverName(dpy, &driver_name); vaStatus = va_getDriverName(dpy, &driver_name);
va_infoMessage("va_getDriverName() returns %d\n", vaStatus); va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
} }
if (VA_STATUS_SUCCESS == vaStatus) if (VA_STATUS_SUCCESS == vaStatus) {
{
vaStatus = va_openDriver(dpy, driver_name); vaStatus = va_openDriver(dpy, driver_name);
va_infoMessage("va_openDriver() returns %d\n", vaStatus); va_infoMessage("va_openDriver() returns %d\n", vaStatus);
...@@ -432,7 +394,7 @@ VAStatus vaInitialize ( ...@@ -432,7 +394,7 @@ VAStatus vaInitialize (
if (driver_name) if (driver_name)
free(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; return vaStatus;
} }
...@@ -463,7 +425,7 @@ VAStatus vaTerminate ( ...@@ -463,7 +425,7 @@ VAStatus vaTerminate (
if (VA_STATUS_SUCCESS == vaStatus) if (VA_STATUS_SUCCESS == vaStatus)
pDisplayContext->vaDestroy(pDisplayContext); pDisplayContext->vaDestroy(pDisplayContext);
VA_TRACE(va_TraceTerminate, dpy); VA_TRACE_LOG(va_TraceTerminate, dpy);
va_TraceEnd(dpy); va_TraceEnd(dpy);
...@@ -484,7 +446,7 @@ const char *vaQueryVendorString ( ...@@ -484,7 +446,7 @@ const char *vaQueryVendorString (
VADisplay dpy VADisplay dpy
) )
{ {
if( !vaDisplayIsValid(dpy) ) if (!vaDisplayIsValid(dpy))
return NULL; return NULL;
return CTX(dpy)->str_vendor; return CTX(dpy)->str_vendor;
...@@ -496,7 +458,7 @@ int vaMaxNumProfiles ( ...@@ -496,7 +458,7 @@ int vaMaxNumProfiles (
VADisplay dpy VADisplay dpy
) )
{ {
if( !vaDisplayIsValid(dpy) ) if (!vaDisplayIsValid(dpy))
return 0; return 0;
return CTX(dpy)->max_profiles; return CTX(dpy)->max_profiles;
...@@ -507,7 +469,7 @@ int vaMaxNumEntrypoints ( ...@@ -507,7 +469,7 @@ int vaMaxNumEntrypoints (
VADisplay dpy VADisplay dpy
) )
{ {
if( !vaDisplayIsValid(dpy) ) if (!vaDisplayIsValid(dpy))
return 0; return 0;
return CTX(dpy)->max_entrypoints; return CTX(dpy)->max_entrypoints;
...@@ -519,7 +481,7 @@ int vaMaxNumConfigAttributes ( ...@@ -519,7 +481,7 @@ int vaMaxNumConfigAttributes (
VADisplay dpy VADisplay dpy
) )
{ {
if( !vaDisplayIsValid(dpy) ) if (!vaDisplayIsValid(dpy))
return 0; return 0;
return CTX(dpy)->max_attributes; return CTX(dpy)->max_attributes;
...@@ -583,11 +545,11 @@ VAStatus vaCreateConfig ( ...@@ -583,11 +545,11 @@ VAStatus vaCreateConfig (
CHECK_DISPLAY(dpy); CHECK_DISPLAY(dpy);
ctx = CTX(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 ); /* record the current entrypoint for further trace/fool determination */
VA_TRACE_FUNC(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
VA_TRACE(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; return vaStatus;
} }
...@@ -638,9 +600,7 @@ VAStatus vaCreateSurfaces ( ...@@ -638,9 +600,7 @@ VAStatus vaCreateSurfaces (
vaStatus = ctx->vtable->vaCreateSurfaces( ctx, width, height, format, num_surfaces, surfaces ); vaStatus = ctx->vtable->vaCreateSurfaces( ctx, width, height, format, num_surfaces, surfaces );
VA_TRACE(va_TraceCreateSurface, dpy, width, height, format, num_surfaces, surfaces); VA_TRACE_LOG(va_TraceCreateSurface, dpy, width, height, format, num_surfaces, surfaces);
VA_FOOL(va_FoolCreateSurfaces, dpy, width, height, format, num_surfaces, surfaces);
return vaStatus; return vaStatus;
} }
...@@ -679,7 +639,8 @@ VAStatus vaCreateContext ( ...@@ -679,7 +639,8 @@ VAStatus vaCreateContext (
vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height, vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height,
flag, render_targets, num_render_targets, context ); 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; return vaStatus;
} }
...@@ -711,7 +672,7 @@ VAStatus vaCreateBuffer ( ...@@ -711,7 +672,7 @@ VAStatus vaCreateBuffer (
ctx = CTX(dpy); ctx = CTX(dpy);
int ret = 0; 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) if (ret)
return VA_STATUS_SUCCESS; return VA_STATUS_SUCCESS;
...@@ -727,7 +688,9 @@ VAStatus vaBufferSetNumElements ( ...@@ -727,7 +688,9 @@ VAStatus vaBufferSetNumElements (
VADriverContextP ctx; VADriverContextP ctx;
CHECK_DISPLAY(dpy); CHECK_DISPLAY(dpy);
ctx = CTX(dpy); ctx = CTX(dpy);
VA_FOOL_RETURN();
return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements ); return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
} }
...@@ -744,15 +707,14 @@ VAStatus vaMapBuffer ( ...@@ -744,15 +707,14 @@ VAStatus vaMapBuffer (
CHECK_DISPLAY(dpy); CHECK_DISPLAY(dpy);
ctx = CTX(dpy); ctx = CTX(dpy);
VA_FOOL(va_FoolMapBuffer, dpy, buf_id, pbuf); VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
if (ret) if (ret)
return VA_STATUS_SUCCESS; return VA_STATUS_SUCCESS;
va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf ); va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
if (va_status == VA_STATUS_SUCCESS) VA_TRACE_LOG(va_TraceMapBuffer, dpy, buf_id, pbuf);
VA_TRACE(va_TraceMapBuffer, dpy, buf_id, pbuf);
return va_status; return va_status;
} }
...@@ -767,7 +729,7 @@ VAStatus vaUnmapBuffer ( ...@@ -767,7 +729,7 @@ VAStatus vaUnmapBuffer (
ctx = CTX(dpy); ctx = CTX(dpy);
int ret = 0; int ret = 0;
VA_FOOL(va_FoolUnmapBuffer, dpy, buf_id); VA_FOOL_FUNC(va_FoolUnmapBuffer, dpy, buf_id);
if (ret) if (ret)
return VA_STATUS_SUCCESS; return VA_STATUS_SUCCESS;
...@@ -783,6 +745,8 @@ VAStatus vaDestroyBuffer ( ...@@ -783,6 +745,8 @@ VAStatus vaDestroyBuffer (
CHECK_DISPLAY(dpy); CHECK_DISPLAY(dpy);
ctx = CTX(dpy); ctx = CTX(dpy);
VA_FOOL_RETURN();
return ctx->vtable->vaDestroyBuffer( ctx, buffer_id ); return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
} }
...@@ -796,9 +760,15 @@ VAStatus vaBufferInfo ( ...@@ -796,9 +760,15 @@ VAStatus vaBufferInfo (
) )
{ {
VADriverContextP ctx; VADriverContextP ctx;
int ret = 0;
CHECK_DISPLAY(dpy); CHECK_DISPLAY(dpy);
ctx = CTX(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 ); return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
} }
...@@ -809,18 +779,18 @@ VAStatus vaBeginPicture ( ...@@ -809,18 +779,18 @@ VAStatus vaBeginPicture (
) )
{ {
VADriverContextP ctx; VADriverContextP ctx;
VAStatus va_status;
int ret = 0; int ret = 0;
CHECK_DISPLAY(dpy); CHECK_DISPLAY(dpy);
ctx = CTX(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) va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
return VA_STATUS_SUCCESS;
return va_status;
return ctx->vtable->vaBeginPicture( ctx, context, render_target );
} }
VAStatus vaRenderPicture ( VAStatus vaRenderPicture (
...@@ -836,11 +806,8 @@ VAStatus vaRenderPicture ( ...@@ -836,11 +806,8 @@ VAStatus vaRenderPicture (
CHECK_DISPLAY(dpy); CHECK_DISPLAY(dpy);
ctx = CTX(dpy); ctx = CTX(dpy);
VA_FOOL(va_FoolRenderPicture, dpy, context, buffers, num_buffers); VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
if (ret) VA_FOOL_RETURN();
return VA_STATUS_SUCCESS;
VA_TRACE(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers ); return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
} }
...@@ -857,15 +824,14 @@ VAStatus vaEndPicture ( ...@@ -857,15 +824,14 @@ VAStatus vaEndPicture (
CHECK_DISPLAY(dpy); CHECK_DISPLAY(dpy);
ctx = CTX(dpy); ctx = CTX(dpy);
VA_FOOL(va_FoolEndPicture, dpy, context); /* dump encode source surface */
if (ret) { VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 0);
VA_TRACE(va_TraceEndPicture, dpy, context); /* return directly if do dummy operation */
return VA_STATUS_SUCCESS; VA_FOOL_RETURN();
}
va_status = ctx->vtable->vaEndPicture( ctx, context ); va_status = ctx->vtable->vaEndPicture( ctx, context );
/* dump decode dest surface */
VA_TRACE(va_TraceEndPicture, dpy, context); VA_TRACE_SURFACE(va_TraceEndPicture, dpy, context, 1);
return va_status; return va_status;
} }
...@@ -882,12 +848,8 @@ VAStatus vaSyncSurface ( ...@@ -882,12 +848,8 @@ VAStatus vaSyncSurface (
CHECK_DISPLAY(dpy); CHECK_DISPLAY(dpy);
ctx = CTX(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_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; return va_status;
} }
...@@ -905,7 +867,7 @@ VAStatus vaQuerySurfaceStatus ( ...@@ -905,7 +867,7 @@ VAStatus vaQuerySurfaceStatus (
va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, 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; return va_status;
} }
...@@ -924,7 +886,7 @@ VAStatus vaQuerySurfaceError ( ...@@ -924,7 +886,7 @@ VAStatus vaQuerySurfaceError (
va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info ); 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; return va_status;
} }
...@@ -934,7 +896,7 @@ int vaMaxNumImageFormats ( ...@@ -934,7 +896,7 @@ int vaMaxNumImageFormats (
VADisplay dpy VADisplay dpy
) )
{ {
if( !vaDisplayIsValid(dpy) ) if (!vaDisplayIsValid(dpy))
return 0; return 0;
return CTX(dpy)->max_image_formats; return CTX(dpy)->max_image_formats;
...@@ -1100,7 +1062,7 @@ int vaMaxNumSubpictureFormats ( ...@@ -1100,7 +1062,7 @@ int vaMaxNumSubpictureFormats (
VADisplay dpy VADisplay dpy
) )
{ {
if( !vaDisplayIsValid(dpy) ) if (!vaDisplayIsValid(dpy))
return 0; return 0;
return CTX(dpy)->max_subpic_formats; return CTX(dpy)->max_subpic_formats;
...@@ -1126,10 +1088,6 @@ VAStatus vaQuerySubpictureFormats ( ...@@ -1126,10 +1088,6 @@ VAStatus vaQuerySubpictureFormats (
CHECK_DISPLAY(dpy); CHECK_DISPLAY(dpy);
ctx = CTX(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); return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
} }
...@@ -1275,12 +1233,12 @@ int vaMaxNumDisplayAttributes ( ...@@ -1275,12 +1233,12 @@ int vaMaxNumDisplayAttributes (
{ {
int tmp; int tmp;
if( !vaDisplayIsValid(dpy) ) if (!vaDisplayIsValid(dpy))
return 0; return 0;
tmp = CTX(dpy)->max_display_attributes; tmp = CTX(dpy)->max_display_attributes;
VA_TRACE(va_TraceMaxNumDisplayAttributes, dpy, tmp); VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
return tmp; return tmp;
} }
...@@ -1298,14 +1256,13 @@ VAStatus vaQueryDisplayAttributes ( ...@@ -1298,14 +1256,13 @@ VAStatus vaQueryDisplayAttributes (
) )
{ {
VADriverContextP ctx; VADriverContextP ctx;
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
VAStatus va_status; VAStatus va_status;
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes ); 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; return va_status;
...@@ -1324,14 +1281,13 @@ VAStatus vaGetDisplayAttributes ( ...@@ -1324,14 +1281,13 @@ VAStatus vaGetDisplayAttributes (
) )
{ {
VADriverContextP ctx; VADriverContextP ctx;
VAStatus va_status;
CHECK_DISPLAY(dpy); CHECK_DISPLAY(dpy);
ctx = CTX(dpy); ctx = CTX(dpy);
VAStatus va_status;
va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes ); 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; return va_status;
} }
...@@ -1349,13 +1305,14 @@ VAStatus vaSetDisplayAttributes ( ...@@ -1349,13 +1305,14 @@ VAStatus vaSetDisplayAttributes (
) )
{ {
VADriverContextP ctx; VADriverContextP ctx;
VAStatus va_status;
CHECK_DISPLAY(dpy); CHECK_DISPLAY(dpy);
ctx = CTX(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, VAStatus vaLockSurface(VADisplay dpy,
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#include <fcntl.h>
/* /*
* Do dummy decode/encode, ignore the input data * Do dummy decode/encode, ignore the input data
...@@ -46,42 +47,37 @@ ...@@ -46,42 +47,37 @@
* We export env "VA_FOOL", with which, we can do fake decode/encode: * We export env "VA_FOOL", with which, we can do fake decode/encode:
* *
* LIBVA_FOOL_DECODE: * LIBVA_FOOL_DECODE:
* . if set, decode does nothing, but fill in some YUV data * . if set, decode does nothing
* LIBVA_FOOL_ENCODE=<clip name>: * LIBVA_FOOL_ENCODE=<framename>:
* . if set, encode does nothing, but fill in the coded buffer from a H264 clip. * . if set, encode does nothing, but fill in the coded buffer from the content of files with
* . VA CONTEXT/CONFIG/SURFACE will call into drivers, but VA Buffer creation is done in here * name framename.0,framename.1,framename.2, ..., framename.N, framename.N,framename.N,...
* . Bypass all "vaBeginPic/vaRenderPic/vaEndPic" * LIBVA_FOOL_JPEG=<framename>:fill the content of filename to codedbuf for jpeg encoding
* LIBVA_FOOL_POSTP: * LIBVA_FOOL_POSTP:
* . if set, do nothing for vaPutSurface * . if set, do nothing for vaPutSurface
*/ */
/* global settings */ /* global settings */
int fool_codec = 0;
/* LIBVA_FOOL_DECODE/LIBVA_FOOL_ENCODE/LIBVA_FOOL_POSTP */
int fool_decode = 0;
int fool_encode = 0;
int fool_postp = 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_CONTEXT_MAX 4
#define FOOL_BUFID_MAGIC 0x12345600
#define FOOL_BUFID_MASK 0xffffff00
/* per context settings */ /* per context settings */
static struct _fool_context { static struct _fool_context {
VADisplay dpy; /* should use context as the key */ VADisplay dpy; /* should use context as the key */
VAProfile fool_profile; /* current profile for buffers */ char *fn_enc;/* file pattern with codedbuf content for encode */
VAEntrypoint fool_entrypoint; /* current entrypoint */ 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 *fn_jpg;/* file name of JPEG fool with codedbuf content */
char *frame_buf; char *segbuf_jpg; /* the segment buffer of coded buffer, load frome fn_jpg */
VACodedBufferSegment *codebuf;
VAEntrypoint entrypoint; /* current entrypoint */
/* all buffers with same type share one malloc-ed memory /* all buffers with same type share one malloc-ed memory
* bufferID = (buffer numbers with the same type << 8) || type * bufferID = (buffer numbers with the same type << 8) || type
* the malloc-ed memory can be find by fool_buf[bufferID & 0xff] * the malloc-ed memory can be find by fool_buf[bufferID & 0xff]
...@@ -89,18 +85,10 @@ static struct _fool_context { ...@@ -89,18 +85,10 @@ static struct _fool_context {
*/ */
char *fool_buf[VABufferTypeMax]; /* memory of fool buffers */ char *fool_buf[VABufferTypeMax]; /* memory of fool buffers */
unsigned int fool_buf_size[VABufferTypeMax]; /* size of 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 */ unsigned int fool_buf_count[VABufferTypeMax]; /* count of created buffers */
VAContextID context; VAContextID context;
} fool_context[FOOL_CONTEXT_MAX] = { {0} }; /* trace five context at the same time */ } fool_context[FOOL_CONTEXT_MAX]; /* trace five context at the same time */
#define FOOL_DECODE(idx) (fool_decode && (fool_context[idx].fool_entrypoint == VAEntrypointVLD))
#define FOOL_ENCODE(idx) \
(fool_encode \
&& (fool_context[idx].fool_entrypoint == VAEntrypointEncSlice) \
&& (fool_context[idx].fool_profile >= VAProfileH264Baseline) \
&& (fool_context[idx].fool_profile <= VAProfileH264High))
#define DPY2INDEX(dpy) \ #define DPY2INDEX(dpy) \
int idx; \ int idx; \
...@@ -112,40 +100,12 @@ static struct _fool_context { ...@@ -112,40 +100,12 @@ static struct _fool_context {
if (idx == FOOL_CONTEXT_MAX) \ if (idx == FOOL_CONTEXT_MAX) \
return 0; /* let driver go */ return 0; /* let driver go */
/* Prototype declarations (functions defined in va.c) */ /* Prototype declarations (functions defined in va.c) */
void va_errorMessage(const char *msg, ...); void va_errorMessage(const char *msg, ...);
void va_infoMessage(const char *msg, ...); void va_infoMessage(const char *msg, ...);
int va_parseConfig(char *env, char *env_value); 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) void va_FoolInit(VADisplay dpy)
{ {
...@@ -159,41 +119,30 @@ void va_FoolInit(VADisplay dpy) ...@@ -159,41 +119,30 @@ void va_FoolInit(VADisplay dpy)
if (fool_index == FOOL_CONTEXT_MAX) if (fool_index == FOOL_CONTEXT_MAX)
return; return;
memset(&fool_context[fool_index], 0, sizeof(struct _fool_context));
if (va_parseConfig("LIBVA_FOOL_POSTP", NULL) == 0) { if (va_parseConfig("LIBVA_FOOL_POSTP", NULL) == 0) {
fool_postp = 1; fool_postp = 1;
va_infoMessage("LIBVA_FOOL_POSTP is on, dummy vaPutSurface\n"); va_infoMessage("LIBVA_FOOL_POSTP is on, dummy vaPutSurface\n");
} }
if (va_parseConfig("LIBVA_FOOL_DECODE", NULL) == 0) { 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"); va_infoMessage("LIBVA_FOOL_DECODE is on, dummy decode\n");
} }
if (va_parseConfig("LIBVA_FOOL_ENCODE", &env_value[0]) == 0) { if (va_parseConfig("LIBVA_FOOL_ENCODE", &env_value[0]) == 0) {
fool_context[fool_index].fool_fp_codedclip = fopen(env_value, "r"); fool_codec |= VA_FOOL_FLAG_ENCODE;
fool_context[fool_index].fn_enc = strdup(env_value);
if (fool_context[fool_index].fool_fp_codedclip) { va_infoMessage("LIBVA_FOOL_ENCODE is on, load encode data from file with patten %s\n",
fool_encode = 1; fool_context[fool_index].fn_enc);
} 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");
} }
if (va_parseConfig("LIBVA_FOOL_JPEG", &env_value[0]) == 0) {
if (fool_encode || fool_decode) 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; fool_context[fool_index].dpy = dpy;
} }
...@@ -201,29 +150,23 @@ void va_FoolInit(VADisplay dpy) ...@@ -201,29 +150,23 @@ void va_FoolInit(VADisplay dpy)
int va_FoolEnd(VADisplay dpy) int va_FoolEnd(VADisplay dpy)
{ {
int i; int i;
DPY2INDEX(dpy); DPY2INDEX(dpy);
for (i = 0; i < VABufferTypeMax; i++) {/* free memory */ for (i = 0; i < VABufferTypeMax; i++) {/* free memory */
if (fool_context[idx].fool_buf[i]) if (fool_context[idx].fool_buf[i])
free(fool_context[idx].fool_buf[i]); free(fool_context[idx].fool_buf[i]);
} }
if (fool_context[idx].fool_fp_codedclip) if (fool_context[idx].segbuf_enc)
fclose(fool_context[idx].fool_fp_codedclip); free(fool_context[idx].segbuf_enc);
if (fool_context[idx].segbuf_jpg)
if (fool_context[idx].frame_buf) free(fool_context[idx].segbuf_jpg);
free(fool_context[idx].frame_buf); 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)); memset(&fool_context[idx], 0, sizeof(struct _fool_context));
return 0;
}
int va_FoolCodedBuf(VADisplay dpy)
{
/* do nothing */
return 0; return 0;
} }
...@@ -239,310 +182,175 @@ int va_FoolCreateConfig( ...@@ -239,310 +182,175 @@ int va_FoolCreateConfig(
{ {
DPY2INDEX(dpy); DPY2INDEX(dpy);
/* call into driver level to allocate real context/surface/buffers, etc */ fool_context[idx].entrypoint = entrypoint;
fool_context[idx].fool_profile = profile;
fool_context[idx].fool_entrypoint = entrypoint; /*
return 0; * 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
static int yuvgen_planar( * which is not desired
int width, int height, */
unsigned char *Y_start, int Y_pitch, if (((fool_codec & VA_FOOL_FLAG_DECODE) && (entrypoint == VAEntrypointVLD)) ||
unsigned char *U_start, int U_pitch, ((fool_codec & VA_FOOL_FLAG_ENCODE) && (entrypoint == VAEntrypointEncSlice)) ||
unsigned char *V_start, int V_pitch, ((fool_codec & VA_FOOL_FLAG_JPEG) && (entrypoint == VAEntrypointEncPicture)))
int UV_interleave, int box_width, int row_shift, ; /* the fool_codec is meaningful */
int field else
) fool_codec = 0;
{
int row; return 0; /* driver continue */
/* 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( VAStatus va_FoolCreateBuffer(
VADisplay dpy, VADisplay dpy,
int width, VAContextID context, /* in */
int height, VABufferType type, /* in */
int format, unsigned int size, /* in */
int num_surfaces, unsigned int num_elements, /* in */
VASurfaceID *surfaces /* out */ void *data, /* in */
VABufferID *buf_id /* out */
) )
{ {
int i; unsigned int new_size = size * num_elements;
unsigned int fourcc; /* following are output argument */ unsigned int old_size;
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); DPY2INDEX(dpy);
if (FOOL_DECODE(idx)) { old_size = fool_context[idx].fool_buf_size[type] * fool_context[idx].fool_buf_element[type];
/* call into driver level to allocate real context/surface/buffers, etc
* fill in the YUV data, will be overwrite if it is encode context if (old_size < new_size)
*/ fool_context[idx].fool_buf[type] = realloc(fool_context[idx].fool_buf[type], new_size);
for (i = 0; i < num_surfaces; i++) {
/* fool decoder: fill with auto-generated YUV data */ fool_context[idx].fool_buf_size[type] = size;
va_status = vaLockSurface(dpy, surfaces[i], &fourcc, fool_context[idx].fool_buf_element[type] = num_elements;
&luma_stride, &chroma_u_stride, &chroma_v_stride, fool_context[idx].fool_buf_count[type]++;
&luma_offset, &chroma_u_offset, &chroma_v_offset, /* because we ignore the vaRenderPicture,
&buffer_name, &buffer); * all buffers with same type share same real memory
* bufferID = (magic number) | type
if (va_status != VA_STATUS_SUCCESS) */
return 0; *buf_id = FOOL_BUFID_MAGIC | type;
if (!buffer) { return 1; /* don't call into driver */
vaUnlockSurface(dpy, surfaces[i]);
return 0;
}
Y_data = buffer;
/* UV should be same for NV12 */
U_data = buffer + chroma_u_offset;
V_data = buffer + chroma_v_offset;
yuvgen_planar(width, height,
Y_data, luma_stride,
U_data, chroma_v_stride,
V_data, chroma_v_stride,
(fourcc==VA_FOURCC_NV12),
box_width, row_shift, 0);
vaUnlockSurface(dpy, surfaces[i]);
row_shift++;
if (row_shift==(2*box_width))
row_shift= 0;
}
return 0; /* the return value is ignored */
}
return 0; /* the return value is ignored */
} }
VAStatus va_FoolCreateBuffer ( VAStatus va_FoolBufferInfo(
VADisplay dpy, VADisplay dpy,
VAContextID context, /* in */ VABufferID buf_id, /* in */
VABufferType type, /* in */ VABufferType *type, /* out */
unsigned int size, /* in */ unsigned int *size, /* out */
unsigned int num_elements, /* in */ unsigned int *num_elements /* out */
void *data, /* in */
VABufferID *buf_id /* out */
) )
{ {
unsigned int magic = buf_id & FOOL_BUFID_MASK;
DPY2INDEX(dpy); DPY2INDEX(dpy);
if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) { /* fool buffer creation */ if (magic != FOOL_BUFID_MAGIC)
int new_size = size * num_elements; return 0;
if (type == VAEncCodedBufferType) /* only a VACodedBufferSegment */
new_size = sizeof(VACodedBufferSegment);
if (fool_context[idx].fool_buf_size[type] == 0)
fool_context[idx].fool_buf[type] = calloc(1, new_size);
else if (fool_context[idx].fool_buf_size[type] <= new_size)
fool_context[idx].fool_buf[type] = realloc(fool_context[idx].fool_buf, new_size);
if (fool_context[idx].fool_buf[type] == NULL) {
va_FoolEnd(dpy);
return 0; /* let driver go */
}
/* because we ignore the vaRenderPicture,
* all buffers with same type share same real memory
* bufferID = (buffer count << 8) | type
*/
fool_context[idx].fool_buf_count[type]++;
*buf_id = (fool_context[idx].fool_buf_count[type] << 8) | type;
return 1; /* don't call into driver */
}
return 0; /* let driver go ... */ *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 ( static int va_FoolFillCodedBufEnc(int idx)
VADisplay dpy,
VABufferID buf_id, /* in */
void **pbuf /* out */
)
{ {
VABufferType type; char file_name[1024];
unsigned int size,frame_size = 0; struct stat file_stat;
unsigned int num_elements; VACodedBufferSegment *codedbuf;
DPY2INDEX(dpy); int i, fd = -1;
if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) { /* fool buffer creation */ /* try file_name.file_count, if fail, try file_name.file_count-- */
unsigned int buf_idx = buf_id & 0xff; for (i=0; i<=1; i++) {
sprintf(file_name, "%s.%d",
/* Image buffer? */ fool_context[idx].fn_enc,
vaBufferInfo(dpy, fool_context[idx].context, buf_id, &type, &size, &num_elements); fool_context[idx].file_count);
if (type == VAImageBufferType && FOOL_ENCODE(idx))
return 0; if ((fd = open(file_name, O_RDONLY)) != -1) {
fstat(fd, &file_stat);
/* buf_id is the buffer type */ fool_context[idx].file_count++; /* open next file */
if (fool_context[idx].fool_buf[buf_idx] != NULL) break;
*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 */
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( static int va_FoolFillCodedBufJPG(int idx)
VADisplay dpy,
VAContextID context,
VASurfaceID render_target
)
{ {
DPY2INDEX(dpy); struct stat file_stat;
VACodedBufferSegment *codedbuf;
if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) { int i, fd = -1;
if (fool_context[idx].context == 0)
fool_context[idx].context = context; if ((fd = open(fool_context[idx].fn_jpg, O_RDONLY)) != -1)
return 1; /* don't call into driver level */ 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 ... */ return 0;
}
int va_FoolRenderPicture(
VADisplay dpy,
VAContextID context,
VABufferID *buffers,
int num_buffers
)
{
DPY2INDEX(dpy);
if (FOOL_ENCODE(idx) || FOOL_DECODE(idx))
return 1; /* don't call into driver level */
return 0; /* let driver go ... */
} }
int va_FoolEndPicture( static int va_FoolFillCodedBuf(int idx)
VADisplay dpy,
VAContextID context
)
{ {
DPY2INDEX(dpy); if (fool_context[idx].entrypoint == VAEntrypointEncSlice)
va_FoolFillCodedBufEnc(idx);
/* don't call into driver level */ else if (fool_context[idx].entrypoint == VAEntrypointEncPicture)
va_FoolFillCodedBufJPG(idx);
/* do real fooling operation here */
return 0;
/* only support H264 encoding currently */
if (FOOL_ENCODE(idx)) {
/* expect vaMapBuffer will handle it
* or else, need to save the codedbuf ID,
* and fool encode it here
*/
/* va_FoolCodedBuf(dpy); */
return 1; /* don't call into driver level */
}
if (FOOL_DECODE(idx))
return 1; /* don't call into driver level */
return 0; /* let driver go ... */
} }
int va_FoolSyncSurface(
VADisplay dpy, VAStatus va_FoolMapBuffer(
VASurfaceID render_target 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); DPY2INDEX(dpy);
/*Fill in black and white squares. */ if (magic != FOOL_BUFID_MAGIC)
if (FOOL_DECODE(idx) || FOOL_DECODE(idx)) return 0;
return 1;
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( VAStatus va_FoolUnmapBuffer(
...@@ -550,28 +358,10 @@ VAStatus va_FoolUnmapBuffer( ...@@ -550,28 +358,10 @@ VAStatus va_FoolUnmapBuffer(
VABufferID buf_id /* in */ VABufferID buf_id /* in */
) )
{ {
DPY2INDEX(dpy); unsigned int magic = buf_id & FOOL_BUFID_MASK;
if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) if (magic != FOOL_BUFID_MAGIC)
return 1; /* fool buffer creation */ 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;
}
...@@ -28,35 +28,40 @@ ...@@ -28,35 +28,40 @@
#include <stdio.h> #include <stdio.h>
void va_FoolInit(VADisplay dpy); #ifdef __cplusplus
extern "C" {
int va_FoolEnd(VADisplay dpy); #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( int va_FoolCreateConfig(
VADisplay dpy, VADisplay dpy,
VAProfile profile, VAProfile profile,
VAEntrypoint entrypoint, VAEntrypoint entrypoint,
VAConfigAttrib *attrib_list, VAConfigAttrib *attrib_list,
int num_attribs, int num_attribs,
VAConfigID *config_id /* out */ 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, VADisplay dpy,
VAContextID context, /* in */ VAContextID context, /* in */
VABufferType type, /* in */ VABufferType type, /* in */
...@@ -72,41 +77,22 @@ VAStatus va_FoolMapBuffer ( ...@@ -72,41 +77,22 @@ VAStatus va_FoolMapBuffer (
void **pbuf /* out */ void **pbuf /* out */
); );
int va_FoolBeginPicture( VAStatus va_FoolUnmapBuffer(
VADisplay dpy, VADisplay dpy,
VAContextID context, VABufferID buf_id /* in */
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_FoolBufferInfo (
VAStatus va_FoolQuerySubpictureFormats (
VADisplay dpy, VADisplay dpy,
VAImageFormat *format_list, VABufferID buf_id, /* in */
unsigned int *flags, VABufferType *type, /* out */
unsigned int *num_formats unsigned int *size, /* out */
); unsigned int *num_elements /* out */
int va_FoolSyncSurface(
VADisplay dpy,
VASurfaceID render_target
); );
#ifdef __cplusplus
}
#endif
#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 @@ ...@@ -40,29 +40,25 @@
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
/* /*
* Env. to debug some issue, e.g. the decode/encode issue in a video conference scenerio: * 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=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_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_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 * .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 * when the size is bigger than the number
*/ */
/* global settings */ /* global settings */
/* LIBVA_TRACE */ /* LIBVA_TRACE */
unsigned int trace_flag = 0; int trace_flag = 0;
/* LIBVA_TRACE_LOGSIZE */ /* LIBVA_TRACE_LOGSIZE */
static unsigned int trace_logsize = 0xffffffff; /* truncate the log when the size is bigger than it */ 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 #define TRACE_CONTEXT_MAX 4
/* per context settings */ /* per context settings */
static struct _trace_context { static struct _trace_context {
...@@ -70,15 +66,15 @@ static struct _trace_context { ...@@ -70,15 +66,15 @@ static struct _trace_context {
/* LIBVA_TRACE */ /* LIBVA_TRACE */
FILE *trace_fp_log; /* save the log into a file */ 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 */ /* LIBVA_TRACE_CODEDBUF */
FILE *trace_fp_codedbuf; /* save the encode result into a file */ 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 */ /* LIBVA_TRACE_SURFACE */
FILE *trace_fp_surface; /* save the surface YUV into a file */ 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 */ VAContextID trace_context; /* current context */
...@@ -94,7 +90,7 @@ static struct _trace_context { ...@@ -94,7 +90,7 @@ static struct _trace_context {
unsigned int trace_frame_width; /* current frame width */ unsigned int trace_frame_width; /* current frame width */
unsigned int trace_frame_height; /* current frame height */ unsigned int trace_frame_height; /* current frame height */
unsigned int trace_sequence_start; /* get a new sequence for encoding or not */ 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) \ #define DPY2INDEX(dpy) \
int idx; \ int idx; \
...@@ -141,11 +137,22 @@ VAStatus vaUnlockSurface(VADisplay dpy, ...@@ -141,11 +137,22 @@ VAStatus vaUnlockSurface(VADisplay dpy,
VASurfaceID surface 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) void va_TraceInit(VADisplay dpy)
{ {
char env_value[1024]; char env_value[1024];
unsigned int suffix = 0xffff & ((unsigned int)time(NULL)); unsigned short suffix = 0xffff & ((unsigned int)time(NULL));
int trace_index = 0; int trace_index = 0;
FILE *tmp; FILE *tmp;
...@@ -156,79 +163,59 @@ void va_TraceInit(VADisplay dpy) ...@@ -156,79 +163,59 @@ void va_TraceInit(VADisplay dpy)
if (trace_index == TRACE_CONTEXT_MAX) if (trace_index == TRACE_CONTEXT_MAX)
return; return;
memset(&trace_context[trace_index], 0, sizeof(struct _trace_context));
if (va_parseConfig("LIBVA_TRACE", &env_value[0]) == 0) { if (va_parseConfig("LIBVA_TRACE", &env_value[0]) == 0) {
trace_flag = 1; FILE_NAME_SUFFIX(env_value);
trace_context[trace_index].trace_log_fn = strdup(env_value);
/*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);
tmp = fopen(env_value, "w"); tmp = fopen(env_value, "w");
if (tmp) { if (tmp) {
trace_context[trace_index].trace_fp_log = tmp; trace_context[trace_index].trace_fp_log = tmp;
strcpy(trace_context[trace_index].trace_log_fn, env_value); va_infoMessage("LIBVA_TRACE is on, save log into %s\n", trace_context[trace_index].trace_log_fn);
} else { trace_flag = VA_TRACE_FLAG_LOG;
} else
va_errorMessage("Open file %s failed (%s)\n", env_value, strerror(errno)); 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 */ /* may re-get the global settings for multiple context */
if (va_parseConfig("LIBVA_TRACE_LOGSIZE", &env_value[0]) == 0) { if (va_parseConfig("LIBVA_TRACE_LOGSIZE", &env_value[0]) == 0) {
trace_logsize = atoi(env_value); trace_logsize = atoi(env_value);
va_infoMessage("LIBVA_TRACE_LOGSIZE is on, size is %d\n", trace_logsize); va_infoMessage("LIBVA_TRACE_LOGSIZE is on, size is %d\n", trace_logsize);
} }
if (va_parseConfig("LIBVA_TRACE_BUFDATA", NULL) == 0) { if ((trace_flag & VA_TRACE_FLAG_LOG) && (va_parseConfig("LIBVA_TRACE_BUFDATA", NULL) == 0)) {
trace_buffer_data = 1; /* dump buffer data */ trace_flag |= VA_TRACE_FLAG_BUFDATA;
va_infoMessage("LIBVA_TRACE_BUFDATA is on, dump buffer into log file\n"); va_infoMessage("LIBVA_TRACE_BUFDATA is on, dump buffer into log file\n");
} }
/* per-context setting */ /* per-context setting */
if (va_parseConfig("LIBVA_TRACE_CODEDBUF", &env_value[0]) == 0) { if (va_parseConfig("LIBVA_TRACE_CODEDBUF", &env_value[0]) == 0) {
if (strnlen(env_value, 1024) < (1024 - 8)) FILE_NAME_SUFFIX(env_value);
snprintf(env_value+strnlen(env_value, 1024), trace_context[trace_index].trace_codedbuf_fn = strdup(env_value);
(1025 - 8 - strnlen(env_value, 1024)), va_infoMessage("LIBVA_TRACE_CODEDBUF is on, save codedbuf into log file %s\n",
".%d.%d", trace_index, suffix); trace_context[trace_index].trace_codedbuf_fn);
trace_flag |= VA_TRACE_FLAG_CODEDBUF;
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);
} }
if (va_parseConfig("LIBVA_TRACE_SURFACE", &env_value[0]) == 0) { 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");
if (tmp) { va_infoMessage("LIBVA_TRACE_SURFACE is on, save surface into %s\n",
trace_context[trace_index].trace_fp_surface = tmp; trace_context[trace_index].trace_surface_fn);
strcpy(trace_context[trace_index].trace_surface_fn, env_value);
} else { /* for surface data dump, it is time-consume, and may
va_errorMessage("Open file %s failed (%s)\n", env_value, strerror(errno)); * cause some side-effect, so only trace the needed surfaces
trace_context[trace_index].trace_fp_surface = stderr; * to trace encode surface, set the trace file name to sth like *enc*
strcpy(trace_context[trace_index].trace_surface_fn, "/dev/stderr"); * to trace decode surface, set the trace file name to sth like *dec*
} * if no dec/enc in file name, set both
*/
va_infoMessage("LIBVA_TRACE_SURFACE is on, save coded clip into %s\n", trace_context[trace_index].trace_surface_fn); 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; trace_context[trace_index].dpy = dpy;
...@@ -239,15 +226,24 @@ void va_TraceEnd(VADisplay dpy) ...@@ -239,15 +226,24 @@ void va_TraceEnd(VADisplay dpy)
{ {
DPY2INDEX(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); 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); 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); 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)); memset(&trace_context[idx], 0, sizeof(struct _trace_context));
} }
...@@ -272,9 +268,11 @@ void va_TraceMsg(int idx, const char *msg, ...) ...@@ -272,9 +268,11 @@ void va_TraceMsg(int idx, const char *msg, ...)
{ {
va_list args; va_list args;
if (!(trace_flag & VA_TRACE_FLAG_LOG))
return;
if (file_size(trace_context[idx].trace_fp_log) >= trace_logsize) if (file_size(trace_context[idx].trace_fp_log) >= trace_logsize)
truncate_file(trace_context[idx].trace_fp_log); truncate_file(trace_context[idx].trace_fp_log);
if (msg) { if (msg) {
va_start(args, msg); va_start(args, msg);
vfprintf(trace_context[idx].trace_fp_log, msg, args); vfprintf(trace_context[idx].trace_fp_log, msg, args);
...@@ -341,7 +339,7 @@ void va_TraceSurface(VADisplay dpy) ...@@ -341,7 +339,7 @@ void va_TraceSurface(VADisplay dpy)
VAStatus va_status; VAStatus va_status;
unsigned char check_sum = 0; unsigned char check_sum = 0;
DPY2INDEX(dpy); DPY2INDEX(dpy);
va_TraceMsg(idx, "==========dump surface data in file %s\n", trace_context[idx].trace_surface_fn); 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)) { if ((file_size(trace_context[idx].trace_fp_surface) >= trace_logsize)) {
...@@ -388,21 +386,14 @@ void va_TraceSurface(VADisplay dpy) ...@@ -388,21 +386,14 @@ void va_TraceSurface(VADisplay dpy)
tmp = Y_data; tmp = Y_data;
for (i=0; i<trace_context[idx].trace_frame_height; i++) { 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) if (trace_context[idx].trace_fp_surface)
fwrite(tmp, trace_context[idx].trace_frame_width, 1, 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 = Y_data + i * luma_stride;
} }
tmp = UV_data; tmp = UV_data;
if (fourcc == VA_FOURCC_NV12) { if (fourcc == VA_FOURCC_NV12) {
for (i=0; i<trace_context[idx].trace_frame_height/2; i++) { 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) if (trace_context[idx].trace_fp_surface)
fwrite(tmp, trace_context[idx].trace_frame_width, 1, 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) ...@@ -412,7 +403,6 @@ void va_TraceSurface(VADisplay dpy)
vaUnlockSurface(dpy, trace_context[idx].trace_rendertarget); vaUnlockSurface(dpy, trace_context[idx].trace_rendertarget);
va_TraceMsg(idx, "\tchecksum = 0x%02x\n", check_sum & 0xff);
va_TraceMsg(idx, NULL); va_TraceMsg(idx, NULL);
} }
...@@ -446,6 +436,7 @@ void va_TraceCreateConfig( ...@@ -446,6 +436,7 @@ void va_TraceCreateConfig(
) )
{ {
int i; int i;
int encode, decode, jpeg;
DPY2INDEX(dpy); DPY2INDEX(dpy);
TRACE_FUNCNAME(idx); TRACE_FUNCNAME(idx);
...@@ -461,6 +452,40 @@ void va_TraceCreateConfig( ...@@ -461,6 +452,40 @@ void va_TraceCreateConfig(
trace_context[idx].trace_profile = profile; trace_context[idx].trace_profile = profile;
trace_context[idx].trace_entrypoint = entrypoint; 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( ...@@ -610,10 +635,10 @@ static void va_TraceVABuffers(
for (i=0; i<size; i++) { for (i=0; i<size; i++) {
unsigned char value = p[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); va_TraceMsg(idx, "\n0x%08x:", i);
if (trace_buffer_data) if (trace_flag & VA_TRACE_FLAG_BUFDATA)
va_TraceMsg(idx, " %02x", value); va_TraceMsg(idx, " %02x", value);
check_sum ^= value; check_sum ^= value;
...@@ -1901,7 +1926,7 @@ void va_TraceRenderPicture( ...@@ -1901,7 +1926,7 @@ void va_TraceRenderPicture(
va_TraceMsg(idx, "\tcontext = 0x%08x\n", context); va_TraceMsg(idx, "\tcontext = 0x%08x\n", context);
va_TraceMsg(idx, "\tnum_buffers = %d\n", num_buffers); va_TraceMsg(idx, "\tnum_buffers = %d\n", num_buffers);
for (i = 0; i < num_buffers; i++) { for (i = 0; i < num_buffers; i++) {
void *pbuf; unsigned char *pbuf;
unsigned int j; unsigned int j;
/* get buffer type information */ /* get buffer type information */
...@@ -1913,7 +1938,7 @@ void va_TraceRenderPicture( ...@@ -1913,7 +1938,7 @@ void va_TraceRenderPicture(
va_TraceMsg(idx, "\t size = %d\n", size); va_TraceMsg(idx, "\t size = %d\n", size);
va_TraceMsg(idx, "\t num_elements = %d\n", num_elements); 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) { switch (trace_context[idx].trace_profile) {
case VAProfileMPEG2Simple: case VAProfileMPEG2Simple:
...@@ -1980,36 +2005,46 @@ void va_TraceRenderPicture( ...@@ -1980,36 +2005,46 @@ void va_TraceRenderPicture(
va_TraceMsg(idx, NULL); va_TraceMsg(idx, NULL);
} }
void va_TraceEndPicture( void va_TraceEndPicture(
VADisplay dpy, VADisplay dpy,
VAContextID context VAContextID context,
int endpic_done
) )
{ {
int encode, decode, jpeg;
DPY2INDEX(dpy); DPY2INDEX(dpy);
TRACE_FUNCNAME(idx); 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 (endpic_done == 0) {
if (trace_context[idx].trace_fp_codedbuf && va_TraceMsg(idx, "\tcontext = 0x%08x\n", context);
((trace_context[idx].trace_entrypoint == VAEntrypointEncSlice) || va_TraceMsg(idx, "\trender_targets = 0x%08x\n", trace_context[idx].trace_rendertarget);
(trace_context[idx].trace_entrypoint == VAEntrypointEncPicture))) { }
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 */ /* force the pipleline finish rendering */
vaSyncSurface(dpy, trace_context[idx].trace_rendertarget); vaSyncSurface(dpy, trace_context[idx].trace_rendertarget);
va_TraceCodedBuf(dpy); va_TraceCodedBuf(dpy);
} }
/* trace decoded surface for decoding, or the source sourface for encoding */ /* want to trace decode dest surface, do it after vaEndPicture */
if (trace_context[idx].trace_fp_surface) { if (decode && (endpic_done == 1)) {
/* force the pipleline finish rendering */ /* force the pipleline finish rendering */
vaSyncSurface(dpy, trace_context[idx].trace_rendertarget); vaSyncSurface(dpy, trace_context[idx].trace_rendertarget);
va_TraceSurface(dpy); va_TraceSurface(dpy);
} }
va_TraceMsg(idx, NULL); va_TraceMsg(idx, NULL);
} }
......
...@@ -25,6 +25,35 @@ ...@@ -25,6 +25,35 @@
#ifndef VA_TRACE_H #ifndef VA_TRACE_H
#define 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_TraceInit(VADisplay dpy);
void va_TraceEnd(VADisplay dpy); void va_TraceEnd(VADisplay dpy);
...@@ -92,7 +121,8 @@ void va_TraceRenderPicture( ...@@ -92,7 +121,8 @@ void va_TraceRenderPicture(
void va_TraceEndPicture( void va_TraceEndPicture(
VADisplay dpy, VADisplay dpy,
VAContextID context VAContextID context,
int endpic_done
); );
void va_TraceSyncSurface( void va_TraceSyncSurface(
...@@ -155,6 +185,9 @@ void va_TracePutSurface ( ...@@ -155,6 +185,9 @@ void va_TracePutSurface (
unsigned int flags /* de-interlacing flags */ unsigned int flags /* de-interlacing flags */
); );
#ifdef __cplusplus
}
#endif
#endif /* VA_TRACE_H */ #endif /* VA_TRACE_H */
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include "sysdeps.h" #include "sysdeps.h"
#include "va.h" #include "va.h"
#include "va_backend.h" #include "va_backend.h"
#include "va_trace.h"
#include "va_fool.h"
#include "va_x11.h" #include "va_x11.h"
#include "va_dri.h" #include "va_dri.h"
#include "va_dri2.h" #include "va_dri2.h"
...@@ -208,13 +210,6 @@ VADisplay vaGetDisplay ( ...@@ -208,13 +210,6 @@ VADisplay vaGetDisplay (
#define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext) #define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
#define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; } #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 ( void va_TracePutSurface (
VADisplay dpy, VADisplay dpy,
VASurfaceID surface, VASurfaceID surface,
...@@ -258,8 +253,8 @@ VAStatus vaPutSurface ( ...@@ -258,8 +253,8 @@ VAStatus vaPutSurface (
CHECK_DISPLAY(dpy); CHECK_DISPLAY(dpy);
ctx = CTX(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, destx, desty, destw, desth,
cliprects, number_cliprects, flags ); cliprects, number_cliprects, flags );
return ctx->vtable->vaPutSurface( ctx, surface, (void *)draw, srcx, srcy, srcw, srch, return ctx->vtable->vaPutSurface( ctx, surface, (void *)draw, srcx, srcy, srcw, srch,
......
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