Move Muxer Creation To Own Method
Moved all the code to do with creating a muxer to its own function to help isolate it. Change-Id: Ib259da7aaa41d325632d5f9bb3d54ae9df8d0e31
This commit is contained in:
parent
ea45ce3158
commit
a9d957e7f0
|
@ -9,14 +9,11 @@
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
CombinedMuxerListener::CombinedMuxerListener(
|
void CombinedMuxerListener::AddListener(
|
||||||
std::list<std::unique_ptr<MuxerListener>>* muxer_listeners) {
|
std::unique_ptr<MuxerListener> listener) {
|
||||||
DCHECK(muxer_listeners);
|
muxer_listeners_.push_back(std::move(listener));
|
||||||
muxer_listeners_.swap(*muxer_listeners);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CombinedMuxerListener::~CombinedMuxerListener() {}
|
|
||||||
|
|
||||||
void CombinedMuxerListener::OnEncryptionInfoReady(
|
void CombinedMuxerListener::OnEncryptionInfoReady(
|
||||||
bool is_initial_encryption_info,
|
bool is_initial_encryption_info,
|
||||||
FourCC protection_scheme,
|
FourCC protection_scheme,
|
||||||
|
@ -25,9 +22,7 @@ void CombinedMuxerListener::OnEncryptionInfoReady(
|
||||||
const std::vector<ProtectionSystemSpecificInfo>& key_system_info) {
|
const std::vector<ProtectionSystemSpecificInfo>& key_system_info) {
|
||||||
for (auto& listener : muxer_listeners_) {
|
for (auto& listener : muxer_listeners_) {
|
||||||
listener->OnEncryptionInfoReady(is_initial_encryption_info,
|
listener->OnEncryptionInfoReady(is_initial_encryption_info,
|
||||||
protection_scheme,
|
protection_scheme, key_id, iv,
|
||||||
key_id,
|
|
||||||
iv,
|
|
||||||
key_system_info);
|
key_system_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,19 +33,17 @@ void CombinedMuxerListener::OnEncryptionStart() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinedMuxerListener::OnMediaStart(
|
void CombinedMuxerListener::OnMediaStart(const MuxerOptions& muxer_options,
|
||||||
const MuxerOptions& muxer_options,
|
|
||||||
const StreamInfo& stream_info,
|
const StreamInfo& stream_info,
|
||||||
uint32_t time_scale,
|
uint32_t time_scale,
|
||||||
ContainerType container_type) {
|
ContainerType container_type) {
|
||||||
for (auto& listener : muxer_listeners_) {
|
for (auto& listener : muxer_listeners_) {
|
||||||
listener->OnMediaStart(
|
listener->OnMediaStart(muxer_options, stream_info, time_scale,
|
||||||
muxer_options, stream_info, time_scale, container_type);
|
container_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinedMuxerListener::OnSampleDurationReady(
|
void CombinedMuxerListener::OnSampleDurationReady(uint32_t sample_duration) {
|
||||||
uint32_t sample_duration) {
|
|
||||||
for (auto& listener : muxer_listeners_) {
|
for (auto& listener : muxer_listeners_) {
|
||||||
listener->OnSampleDurationReady(sample_duration);
|
listener->OnSampleDurationReady(sample_duration);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,9 @@ namespace media {
|
||||||
|
|
||||||
class CombinedMuxerListener : public MuxerListener {
|
class CombinedMuxerListener : public MuxerListener {
|
||||||
public:
|
public:
|
||||||
explicit CombinedMuxerListener(
|
CombinedMuxerListener() = default;
|
||||||
std::list<std::unique_ptr<MuxerListener>>* muxer_listeners);
|
|
||||||
~CombinedMuxerListener() override;
|
void AddListener(std::unique_ptr<MuxerListener> listener);
|
||||||
|
|
||||||
void OnEncryptionInfoReady(bool is_initial_encryption_info,
|
void OnEncryptionInfoReady(bool is_initial_encryption_info,
|
||||||
FourCC protection_scheme,
|
FourCC protection_scheme,
|
||||||
|
|
|
@ -272,7 +272,6 @@ class Job : public base::SimpleThread {
|
||||||
};
|
};
|
||||||
|
|
||||||
bool StreamInfoToTextMediaInfo(const StreamDescriptor& stream_descriptor,
|
bool StreamInfoToTextMediaInfo(const StreamDescriptor& stream_descriptor,
|
||||||
const MuxerOptions& stream_muxer_options,
|
|
||||||
MediaInfo* text_media_info) {
|
MediaInfo* text_media_info) {
|
||||||
const std::string& language = stream_descriptor.language;
|
const std::string& language = stream_descriptor.language;
|
||||||
const std::string format = DetermineTextFileFormat(stream_descriptor.input);
|
const std::string format = DetermineTextFileFormat(stream_descriptor.input);
|
||||||
|
@ -283,18 +282,17 @@ bool StreamInfoToTextMediaInfo(const StreamDescriptor& stream_descriptor,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!File::Copy(stream_descriptor.input.c_str(),
|
if (!File::Copy(stream_descriptor.input.c_str(),
|
||||||
stream_muxer_options.output_file_name.c_str())) {
|
stream_descriptor.output.c_str())) {
|
||||||
LOG(ERROR) << "Failed to copy the input file (" << stream_descriptor.input
|
LOG(ERROR) << "Failed to copy the input file (" << stream_descriptor.input
|
||||||
<< ") to output file (" << stream_muxer_options.output_file_name
|
<< ") to output file (" << stream_descriptor.output << ").";
|
||||||
<< ").";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
text_media_info->set_media_file_name(stream_muxer_options.output_file_name);
|
text_media_info->set_media_file_name(stream_descriptor.output);
|
||||||
text_media_info->set_container_type(MediaInfo::CONTAINER_TEXT);
|
text_media_info->set_container_type(MediaInfo::CONTAINER_TEXT);
|
||||||
|
|
||||||
if (stream_muxer_options.bandwidth != 0) {
|
if (stream_descriptor.bandwidth != 0) {
|
||||||
text_media_info->set_bandwidth(stream_muxer_options.bandwidth);
|
text_media_info->set_bandwidth(stream_descriptor.bandwidth);
|
||||||
} else {
|
} else {
|
||||||
// Text files are usually small and since the input is one file; there's no
|
// Text files are usually small and since the input is one file; there's no
|
||||||
// way for the player to do ranged requests. So set this value to something
|
// way for the player to do ranged requests. So set this value to something
|
||||||
|
@ -311,16 +309,93 @@ bool StreamInfoToTextMediaInfo(const StreamDescriptor& stream_descriptor,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Muxer> CreateOutputMuxer(const MuxerOptions& options,
|
std::unique_ptr<MuxerListener> CreateMuxerListener(
|
||||||
MediaContainerName container) {
|
const StreamDescriptor& stream,
|
||||||
if (container == CONTAINER_WEBM) {
|
int stream_number,
|
||||||
return std::shared_ptr<Muxer>(new webm::WebMMuxer(options));
|
bool output_media_info,
|
||||||
} else if (container == CONTAINER_MPEG2TS) {
|
MpdNotifier* mpd_notifier,
|
||||||
return std::shared_ptr<Muxer>(new mp2t::TsMuxer(options));
|
hls::HlsNotifier* hls_notifier) {
|
||||||
} else {
|
std::unique_ptr<CombinedMuxerListener> combined_listener(
|
||||||
DCHECK_EQ(container, CONTAINER_MOV);
|
new CombinedMuxerListener);
|
||||||
return std::shared_ptr<Muxer>(new mp4::MP4Muxer(options));
|
|
||||||
|
if (output_media_info) {
|
||||||
|
std::unique_ptr<MuxerListener> listener(
|
||||||
|
new VodMediaInfoDumpMuxerListener(stream.output + kMediaInfoSuffix));
|
||||||
|
combined_listener->AddListener(std::move(listener));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mpd_notifier) {
|
||||||
|
std::unique_ptr<MuxerListener> listener(
|
||||||
|
new MpdNotifyMuxerListener(mpd_notifier));
|
||||||
|
combined_listener->AddListener(std::move(listener));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hls_notifier) {
|
||||||
|
// TODO(rkuroiwa): Do some smart stuff to group the audios, e.g. detect
|
||||||
|
// languages.
|
||||||
|
std::string group_id = stream.hls_group_id;
|
||||||
|
std::string name = stream.hls_name;
|
||||||
|
std::string hls_playlist_name = stream.hls_playlist_name;
|
||||||
|
if (group_id.empty())
|
||||||
|
group_id = "audio";
|
||||||
|
if (name.empty())
|
||||||
|
name = base::StringPrintf("stream_%d", stream_number);
|
||||||
|
if (hls_playlist_name.empty())
|
||||||
|
hls_playlist_name = base::StringPrintf("stream_%d.m3u8", stream_number);
|
||||||
|
|
||||||
|
std::unique_ptr<MuxerListener> listener(new HlsNotifyMuxerListener(
|
||||||
|
hls_playlist_name, name, group_id, hls_notifier));
|
||||||
|
combined_listener->AddListener(std::move(listener));
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(combined_listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Muxer> CreateMuxer(const PackagingParams& packaging_params,
|
||||||
|
const StreamDescriptor& stream,
|
||||||
|
base::Clock* clock,
|
||||||
|
std::unique_ptr<MuxerListener> listener) {
|
||||||
|
const MediaContainerName format = GetOutputFormat(stream);
|
||||||
|
|
||||||
|
MuxerOptions options;
|
||||||
|
options.mp4_params = packaging_params.mp4_output_params;
|
||||||
|
options.temp_dir = packaging_params.temp_dir;
|
||||||
|
options.bandwidth = stream.bandwidth;
|
||||||
|
options.output_file_name = stream.output;
|
||||||
|
options.segment_template = stream.segment_template;
|
||||||
|
|
||||||
|
std::shared_ptr<Muxer> muxer;
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case CONTAINER_WEBM:
|
||||||
|
muxer = std::make_shared<webm::WebMMuxer>(options);
|
||||||
|
break;
|
||||||
|
case CONTAINER_MPEG2TS:
|
||||||
|
muxer = std::make_shared<mp2t::TsMuxer>(options);
|
||||||
|
break;
|
||||||
|
case CONTAINER_MOV:
|
||||||
|
muxer = std::make_shared<mp4::MP4Muxer>(options);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG(ERROR) << "Cannot support muxing to " << format;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!muxer) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We successfully created a muxer, then there is a couple settings
|
||||||
|
// we should set before returning it.
|
||||||
|
if (clock) {
|
||||||
|
muxer->set_clock(clock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listener) {
|
||||||
|
muxer->SetMuxerListener(std::move(listener));
|
||||||
|
}
|
||||||
|
|
||||||
|
return muxer;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<MediaHandler> CreateCryptoHandler(
|
std::shared_ptr<MediaHandler> CreateCryptoHandler(
|
||||||
|
@ -399,8 +474,7 @@ Status CreateRemuxJobs(const StreamDescriptorList& stream_descriptors,
|
||||||
if (stream_iter->stream_selector == "text" &&
|
if (stream_iter->stream_selector == "text" &&
|
||||||
output_format != CONTAINER_MOV) {
|
output_format != CONTAINER_MOV) {
|
||||||
MediaInfo text_media_info;
|
MediaInfo text_media_info;
|
||||||
if (!StreamInfoToTextMediaInfo(*stream_iter, stream_muxer_options,
|
if (!StreamInfoToTextMediaInfo(*stream_iter, &text_media_info)) {
|
||||||
&text_media_info)) {
|
|
||||||
return Status(error::INVALID_ARGUMENT,
|
return Status(error::INVALID_ARGUMENT,
|
||||||
"Could not create media info for stream.");
|
"Could not create media info for stream.");
|
||||||
}
|
}
|
||||||
|
@ -414,8 +488,7 @@ Status CreateRemuxJobs(const StreamDescriptorList& stream_descriptors,
|
||||||
}
|
}
|
||||||
} else if (packaging_params.output_media_info) {
|
} else if (packaging_params.output_media_info) {
|
||||||
VodMediaInfoDumpMuxerListener::WriteMediaInfoToFile(
|
VodMediaInfoDumpMuxerListener::WriteMediaInfoToFile(
|
||||||
text_media_info,
|
text_media_info, stream_iter->output + kMediaInfoSuffix);
|
||||||
stream_muxer_options.output_file_name + kMediaInfoSuffix);
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -455,45 +528,19 @@ Status CreateRemuxJobs(const StreamDescriptorList& stream_descriptors,
|
||||||
trick_play_handler.reset();
|
trick_play_handler.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Muxer> muxer(
|
// Create the muxer (output) for this track.
|
||||||
CreateOutputMuxer(stream_muxer_options, output_format));
|
std::unique_ptr<MuxerListener> muxer_listener = CreateMuxerListener(
|
||||||
if (packaging_params.test_params.inject_fake_clock)
|
*stream_iter, stream_number, packaging_params.output_media_info,
|
||||||
muxer->set_clock(fake_clock);
|
mpd_notifier, hls_notifier);
|
||||||
|
std::shared_ptr<Muxer> muxer = CreateMuxer(
|
||||||
|
packaging_params, *stream_iter,
|
||||||
|
packaging_params.test_params.inject_fake_clock ? fake_clock : nullptr,
|
||||||
|
std::move(muxer_listener));
|
||||||
|
|
||||||
std::list<std::unique_ptr<MuxerListener>> muxer_listeners;
|
if (!muxer) {
|
||||||
DCHECK(!(packaging_params.output_media_info && mpd_notifier));
|
return Status(error::INVALID_ARGUMENT, "Failed to create muxer for " +
|
||||||
if (packaging_params.output_media_info) {
|
stream_iter->input + ":" +
|
||||||
const std::string output_media_info_file_name =
|
stream_iter->stream_selector);
|
||||||
stream_muxer_options.output_file_name + kMediaInfoSuffix;
|
|
||||||
muxer_listeners.emplace_back(
|
|
||||||
new VodMediaInfoDumpMuxerListener(output_media_info_file_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mpd_notifier) {
|
|
||||||
muxer_listeners.emplace_back(new MpdNotifyMuxerListener(mpd_notifier));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hls_notifier) {
|
|
||||||
// TODO(rkuroiwa): Do some smart stuff to group the audios, e.g. detect
|
|
||||||
// languages.
|
|
||||||
std::string group_id = stream_iter->hls_group_id;
|
|
||||||
std::string name = stream_iter->hls_name;
|
|
||||||
std::string hls_playlist_name = stream_iter->hls_playlist_name;
|
|
||||||
if (group_id.empty())
|
|
||||||
group_id = "audio";
|
|
||||||
if (name.empty())
|
|
||||||
name = base::StringPrintf("stream_%d", stream_number);
|
|
||||||
if (hls_playlist_name.empty())
|
|
||||||
hls_playlist_name = base::StringPrintf("stream_%d.m3u8", stream_number);
|
|
||||||
|
|
||||||
muxer_listeners.emplace_back(new HlsNotifyMuxerListener(
|
|
||||||
hls_playlist_name, name, group_id, hls_notifier));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!muxer_listeners.empty()) {
|
|
||||||
std::unique_ptr<CombinedMuxerListener> combined_muxer_listener(
|
|
||||||
new CombinedMuxerListener(&muxer_listeners));
|
|
||||||
muxer->SetMuxerListener(std::move(combined_muxer_listener));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new trick_play_handler. Note that the stream_decriptors
|
// Create a new trick_play_handler. Note that the stream_decriptors
|
||||||
|
|
Loading…
Reference in New Issue