Make Muxer::Initialize and Muxer::Finalize private
User should not need to care about how and when to call these APIs. Internal code should call them automatically. Change-Id: Ibc85a709d4e82ecc7b477986cabf09dcfc2e100c
This commit is contained in:
parent
2498da675a
commit
833f27f687
|
@ -172,11 +172,7 @@ bool AddStreamToMuxer(const std::vector<MediaStream*>& streams, Muxer* muxer) {
|
|||
LOG(ERROR) << "No " << FLAGS_stream << " stream found in the input.";
|
||||
return false;
|
||||
}
|
||||
Status status = muxer->AddStream(stream);
|
||||
if (!status.ok()) {
|
||||
LOG(ERROR) << "Muxer failed to add stream: " << status.ToString();
|
||||
return false;
|
||||
}
|
||||
muxer->AddStream(stream);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -234,23 +230,12 @@ bool RunPackager(const std::string& input) {
|
|||
}
|
||||
muxer->SetEncryptorSource(encryptor_source.get(), FLAGS_clear_lead);
|
||||
|
||||
status = muxer->Initialize();
|
||||
if (!status.ok()) {
|
||||
LOG(ERROR) << "Muxer failed to initialize: " << status.ToString();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start remuxing process.
|
||||
status = demuxer.Run();
|
||||
if (!status.ok()) {
|
||||
LOG(ERROR) << "Remuxing failed: " << status.ToString();
|
||||
return false;
|
||||
}
|
||||
status = muxer->Finalize();
|
||||
if (!status.ok()) {
|
||||
LOG(ERROR) << "Muxer failed to finalize: " << status.ToString();
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("Packaging completed successfully.\n");
|
||||
return true;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "base/stl_util.h"
|
||||
#include "media/base/container_names.h"
|
||||
#include "media/base/decryptor_source.h"
|
||||
#include "media/base/media_sample.h"
|
||||
#include "media/base/media_stream.h"
|
||||
#include "media/base/stream_info.h"
|
||||
#include "media/file/file.h"
|
||||
|
@ -37,13 +38,13 @@ Demuxer::~Demuxer() {
|
|||
}
|
||||
|
||||
Status Demuxer::Initialize() {
|
||||
DCHECK(media_file_ == NULL);
|
||||
DCHECK(!media_file_);
|
||||
DCHECK(!init_event_received_);
|
||||
|
||||
media_file_ = File::Open(file_name_.c_str(), "r");
|
||||
if (media_file_ == NULL) {
|
||||
if (!media_file_) {
|
||||
return Status(error::FILE_FAILURE,
|
||||
"Cannot open file for read " + file_name_);
|
||||
"Cannot open file for reading " + file_name_);
|
||||
}
|
||||
|
||||
// Determine media container.
|
||||
|
@ -119,13 +120,25 @@ Status Demuxer::Run() {
|
|||
|
||||
while ((status = Parse()).ok())
|
||||
continue;
|
||||
return status.Matches(Status(error::END_OF_STREAM, "")) ? Status::OK : status;
|
||||
|
||||
if (status.error_code() == error::END_OF_STREAM) {
|
||||
// Push EOS sample to muxer to indicate end of stream.
|
||||
const scoped_refptr<MediaSample>& sample = MediaSample::CreateEOSBuffer();
|
||||
for (std::vector<MediaStream*>::iterator it = streams_.begin();
|
||||
it != streams_.end();
|
||||
++it) {
|
||||
status = (*it)->PushSample(sample);
|
||||
if (!status.ok())
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
Status Demuxer::Parse() {
|
||||
DCHECK(media_file_ != NULL);
|
||||
DCHECK(parser_ != NULL);
|
||||
DCHECK(buffer_ != NULL);
|
||||
DCHECK(media_file_);
|
||||
DCHECK(parser_);
|
||||
DCHECK(buffer_);
|
||||
|
||||
int64 bytes_read = media_file_->Read(buffer_.get(), kBufSize);
|
||||
if (bytes_read <= 0) {
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace media {
|
|||
Muxer::Muxer(const MuxerOptions& options)
|
||||
: options_(options),
|
||||
encryptor_source_(NULL),
|
||||
initialized_(false),
|
||||
clear_lead_in_seconds_(0),
|
||||
muxer_listener_(NULL),
|
||||
clock_(NULL) {}
|
||||
|
@ -27,10 +28,10 @@ void Muxer::SetEncryptorSource(EncryptorSource* encryptor_source,
|
|||
clear_lead_in_seconds_ = clear_lead_in_seconds;
|
||||
}
|
||||
|
||||
Status Muxer::AddStream(MediaStream* stream) {
|
||||
void Muxer::AddStream(MediaStream* stream) {
|
||||
DCHECK(stream);
|
||||
stream->Connect(this);
|
||||
streams_.push_back(stream);
|
||||
return Status::OK;
|
||||
}
|
||||
|
||||
Status Muxer::Run() {
|
||||
|
@ -55,16 +56,36 @@ Status Muxer::Run() {
|
|||
status = AddSample(streams_[current_stream_id], sample);
|
||||
|
||||
// Switch to next stream if the current stream is ready for fragmentation.
|
||||
if (status.Matches(Status(error::FRAGMENT_FINALIZED, ""))) {
|
||||
if (status.error_code() == error::FRAGMENT_FINALIZED) {
|
||||
current_stream_id = (current_stream_id + 1) % streams_.size();
|
||||
status.Clear();
|
||||
}
|
||||
}
|
||||
return status.Matches(Status(error::END_OF_STREAM, "")) ? Status::OK : status;
|
||||
// Finalize the muxer after reaching end of stream.
|
||||
return status.error_code() == error::END_OF_STREAM ? Finalize() : status;
|
||||
}
|
||||
|
||||
void Muxer::SetMuxerListener(media::event::MuxerListener* muxer_listener) {
|
||||
muxer_listener_ = muxer_listener;
|
||||
}
|
||||
|
||||
Status Muxer::AddSample(const MediaStream* stream,
|
||||
scoped_refptr<MediaSample> sample) {
|
||||
DCHECK(std::find(streams_.begin(), streams_.end(), stream) != streams_.end());
|
||||
|
||||
if (!initialized_) {
|
||||
Status status = Initialize();
|
||||
if (!status.ok())
|
||||
return status;
|
||||
initialized_ = true;
|
||||
}
|
||||
if (sample->end_of_stream()) {
|
||||
// EOS sample should be sent only when the sample was pushed from Demuxer
|
||||
// to Muxer. In this case, there should be only one stream in Muxer.
|
||||
DCHECK_EQ(1u, streams_.size());
|
||||
return Finalize();
|
||||
}
|
||||
return DoAddSample(stream, sample);
|
||||
}
|
||||
|
||||
} // namespace media
|
||||
|
|
|
@ -38,26 +38,18 @@ class Muxer {
|
|||
explicit Muxer(const MuxerOptions& options);
|
||||
virtual ~Muxer();
|
||||
|
||||
/// Set encryptor source. Should be called before calling Initialize().
|
||||
/// @param encryptor_source should not be NULL.
|
||||
/// Set encryptor source.
|
||||
/// @param encryptor_source points to the encryptor source to be injected.
|
||||
/// Should not be NULL.
|
||||
/// @param clear_lead_in_seconds specifies clear lead duration in seconds.
|
||||
void SetEncryptorSource(EncryptorSource* encryptor_source,
|
||||
double clear_lead_in_seconds);
|
||||
|
||||
/// Initialize the muxer. Must be called after connecting all the streams.
|
||||
virtual Status Initialize() = 0;
|
||||
|
||||
/// Final clean up.
|
||||
virtual Status Finalize() = 0;
|
||||
|
||||
/// Add video/audio stream.
|
||||
virtual Status AddStream(MediaStream* stream);
|
||||
|
||||
/// Add new media sample.
|
||||
virtual Status AddSample(const MediaStream* stream,
|
||||
scoped_refptr<MediaSample> sample) = 0;
|
||||
void AddStream(MediaStream* stream);
|
||||
|
||||
/// Drive the remuxing from muxer side (pull).
|
||||
virtual Status Run();
|
||||
Status Run();
|
||||
|
||||
/// Set a MuxerListener event handler for this object.
|
||||
/// @param muxer_listener should not be NULL.
|
||||
|
@ -83,9 +75,26 @@ class Muxer {
|
|||
base::Clock* clock() { return clock_; }
|
||||
|
||||
private:
|
||||
friend class MediaStream; // Needed to access AddSample.
|
||||
|
||||
// Add new media sample.
|
||||
Status AddSample(const MediaStream* stream,
|
||||
scoped_refptr<MediaSample> sample);
|
||||
|
||||
// Initialize the muxer.
|
||||
virtual Status Initialize() = 0;
|
||||
|
||||
// Final clean up.
|
||||
virtual Status Finalize() = 0;
|
||||
|
||||
// AddSample implementation.
|
||||
virtual Status DoAddSample(const MediaStream* stream,
|
||||
scoped_refptr<MediaSample> sample) = 0;
|
||||
|
||||
MuxerOptions options_;
|
||||
std::vector<MediaStream*> streams_;
|
||||
EncryptorSource* encryptor_source_;
|
||||
bool initialized_;
|
||||
double clear_lead_in_seconds_;
|
||||
|
||||
event::MuxerListener* muxer_listener_;
|
||||
|
|
|
@ -127,7 +127,7 @@ Status MP4Muxer::Finalize() {
|
|||
return Status::OK;
|
||||
}
|
||||
|
||||
Status MP4Muxer::AddSample(const MediaStream* stream,
|
||||
Status MP4Muxer::DoAddSample(const MediaStream* stream,
|
||||
scoped_refptr<MediaSample> sample) {
|
||||
DCHECK(segmenter_);
|
||||
return segmenter_->AddSample(stream, sample);
|
||||
|
|
|
@ -34,15 +34,13 @@ class MP4Muxer : public Muxer {
|
|||
explicit MP4Muxer(const MuxerOptions& options);
|
||||
virtual ~MP4Muxer();
|
||||
|
||||
/// @name Muxer implementation overrides.
|
||||
/// @{
|
||||
private:
|
||||
// Muxer implementation overrides.
|
||||
virtual Status Initialize() OVERRIDE;
|
||||
virtual Status Finalize() OVERRIDE;
|
||||
virtual Status AddSample(const MediaStream* stream,
|
||||
virtual Status DoAddSample(const MediaStream* stream,
|
||||
scoped_refptr<MediaSample> sample) OVERRIDE;
|
||||
/// @}
|
||||
|
||||
private:
|
||||
// Generate Audio/Video Track atom.
|
||||
void InitializeTrak(const StreamInfo* info, Track* trak);
|
||||
void GenerateAudioTrak(const AudioStreamInfo* audio_info,
|
||||
|
|
|
@ -157,12 +157,10 @@ void PackagerTestBasic::Remux(const std::string& input,
|
|||
new mp4::MP4Muxer(SetupOptions(video_output, single_segment)));
|
||||
muxer_video->set_clock(&fake_clock_);
|
||||
|
||||
ASSERT_OK(muxer_video->AddStream(FindFirstVideoStream(demuxer.streams())));
|
||||
muxer_video->AddStream(FindFirstVideoStream(demuxer.streams()));
|
||||
|
||||
if (enable_encryption)
|
||||
muxer_video->SetEncryptorSource(&encryptor_source, kClearLeadInSeconds);
|
||||
|
||||
ASSERT_OK(muxer_video->Initialize());
|
||||
}
|
||||
|
||||
scoped_ptr<Muxer> muxer_audio;
|
||||
|
@ -171,21 +169,14 @@ void PackagerTestBasic::Remux(const std::string& input,
|
|||
new mp4::MP4Muxer(SetupOptions(audio_output, single_segment)));
|
||||
muxer_audio->set_clock(&fake_clock_);
|
||||
|
||||
ASSERT_OK(muxer_audio->AddStream(FindFirstAudioStream(demuxer.streams())));
|
||||
muxer_audio->AddStream(FindFirstAudioStream(demuxer.streams()));
|
||||
|
||||
if (enable_encryption)
|
||||
muxer_video->SetEncryptorSource(&encryptor_source, kClearLeadInSeconds);
|
||||
|
||||
ASSERT_OK(muxer_audio->Initialize());
|
||||
}
|
||||
|
||||
// Start remuxing process.
|
||||
ASSERT_OK(demuxer.Run());
|
||||
|
||||
if (muxer_video)
|
||||
ASSERT_OK(muxer_video->Finalize());
|
||||
if (muxer_audio)
|
||||
ASSERT_OK(muxer_audio->Finalize());
|
||||
}
|
||||
|
||||
TEST_P(PackagerTestBasic, MP4MuxerSingleSegmentUnencrypted) {
|
||||
|
|
Loading…
Reference in New Issue