7#include <QtCore/qjnitypes.h>
8#include <QtCore/QLoggingCategory>
14bool isWorkaroundForEmulatorNeeded() {
15 const static bool workaroundForEmulator
16 = QtJniTypes::QtVideoDeviceManager::callStaticMethod<jboolean>(
"isEmulator");
17 return workaroundForEmulator;
29 if (!planes.isValid())
32 int numberPlanes = jniEnv->GetArrayLength(planes.object<jarray>());
39 auto resetPlane = [&](
int index) {
43 rowStrides[
index] = 0;
44 pixelStrides[
index] = 0;
45 bufferSize[
index] = 0;
51 if (jniEnv.checkAndClearExceptions() || !
plane.isValid()) {
56 rowStrides[
index] =
plane.callMethod<jint>(
"getRowStride");
57 pixelStrides[
index] =
plane.callMethod<jint>(
"getPixelStride");
59 auto byteBuffer =
plane.callMethod<QtJniTypes::JavaByteBuffer>(
"getBuffer");
60 if (!byteBuffer.isValid()) {
67 buffer[
index] =
static_cast<uint8_t *
>(jniEnv->GetDirectBufferAddress(byteBuffer.object()));
68 bufferSize[
index] = byteBuffer.callMethod<jint>(
"remaining");
77 AndroidImageFormat imageFormat = AndroidImageFormat(
format);
79 switch (imageFormat) {
80 case AndroidImageFormat::JPEG:
83 case AndroidImageFormat::YUV_420_888:
89 if (pixelStrides[1] == 1)
91 else if (pixelStrides[1] == 2) {
98 case AndroidImageFormat::HEIC:
102 case AndroidImageFormat::RAW_PRIVATE:
103 case AndroidImageFormat::RAW_SENSOR:
107 case AndroidImageFormat::FLEX_RGBA_8888:
108 case AndroidImageFormat::FLEX_RGB_888:
113 case AndroidImageFormat::YUV_422_888:
114 case AndroidImageFormat::YUV_444_888:
115 case AndroidImageFormat::YCBCR_P010:
125 qCWarning(qLCAndroidCameraFrame) <<
"Cannot determine image format!";
129 auto copyPlane = [&](
int mapIndex,
int arrayIndex) {
133 m_planes[mapIndex].
rowStride = rowStrides[arrayIndex];
134 m_planes[mapIndex].
size = bufferSize[arrayIndex];
138 int width =
frame.callMethod<jint>(
"getWidth");
142 switch (calculedPixelFormat) {
149 if (isWorkaroundForEmulatorNeeded()) {
150 for (
int i = 0;
i < 3; ++
i) {
175 m_pixelFormat = calculedPixelFormat;
179 <<
"FFmpeg HW Mediacodec does not encode other than YCbCr formats";
203 m_frame = jniEnv->NewGlobalRef(
frame.object());
204 jniEnv.checkAndClearExceptions();
205 }
else if (
frame.isValid()) {
206 frame.callMethod<
void>(
"close");
216 if (qFrame.isValid())
217 qFrame.callMethod<
void>(
"close");
221 jniEnv->DeleteGlobalRef(m_frame);
223 if (isWorkaroundForEmulatorNeeded()) {
225 for (
int i = 0;
i < 3; ++
i)
226 delete[] m_planes[
i].
data;
Plane plane(int index) const
QAndroidCameraFrame(QJniObject frame)
qsizetype bytesPerLine() const
Returns the number of bytes per image scanline.
qsizetype sizeInBytes() const
uchar * bits()
Returns a pointer to the first pixel data.
Format format() const
Returns the format of the image.
static QImage fromData(QByteArrayView data, const char *format=nullptr)
Combined button and popup list for selecting options.
QJniArray< AndroidImagePlane > AndroidImagePlaneArray
#define qCWarning(category,...)
#define Q_STATIC_LOGGING_CATEGORY(name,...)
GLint GLsizei GLsizei height
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei GLsizei GLenum format