Rename MP4GeneralSegmenter and MP4VODSegmenter

Rename MP4GeneralSegmenter to MultiSegmentSegmenter and MP4VODSegmenter
to SingleSegmentSegmenter.

Also drop MP4 from MP4Fragmenter and MP4Segmenter.

Change-Id: I5cefb88164516ec3588e0e3333a16f05b6277e7b
This commit is contained in:
Kongqun Yang 2014-04-08 13:21:07 -07:00 committed by KongQun Yang
parent b34b997bcb
commit 2498da675a
14 changed files with 149 additions and 147 deletions

View File

@ -16,11 +16,11 @@
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "media/base/demuxer.h" #include "media/base/demuxer.h"
#include "media/base/fixed_encryptor_source.h" #include "media/base/fixed_encryptor_source.h"
#include "media/base/widevine_encryptor_source.h"
#include "media/base/media_stream.h" #include "media/base/media_stream.h"
#include "media/base/muxer_options.h" #include "media/base/muxer_options.h"
#include "media/base/request_signer.h" #include "media/base/request_signer.h"
#include "media/base/stream_info.h" #include "media/base/stream_info.h"
#include "media/base/widevine_encryptor_source.h"
#include "media/event/vod_media_info_dump_muxer_listener.h" #include "media/event/vod_media_info_dump_muxer_listener.h"
#include "media/file/file.h" #include "media/file/file.h"
#include "media/file/file_closer.h" #include "media/file/file_closer.h"

View File

