diff --git a/docs/design.md b/docs/design.md deleted file mode 100644 index f85a81e881..0000000000 --- a/docs/design.md +++ /dev/null @@ -1,239 +0,0 @@ -#Design overview# - -Major modules are described below: - -Demuxer is responsible for extracting elementary stream samples from a -multimedia file, e.g. an ISO BMFF file. The demuxed streams can be fed into a -muxer to generate multimedia files. An optional KeySource can be provided to -Demuxer to decrypt CENC and WVM source content. - -Demuxer reads from source through the File interface. A concrete LocalFile -class is already implemented. The users may also implement their own File class -if they want to read/write using a different kinds of protocol, e.g. network -storage, http etc. - -Muxer is responsible for taking elementary stream samples and producing media -segments. An optional KeySource can be provided to Muxer to generate encrypted -outputs. Muxer writes to output using the same File interface as Demuxer. - -Demuxer and Muxer are connected using MediaStream. MediaStream wraps the -elementary streams and is responsible for the interaction between Demuxer and -Muxer. A demuxer can transmits multiple MediaStreams; similarly, A muxer is -able to accept and mux multiple MediaStreams, not necessarily from the same -Demuxer. - -MpdBuilder is responsible for the creation of Media Presentation Description as -specified in ISO/IEC 23009-1 DASH MPD spec. - -API document is available at https://google.github.io/shaka-packager/docs. - -##Creating Demuxer## - -```C++ -// Create a demuxer from |input_media_file|. -// |input_media_file| could be any supported files, e.g. if the users have -// implemented a network file interface with prefix “network”, -// |input_media_file| with value “network://xxxx” would open a network -// file automatically. -Demuxer demuxer(input_media_file); -``` - -##Creating KeySource for source content decryption## - -```C++ -// A KeySource is required if the source content is encrypted, since the media -// must be decrytped prior to further processing. -``` - -###WidevineKeySource### - -```C++ -// Users may use WidevineKeySource to fetch keys from Widevine -// common encryption server. - -scoped_ptr widevine_decryption_key_source( - new WidevineKeySource(key_server_url)); - -// A request signer might be required to sign the common encryption request. -scoped_ptr signer( - RsaRequestSigner::CreateSigner(signer_name, pkcs1_rsa_private_key)); -if (!signer) { … } -widevine_decryption_key_source->set_signer(signer.Pass()); - -// Set encryption key source to demuxer. -muxer->SetKeySource(widevine_decryption_key_source.Pass()); -``` - - -##Creating MpdBuilder## - -```C++ -// |mpd_type| indicates whether the mpd should be for VOD or live profile. -// |mpd_options| contains a set of configurable options. See below for details. -MpdBuilder mpd_builder(mpd_type, mpd_options); -``` - -Mpd Options -```C++ -// Specifies, in seconds, a common duration used in the definition of the MPD -// Representation data rate. -mpd_options.min_buffer_time = 5.0; - -// The below options are for live profile only. - -// Indicates to the player how often to refresh the media presentations, in -// seconds. -mpd_options.minimum_update_period = 5.0; - -// Guranteed duration of the time shifting buffer, in seconds. -mpd_options.time_shift_buffer_depth = 1800.0; - -// Specifies a delay, in seconds, to be added to the media presentation time. -mpd_options.suggested_presentation_delay = 10.0; -``` - -Using MpdBuilder Instance -```C++ -mpd_builder.AddBaseUrl("http://foo.com/bar"); // Add a element. -AdaptationSet* video_adaptation_set = mpd_builder.AddAdaptationSet(); - -// Create MediaInfo object. -Representation* representation = - video_adaptation_set->AddRepresentation(media_info_object); -assert(representation); // Make sure it succeeded. -// |representation| is owned by |video_adatptation_set|, no additional -// operations are required to generate a valid MPD. - -std::cout << mpd_builder.ToString() << std::endl; // Print the MPD to stdout. -``` - -MpdWriter: MpdBuilder Wrapper class -```C++ -// Get file names with MediaInfo protobuf, i.e. media_info_files (array). -MpdWrite mpd_writer; -for (size_t i = 0; i < n; ++i) - mpd_writer.AddFile(media_info_files[i]); - -mpd_writer.WriteMpdToFile("output_file_name.mpd"); -``` - -##Creating Muxer## - -```C++ -// See below for muxer options. -MuxerOptions muxer_options; - -// Create a MP4Muxer with options specified by |options|. -mp4::MP4Muxer muxer(muxer_options); -``` - -Muxer Options -```C++ -// Generate a single segment for each media presentation. This option -// should be set for on demand profile. -muxer_options.single_segment = true; - -// Segment duration in seconds. If single_segment is specified, this parameter -// sets the duration of a subsegment; otherwise, this parameter sets the -// duration of a segment. A segment can contain one to many fragments. -muxer_options.segment_duration = 10.0; - -// Fragment duration in seconds. Should not be larger than the segment -// duration. -muxer_options.fragment_duration = 2.0; - -// Force segments to begin with stream access points. Segment duration may -// not be exactly what asked by segment_duration. -muxer_options.segment_sap_aligned = true; - -// Force fragments to begin with stream access points. Fragment duration -// may not be exactly what asked by segment_duration. Imply -// segment_sap_aligned. -muxer_options.fragment_sap_aligned = true; - -// For ISO BMFF only. -// Set the number of subsegments in each SIDX box. If 0, a single SIDX box -// is used per segment. If -1, no SIDX box is used. Otherwise, the Muxer -// will pack N subsegments in the root SIDX of the segment, with -// segment_duration/N/fragment_duration fragments per subsegment. -muxer_options.num_subsegments_per_sidx = 1; - -// Output file name. If segment_template is not specified, the Muxer -// generates this single output file with all segments concatenated; -// Otherwise, it specifies the init segment name. -muxer_options.output_file_name = …; - -// Specify output segment name pattern for generated segments. It can -// furthermore be configured by using a subset of the SegmentTemplate -// identifiers: $RepresentationID$, $Number$, $Bandwidth$ and $Time$. -// Optional. -muxer_options.segment_template = …; - -// Specify the temporary directory for intermediate files. -muxer_options.temp_dir = …; - -// User specified bit rate for the media stream. If zero, the muxer will -// attempt to estimate. -muxer_options.bandwidth = 0; -``` - -##Creating KeySource for content encryption## - -```C++ -// A KeySource is optional. The stream won’t be encrypted if an -// KeySource is not provided. -``` - -###WidevineKeySource### - -```C++ -// Users may use WidevineKeySource to fetch keys from Widevine -// common encryption server. - -scoped_ptr widevine_encryption_key_source( - new WidevineKeySource(key_server_url, signer.Pass())); - -// A request signer might be required to sign the common encryption request. -scoped_ptr signer( - RsaRequestSigner::CreateSigner(signer_name, pkcs1_rsa_private_key)); -if (!signer) { … } -widevine_encryption_key_source->set_signer(signer.Pass()); - -// Grab keys for the content. -status = widevine_encryption_key_source->FetchKeys(content_id, policy)); -if (!status.ok()) { … } - -// Set encryption key source to muxer. -// |max_sd_pixels| defines the threshold to determine whether a video track -// should be considered as SD or HD and accordingly, whether SD key or HD key -// should be used to encrypt the stream. -// |clear_lead| specifies clear lead duration in seconds. -// |crypto_period_duration| if not zero, enable key rotation with specified -// crypto period. -muxer->SetKeySource( - widevine_encryption_key_source.get(), max_sd_pixels, - clear_lead, crypto_period_duration); -``` - -##Connecting Demuxer and Muxer## - -```C++ - // Initialize the demuxer. - status = demuxer.Initialize(); - if (!status.ok()) { … } - - // After intializing the demuxer, we can query demuxer streams - // using demuxer.streams(). - // The function below adds the first stream into muxer, which sets up - // the connection between Demuxer and Muxer. - status = muxer.AddStream(demuxer.streams()[0]); - if (!status.ok()) { … } -``` - -##Starting Remuxing## - -```C++ - // Starts remuxing process. It runs until completion or abort due to error. - status = demuxer.Run(); - if (!status.ok()) { … } -``` diff --git a/docs/source/conf.py b/docs/source/conf.py index fffeb7f82a..44bed1fc64 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -35,6 +35,7 @@ extensions = ['sphinx.ext.autodoc', 'sphinx.ext.mathjax', 'sphinx.ext.viewcode', 'sphinx.ext.githubpages', + 'sphinxcontrib.plantuml', 'cloud_sptheme.ext.table_styling', 'breathe'] diff --git a/docs/source/design.rst b/docs/source/design.rst new file mode 100644 index 0000000000..d960d11196 --- /dev/null +++ b/docs/source/design.rst @@ -0,0 +1,131 @@ +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] + } + + 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} + } + } + +.. graphviz:: + + digraph shaka_packager { + 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] + } + } + +.. graphviz:: + + digraph shaka_packager { + 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] + } + } + +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 : ... diff --git a/docs/source/index.rst b/docs/source/index.rst index 1dd070ed8f..f2cdb5f20e 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -13,6 +13,7 @@ source code repository: https://github.com/google/shaka-packager documentation.rst tutorials/tutorials.rst + design.rst library.rst .. include a hidden TOC to avoid sphinx complaint. @@ -20,7 +21,6 @@ source code repository: https://github.com/google/shaka-packager :hidden: build_instructions.md - design.rst docker_instructions.md library_details.rst tutorials/encoding.rst