Vitaliy Zarubin
1 year ago
5 changed files with 171 additions and 141 deletions
@ -0,0 +1,124 @@ |
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: Copyright 2023 Open Mobile Platform LLC <community@omp.ru> |
||||||
|
* SPDX-License-Identifier: BSD-3-Clause |
||||||
|
*/ |
||||||
|
#include <embedder_texture/camera_pixel_buffer.h> |
||||||
|
|
||||||
|
CameraPixelBuffer::CameraPixelBuffer(TextureRegistrar *plugin) : m_plugin(plugin) |
||||||
|
{ |
||||||
|
Aurora::StreamCamera::CameraManager *manager = StreamCameraManager(); |
||||||
|
|
||||||
|
if (manager->getNumberOfCameras()) |
||||||
|
{ |
||||||
|
Aurora::StreamCamera::CameraInfo info; |
||||||
|
|
||||||
|
if (manager->getCameraInfo(0, info)) // Camera ID = 0
|
||||||
|
{ |
||||||
|
std::vector<Aurora::StreamCamera::CameraCapability> caps; |
||||||
|
|
||||||
|
if (manager->queryCapabilities(info.id, caps)) |
||||||
|
{ |
||||||
|
m_cap = caps.at(1); |
||||||
|
m_camera = manager->openCamera(info.id); |
||||||
|
m_camera->setListener(this); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
int64_t CameraPixelBuffer::Register() |
||||||
|
{ |
||||||
|
m_textureId = m_plugin->RegisterTexture(TextureType::Pixels, [this](size_t width, size_t height) { |
||||||
|
if (this->m_buffer) { |
||||||
|
return TextureVariant(FlutterPixelBuffer{ this->m_buffer->buffer } ); |
||||||
|
} |
||||||
|
return TextureVariant(FlutterPixelBuffer{}); |
||||||
|
}); |
||||||
|
|
||||||
|
m_camera->startCapture(m_cap); |
||||||
|
|
||||||
|
return m_textureId; |
||||||
|
} |
||||||
|
|
||||||
|
void CameraPixelBuffer::Unregister() |
||||||
|
{ |
||||||
|
m_plugin->UnregisterTexture(m_textureId); |
||||||
|
m_camera->stopCapture(); |
||||||
|
m_buffer = nullptr; |
||||||
|
} |
||||||
|
|
||||||
|
void CameraPixelBuffer::onCameraFrame(std::shared_ptr<Aurora::StreamCamera::GraphicBuffer> buffer) |
||||||
|
{ |
||||||
|
auto frame = buffer->mapYCbCr(); |
||||||
|
|
||||||
|
QSize size(frame->width, frame->height); |
||||||
|
QImage* image = new QImage(size, QImage::Format_ARGB32); |
||||||
|
|
||||||
|
this->planarYuv420ToArgb(frame->y, frame->cb, frame->cr, |
||||||
|
frame->yStride, frame->cStride, frame->cStride, |
||||||
|
frame->chromaStep, |
||||||
|
reinterpret_cast<quint32 *>(image->bits()), |
||||||
|
frame->width, frame->height); |
||||||
|
|
||||||
|
uint8_t *pixels = static_cast<uint8_t *>(image->bits()); |
||||||
|
|
||||||
|
this->m_buffer = new FlutterPixelBuffer { pixels }; |
||||||
|
|
||||||
|
m_plugin->MarkTextureAvailable(m_textureId); |
||||||
|
} |
||||||
|
|
||||||
|
void CameraPixelBuffer::onCameraError(const std::string &errorDescription) |
||||||
|
{ |
||||||
|
std::cout << "onCameraError" << std::endl; |
||||||
|
} |
||||||
|
|
||||||
|
void CameraPixelBuffer::onCameraParameterChanged(Aurora::StreamCamera::CameraParameter parameter, const std::string &value)
|
||||||
|
{ |
||||||
|
std::cout << "onCameraParameterChanged" << std::endl; |
||||||
|
} |
||||||
|
|
||||||
|
quint32 CameraPixelBuffer::yuvToArgb(qint32 y, qint32 rv, qint32 guv, qint32 bu, qint32 a = 255) |
||||||
|
{ |
||||||
|
qint32 yy = (y - 16) * 298; |
||||||
|
|
||||||
|
return (a << 24) |
||||||
|
| qBound(0, (yy + rv) >> 8, 255) << 16 |
||||||
|
| qBound(0, (yy - guv) >> 8, 255) << 8 |
||||||
|
| qBound(0, (yy + bu) >> 8, 255); |
||||||
|
} |
||||||
|
|
||||||
|
void CameraPixelBuffer::planarYuv420ToArgb(const uchar *y, const uchar *u, const uchar *v, |
||||||
|
qint32 yStride, qint32 uStride, qint32 vStride, |
||||||
|
qint32 uvPixelStride, quint32 *rgb, qint32 width, qint32 height) |
||||||
|
{ |
||||||
|
quint32 *rgb0 = rgb; |
||||||
|
quint32 *rgb1 = rgb + width; |
||||||
|
|
||||||
|
for (qint32 j = 0; j < height; j += 2) { |
||||||
|
const uchar *lineY0 = y; |
||||||
|
const uchar *lineY1 = y + yStride; |
||||||
|
const uchar *lineU = u; |
||||||
|
const uchar *lineV = v; |
||||||
|
|
||||||
|
for (qint32 i = 0; i < width; i += 2) { |
||||||
|
const qint32 uu = *lineU - 128; |
||||||
|
const qint32 vv = *lineV - 128; |
||||||
|
const qint32 rv = 409 * vv + 128; |
||||||
|
const qint32 guv = 100 * uu + 208 * vv + 128; |
||||||
|
const qint32 bu = 516 * uu + 128; |
||||||
|
|
||||||
|
lineU += uvPixelStride; |
||||||
|
lineV += uvPixelStride; |
||||||
|
*rgb0++ = yuvToArgb(*lineY0++, rv, guv, bu); |
||||||
|
*rgb0++ = yuvToArgb(*lineY0++, rv, guv, bu); |
||||||
|
*rgb1++ = yuvToArgb(*lineY1++, rv, guv, bu); |
||||||
|
*rgb1++ = yuvToArgb(*lineY1++, rv, guv, bu); |
||||||
|
} |
||||||
|
|
||||||
|
y += yStride << 1; |
||||||
|
u += uStride; |
||||||
|
v += vStride; |
||||||
|
rgb0 += width; |
||||||
|
rgb1 += width; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: Copyright 2023 Open Mobile Platform LLC <community@omp.ru> |
||||||
|
* SPDX-License-Identifier: BSD-3-Clause |
||||||
|
*/ |
||||||
|
#ifndef CAMERA_PIXEL_BUFFER_H |
||||||
|
#define CAMERA_PIXEL_BUFFER_H |
||||||
|
|
||||||
|
#include <flutter/plugin-interface.h> |
||||||
|
#include <streamcamera/streamcamera.h> |
||||||
|
|
||||||
|
#include <QtCore> |
||||||
|
#include <QImage> |
||||||
|
|
||||||
|
class CameraPixelBuffer : public Aurora::StreamCamera::CameraListener |
||||||
|
{ |
||||||
|
|
||||||
|
public: |
||||||
|
CameraPixelBuffer(TextureRegistrar *plugin); |
||||||
|
|
||||||
|
void onCameraError(const std::string &errorDescription) override; |
||||||
|
void onCameraParameterChanged(Aurora::StreamCamera::CameraParameter, const std::string &value) override; |
||||||
|
void onCameraFrame(std::shared_ptr<Aurora::StreamCamera::GraphicBuffer> buffer) override; |
||||||
|
|
||||||
|
int64_t Register(); |
||||||
|
void Unregister(); |
||||||
|
|
||||||
|
private: |
||||||
|
quint32 yuvToArgb(qint32 y, qint32 rv, qint32 guv, qint32 bu, qint32 a); |
||||||
|
void planarYuv420ToArgb(const uchar *y, const uchar *u, const uchar *v, qint32 yStride, qint32 uStride, qint32 vStride, qint32 uvPixelStride, quint32 *rgb, qint32 width, qint32 height); |
||||||
|
|
||||||
|
private: |
||||||
|
int64_t m_textureId; |
||||||
|
TextureRegistrar *m_plugin; |
||||||
|
FlutterPixelBuffer *m_buffer; |
||||||
|
Aurora::StreamCamera::CameraCapability m_cap; |
||||||
|
std::shared_ptr<Aurora::StreamCamera::Camera> m_camera; |
||||||
|
}; |
||||||
|
|
||||||
|
#endif /* CAMERA_PIXEL_BUFFER_H */ |
Loading…
Reference in new issue