HW JPEG: enable HW CSC for BYT

BZ: 116496

Implemented HW CSC after HW decode for BYT

Change-Id: I58da183fee2e4316f526ffdf73b5db3863d169e0
Signed-off-by: Cheng Yao <yao.cheng@intel.com>
Reviewed-on: http://android.intel.com:8080/115240
Reviewed-by: Shi, PingX <pingx.shi@intel.com>
Reviewed-by: cactus <cactus@intel.com>
Tested-by: Shi, PingX <pingx.shi@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
diff --git a/imagedecoder/Android.mk b/imagedecoder/Android.mk
index 9bf4336..ccc6f0f 100644
--- a/imagedecoder/Android.mk
+++ b/imagedecoder/Android.mk
@@ -10,6 +10,7 @@
 
 LOCAL_C_INCLUDES += \
     $(LOCAL_PATH) \
+    $(TOP)/external/jpeg \
     $(TARGET_OUT_HEADERS)/libva
 
 LOCAL_COPY_HEADERS_TO  := libjpeg_hw
@@ -24,12 +25,14 @@
     libva-android     \
     libva             \
     libva-tpi         \
+	libhardware
 
 LOCAL_LDLIBS += -lpthread
 LOCAL_CFLAGS += -Wno-multichar
 LOCAL_CFLAGS += -DUSE_INTEL_JPEGDEC
 
 ifeq ($(JPEGDEC_USES_GEN),true)
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)
 LOCAL_CFLAGS += -DJPEGDEC_USES_GEN
 endif
 
diff --git a/imagedecoder/JPEGDecoder.c b/imagedecoder/JPEGDecoder.c
index 10d4d1c..6a1337b 100644
--- a/imagedecoder/JPEGDecoder.c
+++ b/imagedecoder/JPEGDecoder.c
@@ -23,14 +23,23 @@
 *
 * Authors:
 *    Nana Guo <nana.n.guo@intel.com>
+*    Yao Cheng <yao.cheng@intel.com>
 *
 */
 
 #include "va/va_tpi.h"
+#include "va/va_vpp.h"
+#include "va/va_drmcommon.h"
 #include "JPEGDecoder.h"
 #include "ImageDecoderTrace.h"
 #include "JPEGParser.h"
 #include <string.h>
+#include "jerror.h"
+#include <hardware/gralloc.h>
+#ifdef JPEGDEC_USES_GEN
+#include "ufo/graphics.h"
+#define INTEL_VPG_GRALLOC_MODULE_PERFORM_GET_BO_NAME 4
+#endif
 
 #define JPEG_MAX_SETS_HUFFMAN_TABLES 2
 
@@ -38,99 +47,140 @@
 #define TABLE_CLASS_AC  1
 #define TABLE_CLASS_NUM 2
 
-static int appendFile(unsigned char* _fileName, void* _buf, int _bufLen)
+// for config
+#define HW_DECODE_MIN_WIDTH  100 // for JPEG smaller than this, use SW decode
+#define HW_DECODE_MIN_HEIGHT 100 // for JPEG smaller than this, use SW decode
+
+// for debug
+#define DECODE_DUMP_FILE    "" // no dump by default
+#define YUY2_DUMP_FILE      "" // no dump by default
+#define RGBA_DUMP_FILE      "" // no dump by default
+
+#define JD_CHECK(err, label) \
+        if (err) { \
+            ETRACE("%s::%d: failed: %d", __PRETTY_FUNCTION__, __LINE__, err); \
+            goto label; \
+        }
+
+#define JD_CHECK_RET(err, label, retcode) \
+        if (err) { \
+            status = retcode; \
+            ETRACE("%s::%d: failed: %d", __PRETTY_FUNCTION__, __LINE__, err); \
+            goto label; \
+        }
+
+const char * fourcc2str(uint32_t fourcc)
 {
-	static int firstOpen = 1;
-	FILE * fp = NULL;
-	if( NULL == _buf || _bufLen <= 0 ) return (-1);
-
-	if(firstOpen)
-	{
-		fp = fopen(_fileName, "wb");
-		firstOpen = 0;
-	}
-	else
-	{
-		fp = fopen(_fileName, "ab");
-	}
-
-	if( NULL == fp )
-	{
-		return (-1);
-	}
-
-	fwrite(_buf, _bufLen, 1, fp);
-
-	fclose(fp);
-	fp = NULL;
-
-	return 0;
+    static char str[5];
+    memset(str, 0, sizeof str);
+    str[0] = fourcc & 0xff;
+    str[1] = (fourcc >> 8 )& 0xff;
+    str[2] = (fourcc >> 16) & 0xff;
+    str[3] = (fourcc >> 24)& 0xff;
+    str[4] = '\0';
+    return str;
 }
-#define DUMPYUVFILE "/data/mcgdump.yuv"
-int dump_yuv_image(VAImage va_image, unsigned char *pImage_Src,
-                   float CbCr_h_sampling_factor, float CbCr_v_sampling_factor, int actW, int actH)
+
+// VPG supports only YUY2->RGBA, YUY2->NV12_TILED now
+// needs to convert IMC3/YV16/444P to YUY2 before HW CSC
+static void write_to_YUY2(uint8_t *pDst,
+                          uint32_t dst_stride,
+                          VAImage *pImg,
+                          uint8_t *pSrc)
 {
-  int num_bytes, nWidth, nHeight, nAWidth, nAHeight;
-  unsigned char *pSrc_Y, *pSrc_UV, *pDst, *pDst_Y, *pDst_U, *pDst_V, *pSrcTmp, *pSrc_U, *pSrc_V;
-  int i, j;
+    uint8_t *pY, *pU, *pV;
+    float h_samp_factor, v_samp_factor;
+    int row, col;
+    switch (pImg->format.fourcc) {
+    case VA_FOURCC_IMC3:
+        h_samp_factor = 0.5;
+        v_samp_factor = 0.5;
+        break;
+    case VA_FOURCC_422H:
+        h_samp_factor = 0.5;
+        v_samp_factor = 1;
+        break;
+    case VA_FOURCC_444P:
+        h_samp_factor = 1;
+        v_samp_factor = 1;
+        break;
+    default:
+        // non-supported
+        ETRACE("%s to YUY2: Not-supported input YUV format", fourcc2str(pImg->format.fourcc));
+        return;
+    }
+    pY = pSrc + pImg->offsets[0];
+    pU = pSrc + pImg->offsets[1];
+    pV = pSrc + pImg->offsets[2];
+    for (row = 0; row < pImg->height; ++row) {
+        for (col = 0; col < pImg->width; ++col) {
+            // Y
+            *(pDst + 2 * col) = *(pY + col);
+            uint32_t actual_col = h_samp_factor * col;
+            if (col % 2 == 1) {
+                // U
+                *(pDst + 2 * col + 1) = *(pU + actual_col);
+            }
+            else {
+                // V
+                *(pDst + 2 * col + 1) = *(pV + actual_col);
+            }
+        }
+        pDst += dst_stride * 2;
+        pY += pImg->pitches[0];
+        uint32_t actual_row = row * v_samp_factor;
+        pU = pSrc + pImg->offsets[1] + actual_row * pImg->pitches[1];
+        pV = pSrc + pImg->offsets[2] + actual_row * pImg->pitches[2];
+    }
+}
 
