Shaka Packager SDK
Loading...
Searching...
No Matches
multi_segment_segmenter.cc
1// Copyright 2015 Google LLC. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style
4// license that can be found in the LICENSE file or at
5// https://developers.google.com/open-source/licenses/bsd
6
7#include <packager/media/formats/webm/multi_segment_segmenter.h>
8
9#include <cstdint>
10#include <memory>
11#include <string>
12#include <utility>
13#include <vector>
14
15#include <absl/log/check.h>
16#include <absl/log/log.h>
17#include <mkvmuxer/mkvmuxer.h>
18
19#include <packager/file.h>
20#include <packager/macros/status.h>
21#include <packager/media/base/muxer_options.h>
22#include <packager/media/base/muxer_util.h>
23#include <packager/media/base/range.h>
24#include <packager/media/event/muxer_listener.h>
25#include <packager/media/formats/webm/mkv_writer.h>
26#include <packager/media/formats/webm/segmenter.h>
27#include <packager/status.h>
28
29namespace shaka {
30namespace media {
31namespace webm {
32
33MultiSegmentSegmenter::MultiSegmentSegmenter(const MuxerOptions& options)
34 : Segmenter(options), num_segment_(0) {}
35
36MultiSegmentSegmenter::~MultiSegmentSegmenter() {}
37
38Status MultiSegmentSegmenter::FinalizeSegment(int64_t start_timestamp,
39 int64_t duration_timestamp,
40 bool is_subsegment,
41 int64_t segment_number) {
42 CHECK(cluster());
43 RETURN_IF_ERROR(Segmenter::FinalizeSegment(
44 start_timestamp, duration_timestamp, is_subsegment, segment_number));
45 if (!cluster()->Finalize())
46 return Status(error::FILE_FAILURE, "Error finalizing segment.");
47
48 if (!is_subsegment) {
49 std::string segment_name =
50 GetSegmentName(options().segment_template, start_timestamp,
51 segment_number, options().bandwidth);
52
53 // Close the file, which also does flushing, to make sure the file is
54 // written before manifest is updated.
55 RETURN_IF_ERROR(writer_->Close());
56
57 if (!File::Copy(temp_file_name_.c_str(), segment_name.c_str()))
58 return Status(error::FILE_FAILURE, "Failure to copy memory file.");
59
60 if (!File::Delete(temp_file_name_.c_str()))
61 return Status(error::FILE_FAILURE, "Failure to delete memory file.");
62
63 num_segment_++;
64
65 if (muxer_listener()) {
66 const uint64_t size = cluster()->Size();
67 muxer_listener()->OnNewSegment(segment_name, start_timestamp,
68 duration_timestamp, size, segment_number);
69 }
70 VLOG(1) << "WEBM file '" << segment_name << "' finalized.";
71 }
72 return Status::OK;
73}
74
75bool MultiSegmentSegmenter::GetInitRangeStartAndEnd(uint64_t* /*start*/,
76 uint64_t* /*end*/) {
77 return false;
78}
79
80bool MultiSegmentSegmenter::GetIndexRangeStartAndEnd(uint64_t* /*start*/,
81 uint64_t* /*end*/) {
82 return false;
83}
84
85std::vector<Range> MultiSegmentSegmenter::GetSegmentRanges() {
86 return std::vector<Range>();
87}
88
89Status MultiSegmentSegmenter::DoInitialize() {
90 std::unique_ptr<MkvWriter> writer(new MkvWriter);
91 Status status = writer->Open(options().output_file_name);
92 if (!status.ok())
93 return status;
94 writer_ = std::move(writer);
95 return WriteSegmentHeader(0, writer_.get());
96}
97
98Status MultiSegmentSegmenter::DoFinalize() {
99 return Status::OK;
100}
101
102Status MultiSegmentSegmenter::NewSegment(int64_t start_timestamp,
103 bool is_subsegment) {
104 if (!is_subsegment) {
105 temp_file_name_ =
106 "memory://" + GetSegmentName(options().segment_template,
107 start_timestamp, num_segment_,
108 options().bandwidth);
109
110 writer_.reset(new MkvWriter);
111 Status status = writer_->Open(temp_file_name_);
112
113 if (!status.ok())
114 return status;
115 }
116
117 const int64_t start_timecode = FromBmffTimestamp(start_timestamp);
118 return SetCluster(start_timecode, 0, writer_.get());
119}
120
121} // namespace webm
122} // namespace media
123} // namespace shaka
An implementation of IMkvWriter using our File type.
Definition mkv_writer.h:26
All the methods that are virtual are virtual for mocking.