Referencia Zigmedia-core: motor de medios

media-core/container/bytes.zig

Declaraciones públicas de media-core/container/bytes.zig (media-core: motor de medios).

ImplementadoSin versión del tren todavía· generada desde apps/docs/generated/zig/media-engine.json

Página generada desde native/zig/media-core/media_engine.zig. No se edita a mano: bun run docs:gen la regenera y bun run docs:check falla si difiere.

Byte-range reading for the container parsers and demuxers. styx:parser (dec-0117 §6: S3/S4 apply — untrusted media bytes).

ByteSource is the only door into the media bytes for BOTH engines (dec-0110 §1): total size plus read(offset, dst, purpose). It is the shape SeekableMediaSource exposes in the daemon (LocalFileSource.readAt with a ReadPurpose), and what libav's custom AVIOContext calls into.

RangeReader puts a window on top: every window miss does ONE read of max(n, min_fetch) bytes (clamped to EOF), counts reads and bytes, and checks the request's CancelToken first. Parsers ask for small slices without one syscall per field, and the I/O cost of a probe is measured in one place.

Everything below reads untrusted input: every length is checked against what is actually there (EndOfStream), every declared size against a cap (TooLarge), and nothing indexes out of bounds.

bytes.Purpose

type · línea 22

pub const Purpose = enum

Sin ///.

bytes.ReadError

const · línea 31

pub const ReadError = error{ ReadFailed, Cancelled }

Sin ///.

bytes.ByteSource

type · línea 33

pub const ByteSource = struct

Sin ///.

bytes.ByteSource.VTable

type · línea 37

pub const VTable = struct

Sin ///.

bytes.ByteSource.size

fn · línea 44

pub fn size(self: ByteSource) u64

Sin ///.

bytes.ByteSource.read

fn · línea 48

pub fn read(self: ByteSource, offset: u64, dst: []u8, purpose: Purpose) ReadError!usize

Sin ///.

bytes.ByteSource.readAll

fn · línea 53

pub fn readAll(self: ByteSource, offset: u64, dst: []u8, purpose: Purpose) ReadError!usize

Reads until dst is full or EOF.

bytes.CancelToken

const · línea 66

pub const CancelToken = zkit.CancelToken

Per-request cancellation (r04 / r20 §3.6), set from another thread; every read of an engine checks it first.

bytes.Error

const · línea 71