-  ITRACE("Image width = %d, Height = %d\n", va_image.width, va_image.height);
-
-  pSrc_Y = pImage_Src;
-  pSrc_U = pSrc_Y + va_image.offsets[1];
-  pSrc_V = pSrc_U + va_image.offsets[2];
-  ITRACE("offset = %p, %p, %p\n", pSrc_Y, pSrc_U, pSrc_V);
-  ITRACE("offset = %d, %d, %d\n", va_image.offsets[0], va_image.offsets[1], va_image.offsets[2]);
-  ITRACE("pitch = %d, %d, %d\n", va_image.pitches[0], va_image.pitches[1], va_image.pitches[2]);
-
-// Y
-  nWidth =  va_image.pitches[0];
-  nHeight = va_image.height;
-  num_bytes = nWidth * nHeight;
-  if (NULL == (pDst_Y = (unsigned char*) malloc(num_bytes))) {
-	return 0;
-  }
-  for (i = 0; i < nHeight; i++)
-  {
-    memcpy(pDst_Y + i * nWidth, pSrc_Y + i * va_image.pitches[0], nWidth);
-  }
-  ITRACE(" Y (WxH) %d x %d, bytes = %d\n", nWidth, nHeight, num_bytes);
-  appendFile(DUMPYUVFILE, pDst_Y, nWidth*nHeight);
-
-//U
-  nWidth =  va_image.pitches[0] * CbCr_h_sampling_factor;
-  nHeight = va_image.height * CbCr_v_sampling_factor;
-  num_bytes = nWidth * nHeight;
-  if (NULL == (pDst_U = (unsigned char*) malloc(num_bytes))) {
-	return 0;
-  }
-  for (i = 0; i < nHeight; i++)
-  {
-      memcpy(pDst_U + i * nWidth, pSrc_U + i * va_image.pitches[1], nWidth);
-  }
-  ITRACE(" U (WxH) %d x %d, bytes = %d\n", nWidth, nHeight, num_bytes);
-  appendFile(DUMPYUVFILE, pDst_U, nWidth*nHeight);
-
-  pSrc_V = pSrc_U + nHeight * va_image.pitches[1];
-
-//V
-  nWidth =  va_image.pitches[0] * CbCr_h_sampling_factor;
-  nHeight = va_image.height * CbCr_v_sampling_factor;
-  num_bytes = nWidth * nHeight;
-  if (NULL == (pDst_V = (unsigned char*) malloc(num_bytes))) {
-	return 0;
-  }
-  for (i = 0; i < nHeight; i++)
-  {
-      memcpy(pDst_V + i * nWidth, pSrc_V + i * va_image.pitches[2], nWidth);
-  }
-  ITRACE(" V (WxH) %d x %d, bytes = %d\n", nWidth, nHeight, num_bytes);
-  appendFile(DUMPYUVFILE, pDst_V, nWidth*nHeight);
-
-  if(pDst != NULL)
-	free(pDst);
-
-  return 0;
+static void write_to_file(char *file, VAImage *pImg, uint8_t *pSrc)
+{
+    FILE *fp = fopen(file, "wb");
+    if (!fp) {
+        return;
+    }
+    uint8_t *pY, *pU, *pV;
+    float h_samp_factor, v_samp_factor;
+    int row, col;
+    ITRACE("Dumping decoded YUV to %s", file);
+    switch (pImg->format.fourcc) {
+    case VA_FOURCC_IMC3:
+        h_samp_factor = 0.5;
+        v_samp_factor = 0.5;
+        break;
+    case VA_FOURCC_422H:
+        h_samp_factor = 0.5;
+        v_samp_factor = 1;
+        break;
+    case VA_FOURCC_444P:
+        h_samp_factor = 1;
+        v_samp_factor = 1;
+        break;
+    default:
+        // non-supported
+        ETRACE("%s to YUY2: Not-supported input YUV format", fourcc2str(pImg->format.fourcc));
+        return;
+    }
+    pY = pSrc + pImg->offsets[0];
+    pU = pSrc + pImg->offsets[1];
+    pV = pSrc + pImg->offsets[2];
+    // Y
+    for (row = 0; row < pImg->height; ++row) {
+        fwrite(pY, 1, pImg->width, fp);
+        pY += pImg->pitches[0];
+    }
+    // U
+    for (row = 0; row < pImg->height * v_samp_factor; ++row) {
+        fwrite(pU, 1, pImg->width * h_samp_factor, fp);
+        pU += pImg->pitches[1];
+    }
+    // V
+    for (row = 0; row < pImg->height * v_samp_factor; ++row) {
+        fwrite(pV, 1, pImg->width * h_samp_factor, fp);
+        pV += pImg->pitches[2];
+    }
+    fclose(fp);
 }
 
 /*
@@ -237,10 +287,333 @@
     }
 
     jd_libva_ptr->initialized = FALSE;
+    ITRACE("jdva_deinitialize finished");
     return;
 }
 
-unsigned int jdva_get_surface_format(jd_libva_struct * jd_libva_ptr, VASurfaceAttrib * fourcc) {
+static Decode_Status doColorConversion(jd_libva_struct *jd_libva_ptr, VASurfaceID surface, char ** buf, uint32_t rows)
+{
+#if 0 // dump RGB to file
+        uint8_t* rgb_buf;
+        int32_t data_len = 0;
+        uint32_t surface_width, surface_height;
+        surface_width = (( ( jd_libva_ptr->image_width + 7 ) & ( ~7 )) + 15 ) & ( ~15 );
+        surface_height = (( ( jd_libva_ptr->image_height + 7 ) & ( ~7 )) + 15 ) & ( ~15 );
+
+        rgb_buf = (uint8_t*) malloc((surface_width * surface_height) << 2);
+        if(rgb_buf == NULL){
+            return DECODE_MEMORY_FAIL;
+        }
+        va_status = vaPutSurfaceBuf(jd_libva_ptr->va_display, jd_libva_ptr->va_surfaces[0], rgb_buf, &data_len, 0, 0, surface_width, surface_height, 0, 0, surface_width, surface_height, NULL, 0, 0);
+
+        buf = rgb_buf;
+    // dump RGB data
+        {
+            FILE *pf_tmp = fopen("img_out.rgb", "wb");
+            if(pf_tmp == NULL)
+                ETRACE("Open file error");
+            fwrite(rgb_buf, 1, surface_width * surface_height * 4, pf_tmp);
+            fclose(pf_tmp);
+        }
+#endif
+
+#ifdef JPEGDEC_USES_GEN
+    VAImage decoded_img;
+    uint8_t *decoded_buf = NULL;
+    int row, col;
+    VAStatus vpp_status;
+    uint8_t *pSrc, *pDst;
+    VADisplay display = NULL;
+    VAContextID context = VA_INVALID_ID;
+    VASurfaceID dst_surface = VA_INVALID_ID, src_surface = VA_INVALID_ID;
+    VAConfigID config = VA_INVALID_ID;
+    VAConfigAttrib  vpp_attrib;
+    VASurfaceAttrib dst_surf_attrib, src_surf_attrib;
+    buffer_handle_t dst_handle, src_handle;
+    int32_t dst_stride, src_stride;
+    uint32_t dst_buf_name, src_buf_name;
+    VAProcPipelineParameterBuffer vpp_param;
+    VABufferID vpp_pipeline_buf = VA_INVALID_ID;
+    int major_version, minor_version;
+    uint8_t *src_gralloc_buf, *dst_gralloc_buf;
+    hw_module_t const* module = NULL;
+    alloc_device_t *alloc_dev = NULL;
+    struct gralloc_module_t *gralloc_module = NULL;
+    VAProcPipelineCaps vpp_pipeline_cap ;
+    VARectangle src_rect, dst_rect;
+    int err;
+    Display vppdpy;
+    FILE *fp;
+    Decode_Status status = DECODE_SUCCESS;
+    VASurfaceAttribExternalBuffers vaSurfaceExternBufIn, vaSurfaceExternBufOut;
+
+    decoded_img.image_id = VA_INVALID_ID;
+    vpp_status = vaDeriveImage(jd_libva_ptr->va_display, surface, &decoded_img);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    vpp_status = vaMapBuffer(jd_libva_ptr->va_display, decoded_img.buf, (void **)&decoded_buf);
+    if (vpp_status) {
+        vaDestroyImage(jd_libva_ptr->va_display, decoded_img.image_id);
+    }
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    write_to_file(DECODE_DUMP_FILE, &decoded_img, decoded_buf);
+
+    ITRACE("Start HW CSC: color %s=>RGBA8888", fourcc2str(jd_libva_ptr->fourcc));
+    err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    gralloc_module = (struct gralloc_module_t *)module;
+    err = gralloc_open(module, &alloc_dev);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    err = alloc_dev->alloc(alloc_dev,
+                           jd_libva_ptr->image_width,
+                           jd_libva_ptr->image_height,
+                           HAL_PIXEL_FORMAT_YCbCr_422_I, // YUY2
+                           GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_SW_READ_MASK,
+                           (buffer_handle_t *)&src_handle,
+                           &src_stride);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    ITRACE("src_gralloc_buf: handle=%u, stride=%u", src_handle, src_stride);
+    err = alloc_dev->alloc(alloc_dev,
+                           jd_libva_ptr->image_width,
+                           jd_libva_ptr->image_height,
+                           HAL_PIXEL_FORMAT_RGBA_8888,
+                           GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_SW_READ_MASK,
+                           (buffer_handle_t *)&dst_handle,
+                           &dst_stride);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+    ITRACE("dst_gralloc_buf: handle=%u, stride=%u", dst_handle, dst_stride);
+
+    err = gralloc_module->perform(gralloc_module, INTEL_VPG_GRALLOC_MODULE_PERFORM_GET_BO_NAME, src_handle, &src_buf_name);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+    err = gralloc_module->perform(gralloc_module, INTEL_VPG_GRALLOC_MODULE_PERFORM_GET_BO_NAME, dst_handle, &dst_buf_name);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    // copy decoded buf into the gralloc buf in YUY2 format
+    err = gralloc_module->lock(gralloc_module, src_handle,
+                               GRALLOC_USAGE_SW_WRITE_MASK,
+                               0, 0,
+                               jd_libva_ptr->image_width,
+                               jd_libva_ptr->image_height,
+                               &src_gralloc_buf);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+    ITRACE("Convert %s buf into YUY2:", fourcc2str(jd_libva_ptr->fourcc));
+
+    write_to_YUY2(src_gralloc_buf,
+                  src_stride,
+                  &decoded_img,
+                  decoded_buf);
+    err = gralloc_module->unlock(gralloc_module, src_handle);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    fp = fopen(YUY2_DUMP_FILE, "wb");
+    if (fp) {
+        ITRACE("DUMP YUY2 to " YUY2_DUMP_FILE);
+        err = gralloc_module->lock(gralloc_module, src_handle,
+                                   GRALLOC_USAGE_SW_READ_MASK,
+                                   0, 0,
+                                   jd_libva_ptr->image_width,
+                                   jd_libva_ptr->image_height,
+                                   &src_gralloc_buf);
+        unsigned char *pYUV = src_gralloc_buf;
+        int loop;
+		for(loop=0;loop<jd_libva_ptr->image_height;loop++)
+		{
+            fwrite(pYUV, 2, jd_libva_ptr->image_width, fp);
+            pYUV += 2 * src_stride;
+		}
+        gralloc_module->unlock(gralloc_module, src_handle);
+		fclose(fp);
+    }
+
+    vaUnmapBuffer(jd_libva_ptr->va_display, decoded_img.buf);
+    vaDestroyImage(jd_libva_ptr->va_display, decoded_img.image_id);
+    decoded_buf= NULL;
+
+    display = vaGetDisplay (&vppdpy);
+    vpp_status = vaInitialize(display, &major_version, &minor_version);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    vpp_attrib.type  = VAConfigAttribRTFormat;
+    vpp_attrib.value = VA_RT_FORMAT_YUV420;
+    vpp_status = vaCreateConfig(display,
+                                VAProfileNone,
+                                VAEntrypointVideoProc,
+                                &vpp_attrib,
+                                1,
+                                &config);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    vpp_status = vaCreateContext(display,
+                                 config,
+                                 jd_libva_ptr->image_width,
+                                 jd_libva_ptr->image_height,
+                                 0,
+                                 NULL,
+                                 0,
+                                 &context);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    vaSurfaceExternBufIn.pixel_format  = VA_FOURCC_YUY2;
+    vaSurfaceExternBufIn.width         = jd_libva_ptr->image_width;
+    vaSurfaceExternBufIn.height        = jd_libva_ptr->image_height;
+    vaSurfaceExternBufIn.pitches[0]    = src_stride * 2; // YUY2 is 16bit
+    vaSurfaceExternBufIn.buffers       = &src_buf_name;
+    vaSurfaceExternBufIn.num_buffers   = 1;
+    vaSurfaceExternBufIn.flags         = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
+    src_surf_attrib.type               = VASurfaceAttribExternalBufferDescriptor;
+    src_surf_attrib.flags              = VA_SURFACE_ATTRIB_SETTABLE;
+    src_surf_attrib.value.type         = VAGenericValueTypePointer;
+    src_surf_attrib.value.value.p      = (void *)&vaSurfaceExternBufIn;
+    vpp_status = vaCreateSurfaces(display,
+                                  VA_RT_FORMAT_YUV422,
+                                  jd_libva_ptr->image_width,
+                                  jd_libva_ptr->image_height,
+                                  &src_surface,
+                                  1,
+                                  &src_surf_attrib,
+                                  1);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    vaSurfaceExternBufOut.pixel_format = VA_FOURCC_ARGB;
+    vaSurfaceExternBufOut.width        = jd_libva_ptr->image_width;
+    vaSurfaceExternBufOut.height       = jd_libva_ptr->image_height;
+    vaSurfaceExternBufOut.pitches[0]   = dst_stride * 4; // RGBA is 32bit
+    vaSurfaceExternBufOut.buffers      = &dst_buf_name;
+    vaSurfaceExternBufOut.num_buffers  = 1;
+    vaSurfaceExternBufOut.flags        = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
+    dst_surf_attrib.type               = VASurfaceAttribExternalBufferDescriptor;
+    dst_surf_attrib.flags              = VA_SURFACE_ATTRIB_SETTABLE;
+    dst_surf_attrib.value.type         = VAGenericValueTypePointer;
+    dst_surf_attrib.value.value.p      = (void *)&vaSurfaceExternBufOut;
+    vpp_status = vaCreateSurfaces(display,
+                                  VA_RT_FORMAT_RGB32,
+                                  jd_libva_ptr->image_width,
+                                  jd_libva_ptr->image_height,
+                                  &dst_surface,
+                                  1,
+                                  &dst_surf_attrib,
+                                  1);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+    ITRACE("vaCreateSurfaces got surface %u=>%u", src_surface, dst_surface);
+    //query caps for pipeline
+    vpp_status = vaQueryVideoProcPipelineCaps(display,
+                                              context,
+                                              NULL,
+                                              0,
+                                              &vpp_pipeline_cap);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    src_rect.x = dst_rect.x           = 0;
+    src_rect.y = dst_rect.y           = 0;
+    src_rect.width  = dst_rect.width  = jd_libva_ptr->image_width;
+    src_rect.height = dst_rect.height = jd_libva_ptr->image_height;
+    ITRACE("from (%d, %d, %u, %u) to (%d, %d, %u, %u)",
+        src_rect.x, src_rect.y, src_rect.width, src_rect.height,
+        dst_rect.x, dst_rect.y, dst_rect.width, dst_rect.height);
+    vpp_param.surface                 = src_surface;
+    vpp_param.output_region           = &dst_rect;
+    vpp_param.surface_region          = &src_rect;
+    vpp_param.surface_color_standard  = VAProcColorStandardBT601;   //csc
+    vpp_param.output_background_color = 0x8000;                     //colorfill
+    vpp_param.output_color_standard   = VAProcColorStandardNone;
+    vpp_param.filter_flags            = VA_FRAME_PICTURE;
+    vpp_param.filters                 = NULL;
+    //vpp_param.pipeline_flags          = 1084929476;
+    vpp_param.num_filters             = 0;
+    vpp_param.forward_references      = 0;
+    vpp_param.num_forward_references  = 0;
+    vpp_param.backward_references     = 0;
+    vpp_param.num_backward_references = 0;
+    vpp_param.blend_state             = NULL;
+    vpp_param.rotation_state          = VA_ROTATION_NONE;
+    vpp_status = vaCreateBuffer(display,
+                                context,
+                                VAProcPipelineParameterBufferType,
+                                sizeof(VAProcPipelineParameterBuffer),
+                                1,
+                                &vpp_param,
+                                &vpp_pipeline_buf);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    vpp_status = vaBeginPicture(display,
+                                context,
+                                dst_surface);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    //Render the picture
+    vpp_status = vaRenderPicture(display,
+                                 context,
+                                 &vpp_pipeline_buf,
+                                 1);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    vpp_status = vaEndPicture(display, context);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+
+    vpp_status = vaSyncSurface(display, dst_surface);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+    ITRACE("Finished HW CSC YUY2=>RGBA8888");
+
+    // gralloc lock + copy
+    err = gralloc_module->lock(gralloc_module, dst_handle,
+                               GRALLOC_USAGE_SW_READ_MASK,
+                               0, 0,
+                               jd_libva_ptr->image_width,
+                               jd_libva_ptr->image_height,
+                               &dst_gralloc_buf);
+    JD_CHECK_RET(vpp_status, cleanup, DECODE_DRIVER_FAIL);
+    ITRACE("Copy RGBA8888 buffer (%ux%u) to skia buffer (%ux%u)",
+           jd_libva_ptr->image_width,
+           jd_libva_ptr->image_height,
+           buf[1] - buf[0],
+           rows);
+    pSrc = dst_gralloc_buf;
+    fp = fopen(RGBA_DUMP_FILE, "wb");
+    if (fp)
+        ITRACE("dumping RGBA8888 to " RGBA_DUMP_FILE);
+    // FIXME: is it RGBA? or BGRA? or ARGB?
+    for (row = 0; row < rows; ++ row) {
+        memcpy(buf[row], pSrc, 4 * jd_libva_ptr->image_width);
+        if (fp)
+            fwrite(pSrc, 4, jd_libva_ptr->image_width, fp);
+        pSrc += dst_stride * 4;
+    }
+    if (fp)
+        fclose(fp);
+    gralloc_module->unlock(gralloc_module, dst_handle);
+
+cleanup:
+    if (vpp_pipeline_buf != VA_INVALID_ID)
+        vaDestroyBuffer(display, vpp_pipeline_buf);
+    if (dst_surface != VA_INVALID_ID)
+        vaDestroySurfaces(display, &dst_surface, 1);
+    if (src_surface != VA_INVALID_ID)
+        vaDestroySurfaces(display, &src_surface, 1);
+    if (context != VA_INVALID_ID)
+        vaDestroyContext(display, context);
+    if (config != VA_INVALID_ID)
+        vaDestroyConfig(display, config);
+    if (display)
+        vaTerminate(display);
+    if (alloc_dev) {
+        alloc_dev->free(alloc_dev, dst_handle);
+        alloc_dev->free(alloc_dev, src_handle);
+        gralloc_close(alloc_dev);
+    }
+    return status;
+#else
+    // TODO: CSC with Gralloc On PVR platform
+#endif
+
+
+
+}
+
+static unsigned int getSurfaceFormat(jd_libva_struct * jd_libva_ptr, VASurfaceAttrib * fourcc) {
     int h1, h2, h3, v1, v2, v3;
     h1 = jd_libva_ptr->picture_param_buf.components[0].h_sampling_factor;
     h2 = jd_libva_ptr->picture_param_buf.components[1].h_sampling_factor;
@@ -271,6 +644,7 @@
     else if (h1 == 4 && h2 == 1 && h3 == 1 &&
             v1 == 1 && v2 == 1 && v3 == 1) {
         fourcc->value.value.i = VA_FOURCC_411P;
+        ITRACE("SurfaceFormat: 411P");
         return VA_RT_FORMAT_YUV411;
     }
     else if (h1 == 1 && h2 == 1 && h3 == 1 &&
@@ -308,7 +682,8 @@
     }
 
     VASurfaceAttrib fourcc;
-    unsigned int surface_format = jdva_get_surface_format(jd_libva_ptr, &fourcc);
+    unsigned int surface_format = getSurfaceFormat(jd_libva_ptr, &fourcc);
+    jd_libva_ptr->fourcc = fourcc.value.value.i;
 #ifdef JPEGDEC_USES_GEN
     va_status = vaCreateSurfaces(jd_libva_ptr->va_display, surface_format,
                                     jd_libva_ptr->image_width,
@@ -322,27 +697,22 @@
                                     jd_libva_ptr->va_surfaces,
                                     jd_libva_ptr->surface_count, NULL, 0);
 #endif
-    if (va_status != VA_STATUS_SUCCESS) {
-        ETRACE("vaCreateSurfaces failed. va_status = 0x%x", va_status);
-        status = DECODE_DRIVER_FAIL;
-        goto cleanup;
-    }
+    JD_CHECK(va_status, cleanup);
     va_status = vaCreateContext(jd_libva_ptr->va_display, jd_libva_ptr->va_config,
                                    jd_libva_ptr->image_width,
                                    jd_libva_ptr->image_height,
                                    0,  //VA_PROGRESSIVE
                                    jd_libva_ptr->va_surfaces,
                                    jd_libva_ptr->surface_count, &(jd_libva_ptr->va_context));
-
     if (va_status != VA_STATUS_SUCCESS) {
         ETRACE("vaCreateContext failed. va_status = 0x%x", va_status);
-        status = DECODE_DRIVER_FAIL;
-        goto cleanup;
-
+        return DECODE_DRIVER_FAIL;
     }
+
     jd_libva_ptr->resource_allocated = TRUE;
     return status;
 cleanup:
+    jd_libva_ptr->resource_allocated = FALSE;
 
     if (jd_libva_ptr->va_surfaces) {
         free (jd_libva_ptr->va_surfaces);
@@ -350,7 +720,7 @@
     }
     jdva_deinitialize (jd_libva_ptr);
 
-    return status;
+    return DECODE_DRIVER_FAIL;
 }
 
 Decode_Status jdva_release_resource (jd_libva_struct * jd_libva_ptr) {
@@ -369,12 +739,14 @@
    * It is safe to destroy Surface/Config/Context severl times
    * and it is also safe even their value is NULL
    */
-
     va_status = vaDestroySurfaces(jd_libva_ptr->va_display, jd_libva_ptr->va_surfaces, jd_libva_ptr->surface_count);
+
+    va_status = vaDestroyContext(jd_libva_ptr->va_display, jd_libva_ptr->va_context);
     if (va_status != VA_STATUS_SUCCESS) {
-        ETRACE("vaDestroySurfaces failed. va_status = 0x%x", va_status);
-        return DECODE_DRIVER_FAIL;
+      ETRACE("vaDestroyContext failed. va_status = 0x%x", va_status);
+      return DECODE_DRIVER_FAIL;
     }
+    jd_libva_ptr->va_context = NULL;
 
     if (jd_libva_ptr->va_surfaces) {
         free (jd_libva_ptr->va_surfaces);
@@ -387,32 +759,33 @@
         return DECODE_DRIVER_FAIL;
     }
 
+cleanup:
     jd_libva_ptr->va_config = NULL;
 
-    va_status = vaDestroyContext(jd_libva_ptr->va_display, jd_libva_ptr->va_context);
-    if (va_status != VA_STATUS_SUCCESS) {
-        ETRACE("vaDestroyContext failed. va_status = 0x%x", va_status);
-        return DECODE_DRIVER_FAIL;
-    }
-
-    jd_libva_ptr->va_context = NULL;
-
     jd_libva_ptr->resource_allocated = FALSE;
 
     return va_status;
 }
 
