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