From 0af2c5cdcfa4244a6f6302ac29e826ad2e6fc42f Mon Sep 17 00:00:00 2001 From: KongQun Yang Date: Mon, 7 May 2018 16:08:09 -0700 Subject: [PATCH] Integrate PackedAudioWriter Closes #342. Change-Id: I2fb4a651ad90448ab226b386c92c94e11ff9f9a8 --- README.md | 34 ++++++++++--------- packager/app/muxer_factory.cc | 6 ++++ packager/media/base/container_names.cc | 10 +++++- .../media/event/muxer_listener_internal.cc | 3 ++ packager/mpd/base/media_info.proto | 1 + packager/packager.cc | 21 +++++++----- packager/packager.gyp | 1 + 7 files changed, 51 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 99b20398f3..43166fd7c5 100644 --- a/README.md +++ b/README.md @@ -16,28 +16,30 @@ Shaka Packager supports: - [HLS](https://developer.apple.com/streaming/) - Key systems: - [Widevine](http://www.widevine.com/) - - [PlayReady](https://www.microsoft.com/playready/)1 - - [Fairplay](https://developer.apple.com/streaming/fps/)1 + - [PlayReady](https://www.microsoft.com/playready/)¹ + - [Fairplay](https://developer.apple.com/streaming/fps/)¹ - Encryption standards: - [CENC](https://en.wikipedia.org/wiki/MPEG_Common_Encryption) - [SAMPLE-AES](https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption/Intro/Intro.html) - Media Containers and codecs - | Codecs | ISO-BMFF | WebM | MPEG2-TS | WVM | - |:-----------------:|:------------:|:------------:|:------------:|:-----------:| - | H264 (AVC) | I / O | - | I / O | I | - | H265 (HEVC) | I / O | - | I | - | - | VP8 | I / O | I / O | - | - | - | VP9 | I / O | I / O | - | - | - | AAC | I / O | - | I / O | I | - | Dolby AC3/EAC3 | I / O | - | I | - | - | DTS | I / O | - | - | - | - | FLAC | I / O | - | - | - | - | Opus | *I / O* | I / O | - | - | - | Vorbis | - | I / O | - | - | + | Codecs | ISO-BMFF | WebM | MPEG2-TS | WVM | Packed Audio²| + |:-----------------:|:------------:|:------------:|:------------:|:-----------:|:------------:| + | H264 (AVC) | I / O | - | I / O | I | - | + | H265 (HEVC) | I / O | - | I | - | - | + | VP8 | I / O | I / O | - | - | - | + | VP9 | I / O | I / O | - | - | - | + | AAC | I / O | - | I / O | I | O | + | Dolby AC3/EAC3 | I / O | - | I | - | O | + | DTS | I / O | - | - | - | - | + | FLAC | I / O | - | - | - | - | + | Opus | I / O³ | I / O | - | - | - | + | Vorbis | - | I / O | - | - | - | - ** I for input and O for output. - ** Opus support in ISO-BMFF is experimental. + NOTES: + - I for input and O for output. + - ²: https://tools.ietf.org/html/draft-pantos-http-live-streaming-23#section-3.4 + - ³: Opus support in ISO-BMFF is experimental. - Subtitles - WebVTT in both text form and embedded in MP4 - TTML in text form (DASH only) diff --git a/packager/app/muxer_factory.cc b/packager/app/muxer_factory.cc index 618455de70..402a121512 100644 --- a/packager/app/muxer_factory.cc +++ b/packager/app/muxer_factory.cc @@ -11,6 +11,7 @@ #include "packager/media/base/muxer_options.h" #include "packager/media/formats/mp2t/ts_muxer.h" #include "packager/media/formats/mp4/mp4_muxer.h" +#include "packager/media/formats/packed_audio/packed_audio_writer.h" #include "packager/media/formats/webm/webm_muxer.h" #include "packager/packager.h" @@ -34,6 +35,11 @@ std::shared_ptr MuxerFactory::CreateMuxer( std::shared_ptr muxer; switch (output_format) { + case CONTAINER_AAC: + case CONTAINER_AC3: + case CONTAINER_EAC3: + muxer = std::make_shared(options); + break; case CONTAINER_WEBM: muxer = std::make_shared(options); break; diff --git a/packager/media/base/container_names.cc b/packager/media/base/container_names.cc index 2521bf2427..a07a026a26 100644 --- a/packager/media/base/container_names.cc +++ b/packager/media/base/container_names.cc @@ -1726,7 +1726,15 @@ MediaContainerName DetermineContainer(const uint8_t* buffer, int buffer_size) { MediaContainerName DetermineContainerFromFormatName( const std::string& format_name) { - if (base::EqualsCaseInsensitiveASCII(format_name, "webm")) { + if (base::EqualsCaseInsensitiveASCII(format_name, "aac") || + base::EqualsCaseInsensitiveASCII(format_name, "adts")) { + return CONTAINER_AAC; + } else if (base::EqualsCaseInsensitiveASCII(format_name, "ac3")) { + return CONTAINER_AC3; + } else if (base::EqualsCaseInsensitiveASCII(format_name, "ec3") || + base::EqualsCaseInsensitiveASCII(format_name, "eac3")) { + return CONTAINER_EAC3; + } else if (base::EqualsCaseInsensitiveASCII(format_name, "webm")) { return CONTAINER_WEBM; } else if (base::EqualsCaseInsensitiveASCII(format_name, "m4a") || base::EqualsCaseInsensitiveASCII(format_name, "m4v") || diff --git a/packager/media/event/muxer_listener_internal.cc b/packager/media/event/muxer_listener_internal.cc index dc8974aae5..e8980a78a6 100644 --- a/packager/media/event/muxer_listener_internal.cc +++ b/packager/media/event/muxer_listener_internal.cc @@ -46,6 +46,9 @@ void SetMediaInfoContainerType(MuxerListener::ContainerType container_type, case MuxerListener::kContainerMpeg2ts: media_info->set_container_type(MediaInfo::CONTAINER_MPEG2_TS); break; + case MuxerListener::kContainerPackedAudio: + media_info->set_container_type(MediaInfo::CONTAINER_PACKED_AUDIO); + break; case MuxerListener::kContainerWebM: media_info->set_container_type(MediaInfo::CONTAINER_WEBM); break; diff --git a/packager/mpd/base/media_info.proto b/packager/mpd/base/media_info.proto index 6555306b94..8c9c02d16c 100644 --- a/packager/mpd/base/media_info.proto +++ b/packager/mpd/base/media_info.proto @@ -17,6 +17,7 @@ message MediaInfo { CONTAINER_MPEG2_TS= 2; CONTAINER_WEBM = 3; CONTAINER_TEXT = 4; + CONTAINER_PACKED_AUDIO = 5; } message VideoInfo { diff --git a/packager/packager.cc b/packager/packager.cc index 27efb3aa7d..b8609a0e58 100644 --- a/packager/packager.cc +++ b/packager/packager.cc @@ -218,15 +218,17 @@ Status ValidateStreamDescriptor(bool dump_stream_info, "All TS segments must be self-initializing. Stream " "descriptors 'output' or 'init_segment' are not allowed."); } - } else if (output_format == CONTAINER_WEBVTT) { - // There is no need for an init segment when outputting to WebVTT because - // there is no initialization data. + } else if (output_format == CONTAINER_WEBVTT || + output_format == CONTAINER_AAC || output_format == CONTAINER_AC3 || + output_format == CONTAINER_EAC3) { + // There is no need for an init segment when outputting because there is no + // initialization data. if (stream.segment_template.length() && stream.output.length()) { return Status( error::INVALID_ARGUMENT, - "Segmented WebVTT output cannot have an init segment. Do not specify " - "stream descriptors 'output' or 'init_segment' when using " - "'segment_template' with WebVtt."); + "Segmented WebVTT or PackedAudio output cannot have an init segment. " + "Do not specify stream descriptors 'output' or 'init_segment' when " + "using 'segment_template'."); } } else { // For any other format, if there is a segment template, there must be an @@ -386,8 +388,11 @@ std::shared_ptr CreateEncryptionHandler( // Use Sample AES in MPEG2TS. // TODO(kqyang): Consider adding a new flag to enable Sample AES as we // will support CENC in TS in the future. - if (GetOutputFormat(stream) == CONTAINER_MPEG2TS) { - VLOG(1) << "Use Apple Sample AES encryption for MPEG2TS."; + if (GetOutputFormat(stream) == CONTAINER_MPEG2TS || + GetOutputFormat(stream) == CONTAINER_AAC || + GetOutputFormat(stream) == CONTAINER_AC3 || + GetOutputFormat(stream) == CONTAINER_EAC3) { + VLOG(1) << "Use Apple Sample AES encryption for MPEG2TS or Packed Audio."; encryption_params.protection_scheme = kAppleSampleAesProtectionScheme; } diff --git a/packager/packager.gyp b/packager/packager.gyp index d1ce240f27..f4c03647ea 100644 --- a/packager/packager.gyp +++ b/packager/packager.gyp @@ -36,6 +36,7 @@ 'media/event/media_event.gyp:media_event', 'media/formats/mp2t/mp2t.gyp:mp2t', 'media/formats/mp4/mp4.gyp:mp4', + 'media/formats/packed_audio/packed_audio.gyp:packed_audio', 'media/formats/webm/webm.gyp:webm', 'media/formats/webvtt/webvtt.gyp:webvtt', 'media/formats/wvm/wvm.gyp:wvm',