C2VDAComponent: do not rely on monotonic increasing output timestamp
Unfortuneately the previous assumption of getting monotonic increasing
timestamp as display order of output buffers is not always right. In
testH264_adaptiveSkipBack, the timestamp goes back and forth.
For such cases we cannot rely on timestamp for checking work done anymore, we
cannot help but rely on input flags for recognizing CSD buffer works, which
doesn't have a correlated output buffer; otherwise, work is done only if both
input and output buffer are returned from VDA.
Bug: 80402878
Test: android.media.cts.AdaptivePlaybackTest#testH264_adaptiveSkipBack for
codec2.0 on eve-arcnext
Change-Id: Ib3af3ca0ee90925187662af4ae0eb4d628ad21a6
diff --git a/C2VDAComponent.cpp b/C2VDAComponent.cpp
index 78e5814..fd7b313 100644
--- a/C2VDAComponent.cpp
+++ b/C2VDAComponent.cpp
@@ -208,7 +208,6 @@
mVDAInitResult(VideoDecodeAcceleratorAdaptor::Result::ILLEGAL_STATE),
mComponentState(ComponentState::UNINITIALIZED),
mPendingOutputEOS(false),
- mLastOutputTimestamp(-1),
mCodecProfile(media::VIDEO_CODEC_PROFILE_UNKNOWN),
mState(State::UNLOADED),
mWeakThisFactory(this) {
@@ -423,11 +422,6 @@
C2Buffer::CreateGraphicBuffer(std::move(constBlock)));
info->mGraphicBlock.reset();
- // TODO: this does not work for timestamps as they can wrap around
- int64_t currentTimestamp = ::base::checked_cast<int64_t>(work->input.ordinal.timestamp.peek());
- CHECK_GE(currentTimestamp, mLastOutputTimestamp);
- mLastOutputTimestamp = currentTimestamp;
-
reportFinishedWorkIfAny();
}
@@ -481,9 +475,6 @@
// mPendingWorks must be empty after draining is finished.
CHECK(mPendingWorks.empty());
- // Last stream is finished. Reset the timestamp record.
- mLastOutputTimestamp = -1;
-
// Work dequeueing was stopped while component draining. Restart it.
mTaskRunner->PostTask(FROM_HERE,
::base::Bind(&C2VDAComponent::onDequeueWork, ::base::Unretained(this)));
@@ -545,8 +536,6 @@
void C2VDAComponent::onFlushDone() {
ALOGV("onFlushDone");
reportAbandonedWorks();
- // Reset the timestamp record.
- mLastOutputTimestamp = -1;
mComponentState = ComponentState::STARTED;
// Work dequeueing was stopped while component flushing. Restart it.
@@ -562,7 +551,6 @@
// do something for them?
reportAbandonedWorks();
mPendingOutputFormat.reset();
- mLastOutputTimestamp = -1;
if (mVDAAdaptor.get()) {
mVDAAdaptor->destroy();
mVDAAdaptor.reset(nullptr);
@@ -1120,11 +1108,6 @@
std::list<std::unique_ptr<C2Work>> finishedWorks;
// Work should be reported as done if both input and output buffer are returned by VDA.
-
- // Note that not every input buffer has matched output (ex. CSD header for H.264).
- // However, the timestamp is guaranteed to be monotonic increasing for buffers in display order.
- // That is, since VDA output is in display order, if we get a returned output with timestamp T,
- // it implies all works with timestamp <= T are done.
// EOS work will not be reported here. reportEOSWork() does it.
auto iter = mPendingWorks.begin();
while (iter != mPendingWorks.end()) {
@@ -1157,13 +1140,12 @@
// returned by reportEOSWork() instead.
return false;
}
- if (mLastOutputTimestamp < 0) {
- return false; // No output buffer is returned yet.
+ if (!(work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) &&
+ work->worklets.front()->output.buffers.empty()) {
+ // Output buffer is not returned from VDA yet.
+ return false;
}
- if (work->input.ordinal.timestamp > static_cast<uint64_t>(mLastOutputTimestamp)) {
- return false; // Output buffer is not returned by VDA yet.
- }
- return true; // Output buffer is returned, or it has no related output buffer.
+ return true; // Output buffer is returned, or it has no related output buffer (CSD work).
}
void C2VDAComponent::reportEOSWork() {