FFMpeg libswscale XBGR32 до NV12 почти работает, но цвета неправильные
Я получаю Linx DMA-BUF от графического процессора в формате XBGR32, и мне нужно использовать libswscale FFMpeg для преобразования его на ARM в NV12.
Я был в состоянии почти заставить это работать, основанный на различных должностях SO и документации.
Вот экран LCD, который является фактическим выходом графического процессора:
Вот закодированные данные из фрейма NV12, созданного libswscale - он должен показывать те же цвета, что и экран:
Обратите внимание, что фотографии не были сделаны в одно и то же время.
Что я делаю неправильно?
Вот соответствующая часть моего кода:
/* 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);