diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2020-10-19 23:59:44 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2020-10-19 23:59:44 +0000 |
commit | 32169693ce2bcbbcaf1f7064707789bc6b55c0ac (patch) | |
tree | b207ce2b6cb08f3ba9b14ea81e060885101abb7a | |
parent | 785669782cee8bd0f9df314cded506a749cd45c1 (diff) | |
parent | ec976846efd4d2d8b1b00652b69e3c2f526980f3 (diff) | |
download | v4l2_codec2-android11-mainline-release.tar.gz |
Snap for 6916203 from ec976846efd4d2d8b1b00652b69e3c2f526980f3 to mainline-releaser_aml_301500702android-mainline-12.0.0_r55android-mainline-11.0.0_r9android-mainline-11.0.0_r8android-mainline-11.0.0_r7android-mainline-11.0.0_r6android-mainline-11.0.0_r5android-mainline-11.0.0_r45android-mainline-11.0.0_r4android-mainline-11.0.0_r33android-mainline-11.0.0_r3android-mainline-11.0.0_r29android-mainline-11.0.0_r19android-mainline-11.0.0_r10android11-mainline-sparse-2021-jan-releaseandroid11-mainline-sparse-2020-dec-releaseandroid11-mainline-release
Change-Id: Ided92dd099abc819807ff1ba0c02fb116c4e0004
-rw-r--r-- | components/V4L2Decoder.cpp | 79 | ||||
-rw-r--r-- | components/include/v4l2_codec2/components/V4L2Decoder.h | 1 | ||||
-rw-r--r-- | tests/c2_e2e_test/src/org/chromium/c2/test/E2eTestActivity.java | 20 |
3 files changed, 69 insertions, 31 deletions
diff --git a/components/V4L2Decoder.cpp b/components/V4L2Decoder.cpp index c070d64..d52bd6c 100644 --- a/components/V4L2Decoder.cpp +++ b/components/V4L2Decoder.cpp @@ -270,8 +270,9 @@ void V4L2Decoder::pumpDecodeRequest() { auto request = std::move(mDecodeRequests.front()); mDecodeRequests.pop(); - ALOGV("QBUF to input queue, bitstreadId=%d", request.buffer->id); - inputBuffer->SetTimeStamp({.tv_sec = request.buffer->id}); + const int32_t bitstreamId = request.buffer->id; + ALOGV("QBUF to input queue, bitstreadId=%d", bitstreamId); + inputBuffer->SetTimeStamp({.tv_sec = bitstreamId}); size_t planeSize = inputBuffer->GetPlaneSize(0); if (request.buffer->size > planeSize) { ALOGE("The input size (%zu) is not enough, we need %zu", planeSize, @@ -286,9 +287,13 @@ void V4L2Decoder::pumpDecodeRequest() { inputBuffer->SetPlaneBytesUsed(0, request.buffer->offset + request.buffer->size); std::vector<int> fds; fds.push_back(std::move(request.buffer->dmabuf_fd)); - std::move(*inputBuffer).QueueDMABuf(fds); + if (!std::move(*inputBuffer).QueueDMABuf(fds)) { + ALOGE("%s(): Failed to QBUF to input queue, bitstreamId=%d", __func__, bitstreamId); + onError(); + return; + } - mPendingDecodeCbs.insert(std::make_pair(request.buffer->id, std::move(request.decodeCb))); + mPendingDecodeCbs.insert(std::make_pair(bitstreamId, std::move(request.decodeCb))); } } @@ -387,15 +392,43 @@ void V4L2Decoder::serviceDeviceTask(bool event) { outputDequeued = true; + const size_t bufferId = dequeuedBuffer->BufferId(); + const int32_t bitstreamId = static_cast<int32_t>(dequeuedBuffer->GetTimeStamp().tv_sec); + const size_t bytesUsed = dequeuedBuffer->GetPlaneBytesUsed(0); + const bool isLast = dequeuedBuffer->IsLast(); ALOGV("DQBUF from output queue, bufferId=%zu, corresponding bitstreamId=%d, bytesused=%zu", - dequeuedBuffer->BufferId(), - static_cast<int32_t>(dequeuedBuffer->GetTimeStamp().tv_sec), - dequeuedBuffer->GetPlaneBytesUsed(0)); - if (dequeuedBuffer->GetPlaneBytesUsed(0) > 0) { - sendOutputBuffer(dequeuedBuffer); + bufferId, bitstreamId, bytesUsed); + + // Get the corresponding VideoFrame of the dequeued buffer. + auto it = mFrameAtDevice.find(bufferId); + ALOG_ASSERT(it != mFrameAtDevice.end(), "buffer %zu is not found at mFrameAtDevice", + bufferId); + auto frame = std::move(it->second); + mFrameAtDevice.erase(it); + + if (bytesUsed > 0) { + ALOGV("Send output frame(bitstreamId=%d) to client", bitstreamId); + frame->setBitstreamId(bitstreamId); + frame->setVisibleRect(mVisibleRect); + mOutputCb.Run(std::move(frame)); + } else { + // Workaround(b/168750131): If the buffer is not enqueued before the next drain is done, + // then the driver will fail to notify EOS. So we recycle the buffer immediately. + ALOGV("Recycle empty buffer %zu back to V4L2 output queue.", bufferId); + dequeuedBuffer.reset(); + auto outputBuffer = mOutputQueue->GetFreeBuffer(bufferId); + ALOG_ASSERT(outputBuffer, "V4L2 output queue slot %zu is not freed.", bufferId); + + if (!std::move(*outputBuffer).QueueDMABuf(frame->getFDs())) { + ALOGE("%s(): Failed to recycle empty buffer to output queue.", __func__); + onError(); + return; + } + mFrameAtDevice.insert(std::make_pair(bufferId, std::move(frame))); } - if (mDrainCb && dequeuedBuffer->IsLast()) { - ALOGD("All buffers are drained."); + + if (mDrainCb && isLast) { + ALOGV("All buffers are drained."); sendV4L2DecoderCmd(true); std::move(mDrainCb).Run(VideoDecoder::DecodeStatus::kOk); setState(State::Idle); @@ -422,21 +455,6 @@ void V4L2Decoder::serviceDeviceTask(bool event) { } } -void V4L2Decoder::sendOutputBuffer(media::V4L2ReadableBufferRef buffer) { - ALOGV("%s(bufferId=%zu)", __func__, buffer->BufferId()); - ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence()); - - size_t bufferId = buffer->BufferId(); - auto it = mFrameAtDevice.find(bufferId); - ALOG_ASSERT(it != mFrameAtDevice.end(), "buffer %zu is not found at mFrameAtDevice", bufferId); - auto block = std::move(it->second); - mFrameAtDevice.erase(it); - - block->setBitstreamId(buffer->GetTimeStamp().tv_sec); - block->setVisibleRect(mVisibleRect); - mOutputCb.Run(std::move(block)); -} - bool V4L2Decoder::dequeueResolutionChangeEvent() { ALOGV("%s()", __func__); ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence()); @@ -502,8 +520,6 @@ void V4L2Decoder::tryFetchVideoFrame() { ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence()); ALOG_ASSERT(mVideoFramePool, "mVideoFramePool is null, haven't get the instance yet?"); - if (mState == State::Idle) return; - if (mOutputQueue->FreeBuffersCount() == 0) { ALOGD("No free V4L2 output buffers, ignore."); return; @@ -558,7 +574,12 @@ void V4L2Decoder::onVideoFrameReady( uint32_t v4l2Id = outputBuffer->BufferId(); ALOGV("QBUF to output queue, blockId=%u, V4L2Id=%u", blockId, v4l2Id); - std::move(*outputBuffer).QueueDMABuf(frame->getFDs()); + if (!std::move(*outputBuffer).QueueDMABuf(frame->getFDs())) { + ALOGE("%s(): Failed to QBUF to output queue, blockId=%u, V4L2Id=%u", __func__, blockId, + v4l2Id); + onError(); + return; + } if (mFrameAtDevice.find(v4l2Id) != mFrameAtDevice.end()) { ALOGE("%s(): V4L2 buffer %d already enqueued.", __func__, v4l2Id); onError(); diff --git a/components/include/v4l2_codec2/components/V4L2Decoder.h b/components/include/v4l2_codec2/components/V4L2Decoder.h index 5539042..bdddc7f 100644 --- a/components/include/v4l2_codec2/components/V4L2Decoder.h +++ b/components/include/v4l2_codec2/components/V4L2Decoder.h @@ -62,7 +62,6 @@ private: void pumpDecodeRequest(); void serviceDeviceTask(bool event); - void sendOutputBuffer(media::V4L2ReadableBufferRef buffer); bool dequeueResolutionChangeEvent(); bool changeResolution(); diff --git a/tests/c2_e2e_test/src/org/chromium/c2/test/E2eTestActivity.java b/tests/c2_e2e_test/src/org/chromium/c2/test/E2eTestActivity.java index e423fc2..140ff82 100644 --- a/tests/c2_e2e_test/src/org/chromium/c2/test/E2eTestActivity.java +++ b/tests/c2_e2e_test/src/org/chromium/c2/test/E2eTestActivity.java @@ -29,6 +29,8 @@ public class E2eTestActivity extends Activity implements SurfaceHolder.Callback private SurfaceView mSurfaceView; private Size mSize; + private boolean mSurfaceCreated = false; + private boolean mCanStartTest = false; private Size mExpectedSize; private CountDownLatch mLatch; @@ -44,6 +46,8 @@ public class E2eTestActivity extends Activity implements SurfaceHolder.Callback mSurfaceView = (SurfaceView) findViewById(R.id.surface); mSurfaceView.getHolder().addCallback(this); + + mCanStartTest = !getIntent().getBooleanExtra("delay-start", false); } @Override @@ -55,6 +59,14 @@ public class E2eTestActivity extends Activity implements SurfaceHolder.Callback @Override public void surfaceCreated(SurfaceHolder holder) { + mSurfaceCreated = true; + maybeStartTest(); + } + + private void maybeStartTest() { + if (!mSurfaceCreated || !mCanStartTest) { + return; + } boolean encode = getIntent().getBooleanExtra("do-encode", false); String[] testArgs = getIntent().getStringArrayExtra("test-args") != null @@ -71,7 +83,7 @@ public class E2eTestActivity extends Activity implements SurfaceHolder.Callback encode, testArgs, testArgs.length, - holder.getSurface(), + mSurfaceView.getHolder().getSurface(), logFile); Log.i(TAG, "Test returned result code " + res); @@ -95,6 +107,12 @@ public class E2eTestActivity extends Activity implements SurfaceHolder.Callback @Override public void onNewIntent(Intent intent) { + if (intent.getAction().equals("org.chromium.c2.test.START_TEST")) { + mCanStartTest = true; + maybeStartTest(); + return; + } + synchronized (this) { if (mDecoderPtr != 0) { stopDecoderLoop(mDecoderPtr); |