Skip to content

Commit

Permalink
[DASH] Indicate startNumber in SegmentTemplate.
Browse files Browse the repository at this point in the history
  • Loading branch information
sr1990 committed Jan 31, 2021
1 parent fe39f14 commit b31c7cd
Show file tree
Hide file tree
Showing 20 changed files with 77 additions and 11 deletions.
4 changes: 4 additions & 0 deletions docs/source/options/chunking_options.rst
Expand Up @@ -21,3 +21,7 @@ Chunking options

Force fragments to begin with stream access points. This flag implies
*segment_sap_aligned*. Default enabled.

--start_segment_number

Indicates the startNumber in DASH SegmentTemplate.
3 changes: 3 additions & 0 deletions packager/app/muxer_flags.cc
Expand Up @@ -53,3 +53,6 @@ DEFINE_int32(transport_stream_timestamp_offset_ms,
"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.");
DEFINE_int64(start_segment_number,
1,
"Indicates the startNumber in DASH SegmentTemplate.");
1 change: 1 addition & 0 deletions packager/app/muxer_flags.h
Expand Up @@ -20,5 +20,6 @@ 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);
DECLARE_int64(start_segment_number);

#endif // APP_MUXER_FLAGS_H_
6 changes: 6 additions & 0 deletions packager/app/packager_main.cc
Expand Up @@ -327,6 +327,12 @@ base::Optional<PackagingParams> GetPackagingParams() {
chunking_params.subsegment_duration_in_seconds = FLAGS_fragment_duration;
chunking_params.segment_sap_aligned = FLAGS_segment_sap_aligned;
chunking_params.subsegment_sap_aligned = FLAGS_fragment_sap_aligned;
chunking_params.start_segment_number = FLAGS_start_segment_number;

if (chunking_params.start_segment_number < 0) {
LOG(ERROR) << "Negative --start_segment_number not allowed.";
return base::nullopt;
}

int num_key_providers = 0;
EncryptionParams& encryption_params = packaging_params.encryption_params;
Expand Down
14 changes: 13 additions & 1 deletion packager/app/test/packager_test.py
Expand Up @@ -478,7 +478,8 @@ def _GetFlags(self,
default_language=None,
segment_duration=1.0,
use_fake_clock=True,
allow_codec_switching=False):
allow_codec_switching=False,
start_segment_number=-1):
flags = ['--single_threaded']

if not strip_parameter_set_nalus:
Expand Down Expand Up @@ -562,6 +563,10 @@ def _GetFlags(self,
if allow_codec_switching:
flags += ['--allow_codec_switching']

if start_segment_number != -1:
flags += ['--start_segment_number={0}'.format(
start_segment_number)]

if ad_cues:
flags += ['--ad_cues', ad_cues]

Expand Down Expand Up @@ -781,6 +786,13 @@ def testDashOnlyAndHlsOnly(self):
self._GetFlags(output_dash=True, output_hls=True))
self._CheckTestResults('hls-only-dash-only')

def testDashStartNumber(self):
audio_video_streams = self._GetStreams(['audio', 'video'], segmented=True)
streams = audio_video_streams
self.assertPackageSuccess(streams, self._GetFlags(output_dash=True,
start_segment_number=0))
self._CheckTestResults('dash-start-number')

