7 #include "packager/media/formats/mp4/fragmenter.h"
11 #include "packager/media/base/buffer_writer.h"
12 #include "packager/media/base/audio_stream_info.h"
13 #include "packager/media/base/media_sample.h"
14 #include "packager/media/formats/mp4/box_definitions.h"
21 const int64_t kInvalidTime = std::numeric_limits<int64_t>::max();
23 uint64_t GetSeekPreroll(
const StreamInfo& stream_info) {
24 if (stream_info.stream_type() != kStreamAudio)
26 const AudioStreamInfo& audio_stream_info =
27 static_cast<const AudioStreamInfo&
>(stream_info);
28 return audio_stream_info.seek_preroll_ns();
31 void NewSampleEncryptionEntry(
const DecryptConfig& decrypt_config,
33 TrackFragment* traf) {
34 SampleEncryption& sample_encryption = traf->sample_encryption;
35 SampleEncryptionEntry sample_encryption_entry;
37 sample_encryption_entry.initialization_vector = decrypt_config.iv();
38 sample_encryption_entry.subsamples = decrypt_config.subsamples();
39 sample_encryption.sample_encryption_entries.push_back(
40 sample_encryption_entry);
41 traf->auxiliary_size.sample_info_sizes.push_back(
42 sample_encryption_entry.ComputeSize());
49 : stream_info_(std::move(stream_info)),
50 use_decoding_timestamp_in_timeline_(false),
52 seek_preroll_(GetSeekPreroll(*stream_info_)),
53 fragment_initialized_(false),
54 fragment_finalized_(false),
55 fragment_duration_(0),
56 earliest_presentation_time_(kInvalidTime),
57 first_sap_time_(kInvalidTime) {
62 Fragmenter::~Fragmenter() {}
65 if (sample.duration() == 0) {
66 LOG(WARNING) <<
"Unexpected sample with zero duration @ dts "
70 if (!fragment_initialized_) {
76 if (sample.side_data_size() > 0)
77 LOG(WARNING) <<
"MP4 samples do not support side data. Side data ignored.";
80 traf_->runs[0].sample_sizes.push_back(
81 static_cast<uint32_t>(sample.data_size()));
82 traf_->runs[0].sample_durations.push_back(sample.duration());
83 traf_->runs[0].sample_flags.push_back(
84 sample.is_key_frame() ? 0 : TrackFragmentHeader::kNonKeySampleMask);
86 if (sample.decrypt_config()) {
87 NewSampleEncryptionEntry(
88 *sample.decrypt_config(),
89 !stream_info_->encryption_config().constant_iv.empty(), traf_);
92 data_->AppendArray(sample.data(), sample.data_size());
93 fragment_duration_ += sample.duration();
95 const int64_t pts = sample.pts();
96 const int64_t dts = sample.dts();
98 const int64_t timestamp = use_decoding_timestamp_in_timeline_ ? dts : pts;
101 if (earliest_presentation_time_ > timestamp)
102 earliest_presentation_time_ = timestamp;
104 traf_->runs[0].sample_composition_time_offsets.push_back(pts - dts);
106 traf_->runs[0].flags |= TrackFragmentRun::kSampleCompTimeOffsetsPresentMask;
108 if (sample.is_key_frame()) {
109 if (first_sap_time_ == kInvalidTime)
110 first_sap_time_ = pts;
116 fragment_initialized_ =
true;
117 fragment_finalized_ =
false;
118 traf_->decode_time.decode_time = first_sample_dts;
120 traf_->runs.resize(1);
121 traf_->runs[0].flags = TrackFragmentRun::kDataOffsetPresentMask;
122 traf_->auxiliary_size.sample_info_sizes.clear();
123 traf_->auxiliary_offset.offsets.clear();
124 traf_->sample_encryption.sample_encryption_entries.clear();
125 traf_->sample_group_descriptions.clear();
126 traf_->sample_to_groups.clear();
127 traf_->header.sample_description_index = 1;
128 traf_->header.flags = TrackFragmentHeader::kDefaultBaseIsMoofMask |
129 TrackFragmentHeader::kSampleDescriptionIndexPresentMask;
131 fragment_duration_ = 0;
132 earliest_presentation_time_ = kInvalidTime;
133 first_sap_time_ = kInvalidTime;
139 if (stream_info_->is_encrypted()) {
140 Status status = FinalizeFragmentForEncryption();
146 traf_->runs[0].sample_count =
147 static_cast<uint32_t
>(traf_->runs[0].sample_sizes.size());
149 &traf_->header.default_sample_duration)) {
150 traf_->header.flags |=
151 TrackFragmentHeader::kDefaultSampleDurationPresentMask;
153 traf_->runs[0].flags |= TrackFragmentRun::kSampleDurationPresentMask;
156 &traf_->header.default_sample_size)) {
157 traf_->header.flags |= TrackFragmentHeader::kDefaultSampleSizePresentMask;
159 traf_->runs[0].flags |= TrackFragmentRun::kSampleSizePresentMask;
162 &traf_->header.default_sample_flags)) {
163 traf_->header.flags |= TrackFragmentHeader::kDefaultSampleFlagsPresentMask;
165 traf_->runs[0].flags |= TrackFragmentRun::kSampleFlagsPresentMask;
173 DCHECK_EQ(traf_->sample_to_groups.size(), 0u);
174 if (seek_preroll_ > 0) {
175 traf_->sample_to_groups.resize(traf_->sample_to_groups.size() + 1);
176 SampleToGroup& sample_to_group = traf_->sample_to_groups.back();
177 sample_to_group.grouping_type = FOURCC_roll;
179 sample_to_group.entries.resize(1);
181 sample_to_group_entry.sample_count = traf_->runs[0].sample_count;
182 sample_to_group_entry.group_description_index =
183 SampleToGroupEntry::kTrackGroupDescriptionIndexBase + 1;
185 for (
const auto& sample_group_description :
186 traf_->sample_group_descriptions) {
187 traf_->sample_to_groups.resize(traf_->sample_to_groups.size() + 1);
188 SampleToGroup& sample_to_group = traf_->sample_to_groups.back();
189 sample_to_group.grouping_type = sample_group_description.grouping_type;
191 sample_to_group.entries.resize(1);
193 sample_to_group_entry.sample_count = traf_->runs[0].sample_count;
194 sample_to_group_entry.group_description_index =
195 SampleToGroupEntry::kTrackFragmentGroupDescriptionIndexBase + 1;
198 fragment_finalized_ =
true;
199 fragment_initialized_ =
false;
205 reference->reference_type =
false;
206 reference->subsegment_duration = fragment_duration_;
207 reference->starts_with_sap = StartsWithSAP();
208 if (kInvalidTime == first_sap_time_) {
209 reference->sap_type = SegmentReference::TypeUnknown;
210 reference->sap_delta_time = 0;
212 reference->sap_type = SegmentReference::Type1;
213 reference->sap_delta_time = first_sap_time_ - earliest_presentation_time_;
215 reference->earliest_presentation_time = earliest_presentation_time_;
218 Status Fragmenter::FinalizeFragmentForEncryption() {
220 if (sample_encryption.sample_encryption_entries.empty()) {
224 const uint32_t kClearSampleDescriptionIndex = 2;
225 traf_->header.sample_description_index = kClearSampleDescriptionIndex;
228 if (sample_encryption.sample_encryption_entries.size() !=
229 traf_->runs[0].sample_sizes.size()) {
230 LOG(ERROR) <<
"Partially encrypted segment is not supported";
231 return Status(error::MUXER_FAILURE,
232 "Partially encrypted segment is not supported.");
235 const SampleEncryptionEntry& sample_encryption_entry =
236 sample_encryption.sample_encryption_entries.front();
237 const bool use_subsample_encryption =
238 !sample_encryption_entry.subsamples.empty();
239 if (use_subsample_encryption)
240 traf_->sample_encryption.flags |= SampleEncryption::kUseSubsampleEncryption;
241 traf_->sample_encryption.iv_size =
static_cast<uint8_t
>(
242 sample_encryption_entry.initialization_vector.size());
245 traf_->auxiliary_offset.offsets.push_back(0);
248 SampleAuxiliaryInformationSize& saiz = traf_->auxiliary_size;
249 saiz.sample_count =
static_cast<uint32_t
>(saiz.sample_info_sizes.size());
250 DCHECK_EQ(saiz.sample_info_sizes.size(),
251 traf_->sample_encryption.sample_encryption_entries.size());
253 &saiz.default_sample_info_size)) {
254 saiz.default_sample_info_size = 0;
259 if (saiz.default_sample_info_size == 0 && saiz.sample_info_sizes.empty()) {
260 DCHECK(!use_subsample_encryption);
264 saiz.sample_count = 0;
265 traf_->auxiliary_offset.offsets.clear();
270 bool Fragmenter::StartsWithSAP() {
271 DCHECK(!traf_->runs.empty());
272 uint32_t start_sample_flag;
273 if (traf_->runs[0].flags & TrackFragmentRun::kSampleFlagsPresentMask) {
274 DCHECK(!traf_->runs[0].sample_flags.empty());
275 start_sample_flag = traf_->runs[0].sample_flags[0];
277 DCHECK(traf_->header.flags &
278 TrackFragmentHeader::kDefaultSampleFlagsPresentMask);
279 start_sample_flag = traf_->header.default_sample_flags;
281 return (start_sample_flag & TrackFragmentHeader::kNonKeySampleMask) == 0;