Skip to main content

TrackExtra

Struct TrackExtra 

Source
pub struct TrackExtra { /* private fields */ }
Expand description

Per-TrackInfo extras — the FFmpeg side of one track-table row.

Carries the stream’s CodecTicket — the owned mirror of its AVCodecParameters — which is what opens a decoder for the track, through Self::clone_parameters. That call rebuilds a fresh AVCodecParameters from the ticket with no tie back to the format context, so a decoder outlives the demuxer that named it.

§The handle is gone, and Sync arrived with it

This type used to hold an ffmpeg_next::codec::Parameters — a *mut AVCodecParameters behind a Send-but-not-Sync wrapper. It was the row’s only non-Sync field, and through it the whole track table was !Sync: TrackInfo<Ffmpeg> could not be shared, Arc<TrackInfo<Ffmpeg>> was not Send, and every consumer that hands a track row to more than one task stopped compiling — for a struct FFmpeg documents as a plain descriptor with no thread affinity at all.

The answer is the mirror this crate already lives by rather than an unsafe impl over FFI: CodecTicket holds every seat as owned bytes and plain integers, so Send + Sync are structural facts and there is no safety argument to get wrong. See crate::ticket::tests::the_ticket_is_send_and_sync for the pins, and the ticket’s own docs for the parity the rebuild is held to.

§Clone, and the ruling that banned it

This type refused Clone for two releases, on two arguments. Both were about the raw handle, and both died with it.

The first was safety. A derived Clone went through ffmpeg_next’s Clone for Parameters, which checks neither the allocation nor the copy — so safe public code that merely copied a track row could dereference a null destination or receive parameters that were quietly incomplete, and Clone has no way to report either. That derive really did ship once, and really was reachable.

The second was the message-carrier law: a Clone is a refcount bump, never a deep copy, and avcodec_parameters_copy is not that.

Neither survives the mirror. There is no Parameters left to clone unchecked, so there is nothing for a Clone to fail to report; and a copy is now plain owned Rust — a Vec spine and refcount bumps over Arc<[u8]> — with no FFmpeg allocator anywhere near it, which is exactly what the carrier law asks of a Clone. A ban whose whole rationale is spent is ceremony, so the ban is gone, together with the fallible try_clone and the infallible duplicate that stood in for it.

This does not make a track row cheap to copy by accident. TrackInfo and its TrackParams still have no Clone of their own, so the row-sharing law is untouched: a consumer that needs to share a row still wraps it in Arc once, at the door — which is now a thing it can actually do, because the row finally became Sync.

No Default, though. A track row with no codec parameters describes no track.

disposition is the raw AV_DISPOSITION_* bit set, not ffmpeg_next::format::stream::Disposition. That type’s from_bits_truncate drops bits the linked build has no constant for, and this crate’s stance on bit sets is that every pattern is a value — the same reason PacketFlags reaches the wire as a number.

Implementations§

Source§

impl TrackExtra

Source

pub fn new(stream_index: i32, ticket: CodecTicket) -> Self

Constructs a TrackExtra from the stream index and the owned codec ticket. Everything else starts absent.

Infallible, and that is the news. The old constructor returned a Result for one reason: Parameters::new() and Parameters::default() are safe constructors over an unchecked avcodec_parameters_alloc, so a caller could hand this type a null-backed value having never been told. A CodecTicket has no such state — it cannot be null-backed and it cannot be unmeasurable, because CodecTicket::mirror refused both before it existed. The check moved to where the raw pointer is, and the row stopped carrying an error it could no longer raise.

Not const fn: the ticket owns heap.

Source

pub const fn parameter_bytes(&self) -> usize

The heap bytes a rebuild of this row’s codec parameters allocates — extradata with its padding, the coded_side_data descriptor array and every entry’s payload, and a custom channel map.

The number the session admitted this stream at, and the ceiling DemuxLimits::max_codec_parameter_bytes was judged against — so a row that opened is a row whose every Self::clone_parameters fits the ceiling it opened under.

Not the row’s own residency: the ticket holds the payload without FFmpeg’s trailing padding and shares its buffers by refcount.

Source

pub fn clone_parameters(&self) -> Result<Parameters, DemuxError>

A live AVCodecParameters, rebuilt from the ticket — the handoff that opens a decoder for this track.

FfmpegAudioStreamDecoder::open(track.extra().clone_parameters()?, track.timebase(), limits). Fallible because allocation is: a failure here is the difference between a decoder that is not opened and one opened on parameters that are not the file’s.

Every seat the file declared is written back, so what a decoder receives is what the demuxer read — proved field by field, per codec, by tests/codec_ticket_parity.rs.

Source

pub const fn stream_index(&self) -> i32

Returns the source AVStream.index.

Source

pub const fn disposition(&self) -> i32

Returns the raw AVStream.disposition bit set.

Source

pub const fn start_time(&self) -> Option<i64>

Returns the stream’s start time in the track’s timebase, or None when the container does not carry one.

Source

pub const fn frame_count(&self) -> Option<i64>

Returns AVStream.nb_frames when the container carries it.

Source

pub const fn ticket(&self) -> &CodecTicket

Returns the stream’s owned codec ticket — every seat of its AVCodecParameters, and what Self::clone_parameters rebuilds a decoder’s parameters from.

Source

pub const fn with_disposition(self, value: i32) -> Self

Sets the disposition bits (consuming builder).

Source

pub const fn with_start_time(self, value: Option<i64>) -> Self

Sets the start time (consuming builder).

Source

pub const fn with_frame_count(self, value: Option<i64>) -> Self

Sets the frame count (consuming builder).

Source

pub const fn set_disposition(&mut self, value: i32) -> &mut Self

Sets the disposition bits in place.

Source

pub const fn set_start_time(&mut self, value: Option<i64>) -> &mut Self

Sets the start time in place.

Source

pub const fn set_frame_count(&mut self, value: Option<i64>) -> &mut Self

Sets the frame count in place.

Trait Implementations§

Source§

impl Clone for TrackExtra

Source§

fn clone(&self) -> TrackExtra

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TrackExtra

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Hand-written so the ticket prints as its own summary rather than as a wall of bytes — see CodecTicket’s Debug, which prints sizes for the same reason.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more