2015-10-28 17:23:08 +00:00
|
|
|
// Copyright 2015 Google Inc. All rights reserved.
|
|
|
|
//
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file or at
|
|
|
|
// https://developers.google.com/open-source/licenses/bsd
|
|
|
|
|
|
|
|
#include "packager/media/formats/webm/multi_segment_segmenter.h"
|
|
|
|
|
|
|
|
#include "packager/media/base/media_stream.h"
|
|
|
|
#include "packager/media/base/muxer_options.h"
|
|
|
|
#include "packager/media/base/muxer_util.h"
|
|
|
|
#include "packager/media/base/stream_info.h"
|
|
|
|
#include "packager/media/event/muxer_listener.h"
|
|
|
|
#include "packager/third_party/libwebm/src/mkvmuxer.hpp"
|
|
|
|
|
2016-05-20 21:19:33 +00:00
|
|
|
namespace shaka {
|
2015-10-28 17:23:08 +00:00
|
|
|
namespace media {
|
|
|
|
namespace webm {
|
|
|
|
MultiSegmentSegmenter::MultiSegmentSegmenter(const MuxerOptions& options)
|
|
|
|
: Segmenter(options), num_segment_(0) {}
|
|
|
|
|
|
|
|
MultiSegmentSegmenter::~MultiSegmentSegmenter() {}
|
|
|
|
|
2016-04-15 23:00:27 +00:00
|
|
|
bool MultiSegmentSegmenter::GetInitRangeStartAndEnd(uint64_t* start,
|
|
|
|
uint64_t* end) {
|
2015-10-28 17:23:08 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-04-15 23:00:27 +00:00
|
|
|
bool MultiSegmentSegmenter::GetIndexRangeStartAndEnd(uint64_t* start,
|
|
|
|
uint64_t* end) {
|
2015-10-28 17:23:08 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status MultiSegmentSegmenter::DoInitialize(scoped_ptr<MkvWriter> writer) {
|
|
|
|
writer_ = writer.Pass();
|
|
|
|
return WriteSegmentHeader(0, writer_.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
Status MultiSegmentSegmenter::DoFinalize() {
|
2016-04-15 23:00:27 +00:00
|
|
|
Status status = FinalizeSegment();
|
|
|
|
status.Update(writer_->Close());
|
|
|
|
return status;
|
2015-10-28 17:23:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Status MultiSegmentSegmenter::FinalizeSegment() {
|
|
|
|
if (!cluster()->Finalize())
|
|
|
|
return Status(error::FILE_FAILURE, "Error finalizing segment.");
|
|
|
|
|
|
|
|
if (muxer_listener()) {
|
|
|
|
const uint64_t size = cluster()->Size();
|
|
|
|
const uint64_t start_webm_timecode = cluster()->timecode();
|
|
|
|
const uint64_t start_timescale = FromWebMTimecode(start_webm_timecode);
|
|
|
|
const uint64_t length = static_cast<uint64_t>(
|
2015-12-22 00:33:55 +00:00
|
|
|
cluster_length_sec() * info()->time_scale());
|
2016-03-28 08:23:20 +00:00
|
|
|
muxer_listener()->OnNewSegment(writer_->file()->file_name(),
|
|
|
|
start_timescale, length, size);
|
2015-10-28 17:23:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VLOG(1) << "WEBM file '" << writer_->file()->file_name() << "' finalized.";
|
|
|
|
return Status::OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status MultiSegmentSegmenter::NewSubsegment(uint64_t start_timescale) {
|
|
|
|
if (cluster() && !cluster()->Finalize())
|
|
|
|
return Status(error::FILE_FAILURE, "Error finalizing segment.");
|
|
|
|
|
|
|
|
uint64_t start_webm_timecode = FromBMFFTimescale(start_timescale);
|
|
|
|
return SetCluster(start_webm_timecode, 0, writer_.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
Status MultiSegmentSegmenter::NewSegment(uint64_t start_timescale) {
|
|
|
|
if (cluster()) {
|
|
|
|
Status temp = FinalizeSegment();
|
|
|
|
if (!temp.ok())
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a new file for the new segment.
|
|
|
|
std::string segment_name =
|
2016-07-11 21:40:02 +00:00
|
|
|
GetSegmentName(options().segment_template, start_timescale,
|
|
|
|
start_timescale, num_segment_, options().bandwidth);
|
2015-10-28 17:23:08 +00:00
|
|
|
writer_.reset(new MkvWriter);
|
|
|
|
Status status = writer_->Open(segment_name);
|
|
|
|
if (!status.ok())
|
|
|
|
return status;
|
|
|
|
num_segment_++;
|
|
|
|
|
|
|
|
uint64_t start_webm_timecode = FromBMFFTimescale(start_timescale);
|
|
|
|
return SetCluster(start_webm_timecode, 0, writer_.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace webm
|
|
|
|
} // namespace media
|
2016-05-20 21:19:33 +00:00
|
|
|
} // namespace shaka
|