7 #include "packager/media/formats/mp4/fragmenter.h"
11 #include "packager/media/base/buffer_writer.h"
12 #include "packager/media/base/media_sample.h"
13 #include "packager/media/formats/mp4/box_definitions.h"
15 namespace edash_packager {
20 const int64_t kInvalidTime = std::numeric_limits<int64_t>::max();
25 fragment_initialized_(false),
26 fragment_finalized_(false),
27 fragment_duration_(0),
28 presentation_start_time_(kInvalidTime),
29 earliest_presentation_time_(kInvalidTime),
30 first_sap_time_(kInvalidTime) {
34 Fragmenter::~Fragmenter() {}
38 CHECK_GT(sample->duration(), 0);
40 if (!fragment_initialized_) {
46 if (sample->side_data_size() > 0)
47 LOG(WARNING) <<
"MP4 samples do not support side data. Side data ignored.";
50 traf_->runs[0].sample_sizes.push_back(sample->data_size());
51 traf_->runs[0].sample_durations.push_back(sample->duration());
52 traf_->runs[0].sample_flags.push_back(
53 sample->is_key_frame() ? 0 : TrackFragmentHeader::kNonKeySampleMask);
55 data_->AppendArray(sample->data(), sample->data_size());
56 fragment_duration_ += sample->duration();
58 int64_t pts = sample->pts();
62 if (earliest_presentation_time_ > pts)
63 earliest_presentation_time_ = pts;
65 traf_->runs[0].sample_composition_time_offsets.push_back(pts - sample->dts());
66 if (pts != sample->dts())
67 traf_->runs[0].flags |= TrackFragmentRun::kSampleCompTimeOffsetsPresentMask;
69 if (sample->is_key_frame()) {
70 if (first_sap_time_ == kInvalidTime)
71 first_sap_time_ = pts;
77 fragment_initialized_ =
true;
78 fragment_finalized_ =
false;
79 traf_->decode_time.decode_time = first_sample_dts;
81 traf_->runs.resize(1);
82 traf_->runs[0].flags = TrackFragmentRun::kDataOffsetPresentMask;
83 traf_->header.sample_description_index = 1;
84 traf_->header.flags = TrackFragmentHeader::kDefaultBaseIsMoofMask |
85 TrackFragmentHeader::kSampleDescriptionIndexPresentMask;
86 fragment_duration_ = 0;
87 earliest_presentation_time_ = kInvalidTime;
88 first_sap_time_ = kInvalidTime;
95 traf_->runs[0].sample_count = traf_->runs[0].sample_sizes.size();
97 &traf_->header.default_sample_duration)) {
98 traf_->header.flags |=
99 TrackFragmentHeader::kDefaultSampleDurationPresentMask;
101 traf_->runs[0].flags |= TrackFragmentRun::kSampleDurationPresentMask;
104 &traf_->header.default_sample_size)) {
105 traf_->header.flags |= TrackFragmentHeader::kDefaultSampleSizePresentMask;
107 traf_->runs[0].flags |= TrackFragmentRun::kSampleSizePresentMask;
110 &traf_->header.default_sample_flags)) {
111 traf_->header.flags |= TrackFragmentHeader::kDefaultSampleFlagsPresentMask;
113 traf_->runs[0].flags |= TrackFragmentRun::kSampleFlagsPresentMask;
116 fragment_finalized_ =
true;
117 fragment_initialized_ =
false;
122 reference->reference_type =
false;
123 reference->subsegment_duration = fragment_duration_;
124 reference->starts_with_sap = StartsWithSAP();
125 if (kInvalidTime == first_sap_time_) {
126 reference->sap_type = SegmentReference::TypeUnknown;
127 reference->sap_delta_time = 0;
129 reference->sap_type = SegmentReference::Type1;
130 reference->sap_delta_time = first_sap_time_ - earliest_presentation_time_;
132 reference->earliest_presentation_time = earliest_presentation_time_;
135 bool Fragmenter::StartsWithSAP() {
136 DCHECK(!traf_->runs.empty());
137 uint32_t start_sample_flag;
138 if (traf_->runs[0].flags & TrackFragmentRun::kSampleFlagsPresentMask) {
139 DCHECK(!traf_->runs[0].sample_flags.empty());
140 start_sample_flag = traf_->runs[0].sample_flags[0];
142 DCHECK(traf_->header.flags &
143 TrackFragmentHeader::kDefaultSampleFlagsPresentMask);
144 start_sample_flag = traf_->header.default_sample_flags;
146 return (start_sample_flag & TrackFragmentHeader::kNonKeySampleMask) == 0;