@ -34,7 +34,7 @@ class LocalFile : public File {
/// @} /// @}
protected: protected:
~LocalFile(); virtual ~LocalFile();
virtual bool Open() OVERRIDE; virtual bool Open() OVERRIDE;

View File

@ -4,7 +4,7 @@
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
#include "media/mp4/mp4_fragmenter.h" #include "media/mp4/fragmenter.h"
#include "media/base/aes_encryptor.h" #include "media/base/aes_encryptor.h"
#include "media/base/buffer_reader.h" #include "media/base/buffer_reader.h"
@ -41,11 +41,11 @@ bool OptimizeSampleEntries(std::vector<T>* entries, T* default_value) {
namespace media { namespace media {
namespace mp4 { namespace mp4 {
MP4Fragmenter::MP4Fragmenter(TrackFragment* traf, Fragmenter::Fragmenter(TrackFragment* traf,
scoped_ptr<AesCtrEncryptor> encryptor, scoped_ptr<AesCtrEncryptor> encryptor,
int64 clear_time, int64 clear_time,
uint8 nalu_length_size, uint8 nalu_length_size,
bool normalize_presentation_timestamp) bool normalize_presentation_timestamp)
: encryptor_(encryptor.Pass()), : encryptor_(encryptor.Pass()),
nalu_length_size_(nalu_length_size), nalu_length_size_(nalu_length_size),
traf_(traf), traf_(traf),
@ -57,9 +57,9 @@ MP4Fragmenter::MP4Fragmenter(TrackFragment* traf,
first_sap_time_(kInvalidTime), first_sap_time_(kInvalidTime),
clear_time_(clear_time) {} clear_time_(clear_time) {}
MP4Fragmenter::~MP4Fragmenter() {} Fragmenter::~Fragmenter() {}
Status MP4Fragmenter::AddSample(scoped_refptr<MediaSample> sample) { Status Fragmenter::AddSample(scoped_refptr<MediaSample> sample) {
CHECK_GT(sample->duration(), 0); CHECK_GT(sample->duration(), 0);
if (ShouldEncryptFragment()) { if (ShouldEncryptFragment()) {
@ -112,7 +112,7 @@ Status MP4Fragmenter::AddSample(scoped_refptr<MediaSample> sample) {
return Status::OK; return Status::OK;
} }
void MP4Fragmenter::InitializeFragment() { void Fragmenter::InitializeFragment() {
fragment_finalized_ = false; fragment_finalized_ = false;
traf_->decode_time.decode_time += fragment_duration_; traf_->decode_time.decode_time += fragment_duration_;
traf_->auxiliary_size.sample_info_sizes.clear(); traf_->auxiliary_size.sample_info_sizes.clear();
@ -135,7 +135,7 @@ void MP4Fragmenter::InitializeFragment() {
} }
} }
void MP4Fragmenter::FinalizeFragment() { void Fragmenter::FinalizeFragment() {
if (ShouldEncryptFragment()) { if (ShouldEncryptFragment()) {
DCHECK(encryptor_); DCHECK(encryptor_);
@ -188,7 +188,7 @@ void MP4Fragmenter::FinalizeFragment() {
fragment_finalized_ = true; fragment_finalized_ = true;
} }
void MP4Fragmenter::GenerateSegmentReference(SegmentReference* reference) { void Fragmenter::GenerateSegmentReference(SegmentReference* reference) {
// NOTE: Daisy chain is not supported currently. // NOTE: Daisy chain is not supported currently.
reference->reference_type = false; reference->reference_type = false;
reference->subsegment_duration = fragment_duration_; reference->subsegment_duration = fragment_duration_;
@ -203,12 +203,12 @@ void MP4Fragmenter::GenerateSegmentReference(SegmentReference* reference) {
reference->earliest_presentation_time = earliest_presentation_time_; reference->earliest_presentation_time = earliest_presentation_time_;
} }
void MP4Fragmenter::EncryptBytes(uint8* data, uint32 size) { void Fragmenter::EncryptBytes(uint8* data, uint32 size) {
DCHECK(encryptor_); DCHECK(encryptor_);
CHECK(encryptor_->Encrypt(data, size, data)); CHECK(encryptor_->Encrypt(data, size, data));
} }
Status MP4Fragmenter::EncryptSample(scoped_refptr<MediaSample> sample) { Status Fragmenter::EncryptSample(scoped_refptr<MediaSample> sample) {
DCHECK(encryptor_); DCHECK(encryptor_);
FrameCENCInfo cenc_info(encryptor_->iv()); FrameCENCInfo cenc_info(encryptor_->iv());
@ -244,7 +244,7 @@ Status MP4Fragmenter::EncryptSample(scoped_refptr<MediaSample> sample) {
return Status::OK; return Status::OK;
} }
bool MP4Fragmenter::StartsWithSAP() { bool Fragmenter::StartsWithSAP() {
DCHECK(!traf_->runs.empty()); DCHECK(!traf_->runs.empty());
uint32 start_sample_flag; uint32 start_sample_flag;
if (traf_->runs[0].flags & TrackFragmentRun::kSampleFlagsPresentMask) { if (traf_->runs[0].flags & TrackFragmentRun::kSampleFlagsPresentMask) {

View File

@ -4,8 +4,8 @@
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
#ifndef MEDIA_MP4_MP4_FRAGMENTER_H_ #ifndef MEDIA_MP4_FRAGMENTER_H_
#define MEDIA_MP4_MP4_FRAGMENTER_H_ #define MEDIA_MP4_FRAGMENTER_H_
#include <vector> #include <vector>
@ -24,10 +24,10 @@ namespace mp4 {
struct SegmentReference; struct SegmentReference;
struct TrackFragment; struct TrackFragment;
/// MP4Fragmenter is responsible for the generation of MP4 fragments, i.e. traf /// Fragmenter is responsible for the generation of MP4 fragments, i.e. traf
/// box and corresponding mdat box. The samples are also encrypted if encryption /// box and corresponding mdat box. The samples are also encrypted if encryption
/// is requested. /// is requested.
class MP4Fragmenter { class Fragmenter {
public: public:
/// @param traf points to a TrackFragment box. /// @param traf points to a TrackFragment box.
/// @param encryptor handles encryption of the samples. It can be NULL, which /// @param encryptor handles encryption of the samples. It can be NULL, which
@ -38,12 +38,12 @@ class MP4Fragmenter {
/// encryption. /// encryption.
/// @param normalize_presentation_timestamp defines whether PTS should be /// @param normalize_presentation_timestamp defines whether PTS should be
/// normalized to start from zero. /// normalized to start from zero.
MP4Fragmenter(TrackFragment* traf, Fragmenter(TrackFragment* traf,
scoped_ptr<AesCtrEncryptor> encryptor, scoped_ptr<AesCtrEncryptor> encryptor,
int64 clear_time, int64 clear_time,
uint8 nalu_length_size, uint8 nalu_length_size,
bool normalize_presentation_timestamp); bool normalize_presentation_timestamp);
~MP4Fragmenter(); ~Fragmenter();
/// Add a sample to the fragmenter. /// Add a sample to the fragmenter.
Status AddSample(scoped_refptr<MediaSample> sample); Status AddSample(scoped_refptr<MediaSample> sample);
@ -97,10 +97,10 @@ class MP4Fragmenter {
scoped_ptr<BufferWriter> data_; scoped_ptr<BufferWriter> data_;
scoped_ptr<BufferWriter> aux_data_; scoped_ptr<BufferWriter> aux_data_;
DISALLOW_COPY_AND_ASSIGN(MP4Fragmenter); DISALLOW_COPY_AND_ASSIGN(Fragmenter);
}; };
} // namespace mp4 } // namespace mp4
} // namespace media } // namespace media
#endif // MEDIA_MP4_MP4_FRAGMENTER_H_ #endif // MEDIA_MP4_FRAGMENTER_H_

View File

@ -40,21 +40,21 @@
'es_descriptor.cc', 'es_descriptor.cc',
'es_descriptor.h', 'es_descriptor.h',
'fourccs.h', 'fourccs.h',
'mp4_fragmenter.cc', 'fragmenter.cc',
'mp4_fragmenter.h', 'fragmenter.h',
'mp4_general_segmenter.cc',
'mp4_general_segmenter.h',
'mp4_media_parser.cc', 'mp4_media_parser.cc',
'mp4_media_parser.h', 'mp4_media_parser.h',
'mp4_muxer.cc', 'mp4_muxer.cc',
'mp4_muxer.h', 'mp4_muxer.h',
'mp4_segmenter.cc', 'multi_segment_segmenter.cc',
'mp4_segmenter.h', 'multi_segment_segmenter.h',
'mp4_vod_segmenter.cc',
'mp4_vod_segmenter.h',
'offset_byte_queue.cc', 'offset_byte_queue.cc',
'offset_byte_queue.h', 'offset_byte_queue.h',
'rcheck.h', 'rcheck.h',
'segmenter.cc',
'segmenter.h',
'single_segment_segmenter.cc',
'single_segment_segmenter.h',
'sync_sample_iterator.cc', 'sync_sample_iterator.cc',
'sync_sample_iterator.h', 'sync_sample_iterator.h',
'track_run_iterator.cc', 'track_run_iterator.cc',

View File

@ -19,8 +19,8 @@
#include "media/mp4/box_definitions.h" #include "media/mp4/box_definitions.h"
#include "media/mp4/es_descriptor.h" #include "media/mp4/es_descriptor.h"
#include "media/mp4/fourccs.h" #include "media/mp4/fourccs.h"
#include "media/mp4/mp4_general_segmenter.h" #include "media/mp4/multi_segment_segmenter.h"
#include "media/mp4/mp4_vod_segmenter.h" #include "media/mp4/single_segment_segmenter.h"
namespace { namespace {
// The version of cenc implemented here. CENC 4. // The version of cenc implemented here. CENC 4.
@ -99,10 +99,11 @@ Status MP4Muxer::Initialize() {
} }
if (options().single_segment) { if (options().single_segment) {
segmenter_.reset(new MP4VODSegmenter(options(), ftyp.Pass(), moov.Pass())); segmenter_.reset(
new SingleSegmentSegmenter(options(), ftyp.Pass(), moov.Pass()));
} else { } else {
segmenter_.reset( segmenter_.reset(
new MP4GeneralSegmenter(options(), ftyp.Pass(), moov.Pass())); new MultiSegmentSegmenter(options(), ftyp.Pass(), moov.Pass()));
} }
Status segmenter_initialized = segmenter_->Initialize( Status segmenter_initialized = segmenter_->Initialize(

View File

@ -20,7 +20,7 @@ class VideoStreamInfo;
namespace mp4 { namespace mp4 {
class MP4Segmenter; class Segmenter;
struct ProtectionSchemeInfo; struct ProtectionSchemeInfo;
struct ProtectionSystemSpecificHeader; struct ProtectionSystemSpecificHeader;
@ -79,7 +79,7 @@ class MP4Muxer : public Muxer {
// Get time in seconds since midnight, Jan. 1, 1904, in UTC Time. // Get time in seconds since midnight, Jan. 1, 1904, in UTC Time.
uint64 IsoTimeNow(); uint64 IsoTimeNow();
scoped_ptr<MP4Segmenter> segmenter_; scoped_ptr<Segmenter> segmenter_;
DISALLOW_COPY_AND_ASSIGN(MP4Muxer); DISALLOW_COPY_AND_ASSIGN(MP4Muxer);
}; };

View File

@ -4,7 +4,7 @@
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
#include "media/mp4/mp4_general_segmenter.h" #include "media/mp4/multi_segment_segmenter.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
@ -17,25 +17,25 @@
namespace media { namespace media {
namespace mp4 { namespace mp4 {
MP4GeneralSegmenter::MP4GeneralSegmenter(const MuxerOptions& options, MultiSegmentSegmenter::MultiSegmentSegmenter(const MuxerOptions& options,
scoped_ptr<FileType> ftyp, scoped_ptr<FileType> ftyp,
scoped_ptr<Movie> moov) scoped_ptr<Movie> moov)
: MP4Segmenter(options, ftyp.Pass(), moov.Pass()), : Segmenter(options, ftyp.Pass(), moov.Pass()),
styp_(new SegmentType), styp_(new SegmentType),
num_segments_(0) { num_segments_(0) {
// Use the same brands for styp as ftyp. // Use the same brands for styp as ftyp.
styp_->major_brand = MP4Segmenter::ftyp()->major_brand; styp_->major_brand = Segmenter::ftyp()->major_brand;
styp_->compatible_brands = MP4Segmenter::ftyp()->compatible_brands; styp_->compatible_brands = Segmenter::ftyp()->compatible_brands;
} }
MP4GeneralSegmenter::~MP4GeneralSegmenter() {} MultiSegmentSegmenter::~MultiSegmentSegmenter() {}
Status MP4GeneralSegmenter::Initialize( Status MultiSegmentSegmenter::Initialize(
EncryptorSource* encryptor_source, EncryptorSource* encryptor_source,
double clear_lead_in_seconds, double clear_lead_in_seconds,
const std::vector<MediaStream*>& streams) { const std::vector<MediaStream*>& streams) {
Status status = MP4Segmenter::Initialize( Status status =
encryptor_source, clear_lead_in_seconds, streams); Segmenter::Initialize(encryptor_source, clear_lead_in_seconds, streams);
if (!status.ok()) if (!status.ok())
return status; return status;
@ -58,19 +58,19 @@ Status MP4GeneralSegmenter::Initialize(
return status; return status;
} }
bool MP4GeneralSegmenter::GetInitRange(size_t* offset, size_t* size) { bool MultiSegmentSegmenter::GetInitRange(size_t* offset, size_t* size) {
DLOG(INFO) << "MP4GeneralSegmenter outputs init segment: " DLOG(INFO) << "MultiSegmentSegmenter outputs init segment: "
<< options().output_file_name; << options().output_file_name;
return false; return false;
} }
bool MP4GeneralSegmenter::GetIndexRange(size_t* offset, size_t* size) { bool MultiSegmentSegmenter::GetIndexRange(size_t* offset, size_t* size) {
DLOG(INFO) << "MP4GeneralSegmenter does not have index range."; DLOG(INFO) << "MultiSegmentSegmenter does not have index range.";
return false; return false;
} }
Status MP4GeneralSegmenter::FinalizeSegment() { Status MultiSegmentSegmenter::FinalizeSegment() {
Status status = MP4Segmenter::FinalizeSegment(); Status status = Segmenter::FinalizeSegment();
if (!status.ok()) if (!status.ok())
return status; return status;
@ -134,7 +134,7 @@ Status MP4GeneralSegmenter::FinalizeSegment() {
return WriteSegment(); return WriteSegment();
} }
Status MP4GeneralSegmenter::WriteSegment() { Status MultiSegmentSegmenter::WriteSegment() {
DCHECK(sidx()); DCHECK(sidx());
DCHECK(fragment_buffer()); DCHECK(fragment_buffer());
DCHECK(styp_); DCHECK(styp_);

View File

@ -4,10 +4,10 @@
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
#ifndef MEDIA_MP4_MP4_GENERAL_SEGMENTER_H_ #ifndef MEDIA_MP4_MULTI_SEGMENT_SEGMENTER_H_
#define MEDIA_MP4_MP4_GENERAL_SEGMENTER_H_ #define MEDIA_MP4_MULTI_SEGMENT_SEGMENTER_H_
#include "media/mp4/mp4_segmenter.h" #include "media/mp4/segmenter.h"
namespace media { namespace media {
namespace mp4 { namespace mp4 {
@ -21,20 +21,20 @@ struct SegmentType;
/// contain one or many fragments with fragment duration defined by @b /// contain one or many fragments with fragment duration defined by @b
/// MuxerOptions.fragment_duration. The actual segment or fragment duration /// MuxerOptions.fragment_duration. The actual segment or fragment duration
/// may not match the requested duration exactly, but will be approximated. /// may not match the requested duration exactly, but will be approximated.
/// That is, the segmenter tries to end segment/fragment at the first sample /// That is, the Segmenter tries to end segment/fragment at the first sample
/// with overall segment/fragment duration not smaller than defined duration /// with overall segment/fragment duration not smaller than defined duration
/// and yet meet SAP requirements. The generated segments are written to files /// and yet meet SAP requirements. The generated segments are written to files
/// defined by @b MuxerOptions.segment_template if specified; otherwise, /// defined by @b MuxerOptions.segment_template if specified; otherwise,
/// the segments are appended to the main output file specified by @b /// the segments are appended to the main output file specified by @b
/// MuxerOptions.output_file_name. /// MuxerOptions.output_file_name.
class MP4GeneralSegmenter : public MP4Segmenter { class MultiSegmentSegmenter : public Segmenter {
public: public:
MP4GeneralSegmenter(const MuxerOptions& options, MultiSegmentSegmenter(const MuxerOptions& options,
scoped_ptr<FileType> ftyp, scoped_ptr<FileType> ftyp,
scoped_ptr<Movie> moov); scoped_ptr<Movie> moov);
virtual ~MP4GeneralSegmenter(); virtual ~MultiSegmentSegmenter();
/// @name MP4Segmenter implementation overrides. /// @name Segmenter implementation overrides.
/// @{ /// @{
virtual Status Initialize(EncryptorSource* encryptor_source, virtual Status Initialize(EncryptorSource* encryptor_source,
double clear_lead_in_seconds, double clear_lead_in_seconds,
@ -54,10 +54,10 @@ class MP4GeneralSegmenter : public MP4Segmenter {
scoped_ptr<SegmentType> styp_; scoped_ptr<SegmentType> styp_;
uint32 num_segments_; uint32 num_segments_;
DISALLOW_COPY_AND_ASSIGN(MP4GeneralSegmenter); DISALLOW_COPY_AND_ASSIGN(MultiSegmentSegmenter);
}; };
} // namespace mp4 } // namespace mp4
} // namespace media } // namespace media
#endif // MEDIA_MP4_MP4_GENERAL_SEGMENTER_H_ #endif // MEDIA_MP4_MULTI_SEGMENT_SEGMENTER_H_

View File

@ -4,7 +4,7 @@
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
#include "media/mp4/mp4_segmenter.h" #include "media/mp4/segmenter.h"
#include <algorithm> #include <algorithm>
@ -16,7 +16,7 @@
#include "media/base/muxer_options.h" #include "media/base/muxer_options.h"
#include "media/base/video_stream_info.h" #include "media/base/video_stream_info.h"
#include "media/mp4/box_definitions.h" #include "media/mp4/box_definitions.h"
#include "media/mp4/mp4_fragmenter.h" #include "media/mp4/fragmenter.h"
namespace { namespace {
uint64 Rescale(uint64 time_in_old_scale, uint32 old_scale, uint32 new_scale) { uint64 Rescale(uint64 time_in_old_scale, uint32 old_scale, uint32 new_scale) {
@ -27,9 +27,9 @@ uint64 Rescale(uint64 time_in_old_scale, uint32 old_scale, uint32 new_scale) {
namespace media { namespace media {
namespace mp4 { namespace mp4 {
MP4Segmenter::MP4Segmenter(const MuxerOptions& options, Segmenter::Segmenter(const MuxerOptions& options,
scoped_ptr<FileType> ftyp, scoped_ptr<FileType> ftyp,
scoped_ptr<Movie> moov) scoped_ptr<Movie> moov)
: options_(options), : options_(options),
ftyp_(ftyp.Pass()), ftyp_(ftyp.Pass()),
moov_(moov.Pass()), moov_(moov.Pass()),
@ -39,11 +39,11 @@ MP4Segmenter::MP4Segmenter(const MuxerOptions& options,
segment_initialized_(false), segment_initialized_(false),
end_of_segment_(false) {} end_of_segment_(false) {}
MP4Segmenter::~MP4Segmenter() { STLDeleteElements(&fragmenters_); } Segmenter::~Segmenter() { STLDeleteElements(&fragmenters_); }
Status MP4Segmenter::Initialize(EncryptorSource* encryptor_source, Status Segmenter::Initialize(EncryptorSource* encryptor_source,
double clear_lead_in_seconds, double clear_lead_in_seconds,
const std::vector<MediaStream*>& streams) { const std::vector<MediaStream*>& streams) {
DCHECK_LT(0u, streams.size()); DCHECK_LT(0u, streams.size());
moof_->header.sequence_number = 0; moof_->header.sequence_number = 0;
@ -68,7 +68,7 @@ Status MP4Segmenter::Initialize(EncryptorSource* encryptor_source,
if (!encryptor) if (!encryptor)
return Status(error::MUXER_FAILURE, "Failed to create the encryptor."); return Status(error::MUXER_FAILURE, "Failed to create the encryptor.");
} }
fragmenters_[i] = new MP4Fragmenter( fragmenters_[i] = new Fragmenter(
&moof_->tracks[i], &moof_->tracks[i],
encryptor.Pass(), encryptor.Pass(),
clear_lead_in_seconds * streams[i]->info()->time_scale(), clear_lead_in_seconds * streams[i]->info()->time_scale(),
@ -87,9 +87,9 @@ Status MP4Segmenter::Initialize(EncryptorSource* encryptor_source,
return Status::OK; return Status::OK;
} }
Status MP4Segmenter::Finalize() { Status Segmenter::Finalize() {
end_of_segment_ = true; end_of_segment_ = true;
for (std::vector<MP4Fragmenter*>::iterator it = fragmenters_.begin(); for (std::vector<Fragmenter*>::iterator it = fragmenters_.begin();
it != fragmenters_.end(); it != fragmenters_.end();
++it) { ++it) {
Status status = FinalizeFragment(*it); Status status = FinalizeFragment(*it);
@ -113,13 +113,13 @@ Status MP4Segmenter::Finalize() {
return Status::OK; return Status::OK;
} }
Status MP4Segmenter::AddSample(const MediaStream* stream, Status Segmenter::AddSample(const MediaStream* stream,
scoped_refptr<MediaSample> sample) { scoped_refptr<MediaSample> sample) {
// Find the fragmenter for this stream. // Find the fragmenter for this stream.
DCHECK(stream); DCHECK(stream);
DCHECK(stream_map_.find(stream) != stream_map_.end()); DCHECK(stream_map_.find(stream) != stream_map_.end());
uint32 stream_id = stream_map_[stream]; uint32 stream_id = stream_map_[stream];
MP4Fragmenter* fragmenter = fragmenters_[stream_id]; Fragmenter* fragmenter = fragmenters_[stream_id];
// Set default sample duration if it has not been set yet. // Set default sample duration if it has not been set yet.
if (moov_->extends.tracks[stream_id].default_sample_duration == 0) { if (moov_->extends.tracks[stream_id].default_sample_duration == 0) {
@ -168,11 +168,11 @@ Status MP4Segmenter::AddSample(const MediaStream* stream,
return Status::OK; return Status::OK;
} }
uint32 MP4Segmenter::GetReferenceTimeScale() const { uint32 Segmenter::GetReferenceTimeScale() const {
return moov_->header.timescale; return moov_->header.timescale;
} }
double MP4Segmenter::GetDuration() const { double Segmenter::GetDuration() const {
if (moov_->header.timescale == 0) { if (moov_->header.timescale == 0) {
// Handling the case where this is not properly initialized. // Handling the case where this is not properly initialized.
return 0.0; return 0.0;
@ -181,7 +181,7 @@ double MP4Segmenter::GetDuration() const {
return static_cast<double>(moov_->header.duration) / moov_->header.timescale; return static_cast<double>(moov_->header.duration) / moov_->header.timescale;
} }
void MP4Segmenter::InitializeSegment() { void Segmenter::InitializeSegment() {
sidx_->references.clear(); sidx_->references.clear();
end_of_segment_ = false; end_of_segment_ = false;
std::vector<uint64>::iterator it = segment_durations_.begin(); std::vector<uint64>::iterator it = segment_durations_.begin();
@ -189,30 +189,30 @@ void MP4Segmenter::InitializeSegment() {
*it = 0; *it = 0;
} }
Status MP4Segmenter::FinalizeSegment() { Status Segmenter::FinalizeSegment() {
segment_initialized_ = false; segment_initialized_ = false;
return Status::OK; return Status::OK;
} }
uint32 MP4Segmenter::GetReferenceStreamId() { uint32 Segmenter::GetReferenceStreamId() {
DCHECK(sidx_); DCHECK(sidx_);
return sidx_->reference_id - 1; return sidx_->reference_id - 1;
} }
void MP4Segmenter::InitializeFragments() { void Segmenter::InitializeFragments() {
++moof_->header.sequence_number; ++moof_->header.sequence_number;
for (std::vector<MP4Fragmenter*>::iterator it = fragmenters_.begin(); for (std::vector<Fragmenter*>::iterator it = fragmenters_.begin();
it != fragmenters_.end(); it != fragmenters_.end();
++it) { ++it) {
(*it)->InitializeFragment(); (*it)->InitializeFragment();
} }
} }
Status MP4Segmenter::FinalizeFragment(MP4Fragmenter* fragmenter) { Status Segmenter::FinalizeFragment(Fragmenter* fragmenter) {
fragmenter->FinalizeFragment(); fragmenter->FinalizeFragment();
// Check if all tracks are ready for fragmentation. // Check if all tracks are ready for fragmentation.
for (std::vector<MP4Fragmenter*>::iterator it = fragmenters_.begin(); for (std::vector<Fragmenter*>::iterator it = fragmenters_.begin();
it != fragmenters_.end(); it != fragmenters_.end();
++it) { ++it) {
if (!(*it)->fragment_finalized()) if (!(*it)->fragment_finalized())
@ -225,7 +225,7 @@ Status MP4Segmenter::FinalizeFragment(MP4Fragmenter* fragmenter) {
uint64 base = moof_->ComputeSize() + mdat.ComputeSize(); uint64 base = moof_->ComputeSize() + mdat.ComputeSize();
for (uint i = 0; i < moof_->tracks.size(); ++i) { for (uint i = 0; i < moof_->tracks.size(); ++i) {
TrackFragment& traf = moof_->tracks[i]; TrackFragment& traf = moof_->tracks[i];
MP4Fragmenter* fragmenter = fragmenters_[i]; Fragmenter* fragmenter = fragmenters_[i];
if (fragmenter->aux_data()->Size() > 0) { if (fragmenter->aux_data()->Size() > 0) {
traf.auxiliary_offset.offsets[0] += base; traf.auxiliary_offset.offsets[0] += base;
base += fragmenter->aux_data()->Size(); base += fragmenter->aux_data()->Size();
@ -244,7 +244,7 @@ Status MP4Segmenter::FinalizeFragment(MP4Fragmenter* fragmenter) {
moof_->Write(fragment_buffer_.get()); moof_->Write(fragment_buffer_.get());
for (uint i = 0; i < moof_->tracks.size(); ++i) { for (uint i = 0; i < moof_->tracks.size(); ++i) {
MP4Fragmenter* fragmenter = fragmenters_[i]; Fragmenter* fragmenter = fragmenters_[i];
mdat.data_size = mdat.data_size =
fragmenter->aux_data()->Size() + fragmenter->data()->Size(); fragmenter->aux_data()->Size() + fragmenter->data()->Size();
mdat.Write(fragment_buffer_.get()); mdat.Write(fragment_buffer_.get());

View File

@ -4,8 +4,8 @@
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
#ifndef MEDIA_MP4_MP4_SEGMENTER_H_ #ifndef MEDIA_MP4_SEGMENTER_H_
#define MEDIA_MP4_MP4_SEGMENTER_H_ #define MEDIA_MP4_SEGMENTER_H_
#include <map> #include <map>
#include <vector> #include <vector>
@ -25,25 +25,25 @@ class MediaStream;
namespace mp4 { namespace mp4 {
class MP4Fragmenter; class Fragmenter;
struct FileType; struct FileType;
struct Movie; struct Movie;
struct MovieFragment; struct MovieFragment;
struct SegmentIndex; struct SegmentIndex;
/// This class defines the MP4 Segmenter which is responsible for organizing /// This class defines the Segmenter which is responsible for organizing
/// MP4 fragments into segments/subsegments and package them into a MP4 file. /// fragments into segments/subsegments and package them into a MP4 file.
/// Inherited by MP4GeneralSegmenter and MP4VODSegmenter. MP4VODSegmenter /// Inherited by MultiSegmentSegmenter and SingleSegmentSegmenter.
/// defines the segmenter for DASH Video-On-Demand with a single segment for /// SingleSegmentSegmenter defines the Segmenter for DASH Video-On-Demand with
/// each media presentation while MP4GeneralSegmenter handles all other cases /// a single segment for each media presentation while MultiSegmentSegmenter
/// including DASH live profile. /// handles all other cases including DASH live profile.
class MP4Segmenter { class Segmenter {
public: public:
MP4Segmenter(const MuxerOptions& options, Segmenter(const MuxerOptions& options,
scoped_ptr<FileType> ftyp, scoped_ptr<FileType> ftyp,
scoped_ptr<Movie> moov); scoped_ptr<Movie> moov);
virtual ~MP4Segmenter(); virtual ~Segmenter();
/// Initialize the segmenter. /// Initialize the segmenter.
/// Calling other public methods of this class without this method returning /// Calling other public methods of this class without this method returning
@ -86,7 +86,7 @@ class MP4Segmenter {
private: private:
void InitializeFragments(); void InitializeFragments();
Status FinalizeFragment(MP4Fragmenter* fragment); Status FinalizeFragment(Fragmenter* fragment);
const MuxerOptions& options_; const MuxerOptions& options_;
scoped_ptr<FileType> ftyp_; scoped_ptr<FileType> ftyp_;
@ -94,16 +94,16 @@ class MP4Segmenter {
scoped_ptr<MovieFragment> moof_; scoped_ptr<MovieFragment> moof_;
scoped_ptr<BufferWriter> fragment_buffer_; scoped_ptr<BufferWriter> fragment_buffer_;
scoped_ptr<SegmentIndex> sidx_; scoped_ptr<SegmentIndex> sidx_;
std::vector<MP4Fragmenter*> fragmenters_; std::vector<Fragmenter*> fragmenters_;
std::vector<uint64> segment_durations_; std::vector<uint64> segment_durations_;
std::map<const MediaStream*, uint32> stream_map_; std::map<const MediaStream*, uint32> stream_map_;
bool segment_initialized_; bool segment_initialized_;
bool end_of_segment_; bool end_of_segment_;
DISALLOW_COPY_AND_ASSIGN(MP4Segmenter); DISALLOW_COPY_AND_ASSIGN(Segmenter);
}; };
} // namespace mp4 } // namespace mp4
} // namespace media } // namespace media
#endif // MEDIA_MP4_MP4_SEGMENTER_H_ #endif // MEDIA_MP4_SEGMENTER_H_

View File

@ -4,7 +4,7 @@
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
#include "media/mp4/mp4_vod_segmenter.h" #include "media/mp4/single_segment_segmenter.h"
#include "media/base/buffer_writer.h" #include "media/base/buffer_writer.h"
#include "media/base/media_stream.h" #include "media/base/media_stream.h"
@ -15,17 +15,18 @@
namespace media { namespace media {
namespace mp4 { namespace mp4 {
MP4VODSegmenter::MP4VODSegmenter(const MuxerOptions& options, SingleSegmentSegmenter::SingleSegmentSegmenter(const MuxerOptions& options,
scoped_ptr<FileType> ftyp, scoped_ptr<FileType> ftyp,
scoped_ptr<Movie> moov) scoped_ptr<Movie> moov)
: MP4Segmenter(options, ftyp.Pass(), moov.Pass()) {} : Segmenter(options, ftyp.Pass(), moov.Pass()) {}
MP4VODSegmenter::~MP4VODSegmenter() {} SingleSegmentSegmenter::~SingleSegmentSegmenter() {}
Status MP4VODSegmenter::Initialize(EncryptorSource* encryptor_source, Status SingleSegmentSegmenter::Initialize(
double clear_lead_in_seconds, EncryptorSource* encryptor_source,
const std::vector<MediaStream*>& streams) { double clear_lead_in_seconds,
Status status = MP4Segmenter::Initialize( const std::vector<MediaStream*>& streams) {
encryptor_source, clear_lead_in_seconds, streams); Status status =
Segmenter::Initialize(encryptor_source, clear_lead_in_seconds, streams);
if (!status.ok()) if (!status.ok())
return status; return status;
temp_file_.reset(File::Open(options().temp_file_name.c_str(), "w")); temp_file_.reset(File::Open(options().temp_file_name.c_str(), "w"));
@ -36,8 +37,8 @@ Status MP4VODSegmenter::Initialize(EncryptorSource* encryptor_source,
return Status::OK; return Status::OK;
} }
Status MP4VODSegmenter::Finalize() { Status SingleSegmentSegmenter::Finalize() {
Status status = MP4Segmenter::Finalize(); Status status = Segmenter::Finalize();
if (!status.ok()) if (!status.ok())
return status; return status;
@ -93,14 +94,14 @@ Status MP4VODSegmenter::Finalize() {
return Status::OK; return Status::OK;
} }
bool MP4VODSegmenter::GetInitRange(size_t* offset, size_t* size) { bool SingleSegmentSegmenter::GetInitRange(size_t* offset, size_t* size) {
// In Finalize, ftyp and moov gets written first so offset must be 0. // In Finalize, ftyp and moov gets written first so offset must be 0.
*offset = 0; *offset = 0;
*size = ftyp()->ComputeSize() + moov()->ComputeSize(); *size = ftyp()->ComputeSize() + moov()->ComputeSize();
return true; return true;
} }
bool MP4VODSegmenter::GetIndexRange(size_t* offset, size_t* size) { bool SingleSegmentSegmenter::GetIndexRange(size_t* offset, size_t* size) {
// Index range is right after init range so the offset must be the size of // Index range is right after init range so the offset must be the size of
// ftyp and moov. // ftyp and moov.
*offset = ftyp()->ComputeSize() + moov()->ComputeSize(); *offset = ftyp()->ComputeSize() + moov()->ComputeSize();
@ -108,8 +109,8 @@ bool MP4VODSegmenter::GetIndexRange(size_t* offset, size_t* size) {
return true; return true;
} }
Status MP4VODSegmenter::FinalizeSegment() { Status SingleSegmentSegmenter::FinalizeSegment() {
Status status = MP4Segmenter::FinalizeSegment(); Status status = Segmenter::FinalizeSegment();
if (!status.ok()) if (!status.ok())
return status; return status;

View File

@ -4,11 +4,11 @@
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
#ifndef MEDIA_MP4_MP4_VOD_SEGMENTER_H_ #ifndef MEDIA_MP4_SINGLE_SEGMENT_SEGMENTER_H_
#define MEDIA_MP4_MP4_VOD_SEGMENTER_H_ #define MEDIA_MP4_SINGLE_SEGMENT_SEGMENTER_H_
#include "media/file/file_closer.h" #include "media/file/file_closer.h"
#include "media/mp4/mp4_segmenter.h" #include "media/mp4/segmenter.h"
namespace media { namespace media {
namespace mp4 { namespace mp4 {
@ -20,18 +20,18 @@ namespace mp4 {
/// or many fragments with fragment duration defined by @b /// or many fragments with fragment duration defined by @b
/// MuxerOptions.fragment_duration. The actual subsegment or fragment duration /// MuxerOptions.fragment_duration. The actual subsegment or fragment duration
/// may not match the requested duration exactly, but will be approximated. That /// may not match the requested duration exactly, but will be approximated. That
/// is, the segmenter tries to end subsegment/fragment at the first sample with /// is, the Segmenter tries to end subsegment/fragment at the first sample with
/// overall subsegment/fragment duration not smaller than defined duration and /// overall subsegment/fragment duration not smaller than defined duration and
/// yet meet SAP requirements. VOD segmenter ignores @b /// yet meet SAP requirements. SingleSegmentSegmenter ignores @b
/// MuxerOptions.num_subsegments_per_sidx. /// MuxerOptions.num_subsegments_per_sidx.
class MP4VODSegmenter : public MP4Segmenter { class SingleSegmentSegmenter : public Segmenter {
public: public:
MP4VODSegmenter(const MuxerOptions& options, SingleSegmentSegmenter(const MuxerOptions& options,
scoped_ptr<FileType> ftyp, scoped_ptr<FileType> ftyp,
scoped_ptr<Movie> moov); scoped_ptr<Movie> moov);
virtual ~MP4VODSegmenter(); virtual ~SingleSegmentSegmenter();
/// @name MP4Segmenter implementation overrides. /// @name Segmenter implementation overrides.
/// @{ /// @{
virtual Status Initialize(EncryptorSource* encryptor_source, virtual Status Initialize(EncryptorSource* encryptor_source,
double clear_lead_in_seconds, double clear_lead_in_seconds,
@ -49,10 +49,10 @@ class MP4VODSegmenter : public MP4Segmenter {
scoped_ptr<SegmentIndex> vod_sidx_; scoped_ptr<SegmentIndex> vod_sidx_;
scoped_ptr<File, FileCloser> temp_file_; scoped_ptr<File, FileCloser> temp_file_;
DISALLOW_COPY_AND_ASSIGN(MP4VODSegmenter); DISALLOW_COPY_AND_ASSIGN(SingleSegmentSegmenter);
}; };
} // namespace mp4 } // namespace mp4
} // namespace media } // namespace media
#endif // MEDIA_MP4_MP4_VOD_SEGMENTER_H_ #endif // MEDIA_MP4_SINGLE_SEGMENT_SEGMENTER_H_

View File

@ -252,7 +252,7 @@ TEST_P(PackagerTest, MP4MuxerSingleSegmentUnencryptedSeparateAudioVideo) {
EXPECT_TRUE(ContentsEqual(kOutputAudio, kOutputAudio2)); EXPECT_TRUE(ContentsEqual(kOutputAudio, kOutputAudio2));
} }
TEST_P(PackagerTest, MP4MuxerMultipleSegmentsUnencrypted) { TEST_P(PackagerTest, MP4MuxerMultiSegmentsUnencrypted) {
ASSERT_NO_FATAL_FAILURE(Remux(GetParam(), ASSERT_NO_FATAL_FAILURE(Remux(GetParam(),
kOutputVideo2, kOutputVideo2,
kOutputNone, kOutputNone,