diff --git a/packager/app/stream_descriptor.cc b/packager/app/stream_descriptor.cc index 715e55d30d7..daca20b7032 100644 --- a/packager/app/stream_descriptor.cc +++ b/packager/app/stream_descriptor.cc @@ -36,6 +36,7 @@ enum FieldType { kDashRolesField, kDashOnlyField, kHlsOnlyField, + kInputFormatField, }; struct FieldNameToTypeMapping { @@ -83,6 +84,7 @@ const FieldNameToTypeMapping kFieldNameTypeMappings[] = { {"role", kDashRolesField}, {"dash_only", kDashOnlyField}, {"hls_only", kHlsOnlyField}, + {"input_format", kInputFormatField}, }; FieldType GetFieldType(const std::string& field_name) { @@ -247,6 +249,10 @@ base::Optional ParseStreamDescriptor( } descriptor.hls_only = hls_only_value > 0; break; + case kInputFormatField: { + descriptor.input_format = iter->second; + break; + } default: LOG(ERROR) << "Unknown field in stream descriptor (\"" << iter->first << "\")."; diff --git a/packager/media/demuxer/demuxer.cc b/packager/media/demuxer/demuxer.cc index 10e69a01555..0d7c659c3f1 100644 --- a/packager/media/demuxer/demuxer.cc +++ b/packager/media/demuxer/demuxer.cc @@ -160,18 +160,22 @@ Status Demuxer::InitializeParser() { "Cannot open file for reading " + file_name_); } - // Read enough bytes before detecting the container. int64_t bytes_read = 0; - while (static_cast(bytes_read) < kInitBufSize) { - int64_t read_result = - media_file_->Read(buffer_.get() + bytes_read, kInitBufSize); - if (read_result < 0) - return Status(error::FILE_FAILURE, "Cannot read file " + file_name_); - if (read_result == 0) - break; - bytes_read += read_result; + if (input_format_.empty()) { + // Read enough bytes before detecting the container. + while (static_cast(bytes_read) < kInitBufSize) { + int64_t read_result = + media_file_->Read(buffer_.get() + bytes_read, kInitBufSize); + if (read_result < 0) + return Status(error::FILE_FAILURE, "Cannot read file " + file_name_); + if (read_result == 0) + break; + bytes_read += read_result; + } + container_name_ = DetermineContainer(buffer_.get(), bytes_read); + } else { + container_name_ = DetermineContainerFromFormatName(input_format_); } - container_name_ = DetermineContainer(buffer_.get(), bytes_read); // Initialize media parser. switch (container_name_) { diff --git a/packager/media/demuxer/demuxer.h b/packager/media/demuxer/demuxer.h index 5a5aaa4c89a..4d089ead7d5 100644 --- a/packager/media/demuxer/demuxer.h +++ b/packager/media/demuxer/demuxer.h @@ -75,6 +75,10 @@ class Demuxer : public OriginHandler { dump_stream_info_ = dump_stream_info; } + void set_input_format(std::string input_format) { + input_format_ = input_format; + } + protected: /// @name MediaHandler implementation overrides. /// @{ @@ -148,6 +152,8 @@ class Demuxer : public OriginHandler { // Whether to dump stream info when it is received. bool dump_stream_info_ = false; Status init_event_status_; + // Explicitly defined input format, for avoiding autodetection. + std::string input_format_; }; } // namespace media diff --git a/packager/media/event/muxer_listener_factory.h b/packager/media/event/muxer_listener_factory.h index fd7e384fdcf..86ac9e08692 100644 --- a/packager/media/event/muxer_listener_factory.h +++ b/packager/media/event/muxer_listener_factory.h @@ -53,6 +53,8 @@ class MuxerListenerFactory { std::vector dash_accessiblities; std::vector dash_roles; bool dash_only = false; + + std::string input_format; }; /// Create a new muxer listener. diff --git a/packager/media/formats/webvtt/webvtt_parser.cc b/packager/media/formats/webvtt/webvtt_parser.cc index 197a05bb722..03e5fd418d9 100644 --- a/packager/media/formats/webvtt/webvtt_parser.cc +++ b/packager/media/formats/webvtt/webvtt_parser.cc @@ -223,14 +223,12 @@ bool WebVttParser::Parse() { // Check the header. It is possible for a 0xFEFF BOM to come before the // header text. if (block.size() != 1) { - LOG(ERROR) << "Failed to read WEBVTT header - " - << "block size should be 1 but was " << block.size() << "."; - return false; + LOG(WARNING) << "Failed to read WEBVTT header - " + << "block size should be 1 but was " << block.size() << "."; } if (block[0] != "WEBVTT" && block[0] != "\xEF\xBB\xBFWEBVTT") { - LOG(ERROR) << "Failed to read WEBVTT header - should be WEBVTT but was " - << block[0]; - return false; + LOG(WARNING) << "Failed to read WEBVTT header - should be WEBVTT but was " + << block[0]; } initialized_ = true; } diff --git a/packager/packager.cc b/packager/packager.cc index 25a3d14f078..ac6bdbb7aa5 100644 --- a/packager/packager.cc +++ b/packager/packager.cc @@ -84,6 +84,8 @@ MuxerListenerFactory::StreamData ToMuxerListenerData( data.dash_accessiblities = stream.dash_accessiblities; data.dash_roles = stream.dash_roles; data.dash_only = stream.dash_only; + + data.input_format = stream.input_format; return data; }; @@ -471,6 +473,7 @@ Status CreateDemuxer(const StreamDescriptor& stream, std::shared_ptr* new_demuxer) { std::shared_ptr demuxer = std::make_shared(stream.input); demuxer->set_dump_stream_info(packaging_params.test_params.dump_stream_info); + demuxer->set_input_format(stream.input_format); if (packaging_params.decryption_params.key_provider != KeyProvider::kNone) { std::unique_ptr decryption_key_source( diff --git a/packager/packager.h b/packager/packager.h index 38494853ef7..35ecb10c032 100644 --- a/packager/packager.h +++ b/packager/packager.h @@ -140,6 +140,11 @@ struct StreamDescriptor { bool dash_only = false; /// Set to true to indicate that the stream is for hls only. bool hls_only = false; + + /// Optional value which specifies input container format. + /// Useful for live streaming situations, like auto-detecting webvtt without + /// its initial header. + std::string input_format; }; class SHAKA_EXPORT Packager {