3

我从 XBGR32 格式的 GPU 获得 Linx DMA-BUF,我需要使用 FFMpeg 的 libswscale 将其在 ARM 上转换为 NV12。

根据各种 SO 帖子和文档,我几乎可以让它工作。

这是 GPU 实际输出的 LCD 屏幕: 在此处输入图像描述

这是 libswscale 创建的 NV12 帧的编码数据 - 它应该显示与屏幕相同的颜色: 在此处输入图像描述

请注意,这些照片并非在同一时间拍摄。

我究竟做错了什么?

这是我的代码的相关部分:

/* Prepare to mmap the GBM BO */
union gbm_bo_handle handleUnion = gbm_bo_get_handle(bo);  
struct drm_omap_gem_info req;
req.handle = handleUnion.s32;    
ret = drmCommandWriteRead(m_DRMController.fd, DRM_OMAP_GEM_INFO,&req, sizeof(req));
if (ret) {  
    qDebug() << "drmCommandWriteRead(): Cannot set write/read";
}   

// Perform actual memory mapping of GPU output    
gpuMmapFrame = (char *)mmap(0, req.size, PROT_READ | PROT_WRITE, MAP_SHARED,m_DRMController.fd, req.offset);
assert(gpuMmapFrame != MAP_FAILED);

// Use ffmpeg to do the SW BGR32 to NV12   
static SwsContext *swsCtx = NULL;    
int width    = RNDTO2( convertWidth );    
int height   = RNDTO2( convertHeight );    
int ystride  = RNDTO32 ( width );    
int uvstride = RNDTO32 ( width / 2 );    
int uvsize   = uvstride * ( height / 2 );    
void *plane[] = { y, u, u + uvsize, 0 };    
int stride[] = { ystride, uvstride, uvstride, 0 };    

// Output of GPU is XBGR32    
// #define V4L2_PIX_FMT_XBGR32  v4l2_fourcc('X', 'R', '2', '4') /* 32  BGRX-8-8-8-8  */    
swsCtx = sws_getCachedContext( swsCtx, convertWidth, convertHeight, AV_PIX_FMT_BGR32, width, height, AV_PIX_FMT_NV12, 
                           SWS_FAST_BILINEAR , NULL, NULL, NULL );  
int linesize[1] = { convertWidth * 4 };    
const uint8_t *inData[1] = { (uint8_t*)gpuMmapFrame };    
if ( gpuMmapFrame ) {    
    sws_scale( swsCtx, (const uint8_t *const *)inData, linesize, 0, convertHeight, (uint8_t *const *)plane, stride );    
}        

// Unmap it    
munmap(gpuMmapFrame,req.size);

// Now send the frame to the encoder    
dce.submitFrameToEncode(swEncodeBufferNV12);
4

0 回答 0