diff options
author | Austin Yuan <shengquan.yuan@intel.com> | 2012-08-08 11:34:00 +0800 |
---|---|---|
committer | Austin Yuan <shengquan.yuan@intel.com> | 2012-08-08 11:34:00 +0800 |
commit | 5190a7465756a41808a562c8eccec521dbf77d8c (patch) | |
tree | f76032b23073848b4304acf2eb164fb73e1b21d5 | |
parent | 0af365de4c03c12fc20183093a944f7513a1c7be (diff) |
va_trace: allow surface trace to dump part of surface content
To debug/isolate video record quality issue (blocky/corruption, etc),
we always need to dump the YUV image from camera. LibVA has such
functionality, but due to storage bandwidth issue (~10M Byte/second),
it is hard to write 1080P 30fps YUV data to disk (~88M Byte/second).
Now refine the functionality to only dump part of the image, and
won't need to modify the code in the default build.
The method is:
edit /etc/libva.conf to include bellow (all export them):
LIBVA_TRACE_SURFACE=/data/enc-XXX.yuv
LIBVA_TRACE_GEOMETRY=320x240+20+20
It will only save 320x240 from (20,20) of the source surface to file
/data/enc-XXX.yuv.
Signed-off-by: Austin Yuan <shengquan.yuan@intel.com>
-rw-r--r-- | va/va_trace.c | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/va/va_trace.c b/va/va_trace.c index 893a3fa..08e7873 100644 --- a/va/va_trace.c +++ b/va/va_trace.c @@ -27,6 +27,7 @@ #include "va_enc_h264.h" #include "va_backend.h" #include "va_trace.h" +#include "va_enc_h264.h" #include <assert.h> #include <stdarg.h> @@ -48,6 +49,8 @@ * .LIBVA_TRACE_CODEDBUF=coded_clip_file: save the coded clip into file coded_clip_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_SURFACE_GEOMETRY=WIDTHxHEIGHT+XOFF+YOFF: only save part of surface context into file + * due to storage bandwidth limitation * .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 */ @@ -88,6 +91,11 @@ static struct _trace_context { unsigned int trace_slice_no; /* current slice NO */ unsigned int trace_slice_size; /* current slice buffer size */ + unsigned int trace_surface_width; /* surface dumping geometry */ + unsigned int trace_surface_height; + unsigned int trace_surface_xoff; + unsigned int trace_surface_yoff; + 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 */ @@ -201,7 +209,7 @@ void va_TraceInit(VADisplay dpy) if (va_parseConfig("LIBVA_TRACE_SURFACE", &env_value[0]) == 0) { FILE_NAME_SUFFIX(env_value); trace_context[trace_index].trace_surface_fn = strdup(env_value); - + va_infoMessage("LIBVA_TRACE_SURFACE is on, save surface into %s\n", trace_context[trace_index].trace_surface_fn); @@ -217,6 +225,24 @@ void va_TraceInit(VADisplay dpy) trace_flag |= VA_TRACE_FLAG_SURFACE_ENCODE; if (strstr(env_value, "jpeg") || strstr(env_value, "jpg")) trace_flag |= VA_TRACE_FLAG_SURFACE_JPEG; + + if (va_parseConfig("LIBVA_TRACE_SURFACE_GEOMETRY", &env_value[0]) == 0) { + char *p = env_value, *q; + + trace_context[trace_index].trace_surface_width = strtod(p, &q); + p = q+1; /* skip "x" */ + trace_context[trace_index].trace_surface_height = strtod(p, &q); + p = q+1; /* skip "+" */ + trace_context[trace_index].trace_surface_xoff = strtod(p, &q); + p = q+1; /* skip "+" */ + trace_context[trace_index].trace_surface_yoff = strtod(p, &q); + + va_infoMessage("LIBVA_TRACE_SURFACE_GEOMETRY is on, only dump surface %dx%d+%d+%d content\n", + trace_context[trace_index].trace_surface_width, + trace_context[trace_index].trace_surface_height, + trace_context[trace_index].trace_surface_xoff, + trace_context[trace_index].trace_surface_yoff); + } } trace_context[trace_index].dpy = dpy; @@ -385,20 +411,24 @@ void va_TraceSurface(VADisplay dpy) Y_data = (unsigned char*)buffer; UV_data = (unsigned char*)buffer + chroma_u_offset; - tmp = Y_data; - for (i=0; i<trace_context[idx].trace_frame_height; i++) { + tmp = Y_data + luma_stride * trace_context[idx].trace_surface_yoff; + for (i=0; i<trace_context[idx].trace_surface_height; i++) { 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_surface_xoff, + trace_context[idx].trace_surface_width, + 1, trace_context[idx].trace_fp_surface); - tmp = Y_data + i * luma_stride; + tmp += luma_stride; } - tmp = UV_data; + tmp = UV_data + chroma_u_stride * trace_context[idx].trace_surface_yoff; 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_surface_height/2; i++) { 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_surface_xoff, + trace_context[idx].trace_surface_width, + 1, trace_context[idx].trace_fp_surface); - tmp = UV_data + i * chroma_u_stride; + tmp += chroma_u_stride; } } @@ -550,6 +580,11 @@ void va_TraceCreateContext( trace_context[idx].trace_frame_width = picture_width; trace_context[idx].trace_frame_height = picture_height; + + if (trace_context[idx].trace_surface_width == 0) + trace_context[idx].trace_surface_width = picture_width; + if (trace_context[idx].trace_surface_height == 0) + trace_context[idx].trace_surface_height = picture_height; } |