Dear all,
I want to flip camera stream with g2d api when preview,but it does not work. where is wrong with my test code?
I add g2d_blit test code in function processFrame in preivewStream.cpp, blow is my test code:
int PreviewStream::processFrame(CameraFrame *frame)
{
status_t ret = NO_ERROR;
#if 1
struct g2d_buf s_buf, d_buf;
struct g2d_surface src,dst;
int width,height;
int size;
int g2d_ret = 0;
#endif
if (mShowFps) {
showFps();
}
ret = renderBuffer(frame);
if (ret != NO_ERROR) {
FLOGE("%s renderBuffer failed", __FUNCTION__);
goto err_exit;
}
//the frame held in service.
frame->addReference();
StreamBuffer buffer;
ret = requestBuffer(&buffer);
if (ret != NO_ERROR) {
FLOGE("%s requestBuffer failed", __FUNCTION__);
goto err_exit;
}
#if 1
FLOG_TRACE("%s nwidth=%d, nheight:%d format:%d", __FUNCTION__, buffer.mWidth, buffer.mHeight,buffer.mFormat);
width = 720;
height = 576;
size = (frame->mSize > buffer.mSize) ? buffer.mSize : frame->mSize;
FLOG_TRACE("mSize=%d, size=%d", buffer.mSize,size);
FLOG_TRACE("f mPhyAddr=0x%08x, b mPhyAddr=0x%08x", frame->mPhyAddr, buffer.mPhyAddr);
FLOG_TRACE("f mPhyAddr=0x%08x, b mVirtAddr=0x%08x", frame->mVirtAddr, buffer.mVirtAddr);
s_buf.buf_paddr = frame->mPhyAddr;
s_buf.buf_vaddr = frame->mVirtAddr;
d_buf.buf_paddr = buffer.mPhyAddr;
d_buf.buf_vaddr = buffer.mVirtAddr;
g2d_ret = g2d_copy(g2dHandle, &d_buf, &s_buf, size);
if(g2d_ret){
FLOG_TRACE("g2d_copy fail!");
}
src.planes[0] = s_buf.buf_paddr;
//src.planes[1] = s_buf.buf_paddr+width+height;
//src.planes[2] = s_buf.buf_paddr+width+height*2;
src.left = 0;
src.top = 0;
src.right = width;
src.bottom = height;
src.stride = width;
src.width = width;
src.height = height;
src.format = G2D_RGBA8888;
src.rot = G2D_ROTATION_0;
dst.planes[0] = d_buf.buf_paddr;
dst.left = 0;
dst.top = 0;
dst.right = width;
dst.bottom = height;
dst.stride = width;
dst.width = width;
dst.height = height;
dst.format = G2D_RGBA8888;
dst.rot = G2D_FLIP_H;
g2d_ret = g2d_blit(g2dHandle, &src, &dst);
if(g2d_ret){
FLOG_TRACE("g2d_blit fail!");
}
g2d_finish(g2dHandle);
#endif
for (int i = 0; i < mTotalBuffers; i++) {
if (mCameraBuffer[i].mBufHandle == buffer.mBufHandle) {
//release frame from service.
mCameraBuffer[i].release();
break;
}
}
err_exit:
sem_post(&mRespondSem);
return ret;
}
Thanks!
Hello zeng,
It is not better way to realize camera v flip h by using GPU! Camera module has the function, you can configure corresponding register in camera driver or load API function provided by camera driver on application level to realize your solution.
Best Regards,
Weidong
My camera sensor does not support flip feature according to sensor provider reply.
Now the h flip test code work ,but does not work well.
The camera frame format is yuv422(259=0x103), How to select dst and src format from blow list?
enum g2d_format
{
//rgb formats
G2D_RGB565 = 0,
G2D_RGBA8888 = 1,
G2D_RGBX8888 = 2,
G2D_BGRA8888 = 3,
G2D_BGRX8888 = 4,
//yuv formats
G2D_NV12 = 20,
G2D_I420 = 21,
G2D_YV12 = 22,
G2D_NV21 = 23,
G2D_YUYV = 24,
G2D_YVYU = 25,
G2D_UYVY = 26,
G2D_VYUY = 27,
G2D_NV16 = 28,
G2D_NV61 = 29,
};
blow is my test code:
int PreviewStream::processFrame(CameraFrame *frame)
{
status_t ret = NO_ERROR;
#if 1
struct g2d_buf s_buf, *d_buf;
struct g2d_surface src,dst;
int width,height;
int size;
int g2d_ret = 0;
static int count = 0;
enum g2d_format g2d_format = G2D_NV12;
#endif
if (mShowFps) {
showFps();
}
#if 1
//FLOG_TRACE("%s nwidth=%d, nheight:%d format:%d", __FUNCTION__, frame->mWidth, frame->mHeight,frame->mFormat);
width = 720;
height = 576;
size = frame->mSize;
//FLOG_TRACE("mSize=%d, size=%d", frame->mSize,size);
//FLOG_TRACE("mPhyAddr=0x%08x, mVirtAddr=0x%08x", frame->mPhyAddr, frame->mVirtAddr);
s_buf.buf_paddr = frame->mPhyAddr;
s_buf.buf_vaddr = frame->mVirtAddr;
d_buf = g2d_alloc(size, 0);
g2d_ret = g2d_copy(g2dHandle, d_buf, &s_buf, size);
if(g2d_ret){
FLOG_TRACE("g2d_copy fail!");
}
src.planes[0] = d_buf->buf_paddr;
src.left = 0;
src.top = 0;
src.right = width;
src.bottom = height;
src.stride = width;//+30;
src.width = width;
src.height = height;
//src.format = G2D_RGBA8888;
//src.format = G2D_YUYV;
src.format = g2d_format;
src.rot = G2D_ROTATION_0;
dst.planes[0] = s_buf.buf_paddr;
dst.left = 0;
dst.top = 0;
dst.right = width;
dst.bottom = height;
dst.stride = width;//+30;
dst.width = width;
dst.height = height;
//dst.format = G2D_RGBA8888;//ok
//dst.format = G2D_RGBA8888;//ok
//dst.format = G2D_YUYV;
dst.format = g2d_format;
dst.rot = G2D_FLIP_H;
g2d_ret = g2d_blit(g2dHandle, &src, &dst);
if(g2d_ret){
FLOG_TRACE("zengzh g2d_blit fail!");
}
g2d_finish(g2dHandle);
if(d_buf)
g2d_free(d_buf);
count++;
#endif
ret = renderBuffer(frame);
if (ret != NO_ERROR) {
FLOGE("%s renderBuffer failed", __FUNCTION__);
goto err_exit;
}
//the frame held in service.
frame->addReference();
StreamBuffer buffer;
ret = requestBuffer(&buffer);
if (ret != NO_ERROR) {
FLOGE("%s requestBuffer failed", __FUNCTION__);
goto err_exit;
}
for (int i = 0; i < mTotalBuffers; i++) {
if (mCameraBuffer[i].mBufHandle == buffer.mBufHandle) {
//release frame from service.
mCameraBuffer[i].release();
break;
}
}
err_exit:
sem_post(&mRespondSem);
return ret;
}