class CodecAdapter
Defined at line 62 of file ../../src/media/lib/codec_impl/include/lib/media/codec_impl/codec_adapter.h
The CodecAdapter abstract base class is used by CodecImpl to interface with a
particular SW or HW codec. At the layer of this interface, there's only ever
up to one active stream to worry about, and Codec FIDL protocol enforcement
has already been handled above.
For HW-based codecs that need to share the HW, a CodecAdapter represents up
to one active stream, and does not directly participate in sharing the HW;
that's further down.
The intent of this interface is to be as narrow an in-process codec interface
as feasible between FIDL protocol aspects above, and codec-specific details
below.
For DFv2 drivers, avoid assuming that the thrd_t will be the same for
separate calls in the same ordering domain, as DFv2 is allowed to switch
threads for the same ordering domain as long as it ensures ordering of calls.
This is why we call them "ordering domain(s)" not "threads".
This class is sub-classed to implement a specific codec. The sub-class can be
parameterized as needed to deal with different formats/modes/etc. When a core
codec SW lib or FW/HW has a similar interface for decode and encode, it can
sometimes be reasonable to have a sub-class that's not specific to decode vs
encode, then further decoder vs encoder sub-classes under that. For HW with
very different/separate interfaces for decode vs. encode it's more typical to
sub-class CodecAdapter separately for decode vs. encode. For drivers, some
aspects common to decode and encode can be in the
not-StreamProcessor-server-specific portion of the driver, so only
StreamProcessor-instance-specific stuff would go in the
common-to-decode-and-encode sub-class of CodecAdapter.
Protected Members
std::mutex & lock_
CodecAdapterEvents * events_
list input_queue_
random_device random_device_
mersenne_twister_engine not_for_security_prng_
Public Methods
void CodecAdapter (std::mutex & lock, CodecAdapterEvents * codec_adapter_events)
At least for now, the CodecImpl and CodecAdapter share their main lock.
The CodecImpl won't call CodecAdapter methods with the lock_ held, mainly
to avoid building up dependencies on the lock sharing, and also to avoid
situations where the core codec code would just have to release the lock_
in order to acquire video_decoder_lock_ (which is "before" lock_, due to
calls from interrupt handlers that already have video_decoder_lock_ held).
The CodecAdapter should never call CodecAdapterEvents methods with lock_
held.
Defined at line 11 of file ../../src/media/lib/codec_impl/codec_adapter.cc
void ~CodecAdapter ()
Defined at line 20 of file ../../src/media/lib/codec_impl/codec_adapter.cc
void SetCodecDiagnostics (CodecDiagnostics * codec_diagnostics)
This is called if CodecDiagnostics is available, and not called if not. Codec should not retain
ownership of the CodecDiagnostics object and instead call CreateCodec() and then retain
ownership of that object.
Defined at line 24 of file ../../src/media/lib/codec_impl/codec_adapter.cc
std::optional<media_metrics::StreamProcessorEvents2MigratedMetricDimensionImplementation> CoreCodecMetricsImplementation ()
This will return std::nullopt by default. A sub-class must implement this method if the
sub-class ever calls CodecAdapterEvents.onCoreCodecLogEvent (else metrics won't actually get
updated).
Defined at line 28 of file ../../src/media/lib/codec_impl/codec_adapter.cc
bool IsCoreCodecRequiringOutputConfigForFormatDetection ()
During format detection, a codec may be ok with null output config (false),
or may require an output config (true).
bool IsCoreCodecMappedBufferUseful (CodecPort port)
If true, the codec can make use of VMOs that are mapped for direct access
by the CPU.
If true, the CodecImpl will map the buffer VMOs unless buffers are secure
memory, and CodecBuffer::base() is usable for direct CPU access.
If a codec doesn't support secure memory operation, then buffers won't be
secure memory and will be mapped if IsCoreCodecMappedBufferUseful().
If buffers are secure, then CodecImpl won't actually map the buffer VMOs,
and CodecBuffer::base() isn't usable for direct CPU access. Instead
CodecBuffer::base() will be a vaddr that will fault if accessed as if it
were buffer data, and preserves the low-order vmo_usable_start %
PAGE_SIZE bits.
bool IsCoreCodecHwBased (CodecPort port)
If true, the codec is HW-based, in the sense that at least some of the
processing is performed by specialized processing HW running separately
from any CPU execution context.
void CoreCodecSetSecureMemoryMode (CodecPort port, fuchsia::mediacodec::SecureMemoryMode secure_memory_mode)
The default implementation silently accepts OFF. On any other value, the
default implementation fails the codec.
CodecAdapter sub-classes can accept ON if they support ON. Same for
DYNAMIC if/when we add that. The CodecFactory implementation should
already have information on which codecs support ON (or DYNAMIC) for output
or input, and CodecImpl will enforce consistency of BufferCollection
constraints and BufferCollectionInfo_2 with the SecureMemoryMode specified
during codec creation.
Defined at line 35 of file ../../src/media/lib/codec_impl/codec_adapter.cc
void CoreCodecQueueInputPacket (CodecPacket * packet)
Only permitted between CoreCodecStartStream() and CoreCodecStopStream().
void CoreCodecQueueInputEndOfStream ()
Only permitted between CoreCodecStartStream() and CoreCodecStopStream().
void CoreCodecStopStream ()
Stop the core codec from processing any more data for the stream that was
active and is now stopping.
void CoreCodecResetStreamAfterCurrentFrame ()
Reset the stream. Used in processing a watchdog. If an adapter never generates a watchdog, it
doesn't need to override this method.
Do not discard any input data or output data beyond what was being worked on at the time the
watchdog fired.
Defined at line 59 of file ../../src/media/lib/codec_impl/codec_adapter.cc
void CoreCodecAddBuffer (CodecPort port, const CodecBuffer * buffer)
Add an input or output buffer.
The added buffer is consistent with the most recent prior call to
CoreCodecSetBufferCollectionInfo re. the same port (includes SingleBufferSettings). While the
VMOs are intentionally not included in that call, child VMOs of those VMOS are indicated via
this call. This lets the CodecImpl own allocation of CodecBuffer instances, and lets CodecImpl
detect when a CodecAdapter is completely done removing a buffer. For this reason, the
CodecAdapter won't be able to use fuchsia.sysmem2/Allocator.GetVmoInfo, as the VMO is not
directly supplied by sysmem (child VMOs don't count). The CodecAdapter should have the sysmem
info it needs via CodecImpl.
A CodecAdapter that doesn't support dynamic buffers may be able to fully configure a buffer
during this call and later ignore CoreCodecConfigureBuffers(), or may use
CoreCodecConfigureBuffers() to finish configuring buffers.
A CodecAdapter that supports dynamic buffers must fully configure a buffer during this call
(unless it knows this is an output buffer that it'll never use), and CoreCodecConfigureBuffers
won't get called (whether dynamic buffers are being used by the StreamProcessor client or not).
A CodecAdapter that doesn't support dynamic buffers can rely on CodecImpl to call
CoreCodecEnsureBuffersNotConfigured before adding any buffers with a new BufferCollectionInfo.
A CodecAdapter that supports dynamic buffers can rely on CodecImpl to call
CoreCodecRemoveBuffer for all not-already-started-removing buffers of the same port before
calling CoreCodecSetBufferCollectionInfo and adding a buffer with new SingleBufferSettings via
CoreCodecAddBuffer.
void CoreCodecConfigureBuffers (CodecPort port, const std::vector<std::unique_ptr<CodecPacket>> & packets)
Finish setting up input or output buffer(s).
Consider doing as much as feasible in CoreCodecAddBuffer() instead, to be
_slightly_ nicer to shared_fidl_thread().
When a CodecAdapter supports dynamic buffers, this call won't happen, and
CoreCodecAddBuffer can happen again later. In this case the CodecAdapter
learns about available output packets for the first time via the initial
CoreCodecRecycleOutputPacket. For input packets the CodecAdapter learns
about an input packet for the first time via CoreCodecQueueInputPacket.
Even codecs which don't support dynamic buffers may prefer to ignore the
packets parameter and learn of the available packets via
CoreCodecRecycleOutputPacket.
TODO(dustingreen): Assuming a well-behaved client but time-consuming call
to this method, potentially another Codec instance could be disrupted due
to sharing the shared_fidl_thread(). If we see an example of that
happening, we could switch to not sharing any FIDL threads across Codec
instances.
void CoreCodecRecycleOutputPacket (CodecPacket * packet)
This method can be called at any time while output buffers are configured,
including while there's no active stream.
This will also be called on each of the output packets shortly after the
output packet is created.
* For CodecAdapter(s) that don't support dynamic buffers, this method is
called on each new output packet shortly after
CoreCodecConfigureBuffers() is called. Typically it's cleaner for the
CodecAdapter to ignore the CoreCodecConfigureBuffers packets parameter
and find out about new packets via this call only.
* For CodecAdapter(s) that support dynamic buffers, packets are managed
dynamically by CodecImpl to ensure that there will be at least as many
packets as buffers under each buffer_lifetime_ordinal. New output
packets get added via CoreCodecRecycleOutputPacket before a new output
buffer is added, so a CodecAdapter without show_existing_frame won't
need to pend on availability of an output packet (until
CoreCodecRecycleOutputPacket). The number of output packets will always
be at least as large as the number of buffers, but with
show_existing_frame, the CodecAdapter may still need to wait on
availability of an output packet due to a single buffer potentially
being queued more than once as output using separate packets. So far,
this only comes up for vp9 show_existing_frame.
All CodecPacket instances created under a given buffer_lifetime_ordinal
remain allocated until all buffers of the buffer_lifetime_ordinal have been
dropped by the CodecAdapter. This allows a CodecAdapter to access a
CodecPacket instance as long as the CodecAdapter still has any buffers
under the same buffer_lifetime_ordinal, regardless of whether the packet is
currently free with the CodecAdapter or in-flight with the client. While
this can result in quite a few more currently-allocated packets than
buffers under an old buffer_lifetime_ordinal, the packets aren't large, and
the number of old still-active buffer_lifetime_ordinal values is capped.
If DetailedCodecDescription.supports_dynamic_buffers is true, this call can
happen for packets of an old buffer_lifetime_ordinal. If false, this call
will only happen for packets of the current buffer_lifetime_ordinal.
If DetailedCodecDescription.supports_dynamic_buffers is true, the
CodecAdapter must tolerate this call when the CodecAdapter has already
closed all buffers of the packet's buffer_lifetime_ordinal. This can happen
if CodecImpl hasn't yet processed ZX_VMO_ZERO_CHILDREN corresponding to the
last closed handle to the last buffer of the old buffer_lifetime_ordinal.
For CodecAdapter(s) that need to sometimes output a buffer with an old
buffer_lifetime_ordinal, one way to accomplish this is to keep the
CodecAdapter's context for the old buffer_lifetime_ordinal until
CoreCodecCloseBufferLifetimeOrdinal, even though all handles to the old
buffers have been closed. For CodecAdapter(s) that never output a buffer
with old buffer_lifetime_ordinal, the CodecAdapter can keep no context for
old buffer_lifetime_ordinal(s), and ignore this call if the packet isn't
for the current buffer_lifetime_ordinal.
Despite this recycling mechanism, it's not permitted for a CodecAdapter to
change the contents of any buffer with an old buffer_lifetime_ordinal. Only
buffers of the current buffer_lifetime_ordinal can be written to. When a
StreamProcessor client has not sent StreamProcessor.EnableOldOutputBuffers,
CodecImpl will immediately recycle all the client-owned output packets with
old buffer_lifetime_ordinal as soon as the buffer_lifetime_ordinal is
out-of-date (shortly after CoreCodecEnsureBuffersNotConfigured or
CoreCodecRemoveBuffer has been called applying to all buffers of the
out-of-date buffer_lifetime_ordinal). However, the client will likely still
have some of the old buffers in its output queue or downstream being
rendered etc. This restriction is an additional reason that the
CodecAdapter must not select any buffer of an old buffer_lifetime_ordinal
as a free buffer to be filled with new output data, even if there are no
packets outstanding with that buffer from the CodecAdapter's point of view,
and the new output data would fit. The packets recycled here with old
buffer_lifetime_ordinal are only for the CodecAdapter to potentially use to
output another old output buffer in the output sequence that was filled
back when the buffer's buffer_lifetime_ordinal was current.
void CoreCodecEnsureBuffersNotConfigured (CodecPort port)
De-configure input or output buffers. This will never occur at a time when
the core codec is expected to be processing data. For input, this can only
be called while there's no active stream. For output, this can be called
while there's no active stream, or after a stream is started but before any
input data is queued, or during processing shortly after the core codec
calling onCoreCodecMidStreamOutputConstraintsChange(true), after
CoreCodecMidStreamOutputBufferReConfigPrepare() and before
CoreCodecMidStreamOutputBufferReConfigFinish().
The "ensure" part of the name is because this needs to ensure that buffers
will be fully de-configured (and handles dropped) as soon as the buffer is
no longer needed in the DPB or in an output queue. When not between
CoreCodecMidStreamOutputBufferReConfigPrepare and
CoreCodecMidStreamOutputBufferReConfigFinish calls, this means handles to
all buffers of the specified port should be dropped quickly and before
returning from this call, since there is no active stream or the stream
hasn't seen any input data yet, so (using video decoders as an example)
there are no output frames in the DPB and no reason to retain any buffers
relevant to any output queue (any such output is already known to be safe
to drop).
The handles to VMOs that the CodecAdapter has are handles to child VMOs,
and CodecImpl needs all handles to a child VMO to be closed before
StreamProcessor.RemoveBuffer can complete. Keeping a handle open longer
than necessary is visible to StreamProcessor clients above, and in some
cases could cause the whole pipeline to stall.
Any memory mappings to buffers must also be removed, as these keep the
child VMO from being dropped at zircon layer.
As always, the codec must ensure that zero DMA writes to a buffer will
occur during any interval when the buffer is not pinned.
This call needs to work regardless of whether buffers are presently fully
de-configured already, or if CoreCodecAddBuffer() has been called 1-N times
but CoreCodecConfigureBuffers() hasn't been called yet (and won't be, if
this method is called instead), or if CoreCodecAddBuffer() has been called
N times and CoreCodecConfigureBuffers() has also been called.
The "not configured" means pending removal or removed, as appropriate. An
output buffer that's still used by bitstream-spec-specified decoder state
can still be emitted as output, but as soon as the buffer is no longer used
by bitstream-spec-specified decoder state, any handles to the buffer held
by the CodecAdapter must be closed. Closing any relevant handles during
this call isn't strictly required, but they should be closed asap without
damaging any ongoing decoder state.
For CodecAdapter(s) with IsSupportsDynamicBuffers() true, this won't get
called, and instead CodecImpl will call CoreCodecRemoveBuffer on specific
buffers as appropriate.
If there's a current stream that has seen input, and a buffer is still
needed to retain stream processing context, or to maintain validity of an
item in an output queue, the CodecAdapter should retain at least one
handle to the buffer (based on CodecBuffer.GetChildVmo) until the buffer is
no longer needed, at which point the handle to the buffer should be closed
quickly (this is should, not must). If the CodecAdapter does the preceding,
the CodecAdapter, as appropriate, should also call onCoreCodecOutputPacket
with an old packet and old buffer if output of an old buffer is specified
by the bitstream (this is should, not must, and only if the CodecAdapter is
retaining a duplicated handle). See also
CoreCodecCloseBufferLifetimeOrdinal for a convenient way to manage
tracking/cleanup of old packets.
std::unique_ptr<const fuchsia::media::StreamBufferConstraints> CoreCodecBuildNewInputConstraints ()
This call is deprecated, never called, and will be removed. Sub-classes
should not override this.
Defined at line 47 of file ../../src/media/lib/codec_impl/codec_adapter.cc
std::unique_ptr<const fuchsia::media::StreamOutputConstraints> CoreCodecBuildNewOutputConstraints (uint64_tstream_lifetime_ordinal,uint64_tnew_output_buffer_constraints_version_ordinal,boolbuffer_constraints_action_required)
This call is deprecated, never called, and will be removed. Sub-classes
should not override this.
Defined at line 52 of file ../../src/media/lib/codec_impl/codec_adapter.cc
bool IsSupportsDynamicBuffers ()
The return value from this method must match
DetailedCodecDescription.supports_dynamic_buffers. This setting must be
constant per codec as seen by CodecFactory, per boot.
Defined at line 118 of file ../../src/media/lib/codec_impl/include/lib/media/codec_impl/codec_adapter.h
uint32_t GetDynamicBuffersMax (CodecPort port)
If IsSupportsDynamicBuffers returns true, this must return > 0 for both
input and output.
Defined at line 121 of file ../../src/media/lib/codec_impl/include/lib/media/codec_impl/codec_adapter.h
zx::unowned_bti CoreCodecBti ()
Any core codec that performs DMA that will potentially continue beyond the
lifetime of the process that holds open the VMO handles being DMA(ed)
should override this method to provide CodecImpl with the driver's BTI so
VMOs can be properly pinned for DMA. If a core codec returns true from
IsCoreCodecHwBased(), the core codec should also override this method.
TODO(https://fxbug.dev/42114424): At least the VP9 decoder isn't overriding this method yet.
Also we should enforce that this method be overridden when
IsCoreCodecHwBased() true.
Defined at line 132 of file ../../src/media/lib/codec_impl/include/lib/media/codec_impl/codec_adapter.h
fuchsia_sysmem2::BufferCollectionConstraints CoreCodecGetBufferCollectionConstraints2 (CodecPortport,const fuchsia::media::StreamBufferConstraints &stream_buffer_constraints,const fuchsia::media::StreamBufferPartialSettings &partial_settings)
Deprecated; prefer to override CoreCodecGetBufferCollectionConstraints3
instead. Don't override both.
The returned constraints should not depend on the stream_buffer_constraints
or partial_settings passed into this call. Those parameters should be
completely ignored. See CoreCodecGetBufferCollectionConstraints3 for the
new revision of this method that removes these params.
See comments for CoreCodecGetBufferCollectionConstraints3 for more.
Defined at line 299 of file ../../src/media/lib/codec_impl/include/lib/media/codec_impl/codec_adapter.h
uint64_t CoreCodecGetConstraintsVersion (CodecPort port)
The return value is in the same sequence as the CoreCodecGetBufferCollectionConstraints3Result
constraints_version field.
This method must be overridden if CoreCodecGetBufferCollectionConstraints3 is overridden.
This method must be overridden if IsSupportsDynamicBuffers() is true.
This can get called on any thread, but not on the same stack as an outbound call to CodecImpl.
Defined at line 313 of file ../../src/media/lib/codec_impl/include/lib/media/codec_impl/codec_adapter.h
void CoreCodecInit (const fuchsia::media::FormatDetails & initial_input_format_details)
The initial input format details and later input format details will
_often_ remain the same overall format, and only differ in ways that are
reasonable on a format-specific basis. However, not always. A core codec
should check that any new input format details is still fully compatible
with the core codec's initialized configuration (as set up during
CoreCodecInit()), and if not, fail the CodecImpl using
onCoreCodecFailCodec(). Core codecs may re-configure themselves based
on new input FormatDetails to the degree that's reasonable for the
input format and the core codec's capabilities, but there's no particular
degree to which this is required (for now at least). Core codecs are
discouraged from attempting to reconfigure themselves to process completely
different input formats that are better to think of as a completely
different Codec.
A client that's using different FormatDetails than the initial
FormatDetails (to any degree) should try one more time with a fresh
Codec before giving up (giving up immediately only if the format details at
time of failure match the initial format details specified during Codec
creation).
The core codec can copy the initial_input_format_details during this call
(using fidl::Clone() or similar), but as is the custom with references,
should not stash the passed-in reference.
TODO(dustingreen): Re-visit the lifetime rule and required copy here, once
more is nailed down re. exactly how the core codec relates to CodecImpl.
void CoreCodecRemoveBuffer (CodecPort port, const CodecBuffer * buffer)
When dynamic buffers are supported, this must remove and close handles to an input or output
buffer, when safe to do so.
The buffer should be removed asap, but without resorting to copying of payload data to other
buffers, and without breaking the codec state for the currently active stream (if any).
Unnecessary delay removing and closing the buffer may stall the overall pipeline. The removal
can proceed async after this call returns.
If there is no current stream, or if a stream hasn't seen any input data yet, the buffer should
be removed and closed very quickly (async is still allowed).
For input, this call will never happen between CoreCodecQueueInputPacket and
onCoreCodecInputPacketDone, for any buffer referenced by any such input packet.
For output packets, until the CodecAdapter has closed all handles (based on
CodecBuffer.GetChildVmo), it remains valid to call onCoreCodecOutputPacket with this
CodecBuffer.
If there's a current stream that has seen input, and the buffer is still needed to retain
stream processing context, or to maintain validity of an item in an output queue, the
CodecAdapter _must_ retain at least one handle to the buffer (based on CodecBuffer.GetChildVmo)
until the buffer is no longer needed for correct processing of the stream, at which point the
retained handle to the buffer (and all mappings, and all pins) should be closed/removed
quickly.
See also CoreCodecCloseBufferLifetimeOrdinal for a convenient way to manage tracking/cleanup of
old packets.
Defined at line 504 of file ../../src/media/lib/codec_impl/include/lib/media/codec_impl/codec_adapter.h
std::string CoreCodecGetName ()
Returns a name for the codec that's used for debugging.
Defined at line 744 of file ../../src/media/lib/codec_impl/include/lib/media/codec_impl/codec_adapter.h
void CoreCodecSetBufferCollectionInfo (CodecPort port, const fuchsia_sysmem2::BufferCollectionInfo & buffer_collection_info)
There are no VMO handles in the buffer_collection_info. Those are instead
provided via calls to CoreCodecAddBuffer(), as CodecImpl handles allocation
of CodecBuffer instances (each of which has a VMO).
The buffer_collection_id is redacted, because when using dynamic buffers,
the overall set of buffers for a given port can be from separate buffer
collections, so in that case there's not a single buffer_collection_id.
Despite this, the BufferCollectionInfo is guaranteed by the caller to be
identical for all the current buffers of a given port.
This method allows a core codec to know things like buffer_count (when not
using dynamic buffers; see below), whether sysmem selected CPU domain or
RAM domain for sharing of buffers, whether protected buffers were
allocated, etc.
When using dynamic buffers, the "buffers" field is un-set. In this case the
core codec must rely on CoreCodecAddBuffer calls to know how many current
buffers there are for a given port (until
CoreCodecEnsureBuffersNotConfigured which resets the count of current
buffers to 0 for a given port). In this context, "current buffers" does not
count any old buffers still held by the DPB or in an output queue.
This call occurs shortly before the first CoreCodecAddBuffer when starting
from 0 current buffers. Additional buffers added prior to
If the codec supports dynamic buffers, the buffer_collection_info passed to
this call will have buffers.size() == 0, and the codec should treat that as
normal. Other fields are valid. The codec needs to configure a buffer
dynamically when CoreCodecAddBuffer is called, including after processing
has begun.
A CodecAdapter that supports dynamic buffers and whose output constraints
ever change (inter-stream or intra-stream) must tolerate a call to
CoreCodecSetBufferCollectionInfo (re. output) with SingleBufferSettings
that are not suitable to continue processing the current position of the
current stream (whether the stream is actively processing or not). The
expected way for the CodecAdapter to handle this is to track its own output
constraints version uint64_t which changes atomically along with any
updates to the data from which sysmem constraints for output are derived
(such as when a decoding video stream changes dimensions). The CodecAdapter
should also track whether onCoreCodecMidStreamOutputConstraintsChange has
been called yet for the current output constraints version. When the output
constraints version changes, this called-yet bool gets reset to false. The
CodecAdapter should evaluate whether the current SingleBufferSettings are
suitable for continued processing (a) just after the output constraints
version has changed and (b) just after the SingleBufferSettings are
set/changed by a call to CoreCodecSetBufferCollectionInfo. If the
SingleBufferSettings are not suitable and the called-yet bool is false, the
CodecAdapter must call onCoreCodecMidStreamOutputConstraintsChange and set
the called-yet bool to true. Using this scheme, the CodecAdapter helps
achieve the following:
* Processing doesn't pause if the current buffers are fine.
* Unnecessary buffer reallocations are avoided.
* Reallocation of buffers is reliably triggered when new buffers are
needed.
* The client can start the process of replacing buffers at any time as
needed for client-specific reasons.
The buffer_collection_info and its SingleBufferSettings are guaranteed to
conform to at least one BufferCollectionConstraints previously returned
from a previous call to CoreCodecGetBufferCollectionConstraints3/2. In
other words, the CodecAdapter only needs to check aspects of the settings
here which the CodecAdapter didn't fully constrain already, and doesn't
need to worry about ever seeing a completely-arbitrary BufferCollectionInfo
here.
fuchsia::media::StreamOutputFormat CoreCodecGetOutputFormat (uint64_t stream_lifetime_ordinal, uint64_t new_output_format_details_version_ordinal)
This will be called on the InputData domain, during the core codec's call
to onCoreCodecOutputPacket(), so that the format will be delivered at most
once before any packet which needs a new format to be indicated. The core
codec can trigger this to occur during the next onCoreCodecOutputPacket()
by calling onCoreCodecOutputFormatChange(). The tracking of pending
output format is per-stream, and all streams start with a pending output
format, so a core codec need not call onCoreCodecOutputFormatChange()
unless the format change is mid-stream (but calling before the first packet
is allowed and not harmful).
void CoreCodecMidStreamOutputBufferReConfigPrepare ()
CoreCodecMidStreamOutputBufferReConfigPrepare()
For a mid-stream format change where output buffer re-configuration is
needed (as initiated async by the core codec calling
CodecAdapterEvents::onCoreCodecMidStreamOutputConstraintsChange(true)),
this method is called on the StreamControl thread before the client is
notified of the need for output buffer re-config (via OnOutputConstraints()
with buffer_constraints_action_required true).
The CodecAdapter should do whatever is necessary to ensure that output
buffers are done de-configuring to the extent that it doesn't prevent
correct decoding of the stream, by the time this method returns. If a
CodecAdapter keeps old buffer handles/references around (based on
CodecBuffer.GetChildVmo) as needed by the bitstream spec, the core codec
should drop those handles/references as soon as they're no longer needed
for correct processing of the stream.
As always, calls to CodecAdapterEvents must not be made while holding
lock_.
void CoreCodecMidStreamOutputBufferReConfigFinish ()
This method is only called if !IsSupportsDynamicBuffers(). If
IsSupportsDynamicBuffers(), the CodecAdapter should continue processing as
soon as it has at least one new buffer that's suitable.
If !IsSupportsDynamicBuffers():
This method is called when the mid-stream output buffer re-configuration
has completed. This is called after all the calls to CoreCodecAddBuffer()
and the call to CoreCodecConfigureBuffers() are done.
The core codec should do whatever is necessary to get back into normal
steady-state operation in this method.
The core codec must not onCoreCodecOutputPacket() or
onCoreCodecOutputEndOfStream() until this method has been called, or until
CoreCodecStartStream() is called and some input is available, should the
current stream be stopped before completing mid-stream output buffer
re-config. This works partly because the CodecImpl guarantees that if a
mid-stream re-config didn't finish, there will be a complete output
re-config before the CoreCodecStartStream() - in other words this re-config
is abandoned and a new one takes its place and is fully complete prior to
the new stream starting.
When IsSupportsDynamicBuffers() true, output is buffered as necessary in
CodecImpl, so the CodecAdapter doesn't need to worry about emitting output
too early.
void CoreCodecSetForceNewBuffersOnNewDimensions (bool force)
Defined at line 174 of file ../../src/media/lib/codec_impl/include/lib/media/codec_impl/codec_adapter.h
std::optional<CoreCodecGetBufferCollectionConstraints3Result> CoreCodecGetBufferCollectionConstraints3 (CodecPort port)
Defined at line 286 of file ../../src/media/lib/codec_impl/include/lib/media/codec_impl/codec_adapter.h
void CoreCodecSetStreamControlProfile (zx::unowned_thread stream_control_thread)
If desired, the CodecAdapter can set a scheduler profile on the stream control thread.
CodecImpl will call this function after the creation of the StreamControl thread to give the
CodecAdapter an opportunity to set a scheduler profile on the thread. Ownership of the thread
remains with CodecImpl and the handle should be duplicated as necessary (such as for passing to
fuchsia.media.ProfileProvider). TODO(https://fxbug.dev/42149456): Generalize this mechanism for
all codec_impl threads
DFv2 drivers should prefer to implement
CoreCodecGetSchedulerProfileName(OrderingDomain::StreamControl). If that returns a non-empty
string then this method won't get called. In DFv2 drivers, this won't get called.
DFv1 drivers that need a scheduler profile will continue to implement this method.
Defined at line 758 of file ../../src/media/lib/codec_impl/include/lib/media/codec_impl/codec_adapter.h
std::string CoreCodecGetSchedulerProfileName (OrderingDomain ordering_domain)
For DFv2 drivers, this is how to set the scheduler role (not CoreCodecSetStreamControlProfile).
An empty string will skip attempting to set the scheduler role. CodecAdapter(s) should not
attempt to set the scheduler role by grabbing a handle to the current thread during a call on
StreamControl ordering domain, because DFv2 is technically allowed to switch threads as long as
it ensures sequential calls and handles the scheduler profile correctly.
For DFv1 drivers, this won't work and should not return a non-empty string since it'll only
result in a warning to the log. See CoreCodecSetStreamControlProfile for the DFv1 way which
will only get called if this returns an empty string (such as the default impl).
Defined at line 768 of file ../../src/media/lib/codec_impl/include/lib/media/codec_impl/codec_adapter.h
void CoreCodecCloseBufferLifetimeOrdinal (CodecPort port, uint64_t buffer_lifetime_ordinal)
This will be called only after all handles to buffers of the old buffer_lifetime_ordinal have
been closed by the CodecAdapter and CodecImpl has noticed this via ZX_VMO_ZERO_CHILDREN. Until
the start of this call, CoreCodecRecycleOutputPacket can still be called with a packet of the
old buffer_lifetime_ordinal. After this call, the CodecAdapter should no longer be tracking
anything regarding the specified buffer_lifetime_ordinal (not even packets). The CodecAdapter
should tolerate this call occurring for a buffer_lifetime_ordinal for which there were never
any packets or buffers, or for which the CodecAdapter has already stopped tracking the
buffer_lifetime_ordinal unilaterally.
CodecAdapter(s) which never output a buffer with old buffer_lifetime_ordinal can use the
default implementation (can ignore the call). In this case the CodecAdapter never keeps any
context, buffers, or packets for the old buffer_lifetime_ordinal in the first place.
Defined at line 784 of file ../../src/media/lib/codec_impl/include/lib/media/codec_impl/codec_adapter.h
void CoreCodecStartStream ()
The "Queue" methods will only be called in between CoreCodecStartStream()
and CoreCodecStopStream().
void CoreCodecQueueInputFormatDetails (const fuchsia::media::FormatDetails & per_stream_override_format_details)
The parameter includes the oob_bytes. The core codec is free to call
onCoreCodecFailCodec() (immediately on this stack or async) if the
override input format details can't be accommodated (even in situations
where the override input format details would be ok as initial input format
details, such as when new input buffer config is needed).
That said, the core codec should try to accommodate the change, especially
if the client has configured adequate input buffers, and the basic type of
the input data hasn't changed.
TODO(dustingreen): Nail down the above sorta-vaguely-described rules
better.
Only permitted between CoreCodecStartStream() and CoreCodecStopStream().
Protected Methods
void LogEvent (media_metrics::StreamProcessorEvents2MigratedMetricDimensionEvent event_code)
If SetCodecMetrics() was called, this will log an event. If this method is ever called by a
subclass, then CoreCodecMetricsImplementation() must be implemented by the subclass.