Shaka Packager SDK
media_handler.cc
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 #include "packager/media/base/media_handler.h"
8 
9 #include "packager/status_macros.h"
10 
11 namespace shaka {
12 namespace media {
13 
14 std::string StreamDataTypeToString(StreamDataType type) {
15  switch (type) {
16  case StreamDataType::kStreamInfo:
17  return "stream info";
18  case StreamDataType::kMediaSample:
19  return "media sample";
20  case StreamDataType::kTextSample:
21  return "text sample";
22  case StreamDataType::kSegmentInfo:
23  return "segment info";
24  case StreamDataType::kScte35Event:
25  return "scte35 event";
26  case StreamDataType::kCueEvent:
27  return "cue event";
28  case StreamDataType::kUnknown:
29  return "unknown";
30  }
31  return "unknown";
32 }
33 
34 Status MediaHandler::SetHandler(size_t output_stream_index,
35  std::shared_ptr<MediaHandler> handler) {
36  if (output_handlers_.find(output_stream_index) != output_handlers_.end()) {
37  return Status(error::ALREADY_EXISTS,
38  "The handler at the specified index already exists.");
39  }
40  output_handlers_[output_stream_index] =
41  std::make_pair(handler, handler->num_input_streams_++);
42  next_output_stream_index_ = output_stream_index + 1;
43  return Status::OK;
44 }
45 
47  if (initialized_)
48  return Status::OK;
49  Status status = InitializeInternal();
50  if (!status.ok())
51  return status;
52  for (auto& pair : output_handlers_) {
53  if (!ValidateOutputStreamIndex(pair.first))
54  return Status(error::INVALID_ARGUMENT, "Invalid output stream index");
55  status = pair.second.first->Initialize();
56  if (!status.ok())
57  return status;
58  }
59  initialized_ = true;
60  return Status::OK;
61 }
62 
63 Status MediaHandler::Chain(
64  std::initializer_list<std::shared_ptr<MediaHandler>> list) {
65  std::shared_ptr<MediaHandler> previous;
66 
67  for (auto& next : list) {
68  // Skip null entries.
69  if (!next) {
70  continue;
71  }
72 
73  if (previous) {
74  RETURN_IF_ERROR(previous->AddHandler(next));
75  }
76 
77  previous = std::move(next);
78  }
79 
80  return Status::OK;
81 }
82 
83 Status MediaHandler::OnFlushRequest(size_t input_stream_index) {
84  // The default implementation treats the output stream index to be identical
85  // to the input stream index, which is true for most handlers.
86  const size_t output_stream_index = input_stream_index;
87  return FlushDownstream(output_stream_index);
88 }
89 
90 bool MediaHandler::ValidateOutputStreamIndex(size_t stream_index) const {
91  return stream_index < num_input_streams_;
92 }
93 
94 Status MediaHandler::Dispatch(std::unique_ptr<StreamData> stream_data) const {
95  size_t output_stream_index = stream_data->stream_index;
96  auto handler_it = output_handlers_.find(output_stream_index);
97  if (handler_it == output_handlers_.end()) {
98  return Status(error::NOT_FOUND,
99  "No output handler exist at the specified index.");
100  }
101  stream_data->stream_index = handler_it->second.second;
102  return handler_it->second.first->Process(std::move(stream_data));
103 }
104 
105 Status MediaHandler::FlushDownstream(size_t output_stream_index) {
106  auto handler_it = output_handlers_.find(output_stream_index);
107  if (handler_it == output_handlers_.end()) {
108  return Status(error::NOT_FOUND,
109  "No output handler exist at the specified index.");
110  }
111  return handler_it->second.first->OnFlushRequest(handler_it->second.second);
112 }
113 
115  for (const auto& pair : output_handlers_) {
116  Status status = pair.second.first->OnFlushRequest(pair.second.second);
117  if (!status.ok()) {
118  return status;
119  }
120  }
121  return Status::OK;
122 }
123 } // namespace media
124 } // namespace shaka
virtual bool ValidateOutputStreamIndex(size_t stream_index) const
Validate if the stream at the specified index actually exists.
Status Dispatch(std::unique_ptr< StreamData > stream_data) const
virtual Status InitializeInternal()=0
virtual Status OnFlushRequest(size_t input_stream_index)
Event handler for flush request at the specific input stream index.
All the methods that are virtual are virtual for mocking.
Status FlushAllDownstreams()
Flush all connected downstream handlers.
Status FlushDownstream(size_t output_stream_index)
Flush the downstream connected at the specified output stream index.
Status SetHandler(size_t output_stream_index, std::shared_ptr< MediaHandler > handler)
Connect downstream handler at the specified output stream index.