blob: 3e52538a53d38215e7eb43b49285ac6cd61a922d [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 SRC_MEDIA_PLAYBACK_MEDIAPLAYER_GRAPH_PAYLOADS_VMO_PAYLOAD_ALLOCATOR_H_
#define SRC_MEDIA_PLAYBACK_MEDIAPLAYER_GRAPH_PAYLOADS_VMO_PAYLOAD_ALLOCATOR_H_
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <mutex>
#include <vector>
#include "src/lib/fxl/synchronization/thread_annotations.h"
#include "src/media/playback/mediaplayer/graph/payloads/payload_allocator.h"
#include "src/media/playback/mediaplayer/graph/payloads/payload_config.h"
namespace media_player {
// Allocates |PayloadBuffers| from one or more VMOs.
//
// |VmoPayloadAllocator| supports all three valid |VmoAllocation| modes:
// |kSingleVmo| - There is only one VMO, and buffers are allocated from
// it.
// |kVmoPerBuffer| - Each buffer occupies its own VMO.
// |kUnrestricted| - There are one or more VMOs, and buffers are allocated
// from all of them.
//
// Nodes are free to use their own strategies to allocate from VMOs, in which
// case |VmoPayloadAllocator::AllocatePayloadBuffer| is never called. In the
// case of an output, the node can simply create |PayloadBuffers| that
// reference the VMOs when it needs them. In the case of an input, the node
// registers its allocation function when calling |ConfigureInputToUseVmos| or
// |ConfigureInputToProvideVmos|.
class VmoPayloadAllocator : public PayloadAllocator,
public PayloadVmoProvision,
public fbl::RefCounted<VmoPayloadAllocator> {
public:
static fbl::RefPtr<VmoPayloadAllocator> Create();
VmoPayloadAllocator() = default;
~VmoPayloadAllocator() override = default;
// Dumps this |VmoPayloadAllocator|'s state to |os|.
void Dump(std::ostream& os) const;
// Returns the current |VmoAllocation| configuration. This value is
// |kNotApplicable| initially and must be set only once and before
// |AllocatePayloadBuffer| is called.
VmoAllocation vmo_allocation() const {
std::lock_guard<std::mutex> locker(mutex_);
return vmo_allocation_;
}
// Sets the current |VmoAllocation| configuration. Must be called before
// |AllocatePayloadBuffer| is called. |vmo_allocation| may not be
// |kNotApplicable|.
void SetVmoAllocation(VmoAllocation vmo_allocation);
// PayloadAllocator implementation.
fbl::RefPtr<PayloadBuffer> AllocatePayloadBuffer(uint64_t size) override;
// PayloadVmos implementation.
std::vector<fbl::RefPtr<PayloadVmo>> GetVmos() const override;
// PayloadVmoProvision implementation.
void AddVmo(fbl::RefPtr<PayloadVmo> vmo) override;
void RemoveVmo(fbl::RefPtr<PayloadVmo> payload_vmo) override;
void RemoveAllVmos() override {
std::lock_guard<std::mutex> locker(mutex_);
payload_vmos_.clear();
}
private:
// Attempts to allocate memory from the specified VMO.
fbl::RefPtr<PayloadBuffer> TryAllocateFromVmo(
fbl::RefPtr<PayloadVmo> payload_vmo, uint64_t size)
FXL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
mutable std::mutex mutex_;
VmoAllocation vmo_allocation_ FXL_GUARDED_BY(mutex_) =
VmoAllocation::kNotApplicable;
std::vector<fbl::RefPtr<PayloadVmo>> payload_vmos_ FXL_GUARDED_BY(mutex_);
size_t suggested_allocation_vmo_ FXL_GUARDED_BY(mutex_) = 0;
};
} // namespace media_player
#endif // SRC_MEDIA_PLAYBACK_MEDIAPLAYER_GRAPH_PAYLOADS_VMO_PAYLOAD_ALLOCATOR_H_