-Decode_Status jdva_decode (jd_libva_struct * jd_libva_ptr, uint8_t* buf) {
+Decode_Status jdva_decode (j_decompress_ptr cinfo, jd_libva_struct * jd_libva_ptr) {
     Decode_Status status = DECODE_SUCCESS;
     VAStatus va_status = VA_STATUS_SUCCESS;
     VABufferID desc_buf[5];
     uint32_t bitstream_buffer_size = 0;
     uint32_t scan_idx = 0;
     uint32_t buf_idx = 0;
+    char **buf = jd_libva_ptr->output_image;
+    uint32_t lines = jd_libva_ptr->output_lines;
     uint32_t chopping = VA_SLICE_DATA_FLAG_ALL;
-    uint32_t bytes_remaining = jd_libva_ptr->eoi_offset - jd_libva_ptr->soi_offset;
+    uint32_t bytes_remaining;
+
+    if (jd_libva_ptr->eoi_offset)
+        bytes_remaining = jd_libva_ptr->eoi_offset - jd_libva_ptr->soi_offset;
+    else
+        bytes_remaining = jd_libva_ptr->file_size - jd_libva_ptr->soi_offset;
     uint32_t src_offset = jd_libva_ptr->soi_offset;
-    bitstream_buffer_size = 1024*1024*5;
+    uint32_t cpy_row;
+    bitstream_buffer_size = cinfo->src->bytes_in_buffer;//1024*1024*5;
 
     va_status = vaBeginPicture(jd_libva_ptr->va_display, jd_libva_ptr->va_context, jd_libva_ptr->va_surfaces[0]);
     if (va_status != VA_STATUS_SUCCESS) {
@@ -422,7 +795,7 @@
     }
     va_status = vaCreateBuffer(jd_libva_ptr->va_display, jd_libva_ptr->va_context, VAPictureParameterBufferType, sizeof(VAPictureParameterBufferJPEGBaseline), 1, &jd_libva_ptr->picture_param_buf, &desc_buf[buf_idx]);
     if (va_status != VA_STATUS_SUCCESS) {
-        ETRACE("vaCreateBuffer failed. va_status = 0x%x", va_status);
+        ETRACE("vaCreateBuffer VAPictureParameterBufferType failed. va_status = 0x%x", va_status);
         status = DECODE_DRIVER_FAIL;
         return status;
     }
@@ -430,14 +803,14 @@
     va_status = vaCreateBuffer(jd_libva_ptr->va_display, jd_libva_ptr->va_context, VAIQMatrixBufferType, sizeof(VAIQMatrixBufferJPEGBaseline), 1, &jd_libva_ptr->qmatrix_buf, &desc_buf[buf_idx]);
 
     if (va_status != VA_STATUS_SUCCESS) {
-        ETRACE("vaCreateBuffer failed. va_status = 0x%x", va_status);
+        ETRACE("vaCreateBuffer VAIQMatrixBufferType failed. va_status = 0x%x", va_status);
         status = DECODE_DRIVER_FAIL;
         return status;
     }
     buf_idx++;
     va_status = vaCreateBuffer(jd_libva_ptr->va_display, jd_libva_ptr->va_context, VAHuffmanTableBufferType, sizeof(VAHuffmanTableBufferJPEGBaseline), 1, &jd_libva_ptr->hufman_table_buf, &desc_buf[buf_idx]);
     if (va_status != VA_STATUS_SUCCESS) {
-        ETRACE("vaCreateBuffer failed. va_status = 0x%x", va_status);
+        ETRACE("vaCreateBuffer VAHuffmanTableBufferType failed. va_status = 0x%x", va_status);
         status = DECODE_DRIVER_FAIL;
         return status;
     }
@@ -494,7 +867,7 @@
         /* Get Slice Control Buffer */
         va_status = vaCreateBuffer(jd_libva_ptr->va_display, jd_libva_ptr->va_context, VASliceParameterBufferType, sizeof(VASliceParameterBufferJPEGBaseline) * dest_idx, 1, dest_scan_ctrl, &desc_buf[buf_idx]);
         if (va_status != VA_STATUS_SUCCESS) {
-            ETRACE("vaCreateBuffer failed. va_status = 0x%x", va_status);
+            ETRACE("vaCreateBuffer VASliceParameterBufferType failed. va_status = 0x%x", va_status);
             status = DECODE_DRIVER_FAIL;
             return status;
         }
@@ -502,7 +875,6 @@
         va_status = vaCreateBuffer(jd_libva_ptr->va_display, jd_libva_ptr->va_context, VASliceDataBufferType, bytes, 1, &jd_libva_ptr->bitstream_buf[ src_offset ], &desc_buf[buf_idx]);
         buf_idx++;
         if (va_status != VA_STATUS_SUCCESS) {
-            ETRACE("vaCreateBuffer failed. va_status = 0x%x", va_status);
             status = DECODE_DRIVER_FAIL;
             return status;
         }
@@ -528,81 +900,24 @@
     if (va_status != VA_STATUS_SUCCESS) {
         WTRACE("vaSyncSurface failed. va_status = 0x%x", va_status);
     }
-#if 0
-    uint8_t* rgb_buf;
-    int32_t data_len = 0;
-    uint32_t surface_width, surface_height;
-    surface_width = (( ( jd_libva_ptr->image_width + 7 ) & ( ~7 )) + 15 ) & ( ~15 );
-    surface_height = (( ( jd_libva_ptr->image_height + 7 ) & ( ~7 )) + 15 ) & ( ~15 );
 
-    rgb_buf = (uint8_t*) malloc((surface_width * surface_height) << 2);
-    if(rgb_buf == NULL){
-        return DECODE_MEMORY_FAIL;
-    }
-    va_status = vaPutSurfaceBuf(jd_libva_ptr->va_display, jd_libva_ptr->va_surfaces[0], rgb_buf, &data_len, 0, 0, surface_width, surface_height, 0, 0, surface_width, surface_height, NULL, 0, 0);
+    status = doColorConversion(jd_libva_ptr,
+                               jd_libva_ptr->va_surfaces[0],
+                               buf, lines);
 
-    buf = rgb_buf;
-// dump RGB data
-    {
-        FILE *pf_tmp = fopen("img_out.rgb", "wb");
-        if(pf_tmp == NULL)
-            ETRACE("Open file error");
-        fwrite(rgb_buf, 1, surface_width * surface_height * 4, pf_tmp);
-        fclose(pf_tmp);
-    }
-#endif
-#if 0
-    va_status = vaDeriveImage(jd_libva_ptr->va_display, jd_libva_ptr->va_surfaces[0], &(jd_libva_ptr->surface_image));
-    if (va_status != VA_STATUS_SUCCESS) {
-        ERREXIT1 (cinfo, JERR_VA_DRIVEIMAGE, va_status);
-    }
-
-    va_status = vaMapBuffer(jd_libva_ptr->va_display, jd_libva_ptr->surface_image.buf, (void **)& (jd_libva_ptr->image_buf));
-    if (va_status != VA_STATUS_SUCCESS) {
-        ERREXIT1 (cinfo, JERR_VA_MAPBUFFER, va_status);
-    }
-
-    char fcc[5];
-    fcc[0] = jd_libva_ptr->surface_image.format.fourcc & 0xff;
-    fcc[1] = (jd_libva_ptr->surface_image.format.fourcc >> 8 )& 0xff;
-    fcc[2] = (jd_libva_ptr->surface_image.format.fourcc >> 16) & 0xff;
-    fcc[3] = (jd_libva_ptr->surface_image.format.fourcc >> 24)& 0xff;
-    fcc[4] = '\0';
-    ITRACE("Derived image:");
-    ITRACE("\t%u bytes", jd_libva_ptr->surface_image.data_size);
-    ITRACE("\tfourcc='%s'", fcc);
-    ITRACE("\tpitches=[%u %u %u]", jd_libva_ptr->surface_image.pitches[0], jd_libva_ptr->surface_image.pitches[1], jd_libva_ptr->surface_image.pitches[2]);
-    ITRACE("\toffsets=[%u %u %u]", jd_libva_ptr->surface_image.offsets[0], jd_libva_ptr->surface_image.offsets[1], jd_libva_ptr->surface_image.offsets[2]);
-
-#ifdef JPEGDEC_USES_GEN
-    float CbCr_h = ((float)jd_libva_ptr->picture_param_buf.components[1].h_sampling_factor) / jd_libva_ptr->picture_param_buf.components[0].h_sampling_factor;
-    float CbCr_v = ((float)jd_libva_ptr->picture_param_buf.components[1].v_sampling_factor) / jd_libva_ptr->picture_param_buf.components[0].v_sampling_factor;
-    dump_yuv_image(jd_libva_ptr->surface_image, jd_libva_ptr->image_buf,
-            CbCr_h, CbCr_v, jd_libva_ptr->image_width, jd_libva_ptr->image_height);
-#else
-    dump_yuv_image(jd_libva_ptr->surface_image, jd_libva_ptr->image_buf,
-            1, 1, jd_libva_ptr->image_width, jd_libva_ptr->image_height);
-#endif
-    va_status = vaUnmapBuffer(jd_libva_ptr->va_display, jd_libva_ptr->surface_image.buf);
-    if (va_status != VA_STATUS_SUCCESS) {
-        ERREXIT1(cinfo, JERR_VA_MAPBUFFER, va_status);
-    }
-
-    va_status = vaDestroyImage(jd_libva_ptr->va_display, jd_libva_ptr->surface_image.image_id);
-
-    if (va_status != VA_STATUS_SUCCESS) {
-        ERREXIT1 (cinfo, JERR_VA_MAPBUFFER, va_status);
-    }
-#endif
+    ITRACE("Successfully decoded picture");
     return status;
+cleanup:
+    return DECODE_DRIVER_FAIL;
 }
 
-Decode_Status parseBitstream(jd_libva_struct * jd_libva_ptr) {
+Decode_Status parseBitstream(j_decompress_ptr cinfo, jd_libva_struct * jd_libva_ptr) {
     uint32_t component_order = 0 ;
     uint32_t dqt_ind = 0;
     uint32_t dht_ind = 0;
     uint32_t scan_ind = 0;
     boolean frame_marker_found = FALSE;
+    int i;
 
     uint8_t marker = jd_libva_ptr->JPEGParser->getNextMarker(jd_libva_ptr->JPEGParser);
 
@@ -680,6 +995,14 @@
                 jd_libva_ptr->picture_param_buf.num_components = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser);
 
                 if (jd_libva_ptr->picture_param_buf.num_components > JPEG_MAX_COMPONENTS) {
+                    ETRACE("ERROR: reached max components\n");
+                    return DECODE_PARSER_FAIL;
+                }
+                if (jd_libva_ptr->picture_param_buf.picture_height < HW_DECODE_MIN_HEIGHT
+                    || jd_libva_ptr->picture_param_buf.picture_width < HW_DECODE_MIN_WIDTH) {
+                    ITRACE("PERFORMANCE: %ux%u JPEG will decode faster with SW\n",
+                        jd_libva_ptr->picture_param_buf.picture_width,
+                        jd_libva_ptr->picture_param_buf.picture_height);
                     return DECODE_PARSER_FAIL;
                 }
                 uint8_t comp_ind = 0;
@@ -729,14 +1052,17 @@
                 }
                 uint32_t curr_byte = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser); // Ss
                 if (curr_byte != 0) {
+                    ETRACE("ERROR: curr_byte 0x%08x != 0\n", curr_byte);
                     return DECODE_PARSER_FAIL;
                 }
                 curr_byte = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser);  // Se
                 if (curr_byte != 0x3f) {
+                    ETRACE("ERROR: curr_byte 0x%08x != 0x3f\n", curr_byte);
                     return DECODE_PARSER_FAIL;
                 }
                 curr_byte = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser);  // Ah, Al
                 if (curr_byte != 0) {
+                    ETRACE("ERROR: curr_byte 0x%08x != 0\n", curr_byte);
                     return DECODE_PARSER_FAIL;
                 }
                 // Set slice control variables needed
@@ -773,24 +1099,41 @@
     jd_libva_ptr->huffman_tables_num = dht_ind;
 
     /* The slice for the last scan should run up to the end of the picture */
-    jd_libva_ptr->slice_param_buf[scan_ind - 1].slice_data_size = (jd_libva_ptr->eoi_offset - jd_libva_ptr->slice_param_buf[scan_ind - 1].slice_data_offset);
-
+    if (jd_libva_ptr->eoi_offset) {
+        jd_libva_ptr->slice_param_buf[scan_ind - 1].slice_data_size = (jd_libva_ptr->eoi_offset - jd_libva_ptr->slice_param_buf[scan_ind - 1].slice_data_offset);
+    }
+    else {
+        jd_libva_ptr->slice_param_buf[scan_ind - 1].slice_data_size = (jd_libva_ptr->file_size - jd_libva_ptr->slice_param_buf[scan_ind - 1].slice_data_offset);
+    }
     // throw AppException if SOF0 isn't found
     if (!frame_marker_found) {
         ETRACE("EEORR: Reached end of bitstream while trying to parse headers\n");
         return DECODE_PARSER_FAIL;
     }
 
-    parseTableData(jd_libva_ptr);
+    Decode_Status status = parseTableData(cinfo, jd_libva_ptr);
+    if (status != DECODE_SUCCESS) {
+        ETRACE("ERROR: Parsing table data returns %d", status);
+    }
+    cinfo->original_image_width = jd_libva_ptr->picture_param_buf.picture_width;  /* nominal image width (from SOF marker) */
+    cinfo->image_width = jd_libva_ptr->picture_param_buf.picture_width;   /* nominal image width (from SOF marker) */
+    cinfo->image_height = jd_libva_ptr->picture_param_buf.picture_height;  /* nominal image height */
+    cinfo->num_components = jd_libva_ptr->picture_param_buf.num_components;       /* # of color components in JPEG image */
+    cinfo->jpeg_color_space = JCS_YCbCr; /* colorspace of JPEG image */
+    cinfo->out_color_space = JCS_RGB; /* colorspace for output */
+    cinfo->src->bytes_in_buffer = jd_libva_ptr->file_size;
 
