Skip to content
Haiku OSDeep Dive Published Updated 7 min readViews unavailable

Haiku BMediaFormats: Format Mapping and Encoder Discovery

Use Haiku BMediaFormats and encoder enumeration to map media descriptions, negotiate accepted formats, and diagnose codec availability without guessing.

Haiku’s BMediaFormats and related Media Kit functions help applications map format descriptions to media_format values and discover encoders that accept compatible input and produce requested output. These APIs are useful at the boundary between a media graph and a file container. They do not make every codec available, validate every file, or guarantee that two format structures with similar labels are byte-compatible.

It helps to distinguish four layers. A media format describes data exchanged between nodes. A codec transforms data, such as raw samples into a compressed stream. A file format describes a container that organizes tracks and metadata. An add-on advertises and implements capabilities. BMediaFormats helps identify or create media-format mappings; encoder enumeration asks which encoders can satisfy format constraints. Mixing these layers leads to confusing menus and failed exports.

Map a description to a media format

BMediaFormats::GetFormatFor() maps a media_format_description to a media_format; GetCodeFor() performs the reverse mapping for a specified family. MakeFormatFor() registers or constructs a mapping, with flags such as exclusive registration and no-merge behavior. The public header specifically warns callers to zero-initialize description structures before filling them in, or bogus values may be registered. Follow that warning exactly: initialize the structure, set only documented fields, and validate all values.

Description families include different ways of identifying formats. A four-character code or vendor-specific value is not self-explanatory; it is meaningful only within its family. Preserve the family and code together. Do not reduce a format to a printable name and later reconstruct it from a guess. Names can be localized or duplicated, while the structured description is the programmatic identifier.

Treat registered format mappings as system/shared state managed by the Media Kit. Do not assume an application can permanently claim a format code or that registration is a private per-process setting. Use the flags only when your add-on has a specific, documented collision policy. B_EXCLUSIVE can make a duplicate fail; B_NO_MERGE asks not to renumber clashing prior registrations and to fail instead; B_SET_DEFAULT is specifically documented for encoder add-ons when choosing a default among several registrations. Those are consequential behaviors, not generic “safer” switches.

Enumerate encoders with concrete constraints

The get_next_encoder() overloads enumerate codec capabilities. The API documentation in the header says initialize the cookie to zero before the first call and treat B_BAD_INDEX as the end of enumeration. Overloads can filter by file format and input/output media_format; another can return all encoders without format restrictions. A constrained enumeration can specialize wildcards into accepted input and output formats.

Start with the application’s actual media input and desired output. Ask for an encoder that accepts the input format and produces a format the chosen container can store. Do not populate an export menu by enumerating every encoder and assuming all are compatible with the current track. A codec can exist yet be unusable for that container, input bit depth, color space, or channel layout.

The cookie is iteration state. Keep it local to one enumeration pass, initialize it to zero, and do not reuse a cookie across different constraints unless the API explicitly supports that. Check each status and stop on the documented end condition. An error other than end-of-enumeration should be visible in diagnostics; silently presenting partial results as complete can mislead users.

An outline for iterating all encoders is:

int32 cookie = 0;
media_codec_info info;
status_t status;

while ((status = get_next_encoder(&cookie, &info)) == B_OK) {
    // Keep the stable codec identity and display name for this session.
}

if (status != B_BAD_INDEX) {
    // Report an enumeration error rather than treating it as normal EOF.
}

Use the overload with an input format, output format, and file-format constraint when deciding whether a concrete export can run. The outline intentionally does not create a file or configure a media node; enumeration is discovery, not encoder instantiation.

Wildcards are negotiation tools, not actual payloads

Wildcards let an API describe constraints before a final concrete format has been selected. Once negotiation completes, the pipeline must use the accepted concrete format to calculate bytes, buffer durations, and conversion steps. Do not write data while important fields remain wildcarded. A wildcard is not a request to reinterpret the same bytes in whichever format a codec later chooses.

For example, sample rate, channel count, sample format, video dimensions, color space, field rate, and encoded output parameters can all affect memory layout or codec behavior. Validate the returned accepted formats and create a converter node if the pipeline needs one. If no encoder accepts the pair, explain which constraint failed and offer supported alternatives rather than changing the file extension.

The output format returned by encoder discovery must be compatible with the file format’s capabilities. Container metadata can carry information not present in the elementary coded stream. Validate both the codec and container combination, including timestamps, track count, and metadata requirements. An encoder title alone is not proof of a valid muxing path.

Format descriptions are not MIME security checks

Format mapping and codec discovery identify supported media conventions. They do not establish that an input file is well-formed or safe. A decoder must still validate lengths, offsets, sample counts, dimensions, nesting, and resource use before allocating or reading. Treat files from untrusted sources as hostile input. Do not trust file extensions, MIME labels, or a successful format lookup to bypass parser validation.

When adding an encoder or file-format add-on, publish only formats the implementation actually supports. Test malformed headers, truncated payloads, extreme dimensions, and integer overflow. Set bounds for memory, decode time, and output size. A capability advertised in the registry makes it discoverable; it also creates a compatibility expectation for applications.

Registration and enumeration state

BMediaFormats exposes RewindFormats() and GetNextFormat() for iterating registered formats, plus Lock() and Unlock(). The header comments that callers need the lock only when using that iteration pair. Keep the critical section short and always unlock, including on errors. Do not hold the format lock while showing UI or performing file I/O.

Format registration can be affected by other add-ons and system state. Applications should refresh discovery at an appropriate boundary and should not cache a “codec exists” conclusion indefinitely across media-service restarts or add-on changes. If a codec disappears between listing and activation, handle the instantiation failure and let the user choose another path.

Use stable IDs for internal settings only when the API guarantees their scope. The media_codec_info structure contains IDs passed to file track creation; those values belong to the active format/add-on contract. Do not serialize them as globally permanent identifiers without verifying the add-on versioning and persistence requirements. Persist enough information to re-resolve user intent, then enumerate and match capabilities again.

Diagnostics for export problems

Record the requested input and output format fields, file format, enumerated codec names and IDs, selected encoder, accepted format returned by negotiation, and the status from each registration or enumeration call. Separate “no matching encoder” from “encoder found but node creation failed” and “node ran but muxer rejected the track.” Each failure sits at a different layer.

Test machines with different add-on sets and test after installing or removing a codec. Include wildcard constraints, exact constraints, unsupported combinations, duplicate registrations, and iteration errors. Confirm that the UI reports a useful no-match state instead of offering an export that predictably fails.

Acceptance criteria

A correct integration zero-initializes format descriptions, preserves the family/code identity, enumerates with a fresh cookie, distinguishes normal end from error, and checks the negotiated concrete formats before processing bytes. It treats encoder discovery, node creation, codec execution, and container writing as separate stages. It remains bounded when input metadata is malformed or dimensions are unreasonable.

For an encoder add-on, every registered mapping and flavor should correspond to a tested implementation. Duplicate/collision behavior should be deliberate, and B_SET_DEFAULT should be used only where the header documents it. The output should reopen successfully in an independent reader and should preserve the media properties promised by the UI.

BMediaFormats is most useful when treated as a structured mapping service, not a magic codec switch. Pairing exact format descriptions with constrained encoder discovery gives applications a precise way to explain compatibility and makes export failures diagnosable across different Haiku installations.

Related:

Sources:

Comments