def testAudioVideoWithLanguageOverride(self):
self.assertPackageSuccess(
self._GetStreams(['audio', 'video'], language='por', hls=True),
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
28 changes: 28 additions & 0 deletions packager/app/test/testdata/dash-start-number/output.mpd
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_time" availabilityStartTime="some_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
<Period id="0" start="PT0S">
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
<Representation id="0" bandwidth="974154" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
<SegmentTemplate timescale="30000" initialization="bear-640x360-video-init.mp4" media="bear-640x360-video-$Number$.m4s" startNumber="0">
<SegmentTimeline>
<S t="0" d="30030" r="1"/>
<S t="60060" d="22022"/>
</SegmentTimeline>
</SegmentTemplate>
</Representation>
</AdaptationSet>
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
<Representation id="1" bandwidth="133961" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<SegmentTemplate timescale="44100" initialization="bear-640x360-audio-init.mp4" media="bear-640x360-audio-$Number$.m4s" startNumber="0">
<SegmentTimeline>
<S t="0" d="45056"/>
<S t="45056" d="44032"/>
<S t="89088" d="31744"/>
</SegmentTimeline>
</SegmentTemplate>
</Representation>
</AdaptationSet>
</Period>
</MPD>
6 changes: 3 additions & 3 deletions packager/media/chunking/chunking_handler.cc
Expand Up @@ -153,9 +153,9 @@ Status ChunkingHandler::EndSegmentIfStarted() const {
auto segment_info = std::make_shared<SegmentInfo>();
segment_info->start_timestamp = segment_start_time_.value();
segment_info->duration = max_segment_time_ - segment_start_time_.value();
segment_info->segment_index =
current_segment_index_ + num_segments_before_last_cue_;

segment_info->segment_index = current_segment_index_ +
num_segments_before_last_cue_ +
chunking_params_.start_segment_number - 1;
return DispatchSegmentInfo(kStreamIndex, std::move(segment_info));
}

Expand Down
9 changes: 6 additions & 3 deletions packager/media/chunking/text_chunker.cc
Expand Up @@ -14,8 +14,10 @@ namespace {
const size_t kStreamIndex = 0;
} // namespace

TextChunker::TextChunker(double segment_duration_in_seconds)
: segment_duration_in_seconds_(segment_duration_in_seconds){};
TextChunker::TextChunker(double segment_duration_in_seconds,
int64_t start_segment_number)
: segment_duration_in_seconds_(segment_duration_in_seconds),
start_segment_number_(start_segment_number){};

Status TextChunker::Process(std::unique_ptr<StreamData> data) {
switch (data->stream_data_type) {
Expand Down Expand Up @@ -106,7 +108,8 @@ Status TextChunker::DispatchSegment(int64_t duration) {
std::shared_ptr<SegmentInfo> info = std::make_shared<SegmentInfo>();
info->start_timestamp = segment_start_;
info->duration = duration;
info->segment_index = (segment_start_ / segment_duration_) + num_cues_;
info->segment_index = (segment_start_ / segment_duration_) + num_cues_ +
start_segment_number_ - 1;

RETURN_IF_ERROR(DispatchSegmentInfo(kStreamIndex, std::move(info)));

Expand Down
5 changes: 4 additions & 1 deletion packager/media/chunking/text_chunker.h
Expand Up @@ -20,7 +20,8 @@ namespace media {
// is when a cue event is seen.
class TextChunker : public MediaHandler {
public:
explicit TextChunker(double segment_duration_in_seconds);
explicit TextChunker(double segment_duration_in_seconds,
int64_t start_segment_number);

private:
TextChunker(const TextChunker&) = delete;
Expand Down Expand Up @@ -52,6 +53,8 @@ class TextChunker : public MediaHandler {
int64_t segment_start_ = -1; // Set when the first sample comes in.
int64_t segment_duration_ = -1; // Set in OnStreamInfo.

int64_t start_segment_number_ = 1;

int64_t num_cues_ = 0;

// All samples that make up the current segment. We must store the samples
Expand Down
5 changes: 4 additions & 1 deletion packager/media/chunking/text_chunker_unittest.cc
Expand Up @@ -31,6 +31,8 @@ const bool kSubSegment = true;

const uint64_t kTimescaleMs = 1000;

const int64_t kStartSegmentNumber = 1;

const char* kNoId = "";
const char* kNoPayload = "";
} // namespace
Expand All @@ -39,7 +41,8 @@ class TextChunkerTest : public MediaHandlerTestBase {
protected:
Status Init(double segment_duration) {
return SetUpAndInitializeGraph(
std::make_shared<TextChunker>(segment_duration), kInputs, kOutputs);
std::make_shared<TextChunker>(segment_duration, kStartSegmentNumber),
kInputs, kOutputs);
}
};

Expand Down
3 changes: 3 additions & 0 deletions packager/media/public/chunking_params.h
Expand Up @@ -25,6 +25,9 @@ struct ChunkingParams {
/// Setting to subsegment_sap_aligned to true but segment_sap_aligned to false
/// is not allowed.
bool subsegment_sap_aligned = true;

/// Indicates the startNumber in DASH SegmentTemplate.
int64_t start_segment_number = 1;
};

} // namespace shaka
Expand Down
4 changes: 2 additions & 2 deletions packager/packager.cc
Expand Up @@ -499,8 +499,8 @@ std::unique_ptr<MediaHandler> CreateTextChunker(
const ChunkingParams& chunking_params) {
const float segment_length_in_seconds =
chunking_params.segment_duration_in_seconds;
return std::unique_ptr<MediaHandler>(
new TextChunker(segment_length_in_seconds));
return std::unique_ptr<MediaHandler>(new TextChunker(
segment_length_in_seconds, chunking_params.start_segment_number));
}

Status CreateTtmlJobs(
Expand Down

0 comments on commit b31c7cd

Please sign in to comment.