-    return DECODE_SUCCESS;
+    ITRACE("Successfully parsed table");
+    return status;
 
 }
 
-Decode_Status parseTableData(jd_libva_struct * jd_libva_ptr) {
+Decode_Status parseTableData(j_decompress_ptr cinfo, jd_libva_struct * jd_libva_ptr) {
     CJPEGParse* parser = (CJPEGParse*)malloc(sizeof(CJPEGParse));
-    if (parser == NULL)
+    if (parser == NULL) {
+        ETRACE("%s ERROR: Parsing table data returns %d", __FUNCTION__, DECODE_MEMORY_FAIL);
         return DECODE_MEMORY_FAIL;
+    }
 
     parserInitialize(parser, jd_libva_ptr->bitstream_buf, jd_libva_ptr->file_size);
 
@@ -807,6 +1150,7 @@
                 uint32_t table_length = table_bytes > 64 ? 64 : table_bytes;
                 uint32_t table_precision = table_info >> 4;
                 if (table_precision != 0) {
+                    ETRACE("%s ERROR: Parsing table data returns %d", __FUNCTION__, DECODE_PARSER_FAIL);
                     return DECODE_PARSER_FAIL;
                 }
                 uint32_t table_id = table_info & 0xf;
@@ -820,7 +1164,7 @@
                         jd_libva_ptr->qmatrix_buf.quantiser_table[table_id][byte_ind] = parser->readNextByte(parser);
                     }
                 } else {
-                    ETRACE("DQT table ID is not supported");
+                    ETRACE("%s DQT table ID is not supported", __FUNCTION__);
                     parser->burnBytes(parser, table_length);
                 }
                 table_bytes -= table_length;
