Shaka Packager SDK
segmenter.h
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 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_H_
8 #define PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_H_
9 
10 #include <memory>
11 
12 #include <mkvmuxer/mkvmuxer.h>
13 
14 #include <packager/macros/classes.h>
15 #include <packager/media/base/range.h>
16 #include <packager/media/formats/webm/mkv_writer.h>
17 #include <packager/media/formats/webm/seek_head.h>
18 #include <packager/status.h>
19 
20 namespace shaka {
21 namespace media {
22 
23 struct MuxerOptions;
24 
25 class AudioStreamInfo;
26 class MediaSample;
27 class MuxerListener;
28 class ProgressListener;
29 class StreamInfo;
30 class VideoStreamInfo;
31 
32 namespace webm {
33 
34 class Segmenter {
35  public:
36  explicit Segmenter(const MuxerOptions& options);
37  virtual ~Segmenter();
38 
45  Status Initialize(const StreamInfo& info,
46  ProgressListener* progress_listener,
47  MuxerListener* muxer_listener);
48 
51  Status Finalize();
52 
56  Status AddSample(const MediaSample& sample);
57 
59  virtual Status FinalizeSegment(int64_t start_timestamp,
60  int64_t duration_timestamp,
61  bool is_subsegment,
62  int64_t segment_number) = 0;
63 
66  virtual bool GetInitRangeStartAndEnd(uint64_t* start, uint64_t* end) = 0;
67 
70  virtual bool GetIndexRangeStartAndEnd(uint64_t* start, uint64_t* end) = 0;
71 
72  // Returns an empty vector if there are no specific ranges for the segments,
73  // e.g. the media is in multiple files.
74  // Otherwise, a vector of ranges for the media segments are returned.
75  virtual std::vector<Range> GetSegmentRanges() = 0;
76 
78  float GetDurationInSeconds() const;
79 
80  protected:
82  int64_t FromBmffTimestamp(int64_t bmff_timestamp);
84  int64_t FromWebMTimecode(int64_t webm_timecode);
86  Status WriteSegmentHeader(uint64_t file_size, MkvWriter* writer);
88  Status SetCluster(int64_t start_webm_timecode,
89  uint64_t position,
90  MkvWriter* writer);
91 
93  void UpdateProgress(uint64_t progress);
94  void set_progress_target(uint64_t target) { progress_target_ = target; }
95 
96  const MuxerOptions& options() const { return options_; }
97  mkvmuxer::Cluster* cluster() { return cluster_.get(); }
98  mkvmuxer::Cues* cues() { return &cues_; }
99  MuxerListener* muxer_listener() { return muxer_listener_; }
100  SeekHead* seek_head() { return &seek_head_; }
101 
102  int track_id() const { return track_id_; }
103  uint64_t segment_payload_pos() const { return segment_payload_pos_; }
104 
105  int64_t duration() const { return duration_; }
106 
107  virtual Status DoInitialize() = 0;
108  virtual Status DoFinalize() = 0;
109 
110  private:
111  Status InitializeAudioTrack(const AudioStreamInfo& info,
112  mkvmuxer::AudioTrack* track);
113  Status InitializeVideoTrack(const VideoStreamInfo& info,
114  mkvmuxer::VideoTrack* track);
115 
116  // Writes the previous frame to the file.
117  Status WriteFrame(bool write_duration);
118 
119  // This is called when there needs to be a new (sub)segment.
120  // In single-segment mode, a Cluster is a segment and there is no subsegment.
121  // In multi-segment mode, a new file is a segment and the clusters in the file
122  // are subsegments.
123  virtual Status NewSegment(int64_t start_timestamp, bool is_subsegment) = 0;
124 
125  // Store the previous sample so we know which one is the last frame.
126  std::shared_ptr<const MediaSample> prev_sample_;
127  // The reference frame timestamp; used to populate the ReferenceBlock element
128  // when writing non-keyframe BlockGroups.
129  int64_t reference_frame_timestamp_ = 0;
130 
131  const MuxerOptions& options_;
132 
133  std::unique_ptr<mkvmuxer::Cluster> cluster_;
134  mkvmuxer::Cues cues_;
135  SeekHead seek_head_;
136  mkvmuxer::SegmentInfo segment_info_;
137  mkvmuxer::Tracks tracks_;
138 
139  MuxerListener* muxer_listener_ = nullptr;
140  ProgressListener* progress_listener_ = nullptr;
141  uint64_t progress_target_ = 0;
142  uint64_t accumulated_progress_ = 0;
143 
144  int64_t first_timestamp_ = 0;
145  int64_t sample_durations_[2] = {0, 0};
146  size_t num_samples_ = 0;
147 
148  // The position (in bytes) of the start of the Segment payload in the init
149  // file. This is also the size of the header before the SeekHead.
150  uint64_t segment_payload_pos_ = 0;
151 
152  // Indicate whether a new segment needed to be created, which is always true
153  // in the beginning.
154  bool new_segment_ = true;
155  // Indicate whether a new subsegment needed to be created.
156  bool new_subsegment_ = false;
157  int track_id_ = 0;
158 
159  // The subset of information that we need from StreamInfo
160  bool is_encrypted_ = false;
161  int64_t time_scale_ = 0;
162  int64_t duration_ = 0;
163 
164  DISALLOW_COPY_AND_ASSIGN(Segmenter);
165 };
166 
167 } // namespace webm
168 } // namespace media
169 } // namespace shaka
170 
171 #endif // PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_H_
Class to hold a media sample.
Definition: media_sample.h:25
An implementation of IMkvWriter using our File type.
Definition: mkv_writer.h:23
This class listens to progress updates events.
Abstract class holds stream information.
Definition: stream_info.h:71
Status SetCluster(int64_t start_webm_timecode, uint64_t position, MkvWriter *writer)
Creates a Cluster object with the given parameters.
Definition: segmenter.cc:266
Status Initialize(const StreamInfo &info, ProgressListener *progress_listener, MuxerListener *muxer_listener)
Definition: segmenter.cc:76
void UpdateProgress(uint64_t progress)
Update segmentation progress using ProgressListener.
Definition: segmenter.cc:275
virtual bool GetIndexRangeStartAndEnd(uint64_t *start, uint64_t *end)=0
virtual Status FinalizeSegment(int64_t start_timestamp, int64_t duration_timestamp, bool is_subsegment, int64_t segment_number)=0
Finalize the (sub)segment.
Definition: segmenter.cc:199
virtual bool GetInitRangeStartAndEnd(uint64_t *start, uint64_t *end)=0
float GetDurationInSeconds() const
Definition: segmenter.cc:210
int64_t FromWebMTimecode(int64_t webm_timecode)
Converts the given time in WebM timecode to ISO BMFF timestamp.
Definition: segmenter.cc:222
Status AddSample(const MediaSample &sample)
Definition: segmenter.cc:159
int64_t FromBmffTimestamp(int64_t bmff_timestamp)
Converts the given time in ISO BMFF timestamp to WebM timecode.
Definition: segmenter.cc:216
Status WriteSegmentHeader(uint64_t file_size, MkvWriter *writer)
Writes the Segment header to writer.
Definition: segmenter.cc:228
All the methods that are virtual are virtual for mocking.
Definition: crypto_flags.cc:66
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:19