diff --git a/docs/source/documentation.rst b/docs/source/documentation.rst index 22b3cbc09f..fb0845e53a 100644 --- a/docs/source/documentation.rst +++ b/docs/source/documentation.rst @@ -48,6 +48,8 @@ Synopsis .. include:: /options/mp4_output_options.rst +.. include:: /options/transport_stream_output_options.rst + .. include:: /options/dash_options.rst .. include:: /options/hls_options.rst diff --git a/docs/source/options/transport_stream_output_options.rst b/docs/source/options/transport_stream_output_options.rst new file mode 100644 index 0000000000..bb5594b96f --- /dev/null +++ b/docs/source/options/transport_stream_output_options.rst @@ -0,0 +1,10 @@ +Transport stream output options +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +--transport_stream_timestamp_offset_ms + + Transport stream only (MPEG2-TS, HLS Packed Audio): A positive value, in + milliseconds, by which output timestamps are offset to compensate for + possible negative timestamps in the input. For example, timestamps from + ISO-BMFF after adjusted by EditList could be negative. In transport streams, + timestamps are not allowed to be less than zero. Default: 100ms. diff --git a/packager/app/muxer_factory.cc b/packager/app/muxer_factory.cc index 402a121512..d4f93707be 100644 --- a/packager/app/muxer_factory.cc +++ b/packager/app/muxer_factory.cc @@ -20,6 +20,8 @@ namespace media { MuxerFactory::MuxerFactory(const PackagingParams& packaging_params) : mp4_params_(packaging_params.mp4_output_params), + transport_stream_timestamp_offset_ms_( + packaging_params.transport_stream_timestamp_offset_ms), temp_dir_(packaging_params.temp_dir) {} std::shared_ptr MuxerFactory::CreateMuxer( @@ -27,6 +29,8 @@ std::shared_ptr MuxerFactory::CreateMuxer( const StreamDescriptor& stream) { MuxerOptions options; options.mp4_params = mp4_params_; + options.transport_stream_timestamp_offset_ms = + transport_stream_timestamp_offset_ms_; options.temp_dir = temp_dir_; options.output_file_name = stream.output; options.segment_template = stream.segment_template; diff --git a/packager/app/muxer_factory.h b/packager/app/muxer_factory.h index 3014b68f06..f9e5003e1c 100644 --- a/packager/app/muxer_factory.h +++ b/packager/app/muxer_factory.h @@ -46,8 +46,9 @@ class MuxerFactory { MuxerFactory(const MuxerFactory&) = delete; MuxerFactory& operator=(const MuxerFactory&) = delete; - Mp4OutputParams mp4_params_; - std::string temp_dir_; + const Mp4OutputParams mp4_params_; + const uint32_t transport_stream_timestamp_offset_ms_ = 0; + const std::string temp_dir_; base::Clock* clock_ = nullptr; }; diff --git a/packager/app/muxer_flags.cc b/packager/app/muxer_flags.cc index 37acec6b0b..301262b0ec 100644 --- a/packager/app/muxer_flags.cc +++ b/packager/app/muxer_flags.cc @@ -41,3 +41,10 @@ DEFINE_string(temp_dir, DEFINE_bool(mp4_include_pssh_in_stream, true, "MP4 only: include pssh in the encrypted stream."); +DEFINE_int32(transport_stream_timestamp_offset_ms, + 100, + "A positive value, in milliseconds, by which output timestamps " + "are offset to compensate for possible negative timestamps in the " + "input. For example, timestamps from ISO-BMFF after adjusted by " + "EditList could be negative. In transport streams, timestamps are " + "not allowed to be less than zero."); diff --git a/packager/app/muxer_flags.h b/packager/app/muxer_flags.h index 73df416837..b39a644454 100644 --- a/packager/app/muxer_flags.h +++ b/packager/app/muxer_flags.h @@ -19,5 +19,6 @@ DECLARE_bool(fragment_sap_aligned); DECLARE_bool(generate_sidx_in_media_segments); DECLARE_string(temp_dir); DECLARE_bool(mp4_include_pssh_in_stream); +DECLARE_int32(transport_stream_timestamp_offset_ms); #endif // APP_MUXER_FLAGS_H_ diff --git a/packager/app/packager_main.cc b/packager/app/packager_main.cc index ae07c54b3e..9418fc606f 100644 --- a/packager/app/packager_main.cc +++ b/packager/app/packager_main.cc @@ -381,6 +381,9 @@ base::Optional GetPackagingParams() { FLAGS_generate_sidx_in_media_segments; mp4_params.include_pssh_in_stream = FLAGS_mp4_include_pssh_in_stream; + packaging_params.transport_stream_timestamp_offset_ms = + FLAGS_transport_stream_timestamp_offset_ms; + packaging_params.output_media_info = FLAGS_output_media_info; MpdParams& mpd_params = packaging_params.mpd_params; diff --git a/packager/app/test/packager_test.py b/packager/app/test/packager_test.py index 77aecde6cd..3dd49253f7 100755 --- a/packager/app/test/packager_test.py +++ b/packager/app/test/packager_test.py @@ -1486,7 +1486,8 @@ class PackagerFunctionalTest(PackagerAppTest): self._AssertStreamInfo(self.output[1], 'is_encrypted: true') def testHlsSegmentedWebVtt(self): - streams = self._GetStreams(['audio', 'video'], segmented=True) + streams = self._GetStreams( + ['audio', 'video'], output_format='ts', segmented=True) streams += self._GetStreams( ['text'], test_files=['bear-subtitle-english.vtt'], segmented=True) diff --git a/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-audio-1.ts b/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-audio-1.ts index c492a868c3..5dd10d6c49 100644 Binary files a/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-audio-1.ts and b/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-audio-1.ts differ diff --git a/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-audio-2.ts b/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-audio-2.ts index 5f386328e3..2239833e63 100644 Binary files a/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-audio-2.ts and b/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-audio-2.ts differ diff --git a/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-audio-3.ts b/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-audio-3.ts index fcfe141d34..2c27268df7 100644 Binary files a/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-audio-3.ts and b/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-audio-3.ts differ diff --git a/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-video-1.ts b/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-video-1.ts index c8600d8422..84a65fef8a 100644 Binary files a/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-video-1.ts and b/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-video-1.ts differ diff --git a/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-video-2.ts b/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-video-2.ts index 7dadd15355..d5231acb66 100644 Binary files a/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-video-2.ts and b/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-video-2.ts differ diff --git a/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-video-3.ts b/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-video-3.ts index ab0c79483c..ed0773cdce 100644 Binary files a/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-video-3.ts and b/packager/app/test/testdata/avc-aac-ts-language/bear-640x360-video-3.ts differ diff --git a/packager/app/test/testdata/avc-aac-ts/bear-640x360-audio-1.ts b/packager/app/test/testdata/avc-aac-ts/bear-640x360-audio-1.ts index c492a868c3..5dd10d6c49 100644 Binary files a/packager/app/test/testdata/avc-aac-ts/bear-640x360-audio-1.ts and b/packager/app/test/testdata/avc-aac-ts/bear-640x360-audio-1.ts differ diff --git a/packager/app/test/testdata/avc-aac-ts/bear-640x360-audio-2.ts b/packager/app/test/testdata/avc-aac-ts/bear-640x360-audio-2.ts index 5f386328e3..2239833e63 100644 Binary files a/packager/app/test/testdata/avc-aac-ts/bear-640x360-audio-2.ts and b/packager/app/test/testdata/avc-aac-ts/bear-640x360-audio-2.ts differ diff --git a/packager/app/test/testdata/avc-aac-ts/bear-640x360-audio-3.ts b/packager/app/test/testdata/avc-aac-ts/bear-640x360-audio-3.ts index fcfe141d34..2c27268df7 100644 Binary files a/packager/app/test/testdata/avc-aac-ts/bear-640x360-audio-3.ts and b/packager/app/test/testdata/avc-aac-ts/bear-640x360-audio-3.ts differ diff --git a/packager/app/test/testdata/avc-aac-ts/bear-640x360-video-1.ts b/packager/app/test/testdata/avc-aac-ts/bear-640x360-video-1.ts index c8600d8422..84a65fef8a 100644 Binary files a/packager/app/test/testdata/avc-aac-ts/bear-640x360-video-1.ts and b/packager/app/test/testdata/avc-aac-ts/bear-640x360-video-1.ts differ diff --git a/packager/app/test/testdata/avc-aac-ts/bear-640x360-video-2.ts b/packager/app/test/testdata/avc-aac-ts/bear-640x360-video-2.ts index 7dadd15355..d5231acb66 100644 Binary files a/packager/app/test/testdata/avc-aac-ts/bear-640x360-video-2.ts and b/packager/app/test/testdata/avc-aac-ts/bear-640x360-video-2.ts differ diff --git a/packager/app/test/testdata/avc-aac-ts/bear-640x360-video-3.ts b/packager/app/test/testdata/avc-aac-ts/bear-640x360-video-3.ts index ab0c79483c..ed0773cdce 100644 Binary files a/packager/app/test/testdata/avc-aac-ts/bear-640x360-video-3.ts and b/packager/app/test/testdata/avc-aac-ts/bear-640x360-video-3.ts differ diff --git a/packager/app/test/testdata/avc-aac-ts/output.mpd b/packager/app/test/testdata/avc-aac-ts/output.mpd index 704807cdbe..5f974a63ec 100644 --- a/packager/app/test/testdata/avc-aac-ts/output.mpd +++ b/packager/app/test/testdata/avc-aac-ts/output.mpd @@ -6,8 +6,8 @@ - - + + @@ -17,9 +17,9 @@ - - - + + + diff --git a/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-audio-1.ts b/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-audio-1.ts index 27da4c3090..7bfbd65428 100644 Binary files a/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-audio-1.ts and b/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-audio-1.ts differ diff --git a/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-audio-2.ts b/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-audio-2.ts index 49834de310..5e26cda10f 100644 Binary files a/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-audio-2.ts and b/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-audio-2.ts differ diff --git a/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-audio-3.ts b/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-audio-3.ts index 39a1002c18..244009c822 100644 Binary files a/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-audio-3.ts and b/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-audio-3.ts differ diff --git a/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-video-1.ts b/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-video-1.ts index c8600d8422..84a65fef8a 100644 Binary files a/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-video-1.ts and b/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-video-1.ts differ diff --git a/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-video-2.ts b/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-video-2.ts index 80d082525f..6b44b167a1 100644 Binary files a/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-video-2.ts and b/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-video-2.ts differ diff --git a/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-video-3.ts b/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-video-3.ts index 679ea2f35b..dfe8812409 100644 Binary files a/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-video-3.ts and b/packager/app/test/testdata/avc-ac3-ts-with-encryption/bear-640x360-ac3-video-3.ts differ diff --git a/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-audio-1.ts b/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-audio-1.ts index 27da4c3090..7bfbd65428 100644 Binary files a/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-audio-1.ts and b/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-audio-1.ts differ diff --git a/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-audio-2.ts b/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-audio-2.ts index b5803febbf..babb8b6e83 100644 Binary files a/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-audio-2.ts and b/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-audio-2.ts differ diff --git a/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-audio-3.ts b/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-audio-3.ts index a8de767844..158af46119 100644 Binary files a/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-audio-3.ts and b/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-audio-3.ts differ diff --git a/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-video-1.ts b/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-video-1.ts index c8600d8422..84a65fef8a 100644 Binary files a/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-video-1.ts and b/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-video-1.ts differ diff --git a/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-video-2.ts b/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-video-2.ts index 7dadd15355..d5231acb66 100644 Binary files a/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-video-2.ts and b/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-video-2.ts differ diff --git a/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-video-3.ts b/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-video-3.ts index ab0c79483c..ed0773cdce 100644 Binary files a/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-video-3.ts and b/packager/app/test/testdata/avc-ac3-ts/bear-640x360-ac3-video-3.ts differ diff --git a/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-audio-1.aac b/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-audio-1.aac index 18a9a678bb..fc97583c81 100644 Binary files a/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-audio-1.aac and b/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-audio-1.aac differ diff --git a/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-audio-2.aac b/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-audio-2.aac index 5f7eece6a9..714b92ed39 100644 Binary files a/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-audio-2.aac and b/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-audio-2.aac differ diff --git a/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-audio-3.aac b/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-audio-3.aac index a829d3fedf..ea67c9ef66 100644 Binary files a/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-audio-3.aac and b/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-audio-3.aac differ diff --git a/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-video-1.ts b/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-video-1.ts index c8600d8422..84a65fef8a 100644 Binary files a/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-video-1.ts and b/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-video-1.ts differ diff --git a/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-video-2.ts b/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-video-2.ts index 80d082525f..6b44b167a1 100644 Binary files a/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-video-2.ts and b/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-video-2.ts differ diff --git a/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-video-3.ts b/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-video-3.ts index 679ea2f35b..dfe8812409 100644 Binary files a/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-video-3.ts and b/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/bear-640x360-video-3.ts differ diff --git a/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-audio-1.ac3 b/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-audio-1.ac3 index 55568cff4d..a45eac9562 100644 Binary files a/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-audio-1.ac3 and b/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-audio-1.ac3 differ diff --git a/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-audio-2.ac3 b/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-audio-2.ac3 index 9b35fb84d4..16bfca547d 100644 Binary files a/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-audio-2.ac3 and b/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-audio-2.ac3 differ diff --git a/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-audio-3.ac3 b/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-audio-3.ac3 index 545efd1cbc..e269b9de28 100644 Binary files a/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-audio-3.ac3 and b/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-audio-3.ac3 differ diff --git a/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-video-1.ts b/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-video-1.ts index c8600d8422..84a65fef8a 100644 Binary files a/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-video-1.ts and b/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-video-1.ts differ diff --git a/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-video-2.ts b/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-video-2.ts index 80d082525f..6b44b167a1 100644 Binary files a/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-video-2.ts and b/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-video-2.ts differ diff --git a/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-video-3.ts b/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-video-3.ts index 679ea2f35b..dfe8812409 100644 Binary files a/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-video-3.ts and b/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/bear-640x360-ac3-video-3.ts differ diff --git a/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-audio-1.ts b/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-audio-1.ts index c492a868c3..5dd10d6c49 100644 Binary files a/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-audio-1.ts and b/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-audio-1.ts differ diff --git a/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-audio-2.ts b/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-audio-2.ts index 5f386328e3..2239833e63 100644 Binary files a/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-audio-2.ts and b/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-audio-2.ts differ diff --git a/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-audio-3.ts b/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-audio-3.ts index fcfe141d34..2c27268df7 100644 Binary files a/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-audio-3.ts and b/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-audio-3.ts differ diff --git a/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-video-1.ts b/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-video-1.ts index c8600d8422..84a65fef8a 100644 Binary files a/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-video-1.ts and b/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-video-1.ts differ diff --git a/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-video-2.ts b/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-video-2.ts index 7dadd15355..d5231acb66 100644 Binary files a/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-video-2.ts and b/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-video-2.ts differ diff --git a/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-video-3.ts b/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-video-3.ts index ab0c79483c..ed0773cdce 100644 Binary files a/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-video-3.ts and b/packager/app/test/testdata/avc-ts-event-playlist/bear-640x360-video-3.ts differ diff --git a/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-audio-1.ts b/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-audio-1.ts index c492a868c3..5dd10d6c49 100644 Binary files a/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-audio-1.ts and b/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-audio-1.ts differ diff --git a/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-audio-2.ts b/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-audio-2.ts index 2edc20505b..d83b3a5650 100644 Binary files a/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-audio-2.ts and b/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-audio-2.ts differ diff --git a/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-audio-3.ts b/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-audio-3.ts index 3f18799587..cb0357335f 100644 Binary files a/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-audio-3.ts and b/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-audio-3.ts differ diff --git a/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-video-1.ts b/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-video-1.ts index c8600d8422..84a65fef8a 100644 Binary files a/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-video-1.ts and b/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-video-1.ts differ diff --git a/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-video-2.ts b/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-video-2.ts index 3eb4efe34b..4e9ae7acba 100644 Binary files a/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-video-2.ts and b/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-video-2.ts differ diff --git a/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-video-3.ts b/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-video-3.ts index c0522d752e..742b3b1830 100644 Binary files a/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-video-3.ts and b/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/bear-640x360-video-3.ts differ diff --git a/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-audio-1.ts b/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-audio-1.ts index c492a868c3..5dd10d6c49 100644 Binary files a/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-audio-1.ts and b/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-audio-1.ts differ diff --git a/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-audio-2.ts b/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-audio-2.ts index 5f386328e3..2239833e63 100644 Binary files a/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-audio-2.ts and b/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-audio-2.ts differ diff --git a/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-audio-3.ts b/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-audio-3.ts index fcfe141d34..2c27268df7 100644 Binary files a/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-audio-3.ts and b/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-audio-3.ts differ diff --git a/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-video-1.ts b/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-video-1.ts index c8600d8422..84a65fef8a 100644 Binary files a/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-video-1.ts and b/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-video-1.ts differ diff --git a/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-video-2.ts b/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-video-2.ts index 7dadd15355..d5231acb66 100644 Binary files a/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-video-2.ts and b/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-video-2.ts differ diff --git a/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-video-3.ts b/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-video-3.ts index ab0c79483c..ed0773cdce 100644 Binary files a/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-video-3.ts and b/packager/app/test/testdata/avc-ts-live-playlist/bear-640x360-video-3.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-audio-1.ts b/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-audio-1.ts index c492a868c3..5dd10d6c49 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-audio-1.ts and b/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-audio-1.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-audio-2.ts b/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-audio-2.ts index b7dbc50b73..cd9a366a41 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-audio-2.ts and b/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-audio-2.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-audio-3.ts b/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-audio-3.ts index fafb892ed8..dabd5b90dc 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-audio-3.ts and b/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-audio-3.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-video-1.ts b/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-video-1.ts index c8600d8422..84a65fef8a 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-video-1.ts and b/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-video-1.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-video-2.ts b/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-video-2.ts index 80d082525f..6b44b167a1 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-video-2.ts and b/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-video-2.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-video-3.ts b/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-video-3.ts index 679ea2f35b..dfe8812409 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-video-3.ts and b/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/bear-640x360-video-3.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-1.ts b/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-1.ts index aa01e5c8f6..6534c169de 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-1.ts and b/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-1.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-2.ts b/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-2.ts index 788e8d3f34..4f83164ce9 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-2.ts and b/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-2.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-3.ts b/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-3.ts index 1f7ae51acf..708de44a09 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-3.ts and b/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-3.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-4.ts b/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-4.ts index d7e34bc875..b224e708c4 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-4.ts and b/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-4.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-5.ts b/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-5.ts index 098f57f64a..b0c2de6691 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-5.ts and b/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-5.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-6.ts b/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-6.ts index 408f9a4674..54d6b573bf 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-6.ts and b/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/sintel-1024x436-video-6.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-audio-1.ts b/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-audio-1.ts index c492a868c3..5dd10d6c49 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-audio-1.ts and b/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-audio-1.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-audio-2.ts b/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-audio-2.ts index b7dbc50b73..cd9a366a41 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-audio-2.ts and b/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-audio-2.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-audio-3.ts b/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-audio-3.ts index fafb892ed8..dabd5b90dc 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-audio-3.ts and b/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-audio-3.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-video-1.ts b/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-video-1.ts index c8600d8422..84a65fef8a 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-video-1.ts and b/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-video-1.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-video-2.ts b/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-video-2.ts index 80d082525f..6b44b167a1 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-video-2.ts and b/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-video-2.ts differ diff --git a/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-video-3.ts b/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-video-3.ts index 679ea2f35b..dfe8812409 100644 Binary files a/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-video-3.ts and b/packager/app/test/testdata/avc-ts-with-encryption/bear-640x360-video-3.ts differ diff --git a/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-audio-1.ec3 b/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-audio-1.ec3 index 72e1047a5d..5a0584ca20 100644 Binary files a/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-audio-1.ec3 and b/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-audio-1.ec3 differ diff --git a/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-audio-2.ec3 b/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-audio-2.ec3 index 3a7855c6f5..639c64eefc 100644 Binary files a/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-audio-2.ec3 and b/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-audio-2.ec3 differ diff --git a/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-audio-3.ec3 b/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-audio-3.ec3 index f56cb30bc5..74bc9b8639 100644 Binary files a/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-audio-3.ec3 and b/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-audio-3.ec3 differ diff --git a/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-video-1.ts b/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-video-1.ts index 385eb722c9..4e73a20026 100644 Binary files a/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-video-1.ts and b/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-video-1.ts differ diff --git a/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-video-2.ts b/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-video-2.ts index f8745b5e15..179b1b387d 100644 Binary files a/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-video-2.ts and b/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-video-2.ts differ diff --git a/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-video-3.ts b/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-video-3.ts index 8e717ae5a6..e4eb714d7e 100644 Binary files a/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-video-3.ts and b/packager/app/test/testdata/ec3-packed-audio-encrypted/bear-640x360-ec3-video-3.ts differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-1.m4s b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-1.m4s deleted file mode 100644 index 55ee417db1..0000000000 Binary files a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-1.m4s and /dev/null differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-1.ts b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-1.ts new file mode 100644 index 0000000000..756660723c Binary files /dev/null and b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-1.ts differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-2.m4s b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-2.m4s deleted file mode 100644 index 1ddbee3bdd..0000000000 Binary files a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-2.m4s and /dev/null differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-2.ts b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-2.ts new file mode 100644 index 0000000000..4acfb4f0d2 Binary files /dev/null and b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-2.ts differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-3.m4s b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-3.m4s deleted file mode 100644 index a7100e5c24..0000000000 Binary files a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-3.m4s and /dev/null differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-3.ts b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-3.ts new file mode 100644 index 0000000000..09dbdb3523 Binary files /dev/null and b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-3.ts differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-init.mp4 b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-init.mp4 deleted file mode 100644 index 1ba3d9abb9..0000000000 Binary files a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-audio-init.mp4 and /dev/null differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-1.m4s b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-1.m4s deleted file mode 100644 index 4dbca6653f..0000000000 Binary files a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-1.m4s and /dev/null differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-1.ts b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-1.ts new file mode 100644 index 0000000000..6bb890b64d Binary files /dev/null and b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-1.ts differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-2.m4s b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-2.m4s deleted file mode 100644 index da2f00a606..0000000000 Binary files a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-2.m4s and /dev/null differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-2.ts b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-2.ts new file mode 100644 index 0000000000..1614576aa2 Binary files /dev/null and b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-2.ts differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-3.m4s b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-3.m4s deleted file mode 100644 index 8dfe74ca5b..0000000000 Binary files a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-3.m4s and /dev/null differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-3.ts b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-3.ts new file mode 100644 index 0000000000..4f6728a0e9 Binary files /dev/null and b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-3.ts differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-init.mp4 b/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-init.mp4 deleted file mode 100644 index aa3f67b37c..0000000000 Binary files a/packager/app/test/testdata/hls-segmented-webvtt/bear-640x360-video-init.mp4 and /dev/null differ diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-1.vtt b/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-1.vtt index 81150bae25..16af33b4ae 100644 --- a/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-1.vtt +++ b/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-1.vtt @@ -1,4 +1,5 @@ WEBVTT +X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:9000 00:00:00.000 --> 00:00:00.800 Yup, that's a bear, eh. diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-2.vtt b/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-2.vtt index 933e153959..eccaf726f3 100644 --- a/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-2.vtt +++ b/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-2.vtt @@ -1,4 +1,5 @@ WEBVTT +X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:9000 00:00:01.000 --> 00:00:04.700 He 's... um... doing bear-like stuff. diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-3.vtt b/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-3.vtt index 933e153959..eccaf726f3 100644 --- a/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-3.vtt +++ b/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-3.vtt @@ -1,4 +1,5 @@ WEBVTT +X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:9000 00:00:01.000 --> 00:00:04.700 He 's... um... doing bear-like stuff. diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-4.vtt b/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-4.vtt index 933e153959..eccaf726f3 100644 --- a/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-4.vtt +++ b/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-4.vtt @@ -1,4 +1,5 @@ WEBVTT +X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:9000 00:00:01.000 --> 00:00:04.700 He 's... um... doing bear-like stuff. diff --git a/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-5.vtt b/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-5.vtt index 933e153959..eccaf726f3 100644 --- a/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-5.vtt +++ b/packager/app/test/testdata/hls-segmented-webvtt/bear-subtitle-english-text-5.vtt @@ -1,4 +1,5 @@ WEBVTT +X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:9000 00:00:01.000 --> 00:00:04.700 He 's... um... doing bear-like stuff. diff --git a/packager/app/test/testdata/hls-segmented-webvtt/output.m3u8 b/packager/app/test/testdata/hls-segmented-webvtt/output.m3u8 index bd31185e96..c3d1692173 100644 --- a/packager/app/test/testdata/hls-segmented-webvtt/output.m3u8 +++ b/packager/app/test/testdata/hls-segmented-webvtt/output.m3u8 @@ -5,5 +5,5 @@ #EXT-X-MEDIA:TYPE=SUBTITLES,URI="stream_0.m3u8",GROUP-ID="default-text-group",NAME="stream_0",AUTOSELECT=YES -#EXT-X-STREAM-INF:BANDWIDTH=1108051,AVERAGE-BANDWIDTH=1005999,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group",SUBTITLES="default-text-group" +#EXT-X-STREAM-INF:BANDWIDTH=1217518,AVERAGE-BANDWIDTH=1117319,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group",SUBTITLES="default-text-group" stream_2.m3u8 diff --git a/packager/app/test/testdata/hls-segmented-webvtt/stream_1.m3u8 b/packager/app/test/testdata/hls-segmented-webvtt/stream_1.m3u8 index a717606102..e0ddf92e18 100644 --- a/packager/app/test/testdata/hls-segmented-webvtt/stream_1.m3u8 +++ b/packager/app/test/testdata/hls-segmented-webvtt/stream_1.m3u8 @@ -3,11 +3,10 @@ ## Generated with https://github.com/google/shaka-packager version -- #EXT-X-TARGETDURATION:2 #EXT-X-PLAYLIST-TYPE:VOD -#EXT-X-MAP:URI="bear-640x360-audio-init.mp4" -#EXTINF:1.022, -bear-640x360-audio-1.m4s +#EXTINF:1.045, +bear-640x360-audio-1.ts #EXTINF:0.998, -bear-640x360-audio-2.m4s +bear-640x360-audio-2.ts #EXTINF:0.720, -bear-640x360-audio-3.m4s +bear-640x360-audio-3.ts #EXT-X-ENDLIST diff --git a/packager/app/test/testdata/hls-segmented-webvtt/stream_2.m3u8 b/packager/app/test/testdata/hls-segmented-webvtt/stream_2.m3u8 index 19e29dda02..51a3eafba0 100644 --- a/packager/app/test/testdata/hls-segmented-webvtt/stream_2.m3u8 +++ b/packager/app/test/testdata/hls-segmented-webvtt/stream_2.m3u8 @@ -3,11 +3,10 @@ ## Generated with https://github.com/google/shaka-packager version -- #EXT-X-TARGETDURATION:2 #EXT-X-PLAYLIST-TYPE:VOD -#EXT-X-MAP:URI="bear-640x360-video-init.mp4" #EXTINF:1.001, -bear-640x360-video-1.m4s +bear-640x360-video-1.ts #EXTINF:1.001, -bear-640x360-video-2.m4s +bear-640x360-video-2.ts #EXTINF:0.734, -bear-640x360-video-3.m4s +bear-640x360-video-3.ts #EXT-X-ENDLIST diff --git a/packager/media/base/muxer_options.h b/packager/media/base/muxer_options.h index f409e19fdf..b69d2f794b 100644 --- a/packager/media/base/muxer_options.h +++ b/packager/media/base/muxer_options.h @@ -24,6 +24,10 @@ struct MuxerOptions { /// MP4 (ISO-BMFF) specific parameters. Mp4OutputParams mp4_params; + // A positive value, in milliseconds, by which output timestamps are offset to + // compensate for negative timestamps in the input. + uint32_t transport_stream_timestamp_offset_ms = 0; + /// 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. diff --git a/packager/media/formats/mp2t/pes_packet_generator.cc b/packager/media/formats/mp2t/pes_packet_generator.cc index 5b60d294e0..30a41f9ff2 100644 --- a/packager/media/formats/mp2t/pes_packet_generator.cc +++ b/packager/media/formats/mp2t/pes_packet_generator.cc @@ -30,7 +30,10 @@ const uint8_t kAc3AudioStreamId = 0xBD; // AC3 uses private stream 1 id. const double kTsTimescale = 90000.0; } // namespace -PesPacketGenerator::PesPacketGenerator() {} +PesPacketGenerator::PesPacketGenerator( + uint32_t transport_stream_timestamp_offset) + : transport_stream_timestamp_offset_(transport_stream_timestamp_offset) {} + PesPacketGenerator::~PesPacketGenerator() {} bool PesPacketGenerator::Initialize(const StreamInfo& stream_info) { @@ -76,9 +79,23 @@ bool PesPacketGenerator::PushSample(const MediaSample& sample) { if (!current_processing_pes_) current_processing_pes_.reset(new PesPacket()); + const int64_t pts = + sample.pts() * timescale_scale_ + transport_stream_timestamp_offset_; + const int64_t dts = + sample.dts() * timescale_scale_ + transport_stream_timestamp_offset_; + + if (pts < 0 || dts < 0) { + LOG(ERROR) << "Seeing negative timestamp (" << pts << "," << dts << ")" + << " after applying offset " + << transport_stream_timestamp_offset_ + << ". Please check if it is expected. Adjust " + "--transport_stream_timestamp_offset_ms if needed."; + return false; + } + current_processing_pes_->set_is_key_frame(sample.is_key_frame()); - current_processing_pes_->set_pts(timescale_scale_ * sample.pts()); - current_processing_pes_->set_dts(timescale_scale_ * sample.dts()); + current_processing_pes_->set_pts(pts); + current_processing_pes_->set_dts(dts); if (stream_type_ == kStreamVideo) { DCHECK(converter_); std::vector subsamples; diff --git a/packager/media/formats/mp2t/pes_packet_generator.h b/packager/media/formats/mp2t/pes_packet_generator.h index 51a0ef2d11..5847e83b51 100644 --- a/packager/media/formats/mp2t/pes_packet_generator.h +++ b/packager/media/formats/mp2t/pes_packet_generator.h @@ -28,7 +28,10 @@ class PesPacket; /// Methods are virtual for mocking. class PesPacketGenerator { public: - PesPacketGenerator(); + /// @param transport_stream_timestamp_offset is the offset to be applied to + /// sample timestamps to compensate for possible negative timestamps in + /// the input. + explicit PesPacketGenerator(uint32_t transport_stream_timestamp_offset); virtual ~PesPacketGenerator(); /// Initialize the object. This clears the internal state first so any @@ -62,6 +65,7 @@ class PesPacketGenerator { StreamType stream_type_; + const uint32_t transport_stream_timestamp_offset_ = 0; // Calculated by 90000 / input stream's timescale. This is used to scale the // timestamps. double timescale_scale_ = 0.0; diff --git a/packager/media/formats/mp2t/pes_packet_generator_unittest.cc b/packager/media/formats/mp2t/pes_packet_generator_unittest.cc index 00e025dc43..40265c8b96 100644 --- a/packager/media/formats/mp2t/pes_packet_generator_unittest.cc +++ b/packager/media/formats/mp2t/pes_packet_generator_unittest.cc @@ -36,6 +36,8 @@ using ::testing::SetArgPointee; namespace { +const uint32_t kZeroTransportStreamTimestampOffset = 0; + // Bogus data for testing. const uint8_t kAnyData[] = { 0x56, 0x87, 0x88, 0x33, 0x98, 0xAF, 0xE5, @@ -135,6 +137,8 @@ std::shared_ptr CreateAudioStreamInfo(Codec codec) { class PesPacketGeneratorTest : public ::testing::Test { protected: + PesPacketGeneratorTest() : generator_(kZeroTransportStreamTimestampOffset) {} + void UseMockNalUnitToByteStreamConverter( std::unique_ptr mock_nal_unit_to_byte_stream_converter) { diff --git a/packager/media/formats/mp2t/ts_segmenter.cc b/packager/media/formats/mp2t/ts_segmenter.cc index cec43cfa2e..3474ec1a6c 100644 --- a/packager/media/formats/mp2t/ts_segmenter.cc +++ b/packager/media/formats/mp2t/ts_segmenter.cc @@ -36,7 +36,11 @@ bool IsVideoCodec(Codec codec) { TsSegmenter::TsSegmenter(const MuxerOptions& options, MuxerListener* listener) : muxer_options_(options), listener_(listener), - pes_packet_generator_(new PesPacketGenerator()) {} + transport_stream_timestamp_offset_( + options.transport_stream_timestamp_offset_ms * kTsTimescale / 1000), + pes_packet_generator_( + new PesPacketGenerator(transport_stream_timestamp_offset_)) {} + TsSegmenter::~TsSegmenter() {} Status TsSegmenter::Initialize(const StreamInfo& stream_info) { @@ -184,7 +188,8 @@ Status TsSegmenter::FinalizeSegment(uint64_t start_timestamp, const int64_t file_size = File::GetFileSize(current_segment_path_.c_str()); listener_->OnNewSegment(current_segment_path_, - start_timestamp * timescale_scale_, + start_timestamp * timescale_scale_ + + transport_stream_timestamp_offset_, duration * timescale_scale_, file_size); } ts_writer_file_opened_ = false; diff --git a/packager/media/formats/mp2t/ts_segmenter.h b/packager/media/formats/mp2t/ts_segmenter.h index dc751a0131..78a88d2213 100644 --- a/packager/media/formats/mp2t/ts_segmenter.h +++ b/packager/media/formats/mp2t/ts_segmenter.h @@ -84,6 +84,7 @@ class TsSegmenter { Codec codec_ = kUnknownCodec; std::vector audio_codec_config_; + const uint32_t transport_stream_timestamp_offset_ = 0; // Scale used to scale the input stream to TS's timesccale (which is 90000). // Used for calculating the duration in seconds fo the current segment. double timescale_scale_ = 1.0; diff --git a/packager/media/formats/mp2t/ts_segmenter_unittest.cc b/packager/media/formats/mp2t/ts_segmenter_unittest.cc index 062f9597d0..46a990fc17 100644 --- a/packager/media/formats/mp2t/ts_segmenter_unittest.cc +++ b/packager/media/formats/mp2t/ts_segmenter_unittest.cc @@ -35,6 +35,7 @@ const uint8_t kExtraData[] = { 0x00, }; const int kTrackId = 0; +const uint32_t kZeroTransportStreamTimestampOffset = 0; const uint32_t kTimeScale = 90000; const uint64_t kDuration = 180000; const char kCodecString[] = "avc1"; @@ -53,6 +54,9 @@ const uint8_t kAnyData[] = { class MockPesPacketGenerator : public PesPacketGenerator { public: + MockPesPacketGenerator() + : PesPacketGenerator(kZeroTransportStreamTimestampOffset) {} + MOCK_METHOD1(Initialize, bool(const StreamInfo& info)); MOCK_METHOD1(PushSample, bool(const MediaSample& sample)); diff --git a/packager/media/formats/packed_audio/packed_audio_segmenter.cc b/packager/media/formats/packed_audio/packed_audio_segmenter.cc index 3d7516ae5b..6053dfca97 100644 --- a/packager/media/formats/packed_audio/packed_audio_segmenter.cc +++ b/packager/media/formats/packed_audio/packed_audio_segmenter.cc @@ -24,7 +24,10 @@ std::string TimestampToString(uint64_t timestamp) { } } // namespace -PackedAudioSegmenter::PackedAudioSegmenter() = default; +PackedAudioSegmenter::PackedAudioSegmenter( + uint32_t transport_stream_timestamp_offset) + : transport_stream_timestamp_offset_(transport_stream_timestamp_offset) {} + PackedAudioSegmenter::~PackedAudioSegmenter() = default; Status PackedAudioSegmenter::Initialize(const StreamInfo& stream_info) { @@ -54,7 +57,7 @@ Status PackedAudioSegmenter::AddSample(const MediaSample& sample) { RETURN_IF_ERROR(EncryptionAudioSetup(sample)); if (start_of_new_segment_) { - StartNewSegment(sample); + RETURN_IF_ERROR(StartNewSegment(sample)); start_of_new_segment_ = false; } @@ -118,18 +121,30 @@ Status PackedAudioSegmenter::EncryptionAudioSetup(const MediaSample& sample) { return Status::OK; } -void PackedAudioSegmenter::StartNewSegment(const MediaSample& sample) { +Status PackedAudioSegmenter::StartNewSegment(const MediaSample& sample) { segment_buffer_.Clear(); + const int64_t pts = + sample.pts() * timescale_scale_ + transport_stream_timestamp_offset_; + if (pts < 0) { + LOG(ERROR) << "Seeing negative timestamp " << pts + << " after applying offset " + << transport_stream_timestamp_offset_ + << ". Please check if it is expected. Adjust " + "--transport_stream_timestamp_offset_ms if needed."; + return Status(error::MUXER_FAILURE, "Unsupported negative timestamp."); + } + // Use a unique_ptr so it can be mocked for testing. std::unique_ptr id3_tag = CreateId3Tag(); - id3_tag->AddPrivateFrame(kTimestampOwnerIdentifier, - TimestampToString(sample.pts() * timescale_scale_)); + id3_tag->AddPrivateFrame(kTimestampOwnerIdentifier, TimestampToString(pts)); if (!audio_setup_information_.empty()) { id3_tag->AddPrivateFrame(kAudioDescriptionOwnerIdentifier, audio_setup_information_); } CHECK(id3_tag->WriteToBuffer(&segment_buffer_)); + + return Status::OK; } } // namespace media diff --git a/packager/media/formats/packed_audio/packed_audio_segmenter.h b/packager/media/formats/packed_audio/packed_audio_segmenter.h index c912c75328..62c239e734 100644 --- a/packager/media/formats/packed_audio/packed_audio_segmenter.h +++ b/packager/media/formats/packed_audio/packed_audio_segmenter.h @@ -39,7 +39,10 @@ constexpr char kAudioDescriptionOwnerIdentifier[] = /// simply packed together with minimal framing and no per-sample timestamps. class PackedAudioSegmenter { public: - PackedAudioSegmenter(); + /// @param transport_stream_timestamp_offset is the offset to be applied to + /// sample timestamps to compensate for possible negative timestamps in + /// the input. + explicit PackedAudioSegmenter(uint32_t transport_stream_timestamp_offset); virtual ~PackedAudioSegmenter(); /// Initialize the object. @@ -76,8 +79,9 @@ class PackedAudioSegmenter { virtual std::unique_ptr CreateId3Tag(); Status EncryptionAudioSetup(const MediaSample& sample); - void StartNewSegment(const MediaSample& first_sample); + Status StartNewSegment(const MediaSample& first_sample); + const uint32_t transport_stream_timestamp_offset_ = 0; // Codec for the stream. Codec codec_ = kUnknownCodec; std::vector audio_codec_config_; diff --git a/packager/media/formats/packed_audio/packed_audio_segmenter_unittest.cc b/packager/media/formats/packed_audio/packed_audio_segmenter_unittest.cc index 5fb6ec19a3..65e12ae14d 100644 --- a/packager/media/formats/packed_audio/packed_audio_segmenter_unittest.cc +++ b/packager/media/formats/packed_audio/packed_audio_segmenter_unittest.cc @@ -30,6 +30,7 @@ namespace shaka { namespace media { namespace { +constexpr uint32_t kZeroTransportStreamTimestampOffset = 0; constexpr uint32_t kTimescale = 5625; constexpr double kExpectedTimescaleScale = kPackedAudioTimescale / kTimescale; static_assert(kExpectedTimescaleScale == 16.0, ""); @@ -115,6 +116,9 @@ class MockId3Tag : public Id3Tag { class TestablePackedAudioSegmenter : public PackedAudioSegmenter { public: + TestablePackedAudioSegmenter() + : PackedAudioSegmenter(kZeroTransportStreamTimestampOffset) {} + MOCK_METHOD0(CreateAdtsConverter, std::unique_ptr()); MOCK_METHOD0(CreateId3Tag, std::unique_ptr()); }; diff --git a/packager/media/formats/packed_audio/packed_audio_writer.cc b/packager/media/formats/packed_audio/packed_audio_writer.cc index dc8e703abe..29f796c56e 100644 --- a/packager/media/formats/packed_audio/packed_audio_writer.cc +++ b/packager/media/formats/packed_audio/packed_audio_writer.cc @@ -14,7 +14,12 @@ namespace shaka { namespace media { PackedAudioWriter::PackedAudioWriter(const MuxerOptions& muxer_options) - : Muxer(muxer_options), segmenter_(new PackedAudioSegmenter) {} + : Muxer(muxer_options), + transport_stream_timestamp_offset_( + muxer_options.transport_stream_timestamp_offset_ms * + kPackedAudioTimescale / 1000), + segmenter_(new PackedAudioSegmenter(transport_stream_timestamp_offset_)) { +} PackedAudioWriter::~PackedAudioWriter() = default; @@ -84,7 +89,7 @@ Status PackedAudioWriter::FinalizeSegment(size_t stream_id, if (muxer_listener()) { muxer_listener()->OnNewSegment( - segment_path, segment_timestamp, + segment_path, segment_timestamp + transport_stream_timestamp_offset_, segment_info.duration * segmenter_->TimescaleScale(), segment_size); } return Status::OK; diff --git a/packager/media/formats/packed_audio/packed_audio_writer.h b/packager/media/formats/packed_audio/packed_audio_writer.h index 36a8b21a3c..59f46bb23a 100644 --- a/packager/media/formats/packed_audio/packed_audio_writer.h +++ b/packager/media/formats/packed_audio/packed_audio_writer.h @@ -43,6 +43,7 @@ class PackedAudioWriter : public Muxer { Status CloseFile(std::unique_ptr file); + const uint32_t transport_stream_timestamp_offset_ = 0; std::unique_ptr segmenter_; // Used in single segment mode. diff --git a/packager/media/formats/packed_audio/packed_audio_writer_unittest.cc b/packager/media/formats/packed_audio/packed_audio_writer_unittest.cc index 9ffe6456d2..18c68fe515 100644 --- a/packager/media/formats/packed_audio/packed_audio_writer_unittest.cc +++ b/packager/media/formats/packed_audio/packed_audio_writer_unittest.cc @@ -35,6 +35,7 @@ const size_t kOutputs = 0; const size_t kInput = 0; const size_t kStreamIndex = 0; +const uint32_t kZeroTransportStreamTimestampOffset = 0; const uint32_t kTimescale = 9000; // For single-segment mode. @@ -46,6 +47,9 @@ const char kSegment2Name[] = "memory://test_2.aac"; class MockPackedAudioSegmenter : public PackedAudioSegmenter { public: + MockPackedAudioSegmenter() + : PackedAudioSegmenter(kZeroTransportStreamTimestampOffset) {} + MOCK_METHOD1(Initialize, Status(const StreamInfo& stream_info)); MOCK_METHOD1(AddSample, Status(const MediaSample& sample)); MOCK_METHOD0(FinalizeSegment, Status()); diff --git a/packager/media/formats/webm/webm_muxer.cc b/packager/media/formats/webm/webm_muxer.cc index 793744ed49..dcf02be7a7 100644 --- a/packager/media/formats/webm/webm_muxer.cc +++ b/packager/media/formats/webm/webm_muxer.cc @@ -61,6 +61,10 @@ Status WebMMuxer::Finalize() { Status WebMMuxer::AddSample(size_t stream_id, const MediaSample& sample) { DCHECK(segmenter_); DCHECK_EQ(stream_id, 0u); + if (sample.pts() < 0) { + LOG(ERROR) << "Seeing negative timestamp " << sample.pts(); + return Status(error::MUXER_FAILURE, "Unsupported negative timestamp."); + } return segmenter_->AddSample(sample); } diff --git a/packager/media/formats/webvtt/webvtt_file_buffer.cc b/packager/media/formats/webvtt/webvtt_file_buffer.cc index 92d181f888..28359a7173 100644 --- a/packager/media/formats/webvtt/webvtt_file_buffer.cc +++ b/packager/media/formats/webvtt/webvtt_file_buffer.cc @@ -6,16 +6,21 @@ #include "packager/media/formats/webvtt/webvtt_file_buffer.h" +#include "packager/base/strings/stringprintf.h" #include "packager/media/base/text_sample.h" #include "packager/media/formats/webvtt/webvtt_timestamp.h" namespace shaka { namespace media { namespace { -const char* kHeader = "WEBVTT\n\n"; +const char* kHeader = "WEBVTT\n"; +const int kTsTimescale = 90000; } -WebVttFileBuffer::WebVttFileBuffer() { +WebVttFileBuffer::WebVttFileBuffer( + uint32_t transport_stream_timestamp_offset_ms) + : transport_stream_timestamp_offset_(transport_stream_timestamp_offset_ms * + kTsTimescale / 1000) { // Make sure we start with the same state that we would end up with if // the caller reset our state. Reset(); @@ -26,6 +31,13 @@ void WebVttFileBuffer::Reset() { buffer_.clear(); buffer_.append(kHeader); + if (transport_stream_timestamp_offset_ > 0) { + // https://tools.ietf.org/html/rfc8216#section-3.5 WebVTT. + base::StringAppendF(&buffer_, + "X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:%d\n", + transport_stream_timestamp_offset_); + } + buffer_.append("\n"); // end of header. } void WebVttFileBuffer::Append(const TextSample& sample) { diff --git a/packager/media/formats/webvtt/webvtt_file_buffer.h b/packager/media/formats/webvtt/webvtt_file_buffer.h index be168dd4b7..7ef23541e0 100644 --- a/packager/media/formats/webvtt/webvtt_file_buffer.h +++ b/packager/media/formats/webvtt/webvtt_file_buffer.h @@ -20,7 +20,7 @@ class TextSample; // all the formatting requirements for a webvtt file. class WebVttFileBuffer { public: - WebVttFileBuffer(); + explicit WebVttFileBuffer(uint32_t transport_stream_timestamp_offset_ms); virtual ~WebVttFileBuffer() = default; void Reset(); @@ -35,6 +35,7 @@ class WebVttFileBuffer { WebVttFileBuffer(const WebVttFileBuffer&) = delete; WebVttFileBuffer& operator=(const WebVttFileBuffer&) = delete; + const uint32_t transport_stream_timestamp_offset_ = 0; std::string buffer_; size_t sample_count_ = 0; }; diff --git a/packager/media/formats/webvtt/webvtt_text_output_handler.cc b/packager/media/formats/webvtt/webvtt_text_output_handler.cc index cfb299216a..62b932cbac 100644 --- a/packager/media/formats/webvtt/webvtt_text_output_handler.cc +++ b/packager/media/formats/webvtt/webvtt_text_output_handler.cc @@ -24,7 +24,8 @@ WebVttTextOutputHandler::WebVttTextOutputHandler( const MuxerOptions& muxer_options, std::unique_ptr muxer_listener) : muxer_options_(muxer_options), - muxer_listener_(std::move(muxer_listener)) {} + muxer_listener_(std::move(muxer_listener)), + buffer_(muxer_options.transport_stream_timestamp_offset_ms) {} Status WebVttTextOutputHandler::InitializeInternal() { return Status::OK; diff --git a/packager/packager.cc b/packager/packager.cc index df81c3ac36..82ba9a2ab5 100644 --- a/packager/packager.cc +++ b/packager/packager.cc @@ -73,6 +73,8 @@ MuxerOptions CreateMuxerOptions(const StreamDescriptor& stream, MuxerOptions options; options.mp4_params = params.mp4_output_params; + options.transport_stream_timestamp_offset_ms = + params.transport_stream_timestamp_offset_ms; options.temp_dir = params.temp_dir; options.bandwidth = stream.bandwidth; options.output_file_name = stream.output; @@ -747,6 +749,9 @@ Status CreateAllJobs(const std::vector& stream_descriptors, std::vector> audio_video_streams; + bool has_transport_audio_video_streams = false; + bool has_non_transport_audio_video_streams = false; + for (const StreamDescriptor& stream : stream_descriptors) { // TODO: Find a better way to determine what stream type a stream // descriptor is as |stream_selector| may use an index. This would @@ -755,6 +760,18 @@ Status CreateAllJobs(const std::vector& stream_descriptors, text_streams.push_back(stream); } else { audio_video_streams.push_back(stream); + + switch (GetOutputFormat(stream)) { + case CONTAINER_MPEG2TS: + case CONTAINER_AAC: + case CONTAINER_AC3: + case CONTAINER_EAC3: + has_transport_audio_video_streams = true; + break; + default: + has_non_transport_audio_video_streams = true; + break; + } } } @@ -763,9 +780,26 @@ Status CreateAllJobs(const std::vector& stream_descriptors, std::sort(audio_video_streams.begin(), audio_video_streams.end(), media::StreamDescriptorCompareFn); - RETURN_IF_ERROR(CreateTextJobs(text_streams, packaging_params, sync_points, - muxer_listener_factory, muxer_factory, - mpd_notifier, job_manager)); + if (!text_streams.empty()) { + PackagingParams text_packaging_params = packaging_params; + if (text_packaging_params.transport_stream_timestamp_offset_ms > 0) { + if (has_transport_audio_video_streams && + has_non_transport_audio_video_streams) { + LOG(WARNING) << "There may be problems mixing transport streams and " + "non-transport streams. For example, the subtitles may " + "be out of sync with non-transport streams."; + } else if (has_non_transport_audio_video_streams) { + // Don't insert the X-TIMESTAMP-MAP in WebVTT if there is no transport + // stream. + text_packaging_params.transport_stream_timestamp_offset_ms = 0; + } + } + + RETURN_IF_ERROR(CreateTextJobs(text_streams, text_packaging_params, + sync_points, muxer_listener_factory, + muxer_factory, mpd_notifier, job_manager)); + } + RETURN_IF_ERROR(CreateAudioVideoJobs( audio_video_streams, packaging_params, encryption_key_source, sync_points, muxer_listener_factory, muxer_factory, job_manager)); diff --git a/packager/packager.h b/packager/packager.h index dbe68419d5..1fd621ae82 100644 --- a/packager/packager.h +++ b/packager/packager.h @@ -40,6 +40,10 @@ struct PackagingParams { std::string temp_dir; /// MP4 (ISO-BMFF) output related parameters. Mp4OutputParams mp4_output_params; + /// The offset to be applied to transport stream (e.g. MPEG2-TS, HLS packed + /// audio) timestamps to compensate for possible negative timestamps in the + /// input. + uint32_t transport_stream_timestamp_offset_ms = 0; /// Chunking (segmentation) related parameters. ChunkingParams chunking_params;