高通 Camera HAL3:CAMX中实现Dump YUV、RAW

CMAX开发过程中,经常要在HAL层dump yuv或raw图进行分析

怎么在CAMX中实现Dump YUV、RAW的功能?

废话不多说,上代码

一.Dump YUV 功能实现代码

1. 在头文件中加入如下代码:

typedef long                   MLong;
typedef float                  MFloat;
typedef double                 MDouble;
typedef unsigned char          MByte;
typedef unsigned short         MWord;
typedef unsigned int           MDWord;
typedef void*                  MHandle;
typedef char                   MChar;
typedef long                   MBool;
typedef void                   MVoid;
typedef void*                  MPVoid;
typedef char*                  MPChar;
typedef short                  MShort;
typedef const    char*         MPCChar;
typedef MLong                  MRESULT;
typedef MDWord                 MCOLORREF;
typedef signed   char          MInt8;
typedef unsigned char          MUInt8;
typedef signed   short         MInt16;
typedef unsigned short         MUInt16;
typedef signed   int           MInt32;
typedef unsigned int           MUInt32;
/*Define the image format space*/
typedef struct __tag_ASVL_OFFSCREEN{
	MUInt32	u32PixelArrayFormat;
	MInt32	i32Width;
	MInt32	i32Height;
	MUInt8*	ppu8Plane[4];
	MInt32	pi32Pitch[4];
}ASVLOFFSCREEN, *LPASVLOFFSCREEN;
// used for performance
static long long __attribute__((unused))  gettime(){
    struct timeval time;
    gettimeofday(&time, NULL);
    return ((long long)time.tv_sec * 1000 + time.tv_usec / 1000);
}
VOID DumpYUVData(ASVLOFFSCREEN* pASLIn, UINT index, const CHAR* namePrefix, long long timestamp);  //放到具体node类的private 中

2. 在具体node的.cpp文件中,添加如下代码:

#define DUMP_FILE_PATH "/data/vendor/camera/"
VOID XXXNode::DumpYUVData(ASVLOFFSCREEN* pASLIn, UINT index, const CHAR* namePrefix, long long timestamp){
    CHAR filename[256];
    memset(filename, 0, sizeof(CHAR) * 256);
    snprintf(filename, sizeof(filename), "%s%s_%llu_%d_%dx%d_%d.nv12",DUMP_FILE_PATH,namePrefix,timestamp,index,pASLIn->pi32Pitch[0],pASLIn->i32Height, 0);

    int file_fd = open(filename,O_RDWR|O_CREAT,0777);
    if(file_fd){
        UINT bytes_write;
	    //存储第一个plane, Y, 长度是 所有像素的总个数,即像素图像的宽x高
        bytes_write = write(file_fd,pASLIn->ppu8Plane[0],pASLIn->pi32Pitch[0] * pASLIn->i32Height);
	    //存储第二个plane, UV, UV长度是Y的长度的一半,所以是 像素图像的宽x高/2
        bytes_write = write(file_fd,pASLIn->ppu8Plane[1],pASLIn->pi32Pitch[0] * (pASLIn->i32Height >> 1) );
        close(file_fd);
    }else{
        ALOGE("fileopen  error");
    }
}
CDKResult XXXNode::ProcessRequest(CHINODEPROCESSREQUESTINFO* pProcessRequestInfo){
    CHINODEBUFFERHANDLE hOutput = pProcessRequestInfo->phOutputBuffer[0];
    CHINODEBUFFERHANDLE hInput = pProcessRequestInfo->phInputBuffer[0];
    ASVLOFFSCREEN inputFrame, outputFrame;

    long long t0 = gettime();
    inputFrame.i32Width = hInput->format.width;
    inputFrame.i32Height = hInput->format.height;
    for(UINT j = 0; j < hInput->numberOfPlanes; j++) {
        //nv12就两个plane,第个plane 是Y; 第二个plane 是UV
        inputFrame.pi32Pitch[j] = hInput->format.formatParams.yuvFormat[0].planeStride;      //每个plane的宽
        inputFrame.ppu8Plane[j] = hInput->pImageList[0].pAddr[j];      //每个plane的数据首地址
    }

    outputFrame.i32Width = hOutput->format.width;
    outputFrame.i32Height = hOutput->format.height;
    for(UINT j = 0; j < hOutput->numberOfPlanes; j++) {
        outputFrame.pi32Pitch[j] = hOutput->format.formatParams.yuvFormat[0].planeStride;
        outputFrame.ppu8Plane[j] = hOutput->pImageList[0].pAddr[j];
    }

    DumpYUVData(&inputFrame, 0, "IMG", t0);
    //CopyImage(pProcessRequestInfo->phOutputBuffer[i], pProcessRequestInfo->phInputBuffer[i]);
    DumpYUVData(&outputFrame, 1, "IMG", t0);
}

二.Dump RAW 功能实现代码

1.在camxchixxxxxnode.cpp代码中添加函数:

VOID ChiAWRawHdrNode::DumpRAWData(CHINODEBUFFERHANDLE hRAWIn, const CHAR* namePrefix)
{
    if (hRAWIn == NULL) {
        LOG_INFO(CamxLogGroupChi, "[AW_RAWNS]  hRAWIn is NULL");
        return;
    }
    CHAR filename[128];
    int written_len = 0;
    memset(filename, 0 , sizeof(CHAR) * 128);
    snprintf(filename, sizeof(filename), "/data/vendor/camera/%s_%dx%d.RAW", namePrefix, hRAWIn->format.formatParams.rawFormat.stride, hRAWIn->format.formatParams.rawFormat.sliceHeight);
    LOG_INFO(CamxLogGroupChi, "[AW_RAWNS] try to open file : %s", filename);


    int file_fd = open(filename, O_RDWR | O_CREAT | O_APPEND, 0777);
    if(file_fd)
{
        if (hRAWIn->planeSize[0] != 0) {
            uint32_t index = 0;
            void *data = NULL;
            data = (void *)((uint8_t *)hRAWIn->pImageList[0].pAddr[0]);
            written_len += write(file_fd, data, hRAWIn->planeSize[0]);
            LOG_INFO(CamxLogGroupChi, "[AW_RAWNS] written number of bytes %zu\n", hRAWIn->planeSize[0]);
        }

        close(file_fd);
    }
else
{
        LOG_ERROR(CamxLogGroupChi, "[AW_RAWNS] fileopen  error: %d", file_fd);
    }
}

参数 CHINODEBUFFERHANDLE 在 chinode.h 中定义,高通代码自带,不需要添加

2.在需要Dump的地方添加(例如ProcessRequest()函数中:

CDKResult ChiAWRawHdrNode::ProcessRequest(CHINODEPROCESSREQUESTINFO* pProcessRequestInfo)
{
        if(property_get_int32("debug.vendor.camera.dumpawraw", 0))
        {
		CHAR filename[256];
		long long timestamp = gettime();
		memset(filename, 0 , sizeof(CHAR) * 256);
		snprintf(filename, sizeof(filename), "rawhdr_frame_%llu_input%d", timestamp,i);
		DumpRAWData(pProcessRequestInfo->phInputBuffer[i],filename);
	}
}

三.结束 

猜你喜欢

转载自blog.csdn.net/geyichongchujianghu/article/details/131140588