summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Moskal <bartlomiej.moskal@qt.io>2024-04-23 10:19:21 +0200
committerBartlomiej Moskal <bartlomiej.moskal@qt.io>2024-04-29 05:38:43 +0000
commitb5a5a4f040cc8a60967723fbef1719506f71960b (patch)
tree56b8fc727ba2fbb395cb9588fc956782c2dba7f1
parent997f528ee26a6c118bb257bda1b47316532c0acf (diff)
FFmpeg-Android: Set the configured FPS on Camera
Add implementation for setting up FPS on Android Camera. [0]QCameraFormat (beyond the pixel format and resolution) contains also max/min frame rate. Those parameters were not passed and set on Android Camera. After this commit, the whole configuration kept in QCameraFormat is set on device during camera activation. [0]https://doc.qt.io/qt-6/qcameraformat.html Task-number: QTBUG-113399 Pick-to: 6.7 6.5 Change-Id: Iba4f4c0c8ac4bbdaf3488a0a9005bff42390c428 Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/multimedia/QtCamera2.java22
-rw-r--r--src/plugins/multimedia/ffmpeg/qandroidcamera.cpp22
2 files changed, 30 insertions, 14 deletions
diff --git a/src/android/jar/src/org/qtproject/qt/android/multimedia/QtCamera2.java b/src/android/jar/src/org/qtproject/qt/android/multimedia/QtCamera2.java
index 98af64c31..ac8140197 100644
--- a/src/android/jar/src/org/qtproject/qt/android/multimedia/QtCamera2.java
+++ b/src/android/jar/src/org/qtproject/qt/android/multimedia/QtCamera2.java
@@ -24,6 +24,7 @@ import android.graphics.ImageFormat;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
+import android.util.Range;
import android.view.Surface;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
@@ -62,6 +63,7 @@ public class QtCamera2 {
private int mTorchMode = CameraMetadata.FLASH_MODE_OFF;
private int mAFMode = CaptureRequest.CONTROL_AF_MODE_OFF;
private float mZoomFactor = 1.0f;
+ private Range<Integer> mFpsRange = null;
private QtExifDataHandler mExifDataHandler = null;
native void onCameraOpened(String cameraId);
@@ -261,7 +263,14 @@ public class QtCamera2 {
}
};
- public boolean addImageReader(int width, int height, int format) {
+
+ public void prepareCamera(int width, int height, int format, int minFps, int maxFps) {
+
+ addImageReader(width, height, format);
+ setFrameRate(minFps, maxFps);
+ }
+
+ private void addImageReader(int width, int height, int format) {
if (mImageReader != null)
removeSurface(mImageReader.getSurface());
@@ -276,8 +285,14 @@ public class QtCamera2 {
mCapturedPhotoReader = ImageReader.newInstance(width, height, format, MaxNumberFrames);
mCapturedPhotoReader.setOnImageAvailableListener(mOnPhotoAvailableListener, mBackgroundHandler);
addSurface(mCapturedPhotoReader.getSurface());
+ }
+
+ private void setFrameRate(int minFrameRate, int maxFrameRate) {
- return true;
+ if (minFrameRate <= 0 || maxFrameRate <= 0)
+ mFpsRange = null;
+ else
+ mFpsRange = new Range<>(minFrameRate, maxFrameRate);
}
public boolean addSurface(Surface surface) {
@@ -335,7 +350,8 @@ public class QtCamera2 {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CameraMetadata.CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
if (mZoomFactor != 1.0f)
mPreviewRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, getScalerCropRegion());
-
+ if (mFpsRange != null)
+ mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, mFpsRange);
mPreviewRequest = mPreviewRequestBuilder.build();
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBackgroundHandler);
mIsStarted = true;
diff --git a/src/plugins/multimedia/ffmpeg/qandroidcamera.cpp b/src/plugins/multimedia/ffmpeg/qandroidcamera.cpp
index 97448c707..bf01a4e30 100644
--- a/src/plugins/multimedia/ffmpeg/qandroidcamera.cpp
+++ b/src/plugins/multimedia/ffmpeg/qandroidcamera.cpp
@@ -55,8 +55,8 @@ QCameraFormat getDefaultCameraFormat()
QCameraFormatPrivate *defaultFormat = new QCameraFormatPrivate{
.pixelFormat = QVideoFrameFormat::Format_YUV420P,
.resolution = { 1920, 1080 },
- .minFrameRate = 30,
- .maxFrameRate = 60,
+ .minFrameRate = 12,
+ .maxFrameRate = 30,
};
return defaultFormat->create();
}
@@ -273,6 +273,15 @@ void QAndroidCamera::setActive(bool active)
setState(State::WaitingOpen);
g_qcameras->insert(m_cameraDevice.id(), this);
+ // this should use the camera format.
+ // but there is only 2 fully supported formats on android - JPG and YUV420P
+ // and JPEG is not supported for encoding in FFmpeg, so it's locked for YUV for now.
+ const static int imageFormat =
+ QJniObject::getStaticField<QtJniTypes::AndroidImageFormat, jint>("YUV_420_888");
+ m_jniCamera.callMethod<void>("prepareCamera", jint(width), jint(height),
+ jint(imageFormat), jint(m_cameraFormat.minFrameRate()),
+ jint(m_cameraFormat.maxFrameRate()));
+
bool canOpen = m_jniCamera.callMethod<jboolean>(
"open", QJniObject::fromString(m_cameraDevice.id()).object<jstring>());
@@ -282,15 +291,6 @@ void QAndroidCamera::setActive(bool active)
emit error(QCamera::CameraError,
QString("Failed to start camera: ").append(m_cameraDevice.description()));
}
-
- // this should use the camera format.
- // but there is only 2 fully supported formats on android - JPG and YUV420P
- // and JPEG is not supported for encoding in FFmpeg, so it's locked for YUV for now.
- const static int imageFormat =
- QJniObject::getStaticField<QtJniTypes::AndroidImageFormat, jint>("YUV_420_888");
- m_jniCamera.callMethod<jboolean>("addImageReader", jint(width), jint(height),
- jint(imageFormat));
-
} else {
m_jniCamera.callMethod<void>("stopAndClose");
m_jniCamera.callMethod<void>("clearSurfaces");