DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
media_handler.h
1 // Copyright 2017 Google Inc. 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_BASE_MEDIA_HANDLER_H_
8 #define PACKAGER_MEDIA_BASE_MEDIA_HANDLER_H_
9 
10 #include <map>
11 #include <memory>
12 #include <utility>
13 
14 #include "packager/media/base/media_sample.h"
15 #include "packager/media/base/stream_info.h"
16 #include "packager/media/base/text_sample.h"
17 #include "packager/status.h"
18 
19 namespace shaka {
20 namespace media {
21 
22 enum class StreamDataType {
23  kUnknown,
24  kPeriodInfo,
25  kStreamInfo,
26  kMediaSample,
27  kTextSample,
28  kMediaEvent,
29  kSegmentInfo,
30 };
31 
32 // TODO(kqyang): Define these structures.
33 struct PeriodInfo {};
34 struct MediaEvent {};
35 struct SegmentInfo {
36  bool is_subsegment = false;
37  bool is_encrypted = false;
38  int64_t start_timestamp = -1;
39  int64_t duration = 0;
40  // This is only available if key rotation is enabled. Note that we may have
41  // a |key_rotation_encryption_config| even if the segment is not encrypted,
42  // which is the case for clear lead.
43  std::shared_ptr<EncryptionConfig> key_rotation_encryption_config;
44 };
45 
46 // TODO(kqyang): Should we use protobuf?
47 struct StreamData {
48  size_t stream_index = static_cast<size_t>(-1);
49  StreamDataType stream_data_type = StreamDataType::kUnknown;
50 
51  std::shared_ptr<PeriodInfo> period_info;
52  std::shared_ptr<StreamInfo> stream_info;
53  std::shared_ptr<MediaSample> media_sample;
54  std::shared_ptr<TextSample> text_sample;
55  std::shared_ptr<MediaEvent> media_event;
56  std::shared_ptr<SegmentInfo> segment_info;
57 };
58 
74 class MediaHandler {
75  public:
76  MediaHandler() = default;
77  virtual ~MediaHandler() = default;
78 
80  Status SetHandler(size_t output_stream_index,
81  std::shared_ptr<MediaHandler> handler);
82 
84  Status AddHandler(std::shared_ptr<MediaHandler> handler) {
85  return SetHandler(next_output_stream_index_, handler);
86  }
87 
90  Status Initialize();
91 
93  bool IsConnected() { return num_input_streams_ > 0; }
94 
95  protected:
98  virtual Status InitializeInternal() = 0;
99 
104  virtual Status Process(std::unique_ptr<StreamData> stream_data) = 0;
105 
107  virtual Status OnFlushRequest(size_t input_stream_index);
108 
110  virtual bool ValidateOutputStreamIndex(size_t stream_index) const;
111 
114  Status Dispatch(std::unique_ptr<StreamData> stream_data);
115 
117  Status DispatchPeriodInfo(size_t stream_index,
118  std::shared_ptr<PeriodInfo> period_info) {
119  std::unique_ptr<StreamData> stream_data(new StreamData);
120  stream_data->stream_index = stream_index;
121  stream_data->stream_data_type = StreamDataType::kPeriodInfo;
122  stream_data->period_info = std::move(period_info);
123  return Dispatch(std::move(stream_data));
124  }
125 
127  Status DispatchStreamInfo(size_t stream_index,
128  std::shared_ptr<StreamInfo> stream_info) {
129  std::unique_ptr<StreamData> stream_data(new StreamData);
130  stream_data->stream_index = stream_index;
131  stream_data->stream_data_type = StreamDataType::kStreamInfo;
132  stream_data->stream_info = std::move(stream_info);
133  return Dispatch(std::move(stream_data));
134  }
135 
137  Status DispatchMediaSample(size_t stream_index,
138  std::shared_ptr<MediaSample> media_sample) {
139  std::unique_ptr<StreamData> stream_data(new StreamData);
140  stream_data->stream_index = stream_index;
141  stream_data->stream_data_type = StreamDataType::kMediaSample;
142  stream_data->media_sample = std::move(media_sample);
143  return Dispatch(std::move(stream_data));
144  }
145 
147  // DispatchTextSample should only be override for testing.
148  Status DispatchTextSample(size_t stream_index,
149  std::shared_ptr<TextSample> text_sample) {
150  std::unique_ptr<StreamData> stream_data(new StreamData);
151  stream_data->stream_index = stream_index;
152  stream_data->stream_data_type = StreamDataType::kTextSample;
153  stream_data->text_sample = std::move(text_sample);
154  return Dispatch(std::move(stream_data));
155  }
156 
158  Status DispatchMediaEvent(size_t stream_index,
159  std::shared_ptr<MediaEvent> media_event) {
160  std::unique_ptr<StreamData> stream_data(new StreamData);
161  stream_data->stream_index = stream_index;
162  stream_data->stream_data_type = StreamDataType::kMediaEvent;
163  stream_data->media_event = std::move(media_event);
164  return Dispatch(std::move(stream_data));
165  }
166 
168  Status DispatchSegmentInfo(size_t stream_index,
169  std::shared_ptr<SegmentInfo> segment_info) {
170  std::unique_ptr<StreamData> stream_data(new StreamData);
171  stream_data->stream_index = stream_index;
172  stream_data->stream_data_type = StreamDataType::kSegmentInfo;
173  stream_data->segment_info = std::move(segment_info);
174  return Dispatch(std::move(stream_data));
175  }
176 
178  Status FlushDownstream(size_t output_stream_index);
179 
181  Status FlushAllDownstreams();
182 
183  bool initialized() { return initialized_; }
184  size_t num_input_streams() const { return num_input_streams_; }
185  size_t next_output_stream_index() const { return next_output_stream_index_; }
186  const std::map<size_t, std::pair<std::shared_ptr<MediaHandler>, size_t>>&
187  output_handlers() {
188  return output_handlers_;
189  }
190 
191  private:
192  MediaHandler(const MediaHandler&) = delete;
193  MediaHandler& operator=(const MediaHandler&) = delete;
194 
195  bool initialized_ = false;
196  // Number of input streams.
197  size_t num_input_streams_ = 0;
198  // The next available output stream index, used by AddHandler.
199  size_t next_output_stream_index_ = 0;
200  // output stream index -> {output handler, output handler input stream index}
201  // map.
202  std::map<size_t, std::pair<std::shared_ptr<MediaHandler>, size_t>>
203  output_handlers_;
204 };
205 
206 } // namespace media
207 } // namespace shaka
208 
209 #endif // PACKAGER_MEDIA_BASE_MEDIA_HANDLER_H_
virtual bool ValidateOutputStreamIndex(size_t stream_index) const
Validate if the stream at the specified index actually exists.
Status DispatchMediaSample(size_t stream_index, std::shared_ptr< MediaSample > media_sample)
Dispatch the media sample to downstream handlers.
virtual Status InitializeInternal()=0
Status Dispatch(std::unique_ptr< StreamData > stream_data)
virtual Status OnFlushRequest(size_t input_stream_index)
Event handler for flush request at the specific input stream index.
bool IsConnected()
Validate if the handler is connected to its upstream handler.
Definition: media_handler.h:93
virtual Status Process(std::unique_ptr< StreamData > stream_data)=0
Status FlushAllDownstreams()
Flush all connected downstreams.
Status DispatchMediaEvent(size_t stream_index, std::shared_ptr< MediaEvent > media_event)
Dispatch the media event to downstream handlers.
Status DispatchStreamInfo(size_t stream_index, std::shared_ptr< StreamInfo > stream_info)
Dispatch the stream info to downstream handlers.
Status DispatchPeriodInfo(size_t stream_index, std::shared_ptr< PeriodInfo > period_info)
Dispatch the period info to downstream handlers.
Status DispatchTextSample(size_t stream_index, std::shared_ptr< TextSample > text_sample)
Dispatch the text sample to downsream handlers.
Status AddHandler(std::shared_ptr< MediaHandler > handler)
Connect downstream handler to the next availble output stream index.
Definition: media_handler.h:84
Status FlushDownstream(size_t output_stream_index)
Flush the downstream connected at the specified output stream index.
Status DispatchSegmentInfo(size_t stream_index, std::shared_ptr< SegmentInfo > segment_info)
Dispatch the segment info to downstream handlers.
Status SetHandler(size_t output_stream_index, std::shared_ptr< MediaHandler > handler)
Connect downstream handler at the specified output stream index.