Skip to content

Commit 197f670

Browse files
authored
Merge pull request #1826 from aminsepahan/dev/add_timestamp_callback
added frame capture started callback callback which includes frame ti…
2 parents 1d6ba9c + bf67190 commit 197f670

File tree

4 files changed

+79
-4
lines changed

4 files changed

+79
-4
lines changed

encoder/src/main/java/com/pedro/encoder/input/sources/video/Camera2Source.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import com.pedro.encoder.input.video.Camera2ApiManager
2929
import com.pedro.encoder.input.video.Camera2ApiManager.ImageCallback
3030
import com.pedro.encoder.input.video.CameraCallbacks
3131
import com.pedro.encoder.input.video.CameraHelper
32+
import com.pedro.encoder.input.video.FrameCapturedCallback
3233
import com.pedro.encoder.input.video.facedetector.FaceDetectorCallback
3334

3435
/**
@@ -167,6 +168,10 @@ class Camera2Source(context: Context): VideoSource() {
167168
return if (isRunning()) camera.enableFaceDetection(callback) else false
168169
}
169170

171+
fun enableFrameCaptureCallback(frameCapturedCallback: FrameCapturedCallback?) {
172+
camera.enableFrameCaptureCallback(frameCapturedCallback)
173+
}
174+
170175
fun disableFaceDetection() {
171176
if (isRunning()) camera.disableFaceDetection()
172177
}

encoder/src/main/java/com/pedro/encoder/input/video/Camera2ApiManager.kt

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ class Camera2ApiManager(context: Context) : CameraDevice.StateCallback() {
108108
private var sensorOrientation = 0
109109
private var faceSensorScale: Rect? = null
110110
private var faceDetectorCallback: FaceDetectorCallback? = null
111+
private var frameCapturedCallback: FrameCapturedCallback? = null
111112
private var faceDetectionEnabled = false
112113
private var faceDetectionMode = 0
113114
private var imageReader: ImageReader? = null
@@ -156,7 +157,11 @@ class Camera2ApiManager(context: Context) : CameraDevice.StateCallback() {
156157
try {
157158
it.setRepeatingRequest(
158159
captureRequest,
159-
if (faceDetectionEnabled) cb else null, cameraHandler
160+
if (faceDetectionEnabled || frameCapturedCallback != null){
161+
cb
162+
} else{
163+
null
164+
}, cameraHandler
160165
)
161166
} catch (e: IllegalStateException) {
162167
reOpenCamera(cameraId)
@@ -296,7 +301,7 @@ class Camera2ApiManager(context: Context) : CameraDevice.StateCallback() {
296301
try {
297302
cameraCaptureSession.setRepeatingRequest(
298303
builder.build(),
299-
if (faceDetectionEnabled) cb else null, null
304+
if (faceDetectionEnabled || frameCapturedCallback != null) cb else null, null
300305
)
301306
return true
302307
} catch (e: Exception) {
@@ -630,6 +635,11 @@ class Camera2ApiManager(context: Context) : CameraDevice.StateCallback() {
630635
return true
631636
}
632637

638+
639+
fun enableFrameCaptureCallback(frameCapturedCallback: FrameCapturedCallback?) {
640+
this.frameCapturedCallback = frameCapturedCallback
641+
}
642+
633643
fun disableFaceDetection() {
634644
if (faceDetectionEnabled) {
635645
faceDetectorCallback = null
@@ -646,9 +656,29 @@ class Camera2ApiManager(context: Context) : CameraDevice.StateCallback() {
646656
}
647657

648658
private val cb: CameraCaptureSession.CaptureCallback = object : CameraCaptureSession.CaptureCallback() {
649-
override fun onCaptureCompleted(session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult) {
659+
override fun onCaptureCompleted(
660+
session: CameraCaptureSession,
661+
request: CaptureRequest,
662+
result: TotalCaptureResult
663+
) {
650664
val faces = result.get(CaptureResult.STATISTICS_FACES) ?: return
651-
faceDetectorCallback?.onGetFaces(mapCamera2Faces(faces), faceSensorScale, sensorOrientation)
665+
faceDetectorCallback?.onGetFaces(
666+
faces = mapCamera2Faces(faces = faces),
667+
scaleSensor = faceSensorScale,
668+
sensorOrientation = sensorOrientation
669+
)
670+
}
671+
672+
override fun onCaptureStarted(
673+
session: CameraCaptureSession,
674+
request: CaptureRequest,
675+
timestamp: Long,
676+
frameNumber: Long
677+
) {
678+
frameCapturedCallback?.onFrameCaptured(
679+
frameNumber = frameNumber,
680+
timestamp = timestamp
681+
)
652682
}
653683
}
654684

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (C) 2024 pedroSG94.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.pedro.encoder.input.video
17+
18+
/*
19+
This method is called when the camera device has started capturing the output image for the request,
20+
at the beginning of image exposure, or when the camera device has started processing an input image
21+
for a reprocess request.
22+
For a regular capture request, this callback is invoked right as the capture of a frame begins,
23+
so it is the most appropriate time for playing a shutter sound, or triggering UI indicators of capture.
24+
The request that is being used for this capture is provided, along with the actual timestamp for
25+
the start of exposure. For a reprocess request, this timestamp will be the input image's start of
26+
exposure which matches the result timestamp field of the TotalCaptureResult that was used to create
27+
the reprocess request. This timestamp matches the timestamps that will be included in the result
28+
timestamp field, and in the buffers sent to each output Surface. These buffer timestamps are
29+
accessible through, for example, Image.getTimestamp() or android.graphics.SurfaceTexture.getTimestamp().
30+
The frame number included is equal to the frame number that will be included in CaptureResult.getFrameNumber.
31+
*/
32+
33+
interface FrameCapturedCallback {
34+
fun onFrameCaptured(frameNumber: Long, timestamp: Long)
35+
}

library/src/main/java/com/pedro/library/base/Camera2Base.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import com.pedro.encoder.input.video.CameraCallbacks;
4848
import com.pedro.encoder.input.video.CameraHelper;
4949
import com.pedro.encoder.input.video.CameraOpenException;
50+
import com.pedro.encoder.input.video.FrameCapturedCallback;
5051
import com.pedro.encoder.input.video.facedetector.FaceDetectorCallback;
5152
import com.pedro.encoder.utils.CodecUtil;
5253
import com.pedro.encoder.video.FormatVideoEncoder;
@@ -165,6 +166,10 @@ public boolean enableFaceDetection(FaceDetectorCallback faceDetectorCallback) {
165166
return cameraManager.enableFaceDetection(faceDetectorCallback);
166167
}
167168

169+
public void enableFrameCaptureCallback(FrameCapturedCallback frameCapturedCallback) {
170+
cameraManager.enableFrameCaptureCallback(frameCapturedCallback);
171+
}
172+
168173
public void disableFaceDetection() {
169174
cameraManager.disableFaceDetection();
170175
}

0 commit comments

Comments
 (0)