Shaka Packager SDK
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 <absl/log/check.h>
10 #include <mkvmuxer/mkvmuxer.h>
11 
12 #include <packager/macros/logging.h>
13 #include <packager/macros/status.h>
14 #include <packager/media/base/muxer_options.h>
15 #include <packager/media/base/muxer_util.h>
16 #include <packager/media/base/stream_info.h>
17 #include <packager/media/event/muxer_listener.h>
18 
19 namespace shaka {
20 namespace media {
21 namespace webm {
22 
23 MultiSegmentSegmenter::MultiSegmentSegmenter(const MuxerOptions& options)
24  : Segmenter(options), num_segment_(0) {}
25 
26 MultiSegmentSegmenter::~MultiSegmentSegmenter() {}
27 
28 Status MultiSegmentSegmenter::FinalizeSegment(int64_t start_timestamp,
29  int64_t duration_timestamp,
30  bool is_subsegment,
31  int64_t segment_number) {
32  CHECK(cluster());
33  RETURN_IF_ERROR(Segmenter::FinalizeSegment(
34  start_timestamp, duration_timestamp, is_subsegment, segment_number));
35  if (!cluster()->Finalize())
36  return Status(error::FILE_FAILURE, "Error finalizing segment.");
37 
38  if (!is_subsegment) {
39  std::string segment_name =
40  GetSegmentName(options().segment_template, start_timestamp,
41  segment_number, options().bandwidth);
42 
43  // Close the file, which also does flushing, to make sure the file is
44  // written before manifest is updated.
45  RETURN_IF_ERROR(writer_->Close());
46 
47  if (!File::Copy(temp_file_name_.c_str(), segment_name.c_str()))
48  return Status(error::FILE_FAILURE, "Failure to copy memory file.");
49 
50  if (!File::Delete(temp_file_name_.c_str()))
51  return Status(error::FILE_FAILURE, "Failure to delete memory file.");
52 
53  num_segment_++;
54 
55  if (muxer_listener()) {
56  const uint64_t size = cluster()->Size();
57  muxer_listener()->OnNewSegment(segment_name, start_timestamp,
58  duration_timestamp, size, segment_number);
59  }
60  VLOG(1) << "WEBM file '" << segment_name << "' finalized.";
61  }
62  return Status::OK;
63 }
64 
65 bool MultiSegmentSegmenter::GetInitRangeStartAndEnd(uint64_t* /*start*/,
66  uint64_t* /*end*/) {
67  return false;
68 }
69 
70 bool MultiSegmentSegmenter::GetIndexRangeStartAndEnd(uint64_t* /*start*/,
71  uint64_t* /*end*/) {
72  return false;
73 }
74 
75 std::vector<Range> MultiSegmentSegmenter::GetSegmentRanges() {
76  return std::vector<Range>();
77 }
78 
79 Status MultiSegmentSegmenter::DoInitialize() {
80  std::unique_ptr<MkvWriter> writer(new MkvWriter);
81  Status status = writer->Open(options().output_file_name);
82  if (!status.ok())
83  return status;
84  writer_ = std::move(writer);
85  return WriteSegmentHeader(0, writer_.get());
86 }
87 
88 Status MultiSegmentSegmenter::DoFinalize() {
89  return Status::OK;
90 }
91 
92 Status MultiSegmentSegmenter::NewSegment(int64_t start_timestamp,
93  bool is_subsegment) {
94  if (!is_subsegment) {
95  temp_file_name_ =
96  "memory://" + GetSegmentName(options().segment_template,
97  start_timestamp, num_segment_,
98  options().bandwidth);
99 
100  writer_.reset(new MkvWriter);
101  Status status = writer_->Open(temp_file_name_);
102 
103  if (!status.ok())
104  return status;
105  }
106 
107  const int64_t start_timecode = FromBmffTimestamp(start_timestamp);
108  return SetCluster(start_timecode, 0, writer_.get());
109 }
110 
111 } // namespace webm
112 } // namespace media
113 } // namespace shaka
An implementation of IMkvWriter using our File type.
Definition: mkv_writer.h:23
All the methods that are virtual are virtual for mocking.
Definition: crypto_flags.cc:66