O
Sections
Every group

Document

The arena that owns every object in a timeline.

Symbols in this group are spelled otio_document_…. An SDK drops that prefix, which is why the name beside each call is the short one.

absorb

method

Moves every object out of one document into another.

This is the call that lets a binding offer the API OpenTimelineIO's own Python and C++ users expect, where a `Clip` is built on its own and put inside a `Track` afterwards. An arena has no way to do that with handles alone: a handle means nothing outside the document it was issued for, so an object built in one document has to be *moved* into the other rather than pointed at. Upstream's reference-counted object model gets this for free and pays for it elsewhere; see `docs/adr/0001-ownership-model.md`.

`source` is consumed. On success it is released and the caller's pointer is set to null, so there is nothing left to free and no way to free it twice. On failure nothing moves and the pointer is left alone. A document cannot absorb itself: a `source` that points at `target` is `OTIO_STATUS_INVALID_ARGUMENT`.

The source's root is not adopted, because the target has its own.

# The translation

Every object arrives under a new handle, so every handle the caller still holds into `source` has to be translated. The call fills `out_from` and `out_to` with the old handle and the new one for each object moved, in the same order, and writes how many pairs there are to `out_count`.

Unlike the other calls that answer with a list, this one cannot be asked twice to size the buffer: the first call would already have consumed the source. Size the arrays with [`otio_document_node_count`] on the source before calling, which is exactly how many objects will move. A capacity smaller than that is `OTIO_STATUS_INVALID_ARGUMENT`, and nothing moves.

# Example

```c size_t moving = otio_document_node_count(clip_document); OtioNode *from = malloc(moving * sizeof(OtioNode)); OtioNode *to = malloc(moving * sizeof(OtioNode)); size_t moved = 0; otio_document_absorb(timeline_document, &clip_document, from, to, moving, &moved, std::ptr::null_mut()); /* `clip_document` is now NULL; `clip` is `to[i]` where `from[i]` is `clip`. */ ```

 *     otio_document_absorb(timeline_document, &clip_document, from, to, moving, &moved);
ParameterTypeRole
targetdocumentthe document, changed
source ?documentthe document, consumed
out_from ?list<node>a list written through, sized by the count
out_to ?list<node>a list written through, sized by the count
capacitysizehow many the buffer can hold
out_countsizehow many the call had to give
out_errortextwhy the call failed, or null to skip it

clone

getter

Copies a document, objects and all.

The copy keeps the arena's layout, so a handle into the original, passed with the copy, names the copy of the same object. The two documents are independent afterwards: an object added to or removed from one is not added to or removed from the other, and a handle issued by one after the copy means nothing in the other.

OtioStatus otio_document_clone(
    const OtioDocument *source,
    OtioDocument **out_document,
    OtioBuffer *out_error);
ParameterTypeRole
source ?documentthe document, borrowed
out_documentdocumentwritten through, not read
out_errortextwhy the call failed, or null to skip it

contains

method

Returns whether a handle still names a live object.

bool otio_document_contains(const OtioDocument *source, OtioNode node);
ParameterTypeRole
source ?documentthe document, borrowed
nodenodeinput

deep_clone

method

Copies an object and everything it owns, into the same document.

The copy has no parent, whatever the original had.

OtioStatus otio_document_deep_clone(
    OtioDocument *target,
    OtioNode node,
    OtioNode *out_node,
    OtioBuffer *out_error);
ParameterTypeRole
targetdocumentthe document, changed
nodenodeinput
out_nodenodewritten through, not read
out_errortextwhy the call failed, or null to skip it

free

plumbing

Releases a document and every object in it.

Passing null does nothing. Every handle into the document is stale afterwards; using one is a programming error this library cannot detect, because the arena it would be checked against is gone.

 *     otio_document_free(document);
ParameterTypeRole
document ?documentthe document, changed

from_json

constructor

Reads a document from OTIO JSON.

OtioStatus otio_document_from_json(
    const char *json,
    OtioDocument **out_document,
    OtioBuffer *out_error);
ParameterTypeRole
jsontextinput
out_documentdocumentwritten through, not read
out_errortextwhy the call failed, or null to skip it

new

constructor

Creates an empty document with no root.

Returns null only if the allocation fails. Release it with [`otio_document_free`].

OtioDocument *otio_document_new(void);

node_count

getter

Returns how many live objects the document holds.

size_t otio_document_node_count(const OtioDocument *source);
ParameterTypeRole
source ?documentthe document, borrowed

read_otio_file

constructor

Reads a document from a `.otio` file on disk.

A build without a file system, such as one for WebAssembly, reports `OTIO_STATUS_UNSUPPORTED`; use [`otio_document_from_json`] there.

OtioStatus otio_document_read_from_file(
    const char *path,
    OtioDocument **out_document,
    OtioBuffer *out_error);
ParameterTypeRole
pathtextinput
out_documentdocumentwritten through, not read
out_errortextwhy the call failed, or null to skip it

remove_node

method

Removes one object from the document.

Anything that referred to it still holds a handle, and that handle is now stale: a lookup fails rather than reaching whatever takes the slot next. To remove an object together with everything hanging off it, use [`otio_document_remove_recursive`].

OtioStatus otio_document_remove(
    OtioDocument *target,
    OtioNode node,
    OtioBuffer *out_error);
ParameterTypeRole
targetdocumentthe document, changed
nodenodeinput
out_errortextwhy the call failed, or null to skip it

remove_node_recursive

method

Removes an object and everything it owns: children, markers, effects and media references.

OtioStatus otio_document_remove_recursive(
    OtioDocument *target,
    OtioNode node,
    OtioBuffer *out_error);
ParameterTypeRole
targetdocumentthe document, changed
nodenodeinput
out_errortextwhy the call failed, or null to skip it

root

gettermay answer nothing

Returns the document's root object.

Reports `OTIO_STATUS_NO_VALUE` for a document that has none, which is what a freshly created one is.

 *     otio_document_root(document, &timeline, NULL);
ParameterTypeRole
source ?documentthe document, borrowed
out_nodenodewritten through, not read
out_errortextwhy the call failed, or null to skip it

set_root

setter

Sets the document's root object.

Passing `otio_node_none` clears it.

OtioStatus otio_document_set_root(
    OtioDocument *target,
    OtioNode node,
    OtioBuffer *out_error);
ParameterTypeRole
targetdocumentthe document, changed
node ?nodeinput
out_errortextwhy the call failed, or null to skip it

to_json

method

Writes a document as OTIO JSON, starting from its root.

`indent` is how many spaces each level is indented by; [`otio_default_indent`] is what upstream's Python bindings use.

OtioStatus otio_document_to_json(
    const OtioDocument *source,
    size_t indent,
    OtioBuffer *out_json,
    OtioBuffer *out_error);
ParameterTypeRole
source ?documentthe document, borrowed
indentsizeinput
out_jsontextwritten through, not read
out_errortextwhy the call failed, or null to skip it

write_otio_file

method

Writes a document to a `.otio` file on disk.

A build without a file system, such as one for WebAssembly, reports `OTIO_STATUS_UNSUPPORTED`; use [`otio_document_to_json`] there.

OtioStatus otio_document_write_to_file(
    const OtioDocument *source,
    const char *path,
    size_t indent,
    OtioBuffer *out_error);
ParameterTypeRole
source ?documentthe document, borrowed
pathtextinput
indentsizeinput
out_errortextwhy the call failed, or null to skip it