Shaka Packager SDK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
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<const PeriodInfo> period_info;
52  std::shared_ptr<const StreamInfo> stream_info;
53  std::shared_ptr<const MediaSample> media_sample;
54  std::shared_ptr<const TextSample> text_sample;
55  std::shared_ptr<const MediaEvent> media_event;
56  std::shared_ptr<const SegmentInfo> segment_info;
57 
58  static std::unique_ptr<StreamData> FromPeriodInfo(
59  size_t stream_index, std::shared_ptr<const PeriodInfo> period_info) {
60  std::unique_ptr<StreamData> stream_data(new StreamData);
61  stream_data->stream_index = stream_index;
62  stream_data->stream_data_type = StreamDataType::kPeriodInfo;
63  stream_data->period_info = std::move(period_info);
64  return stream_data;
65  }
66 
67  static std::unique_ptr<StreamData> FromStreamInfo(
68  size_t stream_index, std::shared_ptr<const StreamInfo> stream_info) {
69  std::unique_ptr<StreamData> stream_data(new StreamData);
70  stream_data->stream_index = stream_index;
71  stream_data->stream_data_type = StreamDataType::kStreamInfo;
72  stream_data->stream_info = std::move(stream_info);
73  return stream_data;
74  }
75 
76  static std::unique_ptr<StreamData> FromMediaSample(
77  size_t stream_index, std::shared_ptr<const MediaSample> media_sample) {
78  std::unique_ptr<StreamData> stream_data(new StreamData);
79  stream_data->stream_index = stream_index;
80  stream_data->stream_data_type = StreamDataType::kMediaSample;
81  stream_data->media_sample = std::move(media_sample);
82  return stream_data;
83  }
84 
85  static std::unique_ptr<StreamData> FromTextSample(
86  size_t stream_index, std::shared_ptr<const TextSample> text_sample) {
87  std::unique_ptr<StreamData> stream_data(new StreamData);
88  stream_data->stream_index = stream_index;
89  stream_data->stream_data_type = StreamDataType::kTextSample;
90  stream_data->text_sample = std::move(text_sample);
91  return stream_data;
92  }
93 
94  static std::unique_ptr<StreamData> FromMediaEvent(
95  size_t stream_index, std::shared_ptr<const MediaEvent> media_event) {
96  std::unique_ptr<StreamData> stream_data(new StreamData);
97  stream_data->stream_index = stream_index;
98  stream_data->stream_data_type = StreamDataType::kMediaEvent;
99  stream_data->media_event = std::move(media_event);
100  return stream_data;
101  }
102 
103  static std::unique_ptr<StreamData> FromSegmentInfo(
104  size_t stream_index, std::shared_ptr<const SegmentInfo> segment_info) {
105  std::unique_ptr<StreamData> stream_data(new StreamData);
106  stream_data->stream_index = stream_index;
107  stream_data->stream_data_type = StreamDataType::kSegmentInfo;
108  stream_data->segment_info = std::move(segment_info);
109  return stream_data;
110  }
111 };
112 
129  public:
130  MediaHandler() = default;
131  virtual ~MediaHandler() = default;
132 
134  Status SetHandler(size_t output_stream_index,
135  std::shared_ptr<MediaHandler> handler);
136 
138  Status AddHandler(std::shared_ptr<MediaHandler> handler) {
139  return SetHandler(next_output_stream_index_, handler);
140  }
141 
144  Status Initialize();
145 
147  bool IsConnected() { return num_input_streams_ > 0; }
148 
149  protected:
152  virtual Status InitializeInternal() = 0;
153 
158  virtual Status Process(std::unique_ptr<StreamData> stream_data) = 0;
159 
161  virtual Status OnFlushRequest(size_t input_stream_index);
162 
164  virtual bool ValidateOutputStreamIndex(size_t stream_index) const;
165 
168  Status Dispatch(std::unique_ptr<StreamData> stream_data);
169 
172  size_t stream_index, std::shared_ptr<const PeriodInfo> period_info) {
173  return Dispatch(StreamData::FromPeriodInfo(stream_index, period_info));
174  }
175 
178  size_t stream_index, std::shared_ptr<const StreamInfo> stream_info) {
179  return Dispatch(StreamData::FromStreamInfo(stream_index, stream_info));
180  }
181 
184  size_t stream_index, std::shared_ptr<const MediaSample> media_sample) {
185  return Dispatch(StreamData::FromMediaSample(stream_index, media_sample));
186  }
187 
189  // DispatchTextSample should only be override for testing.
191  size_t stream_index, std::shared_ptr<const TextSample> text_sample) {
192  return Dispatch(StreamData::FromTextSample(stream_index, text_sample));
193  }
194 
197  size_t stream_index, std::shared_ptr<const MediaEvent> media_event) {
198  return Dispatch(StreamData::FromMediaEvent(stream_index, media_event));
199  }
200 
203  size_t stream_index, std::shared_ptr<const SegmentInfo> segment_info) {
204  return Dispatch(StreamData::FromSegmentInfo(stream_index, segment_info));
205  }
206 
208  Status FlushDownstream(size_t output_stream_index);
209 
212 
213  bool initialized() { return initialized_; }
214  size_t num_input_streams() const { return num_input_streams_; }
215  size_t next_output_stream_index() const { return next_output_stream_index_; }
216  const std::map<size_t, std::pair<std::shared_ptr<MediaHandler>, size_t>>&
217  output_handlers() {
218  return output_handlers_;
219  }
220 
221  private:
222  MediaHandler(const MediaHandler&) = delete;
223  MediaHandler& operator=(const MediaHandler&) = delete;
224 
225  bool initialized_ = false;
226  // Number of input streams.
227  size_t num_input_streams_ = 0;
228  // The next available output stream index, used by AddHandler.
229  size_t next_output_stream_index_ = 0;
230  // output stream index -> {output handler, output handler input stream index}
231  // map.
232  std::map<size_t, std::pair<std::shared_ptr<MediaHandler>, size_t>>
233  output_handlers_;
234 };
235 
236 } // namespace media
237 } // namespace shaka
238 
239 #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 DispatchPeriodInfo(size_t stream_index, std::shared_ptr< const PeriodInfo > period_info)
Dispatch the period info 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.
Status DispatchMediaEvent(size_t stream_index, std::shared_ptr< const MediaEvent > media_event)
Dispatch the media event to downstream handlers.
virtual Status Process(std::unique_ptr< StreamData > stream_data)=0
Status FlushAllDownstreams()
Flush all connected downstreams.
Status DispatchTextSample(size_t stream_index, std::shared_ptr< const 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.
Status FlushDownstream(size_t output_stream_index)
Flush the downstream connected at the specified output stream index.
Status DispatchStreamInfo(size_t stream_index, std::shared_ptr< const StreamInfo > stream_info)
Dispatch the stream info to downstream handlers.
Status DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample)
Dispatch the media sample to downstream handlers.
Status DispatchSegmentInfo(size_t stream_index, std::shared_ptr< const 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.