media: Support getStopTimeOffsetUs in GraphicBufferSource.
So MediaCodecSource could use the stopTimeOffset to adjust the stop timeout
dynamically.
Test: Camera recording with video stream delay.
Bug: 35925528
Change-Id: Ic186971992bdc03155e9993cb44027002f71a457
diff --git a/include/media/omx/1.0/WGraphicBufferSource.h b/include/media/omx/1.0/WGraphicBufferSource.h
index 397e576..bf3be9a 100644
--- a/include/media/omx/1.0/WGraphicBufferSource.h
+++ b/include/media/omx/1.0/WGraphicBufferSource.h
@@ -74,6 +74,7 @@
BnStatus setTimeLapseConfig(double fps, double captureFps) override;
BnStatus setStartTimeUs(int64_t startTimeUs) override;
BnStatus setStopTimeUs(int64_t stopTimeUs) override;
+ BnStatus getStopTimeOffsetUs(int64_t *stopTimeOffsetUs) override;
BnStatus setColorAspects(int32_t aspects) override;
BnStatus setTimeOffsetUs(int64_t timeOffsetsUs) override;
BnStatus signalEndOfInputStream() override;
diff --git a/media/libmedia/aidl/android/IGraphicBufferSource.aidl b/media/libmedia/aidl/android/IGraphicBufferSource.aidl
index f3c7abc..12c2767 100644
--- a/media/libmedia/aidl/android/IGraphicBufferSource.aidl
+++ b/media/libmedia/aidl/android/IGraphicBufferSource.aidl
@@ -31,6 +31,7 @@
void setTimeLapseConfig(double fps, double captureFps);
void setStartTimeUs(long startTimeUs);
void setStopTimeUs(long stopTimeUs);
+ long getStopTimeOffsetUs();
void setColorAspects(int aspects);
void setTimeOffsetUs(long timeOffsetsUs);
void signalEndOfInputStream();
diff --git a/media/libmedia/omx/1.0/WGraphicBufferSource.cpp b/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
index 4c543fa..31d1df9 100644
--- a/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
+++ b/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
@@ -67,6 +67,14 @@
return toBinderStatus(mBase->setStopTimeUs(stopTimeUs));
}
+BnStatus LWGraphicBufferSource::getStopTimeOffsetUs(
+ int64_t *stopTimeOffsetUs) {
+ return toBinderStatus(mBase->getStopTimeOffsetUs(
+ [stopTimeOffsetUs](auto, auto offsetUs) {
+ *stopTimeOffsetUs = offsetUs;
+ }));
+}
+
BnStatus LWGraphicBufferSource::setColorAspects(
int32_t aspects) {
return toBinderStatus(mBase->setColorAspects(
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 8b91541..ab1231b 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -7201,6 +7201,16 @@
ALOGE("Failed to set parameter 'stop-time-us' (err %d)", err);
return err;
}
+
+ int64_t stopTimeOffsetUs;
+ err = statusFromBinderStatus(
+ mGraphicBufferSource->getStopTimeOffsetUs(&stopTimeOffsetUs));
+
+ if (err != OK) {
+ ALOGE("Failed to get stop time offset (err %d)", err);
+ return err;
+ }
+ mInputFormat->setInt64("android._stop-time-offset-us", stopTimeOffsetUs);
}
int32_t dummy;
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index 5424372..cfee943 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -1004,12 +1004,21 @@
mStopping = true;
+ int64_t timeoutUs = kStopTimeoutUs;
// if using surface, signal source EOS and wait for EOS to come back.
// otherwise, stop puller (which also clears the input buffer queue)
// and wait for the EOS message. We cannot call source->stop() because
// the encoder may still be processing input buffers.
if (mFlags & FLAG_USE_SURFACE_INPUT) {
mEncoder->signalEndOfInputStream();
+ // Increase the timeout if there is delay in the GraphicBufferSource
+ sp<AMessage> inputFormat;
+ int64_t stopTimeOffsetUs;
+ if (mEncoder->getInputFormat(&inputFormat) == OK &&
+ inputFormat->findInt64("android._stop-time-offset-us", &stopTimeOffsetUs) &&
+ stopTimeOffsetUs > 0) {
+ timeoutUs += stopTimeOffsetUs;
+ }
} else {
mPuller->stop();
}
@@ -1017,7 +1026,7 @@
// complete stop even if encoder/puller stalled
sp<AMessage> timeoutMsg = new AMessage(kWhatStopStalled, mReflector);
timeoutMsg->setInt32("generation", mGeneration);
- timeoutMsg->post(kStopTimeoutUs);
+ timeoutMsg->post(timeoutUs);
break;
}
diff --git a/media/libstagefright/omx/1.0/WGraphicBufferSource.cpp b/media/libstagefright/omx/1.0/WGraphicBufferSource.cpp
index e876306..d8540f8 100644
--- a/media/libstagefright/omx/1.0/WGraphicBufferSource.cpp
+++ b/media/libstagefright/omx/1.0/WGraphicBufferSource.cpp
@@ -206,8 +206,10 @@
Return<void> TWGraphicBufferSource::getStopTimeOffsetUs(
getStopTimeOffsetUs_cb _hidl_cb) {
- // TODO: Implement this when needed.
- _hidl_cb(Status::OK, 0);
+ status_t status;
+ int64_t stopTimeOffsetUs;
+ status = mBase->getStopTimeOffsetUs(&stopTimeOffsetUs);
+ _hidl_cb(toStatus(status), stopTimeOffsetUs);
return Void();
}
diff --git a/media/libstagefright/omx/BWGraphicBufferSource.cpp b/media/libstagefright/omx/BWGraphicBufferSource.cpp
index f2a454f..12237bf 100644
--- a/media/libstagefright/omx/BWGraphicBufferSource.cpp
+++ b/media/libstagefright/omx/BWGraphicBufferSource.cpp
@@ -160,6 +160,11 @@
return Status::fromStatusT(mBase->setStopTimeUs(stopTimeUs));
}
+::android::binder::Status BWGraphicBufferSource::getStopTimeOffsetUs(
+ int64_t *stopTimeOffsetUs) {
+ return Status::fromStatusT(mBase->getStopTimeOffsetUs(stopTimeOffsetUs));
+}
+
::android::binder::Status BWGraphicBufferSource::setColorAspects(
int32_t aspects) {
return Status::fromStatusT(mBase->setColorAspects(aspects));
diff --git a/media/libstagefright/omx/BWGraphicBufferSource.h b/media/libstagefright/omx/BWGraphicBufferSource.h
index 43763c2..92ee7f7 100644
--- a/media/libstagefright/omx/BWGraphicBufferSource.h
+++ b/media/libstagefright/omx/BWGraphicBufferSource.h
@@ -53,6 +53,7 @@
double fps, double captureFps) override;
Status setStartTimeUs(int64_t startTimeUs) override;
Status setStopTimeUs(int64_t stopTimeUs) override;
+ Status getStopTimeOffsetUs(int64_t* stopTimeOffsetUs) override;
Status setColorAspects(int32_t aspects) override;
Status setTimeOffsetUs(int64_t timeOffsetsUs) override;
Status signalEndOfInputStream() override;
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index 0521460..7c8da87 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -264,6 +264,7 @@
mLastDataspace(HAL_DATASPACE_UNKNOWN),
mExecuting(false),
mSuspended(false),
+ mLastFrameTimestampUs(-1),
mStopTimeUs(-1),
mLastActionTimeUs(-1ll),
mSkipFramesBeforeNs(-1ll),
@@ -1214,10 +1215,20 @@
return OK;
}
+status_t GraphicBufferSource::getStopTimeOffsetUs(int64_t *stopTimeOffsetUs) {
+ ALOGV("getStopTimeOffsetUs");
+ Mutex::Autolock autoLock(mMutex);
+ if (mStopTimeUs == -1) {
+ ALOGW("Fail to return stopTimeOffsetUs as stop time is not set");
+ return INVALID_OPERATION;
+ }
+ *stopTimeOffsetUs = mStopTimeUs - mLastFrameTimestampUs;
+ return OK;
+}
+
status_t GraphicBufferSource::setTimeLapseConfig(double fps, double captureFps) {
ALOGV("setTimeLapseConfig: fps=%lg, captureFps=%lg",
fps, captureFps);
-
Mutex::Autolock autoLock(mMutex);
if (mExecuting || !(fps > 0) || !(captureFps > 0)) {
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index 3df1aa1..29b51a8 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -172,6 +172,13 @@
// and not submitted to encoder. timeUs uses SYSTEM_TIME_MONOTONIC time base.
status_t setStopTimeUs(int64_t stopTimeUs);
+ // Gets the stop time offset in us. This is the time offset between latest buffer
+ // time and the stopTimeUs. If stop time is not set, INVALID_OPERATION will be returned.
+ // If return is OK, *stopTimeOffsetUs will contain the valid offset. Otherwise,
+ // *stopTimeOffsetUs will not be modified. Positive stopTimeOffsetUs means buffer time
+ // larger than stopTimeUs.
+ status_t getStopTimeOffsetUs(int64_t *stopTimeOffsetUs);
+
// Sets the desired color aspects, e.g. to be used when producer does not specify a dataspace.
status_t setColorAspects(int32_t aspectsPacked);
@@ -340,6 +347,8 @@
// regardless of the metadata of those buffers
bool areWeDiscardingAvailableBuffers_l();
+ int64_t mLastFrameTimestampUs;
+
// Our BufferQueue interfaces. mProducer is passed to the producer through
// getIGraphicBufferProducer, and mConsumer is used internally to retrieve
// the buffers queued by the producer.