blob: f2a226bd07fd5f6abac609e1dd72a33e6afa4b8f [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_PAYLOAD_CONFIG_H_
#define SRC_MEDIA_PLAYBACK_MEDIAPLAYER_GRAPH_PAYLOADS_PAYLOAD_CONFIG_H_
namespace media_player {
// Indicates how an input or output wants to access/allocate payload buffers.
enum class PayloadMode {
kNotConfigured,
// Payloads are in process virtual memory and are allocated using a
// |PayloadAllocator|.
kUsesLocalMemory,
// Only outputs can use this mode. Payloads are in process virtual memory
// and are allocated by the output.
kProvidesLocalMemory,
// Payloads are in VMOs obtained through |PayloadVmos|.
kUsesVmos,
// Payloads are in VMOs provided by the connector via |PayloadVmoProvision|.
kProvidesVmos
};
// Indicates how buffers should be allocated from VMOs.
enum class VmoAllocation {
kNotApplicable,
// There's just one VMO, and all buffers should be allocated from it.
kSingleVmo,
// Each buffer occupies its own VMO. Each buffers starts at offset zero in
// its VMO and can be smaller than the VMO.
kVmoPerBuffer,
// Buffers may be allocated from VMOs arbitrarily.
kUnrestricted
};
// Configuration constraints of an input or output.
//
// The max_xxx fields are used to determine how much memory will be required
// for payloads on the connection. An output must account for the payloads that
// will be held internal to its node as well as payloads queued on the
// connection. An input only needs to account for payloads that will be held
// internal to its node.
//
// The max_xxx fields overlap to some degree. This allows nodes that have only
// partial information to provide enough context for the payload manager to
// configure allocators correctly.
//
// In some cases, the payload manager needs to determine memory requirements
// for the output and input together. In other cases, it needs to determine
// memory requirements for just the output or just the input.
//
// For the combined case, memory requirement calculations look like this:
//
// max_payload_count = output.max_payload_count + input.max_payload_count
// max_payload_size = max(output.max_payload_size, input.max_payload_size)
// max_aggregate_payload_size = max(output.max_aggregate_payload_size +
// input.max_aggregate_payload_size,
// max_payload_count * max_payload_size)
//
// max_aggregate_payload_size is then rounded up to the nearest multiple of
// max_payload_size. For the separate input or output case, the calculations
// look like this:
//
// max_payload_count = this.max_payload_count
// max_payload_size = max(this.max_payload_size, other.max_payload_size)
// max_aggregate_payload_size = max(this.max_aggregate_payload_size,
// max_payload_count * max_payload_size)
//
// Note that in either case, lack of good |max_aggregate_payload_size_| values
// can be compensated for by good |max_payload_count_| and |max_payload_size_|
// values. Here are some examples of how that plays out:
//
// 1) A video renderer input doesn't know max payload size, either individually
// or in aggregate, but it does know how many payloads it needs to keep
// around. The decoder output that feeds renderer knows the max payload size
// and the number of payloads. This information is enough for the payload
// manager to determine how much memory is needed for the output and input
// combined and for each individually.
// 2) An audio renderer input doesn't know how big payloads will be, but it
// knows how much payload it needs to hold in terms of time and therefore in
// terms of bytes, so it has a good aggregate size. The decoder output that
// feeds the renderer knows the size of the payloads it will produce and how
// many it will need to keep around. Again, this is enough information for
// the required calculations.
// TODO(dalesat): More.
//
struct PayloadConfig {
// Indicates how the input/output will operate with respect to payload
// allocation. See comments on |PayloadMode| above.
PayloadMode mode_ = PayloadMode::kNotConfigured;
// Indicates the amount of memory in bytes the input/output will require.
// See the class comment above.
//
// When an input/output is used a kExternalX mode, it doesn't provide this
// value. Outputs using |kProvidesLocalMemory| mode are assumed to be able to
// allocated an indefinite amount of payload memory. When an input/output
// uses kProvidesVmos mode, the manager examines the provided VMOs to see if
// they fulfill the requirements of the connected output/input.
uint64_t max_aggregate_payload_size_ = 0;
// Indicates the maximum number of payloads the input/output will required.
// See the class comment above.
uint32_t max_payload_count_ = 0;
// Indicates the maximum size for a payload. Only outputs that aren't using
// a kExternalX mode provide this value. This value is used to ensure that
// VMOs allocated for payloads are sufficiently large.
//
// When an input uses |kProvidesVmos| mode, the manager examines the provided
// VMOs to see if they fulfill the requirements of the connected output/input.
uint64_t max_payload_size_ = 0;
// Indicates how buffers should or will be allocated from VMOs. For
// inputs/outputs using a |kExternalVmo| mode, this value indicates how that
// input/output will allocate buffers. For inputs/output using |kUsesVmos|
// mode, this value indicates how buffers must be allocated for that
// input/output.
//
// In some cases, incompatible values of |vmo_allocation_| from the input and
// output in a connection will require that payloads be copied.
VmoAllocation vmo_allocation_ = VmoAllocation::kNotApplicable;
// Indicates whether VMOs should or will be physically contiguous. For
// inputs/outputs using a |kExternalVmo| mode, this value indicates how that
// input/output will create VMOs. For inputs/output using |kUsesVmos| mode,
// this value indicates how VMOs must be created for that input/output.
//
// In some cases, incompatible values of |physically_contiguous_| from the
// input and output in a connection will require that payloads be copied.
bool physically_contiguous_ = false;
};
} // namespace media_player
#endif // SRC_MEDIA_PLAYBACK_MEDIAPLAYER_GRAPH_PAYLOADS_PAYLOAD_CONFIG_H_