Shaka Packager SDK
ttml_to_mp4_handler.cc
1 // Copyright 2020 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/ttml/ttml_to_mp4_handler.h>
8 
9 #include <absl/log/check.h>
10 
11 #include <packager/macros/status.h>
12 
13 namespace shaka {
14 namespace media {
15 namespace ttml {
16 
17 namespace {
18 
19 size_t kTrackId = 0;
20 
21 std::shared_ptr<MediaSample> CreateMediaSample(const std::string& data,
22  int64_t start_time,
23  int64_t duration) {
24  DCHECK_GE(start_time, 0);
25  DCHECK_GT(duration, 0);
26 
27  const bool kIsKeyFrame = true;
28 
29  std::shared_ptr<MediaSample> sample = MediaSample::CopyFrom(
30  reinterpret_cast<const uint8_t*>(data.data()), data.size(), kIsKeyFrame);
31  sample->set_pts(start_time);
32  sample->set_dts(start_time);
33  sample->set_duration(duration);
34 
35  return sample;
36 }
37 
38 } // namespace
39 
40 Status TtmlToMp4Handler::InitializeInternal() {
41  return Status::OK;
42 }
43 
44 Status TtmlToMp4Handler::Process(std::unique_ptr<StreamData> stream_data) {
45  switch (stream_data->stream_data_type) {
46  case StreamDataType::kStreamInfo:
47  return OnStreamInfo(std::move(stream_data));
48  case StreamDataType::kCueEvent:
49  return OnCueEvent(std::move(stream_data));
50  case StreamDataType::kSegmentInfo:
51  return OnSegmentInfo(std::move(stream_data));
52  case StreamDataType::kTextSample:
53  return OnTextSample(std::move(stream_data));
54  default:
55  return Status(error::INTERNAL_ERROR,
56  "Invalid stream data type (" +
57  StreamDataTypeToString(stream_data->stream_data_type) +
58  ") for this TtmlToMp4 handler");
59  }
60 }
61 
62 Status TtmlToMp4Handler::OnStreamInfo(std::unique_ptr<StreamData> stream_data) {
63  DCHECK(stream_data);
64  DCHECK(stream_data->stream_info);
65 
66  auto clone = stream_data->stream_info->Clone();
67  clone->set_codec(kCodecTtml);
68  clone->set_codec_string("ttml");
69 
70  if (clone->stream_type() != kStreamText)
71  return Status(error::MUXER_FAILURE, "Incorrect stream type");
72  auto* text_stream = static_cast<const TextStreamInfo*>(clone.get());
73  generator_.Initialize(text_stream->regions(), text_stream->language(),
74  text_stream->time_scale());
75 
76  return Dispatch(
77  StreamData::FromStreamInfo(stream_data->stream_index, std::move(clone)));
78 }
79 
80 Status TtmlToMp4Handler::OnCueEvent(std::unique_ptr<StreamData> stream_data) {
81  DCHECK(stream_data);
82  DCHECK(stream_data->cue_event);
83  return Dispatch(std::move(stream_data));
84 }
85 
86 Status TtmlToMp4Handler::OnSegmentInfo(
87  std::unique_ptr<StreamData> stream_data) {
88  DCHECK(stream_data);
89  DCHECK(stream_data->segment_info);
90 
91  const auto& segment = stream_data->segment_info;
92 
93  std::string data;
94  if (!generator_.Dump(&data))
95  return Status(error::INTERNAL_ERROR, "Error generating XML");
96  generator_.Reset();
97 
98  RETURN_IF_ERROR(DispatchMediaSample(
99  kTrackId,
100  CreateMediaSample(data, segment->start_timestamp, segment->duration)));
101 
102  return Dispatch(std::move(stream_data));
103 }
104 
105 Status TtmlToMp4Handler::OnTextSample(std::unique_ptr<StreamData> stream_data) {
106  DCHECK(stream_data);
107  DCHECK(stream_data->text_sample);
108 
109  auto& sample = stream_data->text_sample;
110 
111  // Ignore empty samples. This will create gaps, but we will handle that
112  // later.
113  if (sample->body().is_empty()) {
114  return Status::OK;
115  }
116 
117  // Add the new text sample to the cache of samples that belong in the
118  // current segment.
119  generator_.AddSample(*sample);
120  return Status::OK;
121 }
122 
123 } // namespace ttml
124 } // namespace media
125 } // namespace shaka
Status DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) const
Dispatch the media sample to downstream handlers.
Status Dispatch(std::unique_ptr< StreamData > stream_data) const
static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
Definition: media_sample.cc:43
All the methods that are virtual are virtual for mocking.
Definition: crypto_flags.cc:66