pub struct FfmpegBytes(/* private fields */);Expand description
The bytes every packet and frame this crate produces are carried in.
Owned, Send + Sync, 'static, and clone-is-a-refcount-bump: the
core’s D-seat amputation contract, satisfied. Nothing inside
reaches back into libavcodec.
§Why it is opaque
The obvious spelling was the bare Arc<[u8]> this type wraps, and
0.9.0’s first cut used it. It is opaque for one reason, and the
reason is not aesthetics:
Arc<[u8]> is one storage strategy, and it is not going to be the
only one. Every exit currently allocates, copies, and frees per
frame; a decode loop at 4K is asking the global allocator for eight
megabytes sixty times a second and handing it back. The recorded
answer is a plane pool — reusable slabs handed out at the boundary
and returned when the last consumer drops them
(issue #35).
A pooled slab is a different carrier with the same contract: still
owned, still Send + Sync, still refcount-cloned, still holding no
FFmpeg lifetime.
If the carrier were Arc<[u8]> in the public aliases, adding the
pool would change the type of every frame and every packet in the
crate — a breaking release for a change consumers cannot observe.
Behind this newtype it is a new arm of a private enum: no
signature moves, no consumer recompiles differently, and the
AsRef<[u8]> a consumer actually programs against is unchanged.
That extension point is this type’s justification for existing.
The enum has exactly one arm today. It gains the second when the pool is built and not before — this codebase does not carry members nothing can produce.
Implementations§
Source§impl FfmpegBytes
impl FfmpegBytes
Sourcepub fn copy_from_slice(bytes: &[u8]) -> Self
pub fn copy_from_slice(bytes: &[u8]) -> Self
Copies bytes into a fresh carrier.
The copy site. Every exit in this crate lands here or on
Self::empty, so “one copy at the boundary” is a property of
one constructor rather than a promise thirty call sites keep —
and it is the one place a future pooled arm has to be taught
about.
Public because the reverse direction needs it: a consumer building a packet to feed back into a decoder has bytes and needs a carrier, and the alternative is an opaque type nobody outside this crate can construct.
A zero-length copy lands on the shared empty allocation rather than minting its own.
Sourcepub fn empty() -> Self
pub fn empty() -> Self
The zero-length carrier, shared.
Placeholder plane slots and payload-less packets are frequent — a
video frame allocates four slots and populates one to three of
them — and each would otherwise be its own Arc header
allocation. One empty allocation for the process, cloned by
refcount, instead.
Sourcepub fn as_slice(&self) -> &[u8] ⓘ
pub fn as_slice(&self) -> &[u8] ⓘ
The bytes, as a slice.
The same answer AsRef::as_ref gives; inherent so a caller
reaching through a &FfmpegBytes does not have to name the trait.
Sourcepub fn ptr_eq(&self, other: &Self) -> bool
pub fn ptr_eq(&self, other: &Self) -> bool
true when both handles name the same allocation — a clone of
one another, rather than two copies that happen to be equal.
The property the amputation contract is really about: Clone on
a message is a refcount bump. PartialEq answers a different
question (do these hold the same bytes), and a test that wants to
prove the clone did not copy has to ask this one.
Trait Implementations§
Source§impl AsRef<[u8]> for FfmpegBytes
impl AsRef<[u8]> for FfmpegBytes
Source§impl Clone for FfmpegBytes
impl Clone for FfmpegBytes
Source§fn clone(&self) -> FfmpegBytes
fn clone(&self) -> FfmpegBytes
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for FfmpegBytes
impl Debug for FfmpegBytes
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Length only, never the bytes.
A derived Debug would print a decoded 4K plane one integer at a
time; this type is reached from the derived Debug of every
packet, frame and side-data entry in the crate, so the terse form
is the one that keeps those useful. Mirrors what FfmpegBuffer’s
own hand-written Debug did through 0.8.