blob: ce910272d7d3c8bceaad7f207b27caa620373fcb [file] [log] [blame]
#include <system/graphics.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <va/va.h>
#include <va/va_drmcommon.h>
#include <va/va_vpp.h>
#include <va/va_android.h>
#include <va/va_tpi.h>
#include <assert.h>
#include <hardware/gralloc.h>
#include "VideoVPPBase.h"
#include <intel_bufmgr.h>
#include <drm_fourcc.h>
#define ALIGN(x, align) (((x) + (align) - 1) & (~((align) - 1)))
enum {
HAL_PIXEL_FORMAT_NV12_TILED_INTEL = 0x100,
HAL_PIXEL_FORMAT_NV12_LINEAR_INTEL = 0x101,
// deprecated use HAL_PIXEL_FORMAT_NV12_TILED_INTEL
#if HAL_PIXEL_FORMAT_NV12_DEFINED
HAL_PIXEL_FORMAT_INTEL_NV12 = HAL_PIXEL_FORMAT_NV12,
#else
HAL_PIXEL_FORMAT_INTEL_NV12 = HAL_PIXEL_FORMAT_NV12_TILED_INTEL,
#endif
HAL_PIXEL_FORMAT_YCrCb_422_H_INTEL = 0x102, // YV16
// deprecated use HAL_PIXEL_FORMAT_NV12_LINEAR_INTEL
HAL_PIXEL_FORMAT_YUV420PackedSemiPlanar_INTEL = 0x7FA00E00,
// deprecated use HAL_PIXEL_FORMAT_NV12_TILED_INTEL
HAL_PIXEL_FORMAT_YUV420PackedSemiPlanar_Tiled_INTEL = 0x7FA00F00,
};
struct mfx_gralloc_drm_handle_t {
native_handle_t base;
int magic;
int width;
int height;
int format;
int usage;
int name;
int pid; // creator
mutable int other; // registered owner (pid)
mutable union { int data1; mutable drm_intel_bo *bo; }; // drm buffer object
union { int data2; uint32_t fb; }; // framebuffer id
int pitch; // buffer pitch (in bytes)
int allocWidth; // Allocated buffer width in pixels.
int allocHeight; // Allocated buffer height in lines.
};
static void usage(const char *me) {
fprintf(stderr, "color space conversion\n"
"\t\tusage: %s -i input -o output\n"
"\t\t-w width -h height\n",
me);
exit(1);
}
#define VPWRAPPER_NATIVE_DISPLAY 0x18c34078
#define CHECK_VA_STATUS(FUNC) \
if (vret != VA_STATUS_SUCCESS) {\
printf("[%d] " FUNC" failed with 0x%x\n", __LINE__, vret);\
return vret;\
}
static inline unsigned long GetTickCount()
{
struct timeval tv;
if (gettimeofday(&tv, NULL))
return 0;
return tv.tv_usec / 1000 + tv.tv_sec * 1000;
}
int main(int argc, char *argv[])
{
int width = 1280, height = 720;
int i, j, res;
const char *me = argv[0];
char input[128], output[128];
int has_input = 0;
int has_output = 0;
int has_width = 0;
int has_height = 0;
FILE *fIn, *fOut;
while ((res = getopt(argc, argv, "i:o:w:h:")) >= 0) {
switch (res) {
case 'i':
{
strcpy(input, optarg);
has_input = 1;
fIn = fopen(input, "r");
break;
}
case 'o':
{
strcpy(output, optarg);
has_output = 1;
fOut = fopen(output, "w+");
break;
}
case 'w':
{
width = atoi(optarg);
has_width = 1;
break;
}
case 'h':
{
height = atoi(optarg);
has_height = 1;
break;
}
default:
{
usage(me);
}
}
}
if (!has_input || !has_output || !has_width || !has_height || !fIn || !fOut)
usage(me);
hw_module_t const* module;
alloc_device_t *mAllocDev;
int32_t stride_YUY2, stride_NV12;
buffer_handle_t handle_YUY2, handle_NV12;
struct gralloc_module_t *gralloc_module;
struct mfx_gralloc_drm_handle_t *pGrallocHandle;
RenderTarget Src, Dst;
void *vaddr[3];
res = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
gralloc_module = (struct gralloc_module_t*)module;
res = gralloc_open(module, &mAllocDev);
res = mAllocDev->alloc(mAllocDev, width, height,
//HAL_PIXEL_FORMAT_YCbCr_422_I,
HAL_PIXEL_FORMAT_YCrCb_422_H_INTEL,
GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE,// |
//GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK,
&handle_YUY2, &stride_YUY2);
if (res != 0)
printf("%d: alloc()\n", __LINE__);
else {
pGrallocHandle = (struct mfx_gralloc_drm_handle_t *)handle_YUY2;
printf("YUY2 %d %d %d\n", pGrallocHandle->width,
pGrallocHandle->height, pGrallocHandle->pitch);
res = gralloc_module->lock(gralloc_module, handle_YUY2,
GRALLOC_USAGE_SW_WRITE_MASK,
0, 0, width, height, (void**)&vaddr);
if (res != 0) {
printf("lock error\n");
} else {
//res = fread(vaddr[0], 1, width * height * 2, fIn);
for (i = 0; i < height; i++)
res += fread(vaddr[0] + i * pGrallocHandle->pitch, 1, width, fIn);
for (i = 0; i < height; i++)
res += fread(vaddr[0] + (2 * height + i) * pGrallocHandle->pitch, 1,
width / 2, fIn);
for (i = 0; i < height; i++)
res += fread(vaddr[0] + (height + i) * pGrallocHandle->pitch, 1,
width / 2, fIn);
printf("fread %d\n", res);
gralloc_module->unlock(gralloc_module, handle_YUY2);
}
Src.width = pGrallocHandle->width;
Src.height = pGrallocHandle->height;
Src.stride = pGrallocHandle->pitch;
//Src.format = VA_RT_FORMAT_YUV422;
//Src.pixel_format = VA_FOURCC_YUY2;
Src.format = VA_RT_FORMAT_YUV422;
Src.pixel_format = VA_FOURCC_422H;
//Src.type = RenderTarget::KERNEL_DRM;
//Src.handle = pGrallocHandle->name;
Src.type = RenderTarget::ANDROID_GRALLOC;
Src.handle = (unsigned int)handle_YUY2;
Src.rect.x = Src.rect.y = 0;
Src.rect.width = Src.width;
Src.rect.height = Src.height;
}
res = mAllocDev->alloc(mAllocDev, width, height,
//HAL_PIXEL_FORMAT_NV12_TILED_INTEL,
HAL_PIXEL_FORMAT_YCbCr_422_I,
GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE,// |
//GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK,
&handle_NV12, &stride_NV12);
if (res != 0)
printf("%d: alloc()\n", __LINE__);
else {
pGrallocHandle = (struct mfx_gralloc_drm_handle_t *)handle_NV12;
printf("NV12 %d %d %d\n", pGrallocHandle->width,
pGrallocHandle->height, pGrallocHandle->pitch);
Dst.width = pGrallocHandle->width;
Dst.height = pGrallocHandle->height;
Dst.stride = pGrallocHandle->pitch;
//Dst.format = VA_RT_FORMAT_YUV420;
//Dst.pixel_format = VA_FOURCC_NV12;
Dst.format = VA_RT_FORMAT_YUV422;
Dst.pixel_format = VA_FOURCC_YUY2;
Dst.type = RenderTarget::KERNEL_DRM;
Dst.handle = pGrallocHandle->name;
Dst.rect.x = 0;
Dst.rect.y = 0;
Dst.rect.width = Dst.width;
Dst.rect.height = Dst.height;
}
VAStatus vret;
VideoVPPBase * p = new VideoVPPBase();
p->start();
VPParameters *vpp = VPParameters::create(p);
if (vpp) {
FilterConfig filter;
vpp->getNR(filter);
printf("valid %d def %f step %f\n", filter.valid, filter.def, filter.step);
filter.cur = 0.5;
vpp->setNR(FilterConfig::LOW);
vpp->buildfilters();
vret = p->perform(Src, Dst, vpp, false);
CHECK_VA_STATUS("doVp");
vret = p->perform(Src, Dst, vpp, false);
CHECK_VA_STATUS("doVp");
vpp->reset(false);
}
p->stop();
{
res = gralloc_module->lock(gralloc_module, handle_NV12,
GRALLOC_USAGE_SW_READ_MASK,
0, 0, width, height, (void**)&vaddr);
if (res != 0) {
printf("lock error\n");
} else {
unsigned char *pY = (unsigned char*)vaddr[0];
unsigned char *pUV = pY + stride_NV12 * ALIGN(height, 32);
//unsigned char *pUV = pY + stride_NV12 * height;
/*
for (res =0, i = 0; i < height; i++) {
res += fwrite(pY, 1, width, fOut);
pY += stride_NV12;
}
printf("fwrite %d\n", res);
for (res =0, i = 0; i < height / 2; i++) {
res += fwrite(pUV, 1, width, fOut);
pUV += stride_NV12;
}
*/
for (i = 0; i < height; i++)
res += fwrite(vaddr[0] + i * Dst.stride, 1, width * 2, fOut);
printf("fwrite %d\n", res);
gralloc_module->unlock(gralloc_module, handle_NV12);
}
}
mAllocDev->free(mAllocDev, handle_YUY2);
mAllocDev->free(mAllocDev, handle_NV12);
gralloc_close(mAllocDev);
return 0;
}