DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerator
ts_segmenter.cc
1 // Copyright 2016 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/formats/mp2t/ts_segmenter.h"
8 
9 #include <memory>
10 
11 #include "packager/media/base/muxer_util.h"
12 #include "packager/media/base/status.h"
13 
14 namespace edash_packager {
15 namespace media {
16 namespace mp2t {
17 
18 namespace {
19 const int kTsTimescale = 90000;
20 } // namespace
21 
23  : muxer_options_(options),
24  ts_writer_(new TsWriter()),
25  pes_packet_generator_(new PesPacketGenerator()) {}
26 TsSegmenter::~TsSegmenter() {}
27 
29  if (muxer_options_.segment_template.empty())
30  return Status(error::MUXER_FAILURE, "Segment template not specified.");
31  if (!ts_writer_->Initialize(stream_info))
32  return Status(error::MUXER_FAILURE, "Failed to initialize TsWriter.");
33  if (!pes_packet_generator_->Initialize(stream_info)) {
34  return Status(error::MUXER_FAILURE,
35  "Failed to initialize PesPacketGenerator.");
36  }
37 
38  return Status::OK;
39 }
40 
42  if (!pes_packet_generator_->Flush()) {
43  return Status(error::MUXER_FAILURE,
44  "Failed to finalize PesPacketGenerator.");
45  }
46 
47  Status status = WritePesPacketsToFiles();
48  if (!status.ok())
49  return status;
50 
51  if (!ts_writer_file_opened_)
52  return Status::OK;
53 
54  if (!ts_writer_->FinalizeSegment())
55  return Status(error::MUXER_FAILURE, "Failed to finalize TsPacketWriter.");
56  ts_writer_file_opened_ = false;
57  return Status::OK;
58 }
59 
60 Status TsSegmenter::AddSample(scoped_refptr<MediaSample> sample) {
61  if (!pes_packet_generator_->PushSample(sample)) {
62  return Status(error::MUXER_FAILURE,
63  "Failed to add sample to PesPacketGenerator.");
64  }
65  // TODO(rkuriowa): Only segment files before a key frame.
66  return WritePesPacketsToFiles();
67 }
68 
69 void TsSegmenter::InjectTsWriterForTesting(scoped_ptr<TsWriter> writer) {
70  ts_writer_ = writer.Pass();
71 }
72 
74  scoped_ptr<PesPacketGenerator> generator) {
75  pes_packet_generator_ = generator.Pass();
76 }
77 
79  ts_writer_file_opened_ = value;
80 }
81 
82 Status TsSegmenter::FinalizeSegmentIfPastSegmentDuration() {
83  if (current_segment_duration_ > muxer_options_.segment_duration) {
84  if (!ts_writer_->FinalizeSegment())
85  return Status(error::FILE_FAILURE, "Failed to finalize segment.");
86  ts_writer_file_opened_ = false;
87  current_segment_duration_ = 0.0;
88  }
89  return Status::OK;
90 }
91 
92 Status TsSegmenter::OpenNewSegmentIfClosed(uint32_t next_pts) {
93  if (ts_writer_file_opened_)
94  return Status::OK;
95  const std::string segment_name =
96  GetSegmentName(muxer_options_.segment_template, next_pts,
97  segment_number_++, muxer_options_.bandwidth);
98  if (!ts_writer_->NewSegment(segment_name))
99  return Status(error::MUXER_FAILURE, "Failed to initilize TsPacketWriter.");
100  ts_writer_file_opened_ = true;
101  return Status::OK;
102 }
103 
104 Status TsSegmenter::WritePesPacketsToFiles() {
105  while (pes_packet_generator_->NumberOfReadyPesPackets() > 0u) {
106  scoped_ptr<PesPacket> pes_packet =
107  pes_packet_generator_->GetNextPesPacket();
108 
109  Status status = OpenNewSegmentIfClosed(pes_packet->pts());
110  if (!status.ok())
111  return status;
112 
113  const double pes_packet_duration = pes_packet->duration();
114 
115  if (!ts_writer_->AddPesPacket(pes_packet.Pass()))
116  return Status(error::MUXER_FAILURE, "Failed to add PES packet.");
117 
118  current_segment_duration_ += pes_packet_duration / kTsTimescale;
119 
120  status = FinalizeSegmentIfPastSegmentDuration();
121  if (!status.ok())
122  return status;
123  }
124  return Status::OK;
125 }
126 
127 } // namespace mp2t
128 } // namespace media
129 } // namespace edash_packager
Status Initialize(const StreamInfo &stream_info)
Definition: ts_segmenter.cc:28
Abstract class holds stream information.
Definition: stream_info.h:26
void SetTsWriterFileOpenedForTesting(bool value)
Only for testing.
Definition: ts_segmenter.cc:78
void InjectTsWriterForTesting(scoped_ptr< TsWriter > writer)
Only for testing.
Definition: ts_segmenter.cc:69
Status AddSample(scoped_refptr< MediaSample > sample)
Definition: ts_segmenter.cc:60
void InjectPesPacketGeneratorForTesting(scoped_ptr< PesPacketGenerator > generator)
Only for testing.
Definition: ts_segmenter.cc:73
TsSegmenter(const MuxerOptions &options)
Definition: ts_segmenter.cc:22
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:18