Design
======
Architecture diagram
--------------------
.. graphviz::
digraph shaka_packager {
label=<Shaka Packager Architecture>
labelloc=t
subgraph cluster_media {
label=<Media Processing Pipeline>
Demuxer, ChunkingHandler, EncryptionHandler, Replicator,
TrickplayHandler, Muxer [shape=rectangle]
Demuxer -> ChunkingHandler [style=bold headlabel="many" taillabel="1"]
ChunkingHandler -> EncryptionHandler -> Replicator -> TrickplayHandler
-> Muxer [style=bold]
ChunkingHandler -> Replicator -> Muxer [style=bold]
subgraph cluster_demuxer {
style=rounded
label=< >
Demuxer2 [label="Demuxer" shape=rectangle]
Demuxer2 -> MediaParser
[dir=back arrowtail=diamond headlabel="1" taillabel="1"]
MediaParser -> Mp4MediaParser, WebMMediaParser, Mp2tMediaParser,
WvmMediaParser [dir=back arrowtail=onormal]
}
subgraph cluster_muxer {
style=rounded
label=< >
Muxer2 [label="Muxer" shape=rectangle]
Muxer2 -> Mp4Muxer, WebMMuxer, Mp2tMuxer [dir=back arrowtail=onormal]
}
# Hack to place cluster_muxer subgraph below cluster_demuxer subgraph.
WebMMediaParser, Mp2tMediaParser -> Muxer2
[style=invisible arrowhead=none]
}
MuxerListener, MpdNotifyMuxerListener, HlsNotifyMuxerListener,
MpdNotifier, HlsNotifier [shape=rectangle style=rounded]
Muxer -> MuxerListener
MuxerListener -> MpdNotifyMuxerListener, HlsNotifyMuxerListener
[dir=back arrowtail=onormal]
subgraph cluster_manifest {
label=<Manifest Generation>
HlsNotifyMuxerListener -> HlsNotifier [headlabel="1" taillabel="many"]
MpdNotifyMuxerListener -> MpdNotifier [headlabel="1" taillabel="many"]
MasterPlaylist, MediaPlaylist, MpdBuilder, AdaptationSet,
Representation [shape=trapezium]
HlsNotifier -> MasterPlaylist
MasterPlaylist -> MediaPlaylist
[dir=back arrowtail=diamond headlabel="many" taillabel="1"]
MpdNotifier -> MpdBuilder
MpdBuilder -> AdaptationSet -> Representation
[dir=back arrowtail=diamond headlabel="many" taillabel="1"]
{rank=same; MasterPlaylist, MpdBuilder}
{rank=same; MediaPlaylist, Representation}
}
subgraph cluster_legend {
style=rounded
label=<Legend>
node [shape=plaintext]
blank1 [label="" height=0]
blank2 [label="" height=0]
blank3 [label="" height=0]
"Composition" -> blank1 [dir=back arrowtail=diamond]
"Inheritance" -> blank2 [dir=back arrowtail=onormal]
"MediaHandler data flow" -> blank3 [style=bold]
"Bridge Class" [shape=rectangle style=rounded]
"Manifest Class" [shape=trapezium]
MediaHandler [shape=rectangle]
}
# Hack to place legend subgraph in the bottom.
MediaPlaylist -> MediaHandler [style=invisible arrowhead=none]
}
Media handler data flow
-----------------------
.. graphviz::
digraph g {
rankdir=LR
StreamData [
label="{... | SegmentInfo | MediaSample ... | SegmentInfo | MediaSample ... | StreamInfo}"
shape=record
style=rounded
];
MediaHandler [shape=rectangle]
MediaHandler2 [shape=rectangle, label=MediaHandler]
MediaHandler -> StreamData -> MediaHandler2
}
.. uml::
MediaHandler -> MediaHandler2 : StreamInfo
MediaHandler -> MediaHandler2 : MediaSample
MediaHandler -> MediaHandler2 : MediaSample
MediaHandler -> MediaHandler2 : ...
MediaHandler -> MediaHandler2 : MediaSample
MediaHandler -> MediaHandler2 : SegmentInfo
MediaHandler -> MediaHandler2 : MediaSample
MediaHandler -> MediaHandler2 : MediaSample
MediaHandler -> MediaHandler2 : ...
MediaHandler -> MediaHandler2 : MediaSample
MediaHandler -> MediaHandler2 : SegmentInfo
MediaHandler -> MediaHandler2 : ...
Demuxer
^^^^^^^
.. graphviz::
digraph g {
rankdir=LR
StreamData [
label="{MediaSample ... | StreamInfo}", shape=record, style=rounded
]
StreamData2 [
label="{MediaSample ... | StreamInfo}", shape=record, style=rounded
]
Demuxer [shape=rectangle]
Demuxer -> StreamData
Demuxer -> StreamData2
}
.. uml::
Demuxer -> : StreamInfo
Demuxer -> : MediaSample
Demuxer -> : MediaSample
Demuxer -> : ...
ChunkingHandler
^^^^^^^^^^^^^^^
.. graphviz::
digraph g {
rankdir=LR
StreamDataIn [
label="{MediaSample ... | StreamInfo}", shape=record, style=rounded
]
StreamDataOut [
label="{SegmentInfo | MediaSample ... | StreamInfo}"
shape=record
style=rounded
]
ChunkingHandler [shape=rectangle]
StreamDataIn -> ChunkingHandler -> StreamDataOut
}
.. uml::
-> ChunkingHandler : StreamInfo
ChunkingHandler -> : StreamInfo
-> ChunkingHandler : MediaSample
ChunkingHandler -> : MediaSample
-> ChunkingHandler : ...
ChunkingHandler -> : ...
-> ChunkingHandler : MediaSample
ChunkingHandler -> : MediaSample
ChunkingHandler -> : SegmentInfo
-> ChunkingHandler : ...
ChunkingHandler -> : ...
Manifest generation event flow
------------------------------
DASH On Demand
^^^^^^^^^^^^^^
.. uml::
alt stream is encrypted
Muxer -> MuxerListener : OnEncryptionInfoReady
MuxerListener -> MuxerListener : Cache EncryptionInfo
end
Muxer -> MuxerListener : OnMediaStart
MuxerListener -> MuxerListener : Cache MediaInfo
alt segment is not encrypted
Muxer -> MuxerListener : OnNewSegment ...
MuxerListener -> MuxerListener : Cache SegmentInfo
Muxer -> MuxerListener : OnNewSegment N-1
MuxerListener -> MuxerListener : Cache SegmentInfo
end
alt segment is encrypted
Muxer -> MuxerListener : OnEncryptionStart
Muxer -> MuxerListener : OnNewSegment N
MuxerListener -> MuxerListener : Cache SegmentInfo
Muxer -> MuxerListener : OnNewSegment ...
MuxerListener -> MuxerListener : Cache SegmentInfo
alt encryption key changes
Muxer -> MuxerListener : OnEncryptionInfoReady
MuxerListener -> MpdNotifier : NotifyEncryptionUpdate
Muxer -> MuxerListener : OnNewSegment N+k
MuxerListener -> MuxerListener : Cache SegmentInfo
Muxer -> MuxerListener : OnNewSegment ...
MuxerListener -> MuxerListener : Cache SegmentInfo
end
end
Muxer -> MuxerListener : OnMediaEnd
MuxerListener -> MpdNotifier : NotifyNewContainer
MuxerListener -> MpdNotifier : NotifyNewSegment ...
MuxerListener -> MpdNotifier : NotifyNewSegment N
MuxerListener -> MpdNotifier : NotifyNewSegment N+1
MuxerListener -> MpdNotifier : NotifyNewSegment ...
MuxerListener -> MpdNotifier : Flush
DASH Live
^^^^^^^^^
.. uml::
alt stream is encrypted
Muxer -> MuxerListener : OnEncryptionInfoReady
MuxerListener -> MuxerListener : Cache EncryptionInfo
end
Muxer -> MuxerListener : OnMediaStart
MuxerListener -> MpdNotifier : NotifyNewContainer
alt segment is not encrypted
Muxer -> MuxerListener : OnNewSegment ...
MuxerListener -> MpdNotifier : NotifyNewSegment ...
Muxer -> MuxerListener : OnNewSegment N-1
MuxerListener -> MpdNotifier : NotifyNewSegment N-1
end
alt segment is encrypted
Muxer -> MuxerListener : OnEncryptionStart
Muxer -> MuxerListener : OnNewSegment N
MuxerListener -> MpdNotifier : NotifyNewSegment N
Muxer -> MuxerListener : OnNewSegment ...
MuxerListener -> MpdNotifier : NotifyNewSegment ...
alt encryption key changes
Muxer -> MuxerListener : OnEncryptionInfoReady
MuxerListener -> MpdNotifier : NotifyEncryptionUpdate
Muxer -> MuxerListener : OnNewSegment N+k
MuxerListener -> MpdNotifier : NotifyNewSegment N+k
Muxer -> MuxerListener : OnNewSegment ...
MuxerListener -> MpdNotifier : NotifyNewSegment ...
end
end
Muxer -> MuxerListener : OnMediaEnd
MuxerListener -> MpdNotifier : Flush
HLS Single-segment
^^^^^^^^^^^^^^^^^^
.. uml::
alt stream is encrypted
Muxer -> MuxerListener : OnEncryptionInfoReady
MuxerListener -> MuxerListener : Cache EncryptionInfo
end
Muxer -> MuxerListener : OnMediaStart
MuxerListener -> MuxerListener : Cache MediaInfo
alt segment is not encrypted
Muxer -> MuxerListener : OnNewSegment ...
MuxerListener -> MuxerListener : Cache SegmentInfo
Muxer -> MuxerListener : OnNewSegment N-1
MuxerListener -> MuxerListener : Cache SegmentInfo
end
alt segment is encrypted
Muxer -> MuxerListener : OnEncryptionStart
Muxer -> MuxerListener : OnNewSegment N
MuxerListener -> MuxerListener : Cache SegmentInfo
Muxer -> MuxerListener : OnNewSegment ...
MuxerListener -> MuxerListener : Cache SegmentInfo
alt encryption key changes
Muxer -> MuxerListener : OnEncryptionInfoReady
MuxerListener -> HlsNotifier : Cache EncryptionInfo
Muxer -> MuxerListener : OnNewSegment N+k
MuxerListener -> MuxerListener : Cache SegmentInfo
Muxer -> MuxerListener : OnNewSegment ...
MuxerListener -> MuxerListener : Cache SegmentInfo
end
end
Muxer -> MuxerListener : OnMediaEnd
MuxerListener -> HlsNotifier : NotifyNewStream
alt stream is encrypted
MuxerListener -> HlsNotifier : NotifyEncryptionUpdate
end
MuxerListener -> HlsNotifier : NotifyNewSegment ...
MuxerListener -> HlsNotifier : NotifyNewSegment N
MuxerListener -> HlsNotifier : NotifyNewSegment N+1
MuxerListener -> HlsNotifier : NotifyNewSegment ...
HLS Multi-segment
^^^^^^^^^^^^^^^^^
.. uml::
alt stream is encrypted
Muxer -> MuxerListener : OnEncryptionInfoReady
MuxerListener -> MuxerListener : Cache EncryptionInfo
end
Muxer -> MuxerListener : OnMediaStart
MuxerListener -> HlsNotifier : NotifyNewStream
alt segment is not encrypted
Muxer -> MuxerListener : OnNewSegment ...
MuxerListener -> HlsNotifier : NotifyNewSegment ...
Muxer -> MuxerListener : OnNewSegment N-1
MuxerListener -> HlsNotifier : NotifyNewSegment N-1
end
alt segment is encrypted
Muxer -> MuxerListener : OnEncryptionStart
MuxerListener -> HlsNotifier : NotifyEncryptionUpdate
Muxer -> MuxerListener : OnNewSegment N
MuxerListener -> HlsNotifier : NotifyNewSegment N
Muxer -> MuxerListener : OnNewSegment ...
MuxerListener -> HlsNotifier : NotifyNewSegment ...
alt encryption key changes
Muxer -> MuxerListener : OnEncryptionInfoReady
MuxerListener -> HlsNotifier : NotifyEncryptionUpdate
Muxer -> MuxerListener : OnNewSegment N+k
MuxerListener -> HlsNotifier : NotifyNewSegment N+k
Muxer -> MuxerListener : OnNewSegment ...
MuxerListener -> HlsNotifier : NotifyNewSegment ...
end
end
Muxer -> MuxerListener : OnMediaEnd