pub const Error = zkit.safety.bounded_reader.Error || error{ /// Invalid structure (impossible sizes, out-of-range values). Malformed, /// Not a supported container. UnknownFormat, /// Valid input usi …

Parser errors: the zkit.safety.BoundedReader / BitReader vocabulary (EndOfStream = a structure declares bytes beyond the file or its parent) plus the container's own. contract.fromParser maps them to EngineError.

bytes.max_fetch

const · línea 87

pub const max_fetch: usize = 16 * 1024 * 1024

Cap per read. Equals DEFAULT_MAX_RANGE_LENGTH_BYTES of LocalFileSource (ThreatModel-v0 §5): a moov, Cues or cluster larger than this is not read.

bytes.Limits

type · línea 93

pub const Limits = struct

Resource caps of one probe or demuxer, global (summed over all tracks). A tiny file can declare huge counts (trun without per-sample fields, constant stsz, thousands of trak): these caps, not the declared sizes, bound the cost.

bytes.Limits.readBudget

fn · línea 126

pub fn readBudget(self: Limits, size: u64) u64

The read budget of one walk over a file of size bytes (saturating).

bytes.Limits.forFile

fn · línea 135

pub fn forFile(self: Limits, size: u64) Limits

The caps of a demuxer over a file of size bytes. Every sample it can produce occupies at least one byte of the file, so the samples it walks (tables, truns, indexes) never exceed the file size, whatever the file declares: the cost of a walk is linear in the bytes of the input, never in a count written in four of them.

bytes.Budget

type · línea 144

pub const Budget = struct

Counter of Limits for one probe. Each take* reserves before iterating or allocating; if it does not fit it returns TooLarge without doing the work.

bytes.Budget.init

fn · línea 150

pub fn init(limits: Limits) Budget

Sin ///.

bytes.Budget.takeStreams

fn · línea 154

pub fn takeStreams(self: *Budget, n: u32) Error!void

Sin ///.

bytes.Budget.takeSamples

fn · línea 159

pub fn takeSamples(self: *Budget, n: u64) Error!void

Sin ///.

bytes.Budget.takeKeyframes

fn · línea 164

pub fn takeKeyframes(self: *Budget, n: u64) Error!void

Sin ///.

bytes.Budget.giveKeyframes

fn · línea 173

pub fn giveKeyframes(self: *Budget, n: u64) Error!void

Returns n reserved keyframes that were not stored (a rejected sidx): they do not count against what may still arrive. Giving back more than was taken is a broken accounting: the parse fails, it does not panic.

bytes.StateBudget

type · línea 186

pub const StateBudget = struct

Heap of one demuxer's own state, capped at Limits.max_state_bytes: a zkit.safety.BudgetAllocator over the caller's allocator. Every collection a demuxer grows from what the file declares (queues, reorder heaps, fragment expansion, scanned indexes) allocates here, so a cap missing on one of them is a TooLarge of that session at this line, not an OOM of the daemon. It also counts allocations and frees on its own (independent of the demuxer) and logs a leak at deinit.

bytes.StateBudget.init

fn · línea 189

pub fn init(gpa: std.mem.Allocator, limits: Limits) StateBudget

Sin ///.

bytes.StateBudget.allocator

fn · línea 193

pub fn allocator(self: *StateBudget) std.mem.Allocator

Sin ///.

bytes.StateBudget.mark

fn · línea 199

pub fn mark(self: *StateBudget) u64

Denials so far, to tell afterwards whether an OutOfMemory came from this budget.

bytes.StateBudget.classify

fn · línea 205

pub fn classify(self: *StateBudget, e: Error, since: u64) Error

OutOfMemory because this budget refused (the input asked for more state than a demuxer may hold) is TooLarge; anything else is kept.

bytes.StateBudget.deinit

fn · línea 210

pub fn deinit(self: *StateBudget) void

Sin ///.

bytes.ReadStats

type · línea 215

pub const ReadStats = struct

Sin ///.

bytes.RangeReader

type · línea 220

pub const RangeReader = struct

Sin ///.

bytes.RangeReader.scan_chunk

const · línea 237

pub const scan_chunk: usize = 64 * 1024

Largest fetch ahead asks for when the window does not cover a scan.

bytes.RangeReader.init

fn · línea 239

pub fn init(gpa: std.mem.Allocator, source: ByteSource, min_fetch: usize) RangeReader

Sin ///.

bytes.RangeReader.deinit

fn · línea 243

pub fn deinit(self: *RangeReader) void

Sin ///.

bytes.RangeReader.bytes

fn · línea 255

pub fn bytes(self: *RangeReader, off: u64, n: usize) Error![]const u8

Slice of [off, off+n), valid until the next call. EndOfStream if the range leaves the file.

bytes.RangeReader.ahead

fn · línea 288

pub fn ahead(self: *RangeReader, off: u64, max_n: usize, min_n: usize) Error![]const u8

Forward scan view: [off, off+k) with min_n <= k <= max_n (fewer only if the file ends first: EndOfStream). Served from the window whenever it already holds min_n bytes from off; only otherwise one fetch at off. A scan that advances through this view therefore fetches each byte about once, however often it restarts a few bytes further on: what bytes(off, big) per restart does not (it refetches a whole window each time off + big passes the window end).

bytes.RangeReader.exact

fn · línea 303

pub fn exact(self: *RangeReader, off: u64, n: usize) Error![]const u8

Like bytes but never fetches more than asked (point reads far from the window, e.g. moof headers in fMP4).

bytes.MemSource

type · línea 313

pub const MemSource = struct

ByteSource over memory (tests and fuzzing). Counts reads so tests can assert how much of a file a probe touched.

bytes.MemSource.source

fn · línea 317

pub fn source(self: *MemSource) ByteSource

Sin ///.

bytes.unescapeNal

fn · línea 348

pub fn unescapeNal(dst: []u8, nal: []const u8) []u8

Removes emulation-prevention bytes (00 00 03) from a NAL into dst. If the NAL does not fit, returns the prefix that fits (the interesting fields are at the start; anything missing surfaces as EndOfStream).

ZC10-P1-01: the rule only asks "were the last two bytes 00 00?", so the state is a run length clamped at 2 (ZeroRun), not a count of the zeros in the file. It cannot overflow whatever the NAL holds; a u8 counter aborted the daemon (ReleaseSafe) on the 256th zero in a row.

ByteSource

type · línea 33

pub const ByteSource = struct

Sin ///.

ByteSource.VTable

type · línea 37

pub const VTable = struct

Sin ///.

ByteSource.size

fn · línea 44

pub fn size(self: ByteSource) u64

Sin ///.

ByteSource.read

fn · línea 48

pub fn read(self: ByteSource, offset: u64, dst: []u8, purpose: Purpose) ReadError!usize

Sin ///.

ByteSource.readAll

fn · línea 53

pub fn readAll(self: ByteSource, offset: u64, dst: []u8, purpose: Purpose) ReadError!usize

Reads until dst is full or EOF.

CancelToken

const · línea 66

pub const CancelToken = zkit.CancelToken

Per-request cancellation (r04 / r20 §3.6), set from another thread; every read of an engine checks it first.

facts.ReadStats

type · línea 215

pub const ReadStats = struct

Sin ///.

container.Error

const · línea 71

pub const Error = zkit.safety.bounded_reader.Error || error{ /// Invalid structure (impossible sizes, out-of-range values). Malformed, /// Not a supported container. UnknownFormat, /// Valid input usi …

Parser errors: the zkit.safety.BoundedReader / BitReader vocabulary (EndOfStream = a structure declares bytes beyond the file or its parent) plus the container's own. contract.fromParser maps them to EngineError.