7 #include "packager/media/formats/mp2t/ts_segmenter.h"
11 #include "packager/media/base/muxer_util.h"
12 #include "packager/media/base/status.h"
13 #include "packager/media/event/muxer_listener.h"
15 namespace edash_packager {
20 const double kTsTimescale = 90000;
24 : muxer_options_(options),
28 TsSegmenter::~TsSegmenter() {}
32 return Status(error::MUXER_FAILURE,
"Segment template not specified.");
33 if (!ts_writer_->Initialize(stream_info))
34 return Status(error::MUXER_FAILURE,
"Failed to initialize TsWriter.");
35 if (!pes_packet_generator_->Initialize(stream_info)) {
36 return Status(error::MUXER_FAILURE,
37 "Failed to initialize PesPacketGenerator.");
40 timescale_scale_ = kTsTimescale / stream_info.time_scale();
52 const bool passed_segment_duration =
54 if (sample->is_key_frame() && passed_segment_duration) {
60 if (!ts_writer_file_opened_ && !sample->is_key_frame())
61 LOG(WARNING) <<
"A segment will start with a non key frame.";
63 if (!pes_packet_generator_->PushSample(sample)) {
64 return Status(error::MUXER_FAILURE,
65 "Failed to add sample to PesPacketGenerator.");
68 const double scaled_sample_duration = sample->duration() * timescale_scale_;
69 current_segment_total_sample_duration_ +=
70 scaled_sample_duration / kTsTimescale;
72 return WritePesPacketsToFile();
76 ts_writer_ = writer.Pass();
80 scoped_ptr<PesPacketGenerator> generator) {
81 pes_packet_generator_ = generator.Pass();
85 ts_writer_file_opened_ = value;
88 Status TsSegmenter::OpenNewSegmentIfClosed(uint32_t next_pts) {
89 if (ts_writer_file_opened_)
91 const std::string segment_name =
93 segment_number_++, muxer_options_.
bandwidth);
94 if (!ts_writer_->NewSegment(segment_name))
95 return Status(error::MUXER_FAILURE,
"Failed to initilize TsPacketWriter.");
96 current_segment_start_time_ = next_pts;
97 current_segment_path_ = segment_name;
98 ts_writer_file_opened_ =
true;
102 Status TsSegmenter::WritePesPacketsToFile() {
103 while (pes_packet_generator_->NumberOfReadyPesPackets() > 0u) {
104 scoped_ptr<PesPacket> pes_packet =
105 pes_packet_generator_->GetNextPesPacket();
107 Status status = OpenNewSegmentIfClosed(pes_packet->pts());
111 if (!ts_writer_->AddPesPacket(pes_packet.Pass()))
112 return Status(error::MUXER_FAILURE,
"Failed to add PES packet.");
117 Status TsSegmenter::Flush() {
118 if (!pes_packet_generator_->Flush()) {
119 return Status(error::MUXER_FAILURE,
120 "Failed to flush PesPacketGenerator.");
122 Status status = WritePesPacketsToFile();
128 if (ts_writer_file_opened_) {
129 if (!ts_writer_->FinalizeSegment()) {
130 return Status(error::MUXER_FAILURE,
"Failed to finalize TsWriter.");
133 const int64_t file_size =
136 current_segment_path_, current_segment_start_time_,
137 current_segment_total_sample_duration_ * kTsTimescale, file_size);
139 ts_writer_file_opened_ =
false;
141 current_segment_total_sample_duration_ = 0.0;
142 current_segment_start_time_ = 0;
143 current_segment_path_.clear();