Timing resolution and consumer logic¶
EBU-TT part 3 deals with sequences of documents and creates a single timeline/sequence where document begin and end events are kept. Resolving this takes resolving the document timings first. After each document’s internal timing relationships have been worked out the document is inserted into the timeline where possible collisions are detected and resolved with the possible discarding of documents in the process.
Document Timings¶
The document timing resolution logic is built using the validation framework and mostly is in
ebu_tt_live.bindings.validation.TimingValidationMixin
The approach is that the element timing semantics require parent and children derived information to calculate begin and end events on an absolute timeline. For this we hook into the Depth First Search that the validation framework uses to process element validation. It is very important to note that the begin and end times can be calculated either as the algorithm cascades down or on its way up in case information derived from children is required.
The classes involved in the timing resolution are in the diagram below. For every type of element in the XSD there is a python binding class defined. For the sake of simplicity the diagram only contains a fraction of them to provide enough context but omits the parts that are irrelevant to the timing resolution logic.
The functions ebu_tt_live.bindings.validation.base.SemanticDocumentMixin._semantic_before_validation()
and
ebu_tt_live.bindings.validation.base.SemanticDocumentMixin._semantic_after_validation()
are hooks that run
before and after the Depth First Search traversal of the content tree.
The ebu_tt_live.bindings.validation.base.SemanticValidationMixin._semantic_before_traversal()
and
ebu_tt_live.bindings.validation.base.SemanticValidationMixin._semantic_after_traversal()
are element hooks,
which are called before the traversal logic gets to the element and after the traversal logic has finished processing
the children of the element in question. Types that subclass these mixins should override these functions to provide
their own customized hook behaviour. In the case of timing resolution another mixin,
ebu_tt_live.bindings.validation.base.TimingValidationMixin
is involved, which encapsulates the functions
used to process begin and end attributes. In order for a particular element type to gain timing resolution
capability it needs to subclass TimingValidationMixin and SemanticValidationMixin and it must have begin and end
attributes capability. Then it should implement _semantic_before_traversal and _semantic_after_traversal functions
and call the ebu_tt_live.bindings.validation.timing.TimingValidationMixin._semantic_preprocess_timing
in the before traversal and
ebu_tt_live.bindings.validation.timing.TimingValidationMixin._semantic_postprocess_timing
in the after
traversal hook. The following code sample is from the implementation of the div_type class.
def _semantic_before_traversal(self, dataset, element_content=None, parent_binding=None):
self._semantic_register_id(dataset=dataset)
self._semantic_timebase_validation(dataset=dataset, element_content=element_content)
self._semantic_preprocess_timing(dataset=dataset, element_content=element_content)
self._semantic_set_region(dataset=dataset, region_type=region_type)
self._semantic_collect_applicable_styles(
dataset=dataset, style_type=style_type, parent_binding=parent_binding, defer_font_size=True
)
self._semantic_push_styles(dataset=dataset)
def _semantic_after_traversal(self, dataset, element_content=None, parent_binding=None):
self._semantic_postprocess_timing(dataset=dataset, element_content=element_content)
self._semantic_unset_region(dataset=dataset)
In the following sequence diagram we traverse the document structure depicted in the first figure of this page and process the timings.
Sequence Timings¶
The sequence timings are handled by the ebu_tt_live.documents.ebutt3.EBUTT3DocumentSequence
class.
The document is inserted into the sequence after it is validated. The sequence looks at the computed begin and
end times and detects collisions. If there are any, the collisions are resolved by the logic starting in
ebu_tt_live.documents.ebutt3.EBUTT3DocumentSequence._insert_or_discard()