@@ -882,7 +1226,7 @@
                     }//end of else
                 } else {
                     // Find out the number of entries in the table
-                    ETRACE("DHT table ID is not supported");
+                    ETRACE("%s DHT table ID is not supported", __FUNCTION__);
                     uint32_t table_entries = 0;
                     uint32_t bit_ind = 0;
                     for(bit_ind = 0; bit_ind < 16; bit_ind++) {
diff --git a/imagedecoder/JPEGDecoder.h b/imagedecoder/JPEGDecoder.h
index 8e4ee17..a77db7a 100644
--- a/imagedecoder/JPEGDecoder.h
+++ b/imagedecoder/JPEGDecoder.h
@@ -34,6 +34,10 @@
 #include <va/va.h>
 //#include <va/va_android.h>
 #include "va/va_dec_jpeg.h"
+#include <stdio.h>
+#define HAVE_BOOLEAN
+#include "jpeglib.h"
+#include <hardware/gralloc.h>
 
 #define Display unsigned int
 #define BOOL int
@@ -78,6 +82,9 @@
     uint32_t rotation;
     CJPEGParse* JPEGParser;
 
+    char ** output_image;
+    uint32_t output_lines;
+    uint32_t fourcc;
 } jd_libva_struct;
 
 typedef enum {
@@ -97,9 +104,10 @@
 
 Decode_Status jdva_initialize (jd_libva_struct * jd_libva_ptr);
 void jdva_deinitialize (jd_libva_struct * jd_libva_ptr);
-Decode_Status jdva_decode (jd_libva_struct * jd_libva_ptr, uint8_t* buf);
+Decode_Status jdva_decode (j_decompress_ptr cinfo, jd_libva_struct * jd_libva_ptr);
 Decode_Status jdva_create_resource (jd_libva_struct * jd_libva_ptr);
 Decode_Status jdva_release_resource (jd_libva_struct * jd_libva_ptr);
-Decode_Status parseBitstream(jd_libva_struct * jd_libva_ptr);
-Decode_Status parseTableData(jd_libva_struct * jd_libva_ptr);
+Decode_Status parseBitstream(j_decompress_ptr cinfo, jd_libva_struct * jd_libva_ptr);
+Decode_Status parseTableData(j_decompress_ptr cinfo, jd_libva_struct * jd_libva_ptr);
+
 #endif