Skip to content
Snippets Groups Projects
Commit e9d7102e authored by Chih-Yu Huang's avatar Chih-Yu Huang Committed by David Stevens
Browse files

c2_e2e_test: Polish logic of the dropped frame determination.

We determine if a output frame is dropped by the arrival time and its
timestamp. However, the order of input buffers is different from
the display order of output buffers. So the expected arrival time is
wrong. Also, the base timestamp is updated after the first output
buffer dequeued. Therefore the first frame was always marked dropped.

In this CL, we calculate the expected arrival time by the count of
received frames, and set the base timestamp before checking the
arrival time of the first frame.

Bug: 155944233
Test: Run tast.arc.VideoDecodeAccelPerf.h264_2160p_30fps and check
      the first frame is not marked dropped

Change-Id: I1b34688ffa573016dd94d5fb3cc851462a25003d
(cherry picked from commit 4b5c13aa7e6a41d62c9f37338b493cd339548b19)
parent dc952450
No related branches found
No related tags found
No related merge requests found
......@@ -18,6 +18,7 @@
namespace android {
namespace {
constexpr int64_t kSecToNs = 1000000000;
// The timeout of AMediaCodec_dequeueOutputBuffer function calls.
constexpr int kTimeoutWaitForOutputUs = 1000; // 1 millisecond
......@@ -276,14 +277,15 @@ bool MediaCodecDecoder::DequeueOutputBuffer(int32_t index, AMediaCodecBufferInfo
if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) output_done_ = true;
if (info.presentationTimeUs) {
uint64_t now = GetCurrentTimeNs();
if ((now - base_timestamp_ns_) > (info.presentationTimeUs * 1000)) {
drop_frame_count_++;
ALOGD("Drop frame #%d: deadline %lu, actual %lu", drop_frame_count_,
GetReleaseTimestampNs(info), now);
base_timestamp_ns_ = now - info.presentationTimeUs * 1000;
}
const uint64_t now = GetCurrentTimeNs();
if (base_timestamp_ns_ == 0) {
assert(received_outputs_ == 0);
// The first output buffer is dequeued. Set the base timestamp.
base_timestamp_ns_ = now;
} else if (now > GetReleaseTimestampNs(received_outputs_)) {
drop_frame_count_++;
ALOGD("Drop frame #%d: deadline %" PRIu64 "us, actual %" PRIu64 "us", drop_frame_count_,
(received_outputs_ * 1000000 / frame_rate_), (now - base_timestamp_ns_) / 1000);
}
if (!ReceiveOutputBuffer(index, info, render_on_release_)) return false;
......@@ -319,7 +321,9 @@ bool MediaCodecDecoder::FeedInputBuffer(size_t index) {
uint32_t input_flag = 0;
if (fragment->csd_flag) input_flag |= BUFFER_FLAG_CODEC_CONFIG;
uint64_t timestamp_us = input_fragment_index_ * 1000000 / frame_rate_;
// We don't parse the display order of each bitstream buffer. Let's trust the order of received
// output buffers from |codec_|.
uint64_t timestamp_us = 0;
ALOGD("queueInputBuffer(index=%zu, offset=0, size=%zu, time=%" PRIu64 ", flags=%u) #%d", index,
fragment->data.size(), timestamp_us, input_flag, input_fragment_index_);
......@@ -362,8 +366,8 @@ bool MediaCodecDecoder::ReceiveOutputBuffer(size_t index, const AMediaCodecBuffe
}
received_outputs_++;
ALOGD("ReceiveOutputBuffer(index=%zu, size=%d, time=%" PRId64 ", flags=%u) #%d", index,
info.size, info.presentationTimeUs, info.flags, received_outputs_);
ALOGD("ReceiveOutputBuffer(index=%zu, size=%d, flags=%u) #%d", index, info.size, info.flags,
received_outputs_);
// Do not callback for dummy EOS output (info.size == 0)
if (info.size > 0) {
......@@ -372,8 +376,8 @@ bool MediaCodecDecoder::ReceiveOutputBuffer(size_t index, const AMediaCodecBuffe
}
media_status_t status =
render_buffer ? AMediaCodec_releaseOutputBufferAtTime(codec_, index,
GetReleaseTimestampNs(info))
render_buffer ? AMediaCodec_releaseOutputBufferAtTime(
codec_, index, GetReleaseTimestampNs(received_outputs_))
: AMediaCodec_releaseOutputBuffer(codec_, index, false /* render */);
if (status != AMEDIA_OK) {
ALOGE("Failed to releaseOutputBuffer(index=%zu): %d", index, status);
......@@ -445,15 +449,10 @@ bool MediaCodecDecoder::GetOutputFormat() {
return success;
}
int64_t MediaCodecDecoder::GetReleaseTimestampNs(const AMediaCodecBufferInfo& info) {
if (info.presentationTimeUs == 0) {
assert(base_timestamp_ns_ == 0);
base_timestamp_ns_ = GetCurrentTimeNs();
} else {
assert(base_timestamp_ns_ != 0);
}
int64_t MediaCodecDecoder::GetReleaseTimestampNs(size_t frame_order) {
assert(base_timestamp_ns_ != 0);
return base_timestamp_ns_ + info.presentationTimeUs * 1000;
return base_timestamp_ns_ + frame_order * kSecToNs / frame_rate_;
}
} // namespace android
......@@ -110,7 +110,7 @@ private:
// Return false if required information is missing, e.g. width, color format.
bool GetOutputFormat();
int64_t GetReleaseTimestampNs(const AMediaCodecBufferInfo& info);
int64_t GetReleaseTimestampNs(size_t frame_order);
// The target mediacodec decoder.
AMediaCodec* codec_;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment