add support for NV12 camera format

This commit is contained in:
Arisotura 2022-10-02 15:38:31 +02:00
parent 23fc51f4bd
commit 3e7108b2e1
2 changed files with 65 additions and 5 deletions

View File

@ -35,9 +35,22 @@ void CameraFrameDumper::present(const QVideoFrame& _frame)
if (!frame.map(QVideoFrame::ReadOnly))
return;
if (!frame.isReadable())
{
frame.unmap();
return;
}
cam->feedFrame((u32*)frame.bits(0), frame.width(), frame.height(), frame.pixelFormat() == QVideoFrameFormat::Format_YUYV);
switch (frame.pixelFormat())
{
case QVideoFrameFormat::Format_XRGB8888:
case QVideoFrameFormat::Format_YUYV:
cam->feedFrame((u32*)frame.bits(0), frame.width(), frame.height(), frame.pixelFormat() == QVideoFrameFormat::Format_YUYV);
break;
case QVideoFrameFormat::Format_NV12:
cam->feedFrame_NV12((u8*)frame.bits(0), (u8*)frame.bits(1), frame.width(), frame.height());
break;
}
frame.unmap();
}
@ -55,9 +68,22 @@ bool CameraFrameDumper::present(const QVideoFrame& _frame)
if (!frame.map(QAbstractVideoBuffer::ReadOnly))
return false;
if (!frame.isReadable())
{
frame.unmap();
return false;
}
cam->feedFrame((u32*)frame.bits(), frame.width(), frame.height(), frame.pixelFormat() == QVideoFrame::Format_YUYV);
switch (frame.pixelFormat())
{
case QVideoFrame::Format_RGB32:
case QVideoFrame::Format_YUYV:
cam->feedFrame((u32*)frame.bits(0), frame.width(), frame.height(), frame.pixelFormat() == QVideoFrame::Format_YUYV);
break;
case QVideoFrame::Format_NV12:
cam->feedFrame_NV12((u8*)frame.bits(0), (u8*)frame.bits(1), frame.width(), frame.height());
break;
}
frame.unmap();
@ -70,6 +96,7 @@ QList<QVideoFrame::PixelFormat> CameraFrameDumper::supportedPixelFormats(QAbstra
ret.append(QVideoFrame::Format_RGB32);
ret.append(QVideoFrame::Format_YUYV);
ret.append(QVideoFrame::Format_NV12);
return ret;
}
@ -94,6 +121,7 @@ CameraManager::CameraManager(int num, int width, int height, bool yuv) : QObject
int fbsize = frameWidth * frameHeight;
if (yuv) fbsize /= 2;
frameBuffer = new u32[fbsize];
tempFrameBuffer = new u32[fbsize];
inputType = -1;
xFlip = false;
@ -181,6 +209,7 @@ void CameraManager::init()
for (const QCameraFormat& item : supported)
{
if (item.pixelFormat() != QVideoFrameFormat::Format_YUYV &&
item.pixelFormat() != QVideoFrameFormat::Format_NV12 &&
item.pixelFormat() != QVideoFrameFormat::Format_XRGB8888)
continue;
@ -223,6 +252,7 @@ void CameraManager::init()
for (const QCameraViewfinderSettings& item : supported)
{
if (item.pixelFormat() != QVideoFrame::Format_YUYV &&
item.pixelFormat() != QVideoFrame::Format_NV12 &&
item.pixelFormat() != QVideoFrame::Format_RGB32)
continue;
@ -387,6 +417,34 @@ void CameraManager::feedFrame(u32* frame, int width, int height, bool yuv)
frameMutex.unlock();
}
void CameraManager::feedFrame_NV12(u8* planeY, u8* planeUV, int width, int height)
{
for (int y = 0; y < frameHeight; y++)
{
int sy = (y * height) / frameHeight;
for (int x = 0; x < frameWidth; x+=2)
{
int sx1 = (x * width) / frameWidth;
int sx2 = ((x+1) * width) / frameWidth;
u32 val;
u8 y1 = planeY[(sy*width) + sx1];
u8 y2 = planeY[(sy*width) + sx2];
int uvpos = (((sy>>1)*(width>>1)) + (sx1>>1));
u8 u = planeUV[uvpos << 1];
u8 v = planeUV[(uvpos << 1) + 1];
val = y1 | (u << 8) | (y2 << 16) | (v << 24);
tempFrameBuffer[((y*frameWidth) + x) >> 1] = val;
}
}
feedFrame(tempFrameBuffer, frameWidth, frameHeight, true);
}
void CameraManager::copyFrame_Straight(u32* src, int swidth, int sheight, u32* dst, int dwidth, int dheight, bool xflip, bool yuv)
{
if (yuv)

View File

@ -42,13 +42,13 @@ class CameraManager;
class CameraFrameDumper : public QVideoSink
{
Q_OBJECT
public:
CameraFrameDumper(QObject* parent = nullptr);
public slots:
void present(const QVideoFrame& frame);
private:
CameraManager* cam;
};
@ -92,6 +92,7 @@ public:
void captureFrame(u32* frame, int width, int height, bool yuv);
void feedFrame(u32* frame, int width, int height, bool yuv);
void feedFrame_NV12(u8* planeY, u8* planeUV, int width, int height);
signals:
void camStartSignal();
@ -119,6 +120,7 @@ private:
int frameWidth, frameHeight;
bool frameFormatYUV;
u32* frameBuffer;
u32* tempFrameBuffer;
QMutex frameMutex;
bool xFlip;