7 #include <packager/media/formats/packed_audio/packed_audio_writer.h>
9 #include <absl/log/check.h>
11 #include <packager/macros/status.h>
12 #include <packager/media/base/muxer_util.h>
13 #include <packager/media/formats/packed_audio/packed_audio_segmenter.h>
19 :
Muxer(muxer_options),
20 transport_stream_timestamp_offset_(
21 muxer_options.transport_stream_timestamp_offset_ms *
22 kPackedAudioTimescale / 1000),
26 PackedAudioWriter::~PackedAudioWriter() =
default;
28 Status PackedAudioWriter::InitializeMuxer() {
29 if (streams().size() > 1u)
30 return Status(error::MUXER_FAILURE,
"Cannot handle more than one streams.");
32 RETURN_IF_ERROR(segmenter_->Initialize(*streams()[0]));
34 if (options().segment_template.empty()) {
36 DCHECK(!file_name.empty());
37 output_file_.reset(File::Open(file_name.c_str(),
"w"));
39 return Status(error::FILE_FAILURE,
40 "Cannot open file for write " + file_name);
44 if (muxer_listener()) {
45 muxer_listener()->
OnMediaStart(options(), *streams().front(),
46 kPackedAudioTimescale,
47 MuxerListener::kContainerPackedAudio);
52 Status PackedAudioWriter::Finalize() {
54 RETURN_IF_ERROR(CloseFile(std::move(output_file_)));
56 if (muxer_listener()) {
58 media_ranges_, total_duration_ * segmenter_->TimescaleScale());
63 Status PackedAudioWriter::AddMediaSample(
size_t stream_id,
64 const MediaSample& sample) {
65 DCHECK_EQ(stream_id, 0u);
66 return segmenter_->AddSample(sample);
69 Status PackedAudioWriter::FinalizeSegment(
size_t stream_id,
70 const SegmentInfo& segment_info) {
71 DCHECK_EQ(stream_id, 0u);
73 if (segment_info.is_subsegment)
76 RETURN_IF_ERROR(segmenter_->FinalizeSegment());
78 const int64_t segment_timestamp =
79 segment_info.start_timestamp * segmenter_->TimescaleScale();
80 std::string segment_path =
83 : GetSegmentName(options().segment_template, segment_timestamp,
84 segment_info.segment_number, options().bandwidth);
87 const size_t segment_size = segmenter_->segment_buffer()->Size();
89 RETURN_IF_ERROR(WriteSegment(segment_path, segmenter_->segment_buffer()));
90 total_duration_ += segment_info.duration;
92 if (muxer_listener()) {
94 segment_path, segment_timestamp + transport_stream_timestamp_offset_,
95 segment_info.duration * segmenter_->TimescaleScale(), segment_size,
96 segment_info.segment_number);
101 Status PackedAudioWriter::WriteSegment(
const std::string& segment_path,
102 BufferWriter* segment_buffer) {
103 std::unique_ptr<File, FileCloser> file;
110 range.end = range.start + segment_buffer->Size() - 1;
113 file.reset(File::Open(segment_path.c_str(),
"w"));
115 return Status(error::FILE_FAILURE,
116 "Cannot open file for write " + segment_path);
120 RETURN_IF_ERROR(segment_buffer->WriteToFile(output_file_ ? output_file_.get()
124 RETURN_IF_ERROR(CloseFile(std::move(file)));
128 Status PackedAudioWriter::CloseFile(std::unique_ptr<File, FileCloser> file) {
129 std::string file_name = file->file_name();
130 if (!file.release()->Close()) {
133 "Cannot close file " + file_name +
134 ", possibly file permission issue or running out of disk space.");
All the methods that are virtual are virtual for mocking.