Use PTS instead of DTS in ChunkingHandler
DTS was used in ChunkingHandler. As a result, SegmentInfo contained timestamp in DTS. MP4Muxer has a logic to change SegmentInfo to use PTS but not in other muxers. Benefits of using PTS in ChunkingHandler: - De-dup the redundant logic in MP4Muxer - Ensure consistent behavior in different output containers - Consistent with other timestamps, e.g. Ad Cue timestamps Issue #413 Change-Id: Ib671badf144e0c0866d60f4ff0ac0cbbdd33817e
This commit is contained in:
parent
5f072e3b08
commit
571ee24f3e
|
@ -10,7 +10,7 @@ bear-640x360-video-1.ts
|
|||
#EXTINF:1.001,
|
||||
#EXT-X-BYTERANGE:18236@376
|
||||
bear-640x360-video-2.ts
|
||||
#EXTINF:0.667,
|
||||
#EXTINF:0.734,
|
||||
#EXT-X-BYTERANGE:19928@376
|
||||
bear-640x360-video-3.ts
|
||||
#EXT-X-ENDLIST
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
#EXT-X-STREAM-INF:BANDWIDTH=1217520,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
bear-640x360-video.m3u8
|
||||
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=238898,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
|
|
|
@ -10,7 +10,7 @@ bear-640x360-video-1.ts
|
|||
#EXTINF:1.001,
|
||||
#EXT-X-BYTERANGE:18236@376
|
||||
bear-640x360-video-2.ts
|
||||
#EXTINF:0.667,
|
||||
#EXTINF:0.734,
|
||||
#EXT-X-BYTERANGE:19928@376
|
||||
bear-640x360-video-3.ts
|
||||
#EXT-X-ENDLIST
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
#EXT-X-STREAM-INF:BANDWIDTH=1217520,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
bear-640x360-video.m3u8
|
||||
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=238898,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<Representation id="0" bandwidth="1023201" codecs="avc1.64001e" mimeType="video/MP2T" sar="1:1" frameRate="90000/0">
|
||||
<SegmentTemplate timescale="90000" media="bear-640x360-video-$Number$.ts" startNumber="1">
|
||||
<SegmentTimeline>
|
||||
<S t="0" d="90090" r="1"/>
|
||||
<S t="180180" d="66066"/>
|
||||
<S t="6006" d="90090" r="1"/>
|
||||
<S t="186186" d="66066"/>
|
||||
</SegmentTimeline>
|
||||
</SegmentTemplate>
|
||||
</Representation>
|
||||
|
|
|
@ -12,7 +12,7 @@ bear-640x360-ac3-video-1.ts
|
|||
#EXTINF:1.001,
|
||||
#EXT-X-BYTERANGE:18236@376
|
||||
bear-640x360-ac3-video-2.ts
|
||||
#EXTINF:0.667,
|
||||
#EXTINF:0.734,
|
||||
#EXT-X-BYTERANGE:19928@376
|
||||
bear-640x360-ac3-video-3.ts
|
||||
#EXT-X-ENDLIST
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
#EXT-X-STREAM-INF:BANDWIDTH=1242863,CODECS="avc1.64001e,ac-3",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
bear-640x360-ac3-video.m3u8
|
||||
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=238898,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ac3-video-iframe.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ac3-video-iframe.m3u8"
|
||||
|
|
|
@ -10,7 +10,7 @@ bear-640x360-ac3-video-1.ts
|
|||
#EXTINF:1.001,
|
||||
#EXT-X-BYTERANGE:18236@376
|
||||
bear-640x360-ac3-video-2.ts
|
||||
#EXTINF:0.667,
|
||||
#EXTINF:0.734,
|
||||
#EXT-X-BYTERANGE:19928@376
|
||||
bear-640x360-ac3-video-3.ts
|
||||
#EXT-X-ENDLIST
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
#EXT-X-STREAM-INF:BANDWIDTH=1242863,CODECS="avc1.64001e,ac-3",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
bear-640x360-ac3-video.m3u8
|
||||
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=238898,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ac3-video-iframe.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ac3-video-iframe.m3u8"
|
||||
|
|
|
@ -12,7 +12,7 @@ bear-640x360-video-1.ts
|
|||
#EXTINF:1.001,
|
||||
#EXT-X-BYTERANGE:18236@376
|
||||
bear-640x360-video-2.ts
|
||||
#EXTINF:0.667,
|
||||
#EXTINF:0.734,
|
||||
#EXT-X-BYTERANGE:19928@376
|
||||
bear-640x360-video-3.ts
|
||||
#EXT-X-ENDLIST
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
#EXT-X-STREAM-INF:BANDWIDTH=1154999,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
bear-640x360-video.m3u8
|
||||
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=238898,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
|
|
|
@ -12,7 +12,7 @@ bear-640x360-ac3-video-1.ts
|
|||
#EXTINF:1.001,
|
||||
#EXT-X-BYTERANGE:18236@376
|
||||
bear-640x360-ac3-video-2.ts
|
||||
#EXTINF:0.667,
|
||||
#EXTINF:0.734,
|
||||
#EXT-X-BYTERANGE:19928@376
|
||||
bear-640x360-ac3-video-3.ts
|
||||
#EXT-X-ENDLIST
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
#EXT-X-STREAM-INF:BANDWIDTH=1216578,CODECS="avc1.64001e,ac-3",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
bear-640x360-ac3-video.m3u8
|
||||
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=238898,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ac3-video-iframe.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ac3-video-iframe.m3u8"
|
||||
|
|
|
@ -10,6 +10,6 @@ bear-640x360-video-1.ts
|
|||
#EXTINF:1.001,
|
||||
#EXT-X-BYTERANGE:18236@376
|
||||
bear-640x360-video-2.ts
|
||||
#EXTINF:0.667,
|
||||
#EXTINF:0.734,
|
||||
#EXT-X-BYTERANGE:19928@376
|
||||
bear-640x360-video-3.ts
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
#EXT-X-STREAM-INF:BANDWIDTH=1217520,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
bear-640x360-video.m3u8
|
||||
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=238898,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
#EXT-X-BYTERANGE:18236@376
|
||||
bear-640x360-video-2.ts
|
||||
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="data:text/plain;base64,MzQ1Njc4OTAxMjM0NTYxMg==",IV=0x3334353637383930,KEYFORMAT="identity"
|
||||
#EXTINF:0.667,
|
||||
#EXTINF:0.734,
|
||||
#EXT-X-BYTERANGE:19928@376
|
||||
bear-640x360-video-3.ts
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
#EXT-X-STREAM-INF:BANDWIDTH=1217520,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
bear-640x360-video.m3u8
|
||||
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=238898,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
#EXTINF:1.001,
|
||||
#EXT-X-BYTERANGE:18236@376
|
||||
bear-640x360-video-2.ts
|
||||
#EXTINF:0.667,
|
||||
#EXTINF:0.734,
|
||||
#EXT-X-BYTERANGE:19928@376
|
||||
bear-640x360-video-3.ts
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
#EXT-X-STREAM-INF:BANDWIDTH=1217520,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
bear-640x360-video.m3u8
|
||||
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=238898,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
|
|
|
@ -12,7 +12,7 @@ bear-640x360-video-1.ts
|
|||
#EXTINF:1.001,
|
||||
#EXT-X-BYTERANGE:18236@376
|
||||
bear-640x360-video-2.ts
|
||||
#EXTINF:0.667,
|
||||
#EXTINF:0.734,
|
||||
#EXT-X-BYTERANGE:19928@376
|
||||
bear-640x360-video-3.ts
|
||||
#EXT-X-ENDLIST
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
#EXT-X-STREAM-INF:BANDWIDTH=1217520,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
bear-640x360-video.m3u8
|
||||
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=238898,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
#EXT-X-STREAM-INF:BANDWIDTH=1183949,CODECS="avc1.64001f",RESOLUTION=1024x436
|
||||
sintel-1024x436-video.m3u8
|
||||
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=745984,CODECS="avc1.64001f",RESOLUTION=1024x436,URI="sintel-1024x436-video-iframe.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=447591,CODECS="avc1.64001f",RESOLUTION=1024x436,URI="sintel-1024x436-video-iframe.m3u8"
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -16,15 +16,15 @@ sintel-1024x436-video-2.ts
|
|||
#EXT-X-BYTERANGE:376@376
|
||||
sintel-1024x436-video-3.ts
|
||||
#EXTINF:0.958,
|
||||
#EXT-X-BYTERANGE:376@4700
|
||||
sintel-1024x436-video-3.ts
|
||||
#EXT-X-BYTERANGE:376@376
|
||||
sintel-1024x436-video-4.ts
|
||||
#EXTINF:0.917,
|
||||
#EXT-X-BYTERANGE:5452@376
|
||||
#EXT-X-BYTERANGE:5452@41924
|
||||
sintel-1024x436-video-4.ts
|
||||
#EXTINF:1.000,
|
||||
#EXT-X-BYTERANGE:11092@376
|
||||
sintel-1024x436-video-5.ts
|
||||
#EXTINF:0.125,
|
||||
#EXTINF:0.208,
|
||||
#EXT-X-BYTERANGE:11656@376
|
||||
sintel-1024x436-video-6.ts
|
||||
#EXT-X-ENDLIST
|
||||
|
|
|
@ -9,9 +9,9 @@ sintel-1024x436-video-1.ts
|
|||
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="data:text/plain;base64,MTIzNDU2Nzg5MDEyMzQ1Ng==",IV=0x3334353637383930,KEYFORMAT="identity"
|
||||
#EXTINF:1.000,
|
||||
sintel-1024x436-video-2.ts
|
||||
#EXTINF:1.875,
|
||||
sintel-1024x436-video-3.ts
|
||||
#EXTINF:0.917,
|
||||
sintel-1024x436-video-3.ts
|
||||
#EXTINF:1.875,
|
||||
sintel-1024x436-video-4.ts
|
||||
#EXTINF:1.000,
|
||||
sintel-1024x436-video-5.ts
|
||||
|
|
|
@ -12,7 +12,7 @@ bear-640x360-video-1.ts
|
|||
#EXTINF:1.001,
|
||||
#EXT-X-BYTERANGE:18236@376
|
||||
bear-640x360-video-2.ts
|
||||
#EXTINF:0.667,
|
||||
#EXTINF:0.734,
|
||||
#EXT-X-BYTERANGE:19928@376
|
||||
bear-640x360-video-3.ts
|
||||
#EXT-X-ENDLIST
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
#EXT-X-STREAM-INF:BANDWIDTH=1217520,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
bear-640x360-video.m3u8
|
||||
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=238898,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8"
|
||||
|
|
|
@ -12,7 +12,7 @@ bear-640x360-ec3-video-1.ts
|
|||
#EXTINF:1.001,
|
||||
#EXT-X-BYTERANGE:18236@376
|
||||
bear-640x360-ec3-video-2.ts
|
||||
#EXTINF:0.667,
|
||||
#EXTINF:0.734,
|
||||
#EXT-X-BYTERANGE:19928@376
|
||||
bear-640x360-ec3-video-3.ts
|
||||
#EXT-X-ENDLIST
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
#EXT-X-STREAM-INF:BANDWIDTH=1216655,CODECS="avc1.64001e,ec-3",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
bear-640x360-ec3-video.m3u8
|
||||
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=238898,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ec3-video-iframe.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ec3-video-iframe.m3u8"
|
||||
|
|
|
@ -16,6 +16,16 @@ namespace shaka {
|
|||
namespace media {
|
||||
namespace {
|
||||
const size_t kStreamIndex = 0;
|
||||
|
||||
bool IsNewSegmentIndex(int64_t new_index, int64_t current_index) {
|
||||
return new_index != current_index &&
|
||||
// Index is calculated from pts, which could decrease. We do not expect
|
||||
// it to decrease by more than one segment though, which could happen
|
||||
// only if there is a big overlap in the timeline, in which case, we
|
||||
// will create a new segment and leave it to the player to handle it.
|
||||
new_index != current_index - 1;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ChunkingHandler::ChunkingHandler(const ChunkingParams& chunking_params)
|
||||
|
@ -80,7 +90,7 @@ Status ChunkingHandler::OnMediaSample(
|
|||
std::shared_ptr<const MediaSample> sample) {
|
||||
DCHECK_NE(time_scale_, 0u) << "kStreamInfo should arrive before kMediaSample";
|
||||
|
||||
const int64_t timestamp = sample->dts();
|
||||
const int64_t timestamp = sample->pts();
|
||||
|
||||
bool started_new_segment = false;
|
||||
const bool can_start_new_segment =
|
||||
|
@ -89,7 +99,8 @@ Status ChunkingHandler::OnMediaSample(
|
|||
const int64_t segment_index =
|
||||
timestamp < cue_offset_ ? 0
|
||||
: (timestamp - cue_offset_) / segment_duration_;
|
||||
if (!segment_start_time_ || segment_index != current_segment_index_) {
|
||||
if (!segment_start_time_ ||
|
||||
IsNewSegmentIndex(segment_index, current_segment_index_)) {
|
||||
current_segment_index_ = segment_index;
|
||||
// Reset subsegment index.
|
||||
current_subsegment_index_ = 0;
|
||||
|
@ -97,6 +108,7 @@ Status ChunkingHandler::OnMediaSample(
|
|||
RETURN_IF_ERROR(EndSegmentIfStarted());
|
||||
segment_start_time_ = timestamp;
|
||||
subsegment_start_time_ = timestamp;
|
||||
max_segment_time_ = timestamp + sample->duration();
|
||||
started_new_segment = true;
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +118,7 @@ Status ChunkingHandler::OnMediaSample(
|
|||
if (can_start_new_subsegment) {
|
||||
const int64_t subsegment_index =
|
||||
(timestamp - segment_start_time_.value()) / subsegment_duration_;
|
||||
if (subsegment_index != current_subsegment_index_) {
|
||||
if (IsNewSegmentIndex(subsegment_index, current_subsegment_index_)) {
|
||||
current_subsegment_index_ = subsegment_index;
|
||||
|
||||
RETURN_IF_ERROR(EndSubsegmentIfStarted());
|
||||
|
@ -118,11 +130,17 @@ Status ChunkingHandler::OnMediaSample(
|
|||
VLOG(3) << "Sample ts: " << timestamp << " "
|
||||
<< " duration: " << sample->duration() << " scale: " << time_scale_
|
||||
<< (segment_start_time_ ? " dispatch " : " discard ");
|
||||
if (!segment_start_time_) {
|
||||
DCHECK(!subsegment_start_time_);
|
||||
// Discard samples before segment start. If the segment has started,
|
||||
// |segment_start_time_| won't be null.
|
||||
if (!segment_start_time_)
|
||||
return Status::OK;
|
||||
last_sample_end_timestamp_ = timestamp + sample->duration();
|
||||
}
|
||||
|
||||
segment_start_time_ = std::min(segment_start_time_.value(), timestamp);
|
||||
subsegment_start_time_ = std::min(subsegment_start_time_.value(), timestamp);
|
||||
max_segment_time_ =
|
||||
std::max(max_segment_time_, timestamp + sample->duration());
|
||||
return DispatchMediaSample(kStreamIndex, std::move(sample));
|
||||
}
|
||||
|
||||
|
@ -132,8 +150,7 @@ Status ChunkingHandler::EndSegmentIfStarted() const {
|
|||
|
||||
auto segment_info = std::make_shared<SegmentInfo>();
|
||||
segment_info->start_timestamp = segment_start_time_.value();
|
||||
segment_info->duration =
|
||||
last_sample_end_timestamp_ - segment_start_time_.value();
|
||||
segment_info->duration = max_segment_time_ - segment_start_time_.value();
|
||||
return DispatchSegmentInfo(kStreamIndex, std::move(segment_info));
|
||||
}
|
||||
|
||||
|
@ -144,7 +161,7 @@ Status ChunkingHandler::EndSubsegmentIfStarted() const {
|
|||
auto subsegment_info = std::make_shared<SegmentInfo>();
|
||||
subsegment_info->start_timestamp = subsegment_start_time_.value();
|
||||
subsegment_info->duration =
|
||||
last_sample_end_timestamp_ - subsegment_start_time_.value();
|
||||
max_segment_time_ - subsegment_start_time_.value();
|
||||
subsegment_info->is_subsegment = true;
|
||||
return DispatchSegmentInfo(kStreamIndex, std::move(subsegment_info));
|
||||
}
|
||||
|
|
|
@ -80,9 +80,8 @@ class ChunkingHandler : public MediaHandler {
|
|||
|
||||
base::Optional<int64_t> segment_start_time_;
|
||||
base::Optional<int64_t> subsegment_start_time_;
|
||||
int64_t max_segment_time_ = 0;
|
||||
uint32_t time_scale_ = 0;
|
||||
// The end timestamp of the last dispatched sample.
|
||||
int64_t last_sample_end_timestamp_ = 0;
|
||||
|
||||
// The offset is applied to sample timestamps so a full segment is generated
|
||||
// after cue points.
|
||||
|
|
Loading…
Reference in New Issue