blob: 7c3f8823072fc621e9c9a89dffb7a9b9d5d69748 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_GPU_ANDROID_CODEC_BUFFER_WAIT_COORDINATOR_H_
#define MEDIA_GPU_ANDROID_CODEC_BUFFER_WAIT_COORDINATOR_H_
#include "base/memory/ref_counted.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "gpu/command_buffer/service/ref_counted_lock.h"
#include "gpu/command_buffer/service/texture_owner.h"
#include "media/base/tuneable.h"
#include "media/gpu/media_gpu_export.h"
namespace media {
struct FrameAvailableEvent;
// This class supports waiting for codec buffers to be released/rendered before
// using them. This class is RefCountedThreadSafe to make sure it's safe to
// keep and drop refptrs to it on any thread. Note that when DrDc is
// enabled(kEnableDrDc), a per codec dr-dc lock is expected to be held while
// calling methods of this class. This is ensured by adding
// AssertAcquiredDrDcLock() to those methods.
class MEDIA_GPU_EXPORT CodecBufferWaitCoordinator
: public base::RefCountedThreadSafe<CodecBufferWaitCoordinator>,
public gpu::RefCountedLockHelperDrDc {
public:
explicit CodecBufferWaitCoordinator(
scoped_refptr<gpu::TextureOwner> texture_owner,
scoped_refptr<gpu::RefCountedLock> drdc_lock);
scoped_refptr<gpu::TextureOwner> texture_owner() const {
DCHECK(texture_owner_);
return texture_owner_;
}
// Codec buffer wait management apis.
// Sets the expectation of onFrameAVailable for a new frame because a buffer
// was just released to this surface.
virtual void SetReleaseTimeToNow();
// Whether we're expecting onFrameAvailable. True when SetReleaseTimeToNow()
// was called but WaitForFrameAvailable() have not been called since.
virtual bool IsExpectingFrameAvailable();
// Waits for onFrameAvailable until it's been 5ms since the buffer was
// released. This must only be called if IsExpectingFrameAvailable().
virtual void WaitForFrameAvailable();
scoped_refptr<base::SingleThreadTaskRunner> task_runner() {
return task_runner_;
}
protected:
virtual ~CodecBufferWaitCoordinator();
private:
friend class base::RefCountedThreadSafe<CodecBufferWaitCoordinator>;
scoped_refptr<gpu::TextureOwner> texture_owner_;
base::TimeTicks release_time_;
scoped_refptr<FrameAvailableEvent> frame_available_event_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
// 5msec covers >99.9% of cases, so just wait for up to that much before
// giving up. If an error occurs, we might not ever get a notification.
Tuneable<base::TimeDelta> max_wait_ = {
"MediaCodecOutputBufferMaxWaitTime", base::Milliseconds(0),
base::Milliseconds(5), base::Milliseconds(20)};
DISALLOW_COPY_AND_ASSIGN(CodecBufferWaitCoordinator);
};
} // namespace media
#endif // MEDIA_GPU_ANDROID_CODEC_BUFFER_WAIT_COORDINATOR_H_