7 #include "packager/media/formats/mp2t/ts_segmenter.h"
11 #include "packager/media/base/aes_encryptor.h"
12 #include "packager/media/base/key_source.h"
13 #include "packager/media/base/muxer_util.h"
14 #include "packager/media/base/status.h"
15 #include "packager/media/base/video_stream_info.h"
16 #include "packager/media/event/muxer_listener.h"
17 #include "packager/media/event/progress_listener.h"
24 const double kTsTimescale = 90000;
28 : muxer_options_(options),
32 TsSegmenter::~TsSegmenter() {}
36 return Status(error::MUXER_FAILURE,
"Segment template not specified.");
37 if (!ts_writer_->Initialize(stream_info))
38 return Status(error::MUXER_FAILURE,
"Failed to initialize TsWriter.");
39 if (!pes_packet_generator_->Initialize(stream_info)) {
40 return Status(error::MUXER_FAILURE,
41 "Failed to initialize PesPacketGenerator.");
44 timescale_scale_ = kTsTimescale / stream_info.time_scale();
53 if (sample->is_encrypted())
54 ts_writer_->SignalEncrypted();
56 if (!ts_writer_file_opened_ && !sample->is_key_frame())
57 LOG(WARNING) <<
"A segment will start with a non key frame.";
59 if (!pes_packet_generator_->PushSample(sample)) {
60 return Status(error::MUXER_FAILURE,
61 "Failed to add sample to PesPacketGenerator.");
63 return WritePesPacketsToFile();
67 ts_writer_ = std::move(writer);
71 std::unique_ptr<PesPacketGenerator> generator) {
72 pes_packet_generator_ = std::move(generator);
76 ts_writer_file_opened_ = value;
79 Status TsSegmenter::OpenNewSegmentIfClosed(uint32_t next_pts) {
80 if (ts_writer_file_opened_)
82 const std::string segment_name =
84 segment_number_++, muxer_options_.
bandwidth);
85 if (!ts_writer_->NewSegment(segment_name))
86 return Status(error::MUXER_FAILURE,
"Failed to initilize TsPacketWriter.");
87 current_segment_path_ = segment_name;
88 ts_writer_file_opened_ =
true;
92 Status TsSegmenter::WritePesPacketsToFile() {
93 while (pes_packet_generator_->NumberOfReadyPesPackets() > 0u) {
94 std::unique_ptr<PesPacket> pes_packet =
95 pes_packet_generator_->GetNextPesPacket();
97 Status status = OpenNewSegmentIfClosed(pes_packet->pts());
101 if (!ts_writer_->AddPesPacket(std::move(pes_packet)))
102 return Status(error::MUXER_FAILURE,
"Failed to add PES packet.");
109 if (!pes_packet_generator_->Flush()) {
110 return Status(error::MUXER_FAILURE,
111 "Failed to flush PesPacketGenerator.");
113 Status status = WritePesPacketsToFile();
119 if (ts_writer_file_opened_) {
120 if (!ts_writer_->FinalizeSegment()) {
121 return Status(error::MUXER_FAILURE,
"Failed to finalize TsWriter.");
124 const int64_t file_size =
127 start_timestamp * timescale_scale_,
128 duration * timescale_scale_, file_size);
130 ts_writer_file_opened_ =
false;
132 current_segment_path_.clear();