Added architecture diagram
Also remove outdated design.md. Change-Id: I237b374a2fffe348b1daf5f8d1c37c57b4898fde
This commit is contained in:
parent
068e220ac7
commit
75e1fc3175
239
docs/design.md
239
docs/design.md
|
@ -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<WidevineKeySource> widevine_decryption_key_source(
|
||||
new WidevineKeySource(key_server_url));
|
||||
|
||||
// A request signer might be required to sign the common encryption request.
|
||||
scoped_ptr<RequestSigner> 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 <BaseURL> 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<WidevineKeySource> 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<RequestSigner> 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()) { … }
|
||||
```
|
|
@ -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']
|
||||
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
Design
|
||||
======
|
||||
|
||||
Architecture diagram
|
||||
--------------------
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph shaka_packager {
|
||||
label=<<u>Shaka Packager Architecture</u>>
|
||||
labelloc=t
|
||||
|
||||
subgraph cluster_media {
|
||||
label=<<u>Media Processing Pipeline</u>>
|
||||
|
||||
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=<<u>Manifest Generation</u>>
|
||||
|
||||
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=<<u> </u>>
|
||||
|
||||
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=<<u> </u>>
|
||||
|
||||
Muxer2 [label="Muxer" shape=rectangle]
|
||||
Muxer2 -> Mp4Muxer, WebMMuxer, Mp2tMuxer [dir=back arrowtail=onormal]
|
||||
}
|
||||
}
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph shaka_packager {
|
||||
subgraph cluster_legend {
|
||||
style=rounded
|
||||
label=<<u>Legend</u>>
|
||||
|
||||
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 : ...
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue