diff options
Diffstat (limited to 'media')
30 files changed, 278 insertions, 140 deletions
diff --git a/media/base/media_log.cc b/media/base/media_log.cc index cadf291..abd845b 100644 --- a/media/base/media_log.cc +++ b/media/base/media_log.cc @@ -54,6 +54,8 @@ const char* MediaLog::EventTypeToString(MediaLogEvent::Type type) { return "AUDIO_RENDERER_DISABLED"; case MediaLogEvent::BUFFERED_EXTENTS_CHANGED: return "BUFFERED_EXTENTS_CHANGED"; + case MediaLogEvent::MEDIA_SOURCE_ERROR: + return "MEDIA_SOURCE_ERROR"; } NOTREACHED(); return NULL; @@ -98,6 +100,14 @@ const char* MediaLog::PipelineStatusToString(PipelineStatus status) { return NULL; } +LogHelper::LogHelper(const LogCB& log_cb) : log_cb_(log_cb) {} + +LogHelper::~LogHelper() { + if (log_cb_.is_null()) + return; + log_cb_.Run(stream_.str()); +} + MediaLog::MediaLog() : id_(g_media_log_count.GetNext()) {} MediaLog::~MediaLog() {} @@ -178,4 +188,12 @@ scoped_ptr<MediaLogEvent> MediaLog::CreateBufferedExtentsChangedEvent( return event.Pass(); } +scoped_ptr<MediaLogEvent> MediaLog::CreateMediaSourceErrorEvent( + const std::string& error) { + scoped_ptr<MediaLogEvent> event( + CreateEvent(MediaLogEvent::MEDIA_SOURCE_ERROR)); + event->params.SetString("error", error); + return event.Pass(); +} + } //namespace media diff --git a/media/base/media_log.h b/media/base/media_log.h index 3ad2c0b..e776ef6 100644 --- a/media/base/media_log.h +++ b/media/base/media_log.h @@ -5,6 +5,9 @@ #ifndef MEDIA_BASE_MEDIA_LOG_H_ #define MEDIA_BASE_MEDIA_LOG_H_ +#include <sstream> +#include <string> + #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "media/base/media_export.h" @@ -14,6 +17,25 @@ namespace media { +// Indicates a string should be added to the log. +// First parameter - The string to add to the log. +typedef base::Callback<void(const std::string&)> LogCB; + +// Helper class to make it easier to use log_cb like DVLOG(). +class LogHelper { + public: + LogHelper(const LogCB& Log_cb); + ~LogHelper(); + + std::ostream& stream() { return stream_; } + + private: + LogCB log_cb_; + std::stringstream stream_; +}; + +#define MEDIA_LOG(log_cb) LogHelper(log_cb).stream() + class MEDIA_EXPORT MediaLog : public base::RefCountedThreadSafe<MediaLog> { public: // Convert various enums to strings. @@ -43,6 +65,8 @@ class MEDIA_EXPORT MediaLog : public base::RefCountedThreadSafe<MediaLog> { size_t width, size_t height); scoped_ptr<MediaLogEvent> CreateBufferedExtentsChangedEvent( size_t start, size_t current, size_t end); + scoped_ptr<MediaLogEvent> CreateMediaSourceErrorEvent( + const std::string& error); protected: friend class base::RefCountedThreadSafe<MediaLog>; diff --git a/media/base/media_log_event.h b/media/base/media_log_event.h index 4424b68..9b0f6e1 100644 --- a/media/base/media_log_event.h +++ b/media/base/media_log_event.h @@ -68,6 +68,10 @@ struct MediaLogEvent { // "buffer_current": <current offset>. // "buffer_end": <last buffered byte>. BUFFERED_EXTENTS_CHANGED, + + // Errors reported by Media Source Extensions code. + MEDIA_SOURCE_ERROR, + // params: "error": Error string describing the error detected. }; int32 id; diff --git a/media/base/stream_parser.h b/media/base/stream_parser.h index d4eb335..5c5e6e6 100644 --- a/media/base/stream_parser.h +++ b/media/base/stream_parser.h @@ -13,6 +13,7 @@ #include "base/memory/scoped_ptr.h" #include "base/time.h" #include "media/base/media_export.h" +#include "media/base/media_log.h" namespace media { @@ -79,7 +80,8 @@ class MEDIA_EXPORT StreamParser { const NewBuffersCB& video_cb, const NeedKeyCB& need_key_cb, const NewMediaSegmentCB& new_segment_cb, - const base::Closure& end_of_segment_cb) = 0; + const base::Closure& end_of_segment_cb, + const LogCB& log_cb) = 0; // Called when a seek occurs. This flushes the current parser state // and puts the parser in a state where it can receive data for the new seek diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc index c3cbbb7..6af84a3 100644 --- a/media/filters/chunk_demuxer.cc +++ b/media/filters/chunk_demuxer.cc @@ -107,6 +107,7 @@ static const SupportedTypeInfo kSupportedTypeInfo[] = { // and |has_video| are undefined. static bool IsSupported(const std::string& type, std::vector<std::string>& codecs, + const LogCB& log_cb, ParserFactoryFunction* factory_function, bool* has_audio, bool* has_video) { @@ -133,8 +134,11 @@ static bool IsSupported(const std::string& type, } } - if (!found_codec) + if (!found_codec) { + MEDIA_LOG(log_cb) << "Codec '" << codecs[j] + <<"' is not supported for '" << type << "'"; return false; + } switch (codec_type) { case DemuxerStream::AUDIO: @@ -144,8 +148,8 @@ static bool IsSupported(const std::string& type, *has_video = true; break; default: - DVLOG(1) << "Unsupported codec type '"<< codec_type << "' for " - << codecs[j]; + MEDIA_LOG(log_cb) << "Unsupported codec type '"<< codec_type + << "' for " << codecs[j]; return false; } } @@ -167,8 +171,10 @@ class ChunkDemuxerStream : public DemuxerStream { typedef std::deque<ReadCB> ReadCBQueue; typedef std::deque<base::Closure> ClosureQueue; - explicit ChunkDemuxerStream(const AudioDecoderConfig& audio_config); - explicit ChunkDemuxerStream(const VideoDecoderConfig& video_config); + ChunkDemuxerStream(const AudioDecoderConfig& audio_config, + const LogCB& log_cb); + ChunkDemuxerStream(const VideoDecoderConfig& video_config, + const LogCB& log_cb); void StartWaitingForSeek(); void Seek(TimeDelta time); @@ -248,18 +254,20 @@ class ChunkDemuxerStream : public DemuxerStream { DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); }; -ChunkDemuxerStream::ChunkDemuxerStream(const AudioDecoderConfig& audio_config) +ChunkDemuxerStream::ChunkDemuxerStream(const AudioDecoderConfig& audio_config, + const LogCB& log_cb) : type_(AUDIO), state_(RETURNING_DATA_FOR_READS), end_of_stream_(false) { - stream_.reset(new SourceBufferStream(audio_config)); + stream_.reset(new SourceBufferStream(audio_config, log_cb)); } -ChunkDemuxerStream::ChunkDemuxerStream(const VideoDecoderConfig& video_config) +ChunkDemuxerStream::ChunkDemuxerStream(const VideoDecoderConfig& video_config, + const LogCB& log_cb) : type_(VIDEO), state_(RETURNING_DATA_FOR_READS), end_of_stream_(false) { - stream_.reset(new SourceBufferStream(video_config)); + stream_.reset(new SourceBufferStream(video_config, log_cb)); } void ChunkDemuxerStream::StartWaitingForSeek() { @@ -533,11 +541,13 @@ bool ChunkDemuxerStream::GetNextBuffer_Locked( } ChunkDemuxer::ChunkDemuxer(const base::Closure& open_cb, - const NeedKeyCB& need_key_cb) + const NeedKeyCB& need_key_cb, + const LogCB& log_cb) : state_(WAITING_FOR_INIT), host_(NULL), open_cb_(open_cb), - need_key_cb_(need_key_cb) { + need_key_cb_(need_key_cb), + log_cb_(log_cb) { DCHECK(!open_cb_.is_null()); DCHECK(!need_key_cb_.is_null()); } @@ -662,8 +672,11 @@ ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id, bool has_audio = false; bool has_video = false; ParserFactoryFunction factory_function = NULL; - if (!IsSupported(type, codecs, &factory_function, &has_audio, &has_video)) + std::string error; + if (!IsSupported(type, codecs, log_cb_, &factory_function, &has_audio, + &has_video)) { return kNotSupported; + } if ((has_audio && !source_id_audio_.empty()) || (has_video && !source_id_video_.empty())) @@ -696,7 +709,8 @@ ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id, base::Bind(&ChunkDemuxer::OnNeedKey, base::Unretained(this)), base::Bind(&ChunkDemuxer::OnNewMediaSegment, base::Unretained(this), id), base::Bind(&ChunkDemuxer::OnEndOfMediaSegment, - base::Unretained(this), id)); + base::Unretained(this), id), + log_cb_); stream_parser_map_[id] = stream_parser.release(); SourceInfo info = { base::TimeDelta(), true }; @@ -1046,13 +1060,23 @@ bool ChunkDemuxer::OnNewConfigs(bool has_audio, bool has_video, // specified in AddId() or more configs after a stream is initialized. // Only allow a single audio config for now. if (has_audio != audio_config.IsValidConfig()) { - DVLOG(1) << "OnNewConfigs() : Got unexpected audio config."; + MEDIA_LOG(log_cb_) + << "Initialization segment" + << (audio_config.IsValidConfig() ? " has" : " does not have") + << " an audio track, but the mimetype" + << (has_audio ? " specifies" : " does not specify") + << " an audio codec."; return false; } // Only allow a single video config for now. if (has_video != video_config.IsValidConfig()) { - DVLOG(1) << "OnNewConfigs() : Got unexpected video config."; + MEDIA_LOG(log_cb_) + << "Initialization segment" + << (video_config.IsValidConfig() ? " has" : " does not have") + << " a video track, but the mimetype" + << (has_video ? " specifies" : " does not specify") + << " a video codec."; return false; } @@ -1061,7 +1085,7 @@ bool ChunkDemuxer::OnNewConfigs(bool has_audio, bool has_video, if (audio_) { success &= audio_->UpdateAudioConfig(audio_config); } else { - audio_ = new ChunkDemuxerStream(audio_config); + audio_ = new ChunkDemuxerStream(audio_config, log_cb_); } } @@ -1069,7 +1093,7 @@ bool ChunkDemuxer::OnNewConfigs(bool has_audio, bool has_video, if (video_) { success &= video_->UpdateVideoConfig(video_config); } else { - video_ = new ChunkDemuxerStream(video_config); + video_ = new ChunkDemuxerStream(video_config, log_cb_); } } diff --git a/media/filters/chunk_demuxer.h b/media/filters/chunk_demuxer.h index 6855b61..dde71ae 100644 --- a/media/filters/chunk_demuxer.h +++ b/media/filters/chunk_demuxer.h @@ -40,7 +40,10 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer { // is ready to receive media data via AppenData(). // |need_key_cb| Run when the demuxer determines that an encryption key is // needed to decrypt the content. - ChunkDemuxer(const base::Closure& open_cb, const NeedKeyCB& need_key_cb); + // |log_cb| Run when parsing error messages need to be logged to the error + // console. + ChunkDemuxer(const base::Closure& open_cb, const NeedKeyCB& need_key_cb, + const LogCB& log_cb); // Demuxer implementation. virtual void Initialize(DemuxerHost* host, @@ -171,6 +174,7 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer { DemuxerHost* host_; base::Closure open_cb_; NeedKeyCB need_key_cb_; + LogCB log_cb_; PipelineStatusCB init_cb_; PipelineStatusCB seek_cb_; diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc index 3fbfa6b..6506e42 100644 --- a/media/filters/chunk_demuxer_unittest.cc +++ b/media/filters/chunk_demuxer_unittest.cc @@ -164,7 +164,7 @@ class ChunkDemuxerTest : public testing::Test { base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this)); ChunkDemuxer::NeedKeyCB need_key_cb = base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this)); - demuxer_ = new ChunkDemuxer(open_cb, need_key_cb); + demuxer_ = new ChunkDemuxer(open_cb, need_key_cb, LogCB()); } virtual ~ChunkDemuxerTest() { diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc index a9f065b..088d991 100644 --- a/media/filters/pipeline_integration_test.cc +++ b/media/filters/pipeline_integration_test.cc @@ -44,7 +44,8 @@ class MockMediaSource { mimetype_(mimetype) { chunk_demuxer_ = new ChunkDemuxer( base::Bind(&MockMediaSource::DemuxerOpened, base::Unretained(this)), - base::Bind(&MockMediaSource::DemuxerNeedKey, base::Unretained(this))); + base::Bind(&MockMediaSource::DemuxerNeedKey, base::Unretained(this)), + LogCB()); file_data_ = ReadTestDataFile(filename); diff --git a/media/filters/source_buffer_stream.cc b/media/filters/source_buffer_stream.cc index acdcebf..5507acc 100644 --- a/media/filters/source_buffer_stream.cc +++ b/media/filters/source_buffer_stream.cc @@ -286,8 +286,10 @@ static int kDefaultVideoMemoryLimit = 150 * 1024 * 1024; namespace media { -SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config) - : current_config_index_(0), +SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, + const LogCB& log_cb) + : log_cb_(log_cb), + current_config_index_(0), append_config_index_(0), seek_pending_(false), seek_buffer_timestamp_(kNoTimestamp()), @@ -304,8 +306,10 @@ SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config) audio_configs_.back()->CopyFrom(audio_config); } -SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config) - : current_config_index_(0), +SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, + const LogCB& log_cb) + : log_cb_(log_cb), + current_config_index_(0), append_config_index_(0), seek_pending_(false), seek_buffer_timestamp_(kNoTimestamp()), @@ -358,19 +362,20 @@ bool SourceBufferStream::Append( // New media segments must begin with a keyframe. if (new_media_segment_ && !buffers.front()->IsKeyframe()) { - DVLOG(1) << "Media segment did not begin with keyframe."; + MEDIA_LOG(log_cb_) <<"Media segment did not begin with keyframe."; return false; } // Buffers within a media segment should be monotonically increasing. if (!IsMonotonicallyIncreasing(buffers)) { - DVLOG(1) << "Buffers were not monotonically increasing."; + MEDIA_LOG(log_cb_) <<"Buffers were not monotonically increasing."; return false; } if (media_segment_start_time_ < base::TimeDelta() || buffers.front()->GetDecodeTimestamp() < base::TimeDelta()) { - DVLOG(1) << "Cannot append a media segment with negative timestamps."; + MEDIA_LOG(log_cb_) + << "Cannot append a media segment with negative timestamps."; return false; } @@ -1037,22 +1042,22 @@ bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { DCHECK(video_configs_.empty()); if (audio_configs_[0]->codec() != config.codec()) { - DVLOG(1) << "UpdateAudioConfig() : Codec changes not allowed."; + MEDIA_LOG(log_cb_) << "Audio codec changes not allowed."; return false; } if (audio_configs_[0]->samples_per_second() != config.samples_per_second()) { - DVLOG(1) << "UpdateAudioConfig() : Sample rate changes not allowed."; + MEDIA_LOG(log_cb_) << "Audio sample rate changes not allowed."; return false; } if (audio_configs_[0]->channel_layout() != config.channel_layout()) { - DVLOG(1) << "UpdateAudioConfig() : Channel layout changes not allowed."; + MEDIA_LOG(log_cb_) << "Audio channel layout changes not allowed."; return false; } if (audio_configs_[0]->bits_per_channel() != config.bits_per_channel()) { - DVLOG(1) << "UpdateAudioConfig() : Bits per channel changes not allowed."; + MEDIA_LOG(log_cb_) << "Audio bits per channel changes not allowed."; return false; } @@ -1077,12 +1082,12 @@ bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { DCHECK(audio_configs_.empty()); if (video_configs_[0]->is_encrypted() != config.is_encrypted()) { - DVLOG(1) << "UpdateVideoConfig() : Encryption changes not allowed."; + MEDIA_LOG(log_cb_) <<"Video Encryption changes not allowed."; return false; } if (video_configs_[0]->codec() != config.codec()) { - DVLOG(1) << "UpdateVideoConfig() : Codec changes not allowed."; + MEDIA_LOG(log_cb_) <<"Video codec changes not allowed."; return false; } diff --git a/media/filters/source_buffer_stream.h b/media/filters/source_buffer_stream.h index a3757cb..32de333 100644 --- a/media/filters/source_buffer_stream.h +++ b/media/filters/source_buffer_stream.h @@ -18,6 +18,7 @@ #include "base/memory/ref_counted.h" #include "media/base/audio_decoder_config.h" #include "media/base/media_export.h" +#include "media/base/media_log.h" #include "media/base/ranges.h" #include "media/base/stream_parser_buffer.h" #include "media/base/video_decoder_config.h" @@ -42,8 +43,10 @@ class MEDIA_EXPORT SourceBufferStream { kConfigChange, }; - explicit SourceBufferStream(const AudioDecoderConfig& audio_config); - explicit SourceBufferStream(const VideoDecoderConfig& video_config); + SourceBufferStream(const AudioDecoderConfig& audio_config, + const LogCB& log_cb); + SourceBufferStream(const VideoDecoderConfig& video_config, + const LogCB& log_cb); ~SourceBufferStream(); @@ -237,6 +240,10 @@ class MEDIA_EXPORT SourceBufferStream { // kSuccess. void CompleteConfigChange(); + // Callback used to report error strings that can help the web developer + // figure out what is wrong with the content. + LogCB log_cb_; + // List of disjoint buffered ranges, ordered by start time. RangeList ranges_; diff --git a/media/filters/source_buffer_stream_unittest.cc b/media/filters/source_buffer_stream_unittest.cc index dd272d6..722d6d6 100644 --- a/media/filters/source_buffer_stream_unittest.cc +++ b/media/filters/source_buffer_stream_unittest.cc @@ -11,6 +11,7 @@ #include "base/string_split.h" #include "base/string_util.h" #include "media/base/data_buffer.h" +#include "media/base/media_log.h" #include "testing/gtest/include/gtest/gtest.h" namespace media { @@ -28,7 +29,7 @@ class SourceBufferStreamTest : public testing::Test { config_.Initialize(kCodecVP8, VIDEO_CODEC_PROFILE_UNKNOWN, VideoFrame::YV12, kCodedSize, gfx::Rect(kCodedSize), kCodedSize, NULL, 0, false, false); - stream_.reset(new SourceBufferStream(config_)); + stream_.reset(new SourceBufferStream(config_, LogCB())); SetStreamInfo(kDefaultFramesPerSecond, kDefaultKeyframesPerSecond); } diff --git a/media/mp4/box_reader.cc b/media/mp4/box_reader.cc index 1285ebf..71d93a0 100644 --- a/media/mp4/box_reader.cc +++ b/media/mp4/box_reader.cc @@ -79,8 +79,10 @@ bool BufferReader::Read4sInto8s(int64* v) { } -BoxReader::BoxReader(const uint8* buf, const int size) +BoxReader::BoxReader(const uint8* buf, const int size, + const LogCB& log_cb) : BufferReader(buf, size), + log_cb_(log_cb), type_(FOURCC_NULL), version_(0), flags_(0), @@ -99,12 +101,13 @@ BoxReader::~BoxReader() { // static BoxReader* BoxReader::ReadTopLevelBox(const uint8* buf, const int buf_size, + const LogCB& log_cb, bool* err) { - scoped_ptr<BoxReader> reader(new BoxReader(buf, buf_size)); + scoped_ptr<BoxReader> reader(new BoxReader(buf, buf_size, log_cb)); if (!reader->ReadHeader(err)) return NULL; - if (!IsValidTopLevelBox(reader->type())) { + if (!IsValidTopLevelBox(reader->type(), log_cb)) { *err = true; return NULL; } @@ -118,12 +121,13 @@ BoxReader* BoxReader::ReadTopLevelBox(const uint8* buf, // static bool BoxReader::StartTopLevelBox(const uint8* buf, const int buf_size, + const LogCB& log_cb, FourCC* type, int* box_size, bool* err) { - BoxReader reader(buf, buf_size); + BoxReader reader(buf, buf_size, log_cb); if (!reader.ReadHeader(err)) return false; - if (!IsValidTopLevelBox(reader.type())) { + if (!IsValidTopLevelBox(reader.type(), log_cb)) { *err = true; return false; } @@ -133,7 +137,8 @@ bool BoxReader::StartTopLevelBox(const uint8* buf, } // static -bool BoxReader::IsValidTopLevelBox(const FourCC& type) { +bool BoxReader::IsValidTopLevelBox(const FourCC& type, + const LogCB& log_cb) { switch (type) { case FOURCC_FTYP: case FOURCC_PDIN: @@ -152,8 +157,8 @@ bool BoxReader::IsValidTopLevelBox(const FourCC& type) { return true; default: // Hex is used to show nonprintable characters and aid in debugging - LOG(WARNING) << "Unrecognized top-level box type 0x" - << std::hex << type; + MEDIA_LOG(log_cb) << "Unrecognized top-level box type 0x" + << std::hex << type; return false; } } @@ -164,7 +169,7 @@ bool BoxReader::ScanChildren() { bool err = false; while (pos() < size()) { - BoxReader child(&buf_[pos_], size_ - pos_); + BoxReader child(&buf_[pos_], size_ - pos_, log_cb_); if (!child.ReadHeader(&err)) break; children_.insert(std::pair<FourCC, BoxReader>(child.type(), child)); diff --git a/media/mp4/box_reader.h b/media/mp4/box_reader.h index bcc3200..43f11d56 100644 --- a/media/mp4/box_reader.h +++ b/media/mp4/box_reader.h @@ -11,6 +11,7 @@ #include "base/compiler_specific.h" #include "base/logging.h" #include "media/base/media_export.h" +#include "media/base/media_log.h" #include "media/mp4/fourccs.h" #include "media/mp4/rcheck.h" @@ -78,6 +79,7 @@ class MEDIA_EXPORT BoxReader : public BufferReader { // |buf| is retained but not owned, and must outlive the BoxReader instance. static BoxReader* ReadTopLevelBox(const uint8* buf, const int buf_size, + const LogCB& log_cb, bool* err); // Read the box header from the current buffer. This function returns true if @@ -88,6 +90,7 @@ class MEDIA_EXPORT BoxReader : public BufferReader { // |buf| is not retained. static bool StartTopLevelBox(const uint8* buf, const int buf_size, + const LogCB& log_cb, FourCC* type, int* box_size, bool* err) WARN_UNUSED_RESULT; @@ -95,7 +98,8 @@ class MEDIA_EXPORT BoxReader : public BufferReader { // Returns true if |type| is recognized to be a top-level box, false // otherwise. This returns true for some boxes which we do not parse. // Helpful in debugging misaligned appends. - static bool IsValidTopLevelBox(const FourCC& type); + static bool IsValidTopLevelBox(const FourCC& type, + const LogCB& log_cb); // Scan through all boxes within the current box, starting at the current // buffer position. Must be called before any of the *Child functions work. @@ -133,7 +137,7 @@ class MEDIA_EXPORT BoxReader : public BufferReader { uint32 flags() const { return flags_; } private: - BoxReader(const uint8* buf, const int size); + BoxReader(const uint8* buf, const int size, const LogCB& log_cb); // Must be called immediately after init. If the return is false, this // indicates that the box header and its contents were not available in the @@ -144,6 +148,7 @@ class MEDIA_EXPORT BoxReader : public BufferReader { // true, the error is unrecoverable and the stream should be aborted. bool ReadHeader(bool* err); + LogCB log_cb_; FourCC type_; uint8 version_; uint32 flags_; @@ -192,7 +197,7 @@ bool BoxReader::ReadAllChildren(std::vector<T>* children) { bool err = false; while (pos() < size()) { - BoxReader child_reader(&buf_[pos_], size_ - pos_); + BoxReader child_reader(&buf_[pos_], size_ - pos_, log_cb_); if (!child_reader.ReadHeader(&err)) break; T child; RCHECK(child.Parse(&child_reader)); diff --git a/media/mp4/box_reader_unittest.cc b/media/mp4/box_reader_unittest.cc index 38fd896..419b5af 100644 --- a/media/mp4/box_reader_unittest.cc +++ b/media/mp4/box_reader_unittest.cc @@ -86,7 +86,7 @@ TEST_F(BoxReaderTest, ExpectedOperationTest) { std::vector<uint8> buf = GetBuf(); bool err; scoped_ptr<BoxReader> reader( - BoxReader::ReadTopLevelBox(&buf[0], buf.size(), &err)); + BoxReader::ReadTopLevelBox(&buf[0], buf.size(), LogCB(), &err)); EXPECT_FALSE(err); EXPECT_TRUE(reader.get()); @@ -114,7 +114,7 @@ TEST_F(BoxReaderTest, OuterTooShortTest) { // Create a soft failure by truncating the outer box. scoped_ptr<BoxReader> r( - BoxReader::ReadTopLevelBox(&buf[0], buf.size() - 2, &err)); + BoxReader::ReadTopLevelBox(&buf[0], buf.size() - 2, LogCB(), &err)); EXPECT_FALSE(err); EXPECT_FALSE(r.get()); @@ -127,7 +127,7 @@ TEST_F(BoxReaderTest, InnerTooLongTest) { // Make an inner box too big for its outer box. buf[25] = 1; scoped_ptr<BoxReader> reader( - BoxReader::ReadTopLevelBox(&buf[0], buf.size(), &err)); + BoxReader::ReadTopLevelBox(&buf[0], buf.size(), LogCB(), &err)); SkipBox box; EXPECT_FALSE(box.Parse(reader.get())); @@ -140,7 +140,7 @@ TEST_F(BoxReaderTest, WrongFourCCTest) { // Set an unrecognized top-level FourCC. buf[5] = 1; scoped_ptr<BoxReader> reader( - BoxReader::ReadTopLevelBox(&buf[0], buf.size(), &err)); + BoxReader::ReadTopLevelBox(&buf[0], buf.size(), LogCB(), &err)); EXPECT_FALSE(reader.get()); EXPECT_TRUE(err); } @@ -149,7 +149,7 @@ TEST_F(BoxReaderTest, ScanChildrenTest) { std::vector<uint8> buf = GetBuf(); bool err; scoped_ptr<BoxReader> reader( - BoxReader::ReadTopLevelBox(&buf[0], buf.size(), &err)); + BoxReader::ReadTopLevelBox(&buf[0], buf.size(), LogCB(), &err)); EXPECT_TRUE(reader->SkipBytes(16) && reader->ScanChildren()); @@ -173,7 +173,7 @@ TEST_F(BoxReaderTest, ReadAllChildrenTest) { buf[3] = 0x38; bool err; scoped_ptr<BoxReader> reader( - BoxReader::ReadTopLevelBox(&buf[0], buf.size(), &err)); + BoxReader::ReadTopLevelBox(&buf[0], buf.size(), LogCB(), &err)); std::vector<PsshBox> kids; EXPECT_TRUE(reader->SkipBytes(16) && reader->ReadAllChildren(&kids)); diff --git a/media/mp4/mp4_stream_parser.cc b/media/mp4/mp4_stream_parser.cc index 3546be9..69a35f2 100644 --- a/media/mp4/mp4_stream_parser.cc +++ b/media/mp4/mp4_stream_parser.cc @@ -42,7 +42,8 @@ void MP4StreamParser::Init(const InitCB& init_cb, const NewBuffersCB& video_cb, const NeedKeyCB& need_key_cb, const NewMediaSegmentCB& new_segment_cb, - const base::Closure& end_of_segment_cb) { + const base::Closure& end_of_segment_cb, + const LogCB& log_cb) { DCHECK_EQ(state_, kWaitingForInit); DCHECK(init_cb_.is_null()); DCHECK(!init_cb.is_null()); @@ -59,6 +60,7 @@ void MP4StreamParser::Init(const InitCB& init_cb, need_key_cb_ = need_key_cb; new_segment_cb_ = new_segment_cb; end_of_segment_cb_ = end_of_segment_cb; + log_cb_ = log_cb; } void MP4StreamParser::Reset() { @@ -120,7 +122,8 @@ bool MP4StreamParser::ParseBox(bool* err) { queue_.Peek(&buf, &size); if (!size) return false; - scoped_ptr<BoxReader> reader(BoxReader::ReadTopLevelBox(buf, size, err)); + scoped_ptr<BoxReader> reader( + BoxReader::ReadTopLevelBox(buf, size, log_cb_, err)); if (reader.get() == NULL) return false; if (reader->type() == FOURCC_MOOV) { @@ -138,8 +141,8 @@ bool MP4StreamParser::ParseBox(bool* err) { // before the head of the 'moof', so keeping this box around is sufficient.) return !(*err); } else { - DVLOG(2) << "Skipping unrecognized top-level box: " - << FourCCToString(reader->type()); + MEDIA_LOG(log_cb_) << "Skipping unrecognized top-level box: " + << FourCCToString(reader->type()); } queue_.Pop(reader->size()); @@ -150,7 +153,7 @@ bool MP4StreamParser::ParseBox(bool* err) { bool MP4StreamParser::ParseMoov(BoxReader* reader) { moov_.reset(new Movie); RCHECK(moov_->Parse(reader)); - runs_.reset(new TrackRunIterator(moov_.get())); + runs_.reset(new TrackRunIterator(moov_.get(), log_cb_)); has_audio_ = false; has_video_ = false; @@ -412,7 +415,7 @@ bool MP4StreamParser::EnqueueSample(BufferQueue* audio_buffers, if (video) { if (!PrepareAVCBuffer(runs_->video_description().avcc, &frame_buf, &subsamples)) { - DLOG(ERROR) << "Failed to prepare AVC sample for decode"; + MEDIA_LOG(log_cb_) << "Failed to prepare AVC sample for decode"; *err = true; return false; } @@ -421,7 +424,7 @@ bool MP4StreamParser::EnqueueSample(BufferQueue* audio_buffers, if (audio) { if (!PrepareAACBuffer(runs_->audio_description().esds.aac, &frame_buf, &subsamples)) { - DLOG(ERROR) << "Failed to prepare AAC sample for decode"; + MEDIA_LOG(log_cb_) << "Failed to prepare AAC sample for decode"; *err = true; return false; } @@ -486,12 +489,13 @@ bool MP4StreamParser::ReadAndDiscardMDATsUntil(const int64 offset) { FourCC type; int box_sz; - if (!BoxReader::StartTopLevelBox(buf, size, &type, &box_sz, &err)) + if (!BoxReader::StartTopLevelBox(buf, size, log_cb_, + &type, &box_sz, &err)) break; if (type != FOURCC_MDAT) { - DLOG(WARNING) << "Unexpected box type while parsing MDATs: " - << FourCCToString(type); + MEDIA_LOG(log_cb_) << "Unexpected box type while parsing MDATs: " + << FourCCToString(type); } mdat_tail_ += box_sz; } diff --git a/media/mp4/mp4_stream_parser.h b/media/mp4/mp4_stream_parser.h index 41b8272..292f628 100644 --- a/media/mp4/mp4_stream_parser.h +++ b/media/mp4/mp4_stream_parser.h @@ -32,7 +32,8 @@ class MEDIA_EXPORT MP4StreamParser : public StreamParser { const NewBuffersCB& video_cb, const NeedKeyCB& need_key_cb, const NewMediaSegmentCB& new_segment_cb, - const base::Closure& end_of_segment_cb) OVERRIDE; + const base::Closure& end_of_segment_cb, + const LogCB& log_cb) OVERRIDE; virtual void Flush() OVERRIDE; virtual bool Parse(const uint8* buf, int size) OVERRIDE; @@ -85,6 +86,7 @@ class MEDIA_EXPORT MP4StreamParser : public StreamParser { NeedKeyCB need_key_cb_; NewMediaSegmentCB new_segment_cb_; base::Closure end_of_segment_cb_; + LogCB log_cb_; OffsetByteQueue queue_; diff --git a/media/mp4/mp4_stream_parser_unittest.cc b/media/mp4/mp4_stream_parser_unittest.cc index 81dbdd8..66f3410 100644 --- a/media/mp4/mp4_stream_parser_unittest.cc +++ b/media/mp4/mp4_stream_parser_unittest.cc @@ -106,7 +106,8 @@ class MP4StreamParserTest : public testing::Test { base::Bind(&MP4StreamParserTest::KeyNeededF, base::Unretained(this)), base::Bind(&MP4StreamParserTest::NewSegmentF, base::Unretained(this)), base::Bind(&MP4StreamParserTest::EndOfSegmentF, - base::Unretained(this))); + base::Unretained(this)), + LogCB()); } bool ParseMP4File(const std::string& filename, int append_bytes) { diff --git a/media/mp4/track_run_iterator.cc b/media/mp4/track_run_iterator.cc index 36ec206..5538562 100644 --- a/media/mp4/track_run_iterator.cc +++ b/media/mp4/track_run_iterator.cc @@ -62,10 +62,12 @@ TimeDelta TimeDeltaFromRational(int64 numer, int64 denom) { base::Time::kMicrosecondsPerSecond * numer / denom); } -TrackRunIterator::TrackRunIterator(const Movie* moov) - : moov_(moov), sample_offset_(0) { +TrackRunIterator::TrackRunIterator(const Movie* moov, + const LogCB& log_cb) + : moov_(moov), log_cb_(log_cb), sample_offset_(0) { CHECK(moov); } + TrackRunIterator::~TrackRunIterator() {} static void PopulateSampleInfo(const TrackExtends& trex, @@ -430,7 +432,7 @@ scoped_ptr<DecryptConfig> TrackRunIterator::GetDecryptConfig() { if (!cenc_info.subsamples.empty() && (cenc_info.GetTotalSizeOfSubsamples() != static_cast<size_t>(sample_size()))) { - DVLOG(1) << "Incorrect CENC subsample size."; + MEDIA_LOG(log_cb_) << "Incorrect CENC subsample size."; return scoped_ptr<DecryptConfig>(); } diff --git a/media/mp4/track_run_iterator.h b/media/mp4/track_run_iterator.h index 85cadce..1e083ca 100644 --- a/media/mp4/track_run_iterator.h +++ b/media/mp4/track_run_iterator.h @@ -10,6 +10,7 @@ #include "base/memory/scoped_ptr.h" #include "base/time.h" #include "media/base/media_export.h" +#include "media/base/media_log.h" #include "media/mp4/box_definitions.h" #include "media/mp4/cenc.h" @@ -29,7 +30,7 @@ class MEDIA_EXPORT TrackRunIterator { public: // Create a new TrackRunIterator. A reference to |moov| will be retained for // the lifetime of this object. - explicit TrackRunIterator(const Movie* moov); + TrackRunIterator(const Movie* moov, const LogCB& log_cb); ~TrackRunIterator(); void Reset(); @@ -92,6 +93,7 @@ class MEDIA_EXPORT TrackRunIterator { const TrackEncryption& track_encryption() const; const Movie* moov_; + LogCB log_cb_; std::vector<TrackRunInfo> runs_; std::vector<TrackRunInfo>::const_iterator run_itr_; diff --git a/media/mp4/track_run_iterator_unittest.cc b/media/mp4/track_run_iterator_unittest.cc index 40385cc..c0cbbe6 100644 --- a/media/mp4/track_run_iterator_unittest.cc +++ b/media/mp4/track_run_iterator_unittest.cc @@ -48,6 +48,7 @@ class TrackRunIteratorTest : public testing::Test { protected: Movie moov_; + LogCB log_cb_; scoped_ptr<TrackRunIterator> iter_; void CreateMovie() { @@ -153,14 +154,14 @@ class TrackRunIteratorTest : public testing::Test { }; TEST_F(TrackRunIteratorTest, NoRunsTest) { - iter_.reset(new TrackRunIterator(&moov_)); + iter_.reset(new TrackRunIterator(&moov_, log_cb_)); ASSERT_TRUE(iter_->Init(MovieFragment())); EXPECT_FALSE(iter_->IsRunValid()); EXPECT_FALSE(iter_->IsSampleValid()); } TEST_F(TrackRunIteratorTest, BasicOperationTest) { - iter_.reset(new TrackRunIterator(&moov_)); + iter_.reset(new TrackRunIterator(&moov_, log_cb_)); MovieFragment moof = CreateFragment(); // Test that runs are sorted correctly, and that properties of the initial @@ -218,7 +219,7 @@ TEST_F(TrackRunIteratorTest, TrackExtendsDefaultsTest) { moov_.extends.tracks[0].default_sample_size = 3; moov_.extends.tracks[0].default_sample_flags = kSampleIsDifferenceSampleFlagMask; - iter_.reset(new TrackRunIterator(&moov_)); + iter_.reset(new TrackRunIterator(&moov_, log_cb_)); MovieFragment moof = CreateFragment(); moof.tracks[0].header.has_default_sample_flags = false; moof.tracks[0].header.default_sample_size = 0; @@ -237,7 +238,7 @@ TEST_F(TrackRunIteratorTest, FirstSampleFlagTest) { // Ensure that keyframes are flagged correctly in the face of BMFF boxes which // explicitly specify the flags for the first sample in a run and rely on // defaults for all subsequent samples - iter_.reset(new TrackRunIterator(&moov_)); + iter_.reset(new TrackRunIterator(&moov_, log_cb_)); MovieFragment moof = CreateFragment(); moof.tracks[1].header.has_default_sample_flags = true; moof.tracks[1].header.default_sample_flags = @@ -251,7 +252,7 @@ TEST_F(TrackRunIteratorTest, FirstSampleFlagTest) { } TEST_F(TrackRunIteratorTest, MinDecodeTest) { - iter_.reset(new TrackRunIterator(&moov_)); + iter_.reset(new TrackRunIterator(&moov_, log_cb_)); MovieFragment moof = CreateFragment(); moof.tracks[0].decode_time.decode_time = kAudioScale; ASSERT_TRUE(iter_->Init(moof)); @@ -276,7 +277,7 @@ TEST_F(TrackRunIteratorTest, ReorderingTest) { // (that is, 2 / kVideoTimescale) and a duration of zero (which is treated as // infinite according to 14496-12:2012). This will cause the first 80ms of the // media timeline - which will be empty, due to CTS biasing - to be discarded. - iter_.reset(new TrackRunIterator(&moov_)); + iter_.reset(new TrackRunIterator(&moov_, log_cb_)); EditListEntry entry; entry.segment_duration = 0; entry.media_time = 2; @@ -313,7 +314,7 @@ TEST_F(TrackRunIteratorTest, ReorderingTest) { } TEST_F(TrackRunIteratorTest, IgnoreUnknownAuxInfoTest) { - iter_.reset(new TrackRunIterator(&moov_)); + iter_.reset(new TrackRunIterator(&moov_, log_cb_)); MovieFragment moof = CreateFragment(); moof.tracks[1].auxiliary_offset.offsets.push_back(50); moof.tracks[1].auxiliary_size.default_sample_info_size = 2; @@ -326,7 +327,7 @@ TEST_F(TrackRunIteratorTest, IgnoreUnknownAuxInfoTest) { TEST_F(TrackRunIteratorTest, DecryptConfigTest) { AddEncryption(&moov_.tracks[1]); - iter_.reset(new TrackRunIterator(&moov_)); + iter_.reset(new TrackRunIterator(&moov_, log_cb_)); MovieFragment moof = CreateFragment(); AddAuxInfoHeaders(50, &moof.tracks[1]); @@ -366,7 +367,7 @@ TEST_F(TrackRunIteratorTest, DecryptConfigTest) { TEST_F(TrackRunIteratorTest, SharedAuxInfoTest) { AddEncryption(&moov_.tracks[0]); AddEncryption(&moov_.tracks[1]); - iter_.reset(new TrackRunIterator(&moov_)); + iter_.reset(new TrackRunIterator(&moov_, log_cb_)); MovieFragment moof = CreateFragment(); moof.tracks[0].runs.resize(1); @@ -408,7 +409,7 @@ TEST_F(TrackRunIteratorTest, SharedAuxInfoTest) { TEST_F(TrackRunIteratorTest, UnexpectedOrderingTest) { AddEncryption(&moov_.tracks[0]); AddEncryption(&moov_.tracks[1]); - iter_.reset(new TrackRunIterator(&moov_)); + iter_.reset(new TrackRunIterator(&moov_, log_cb_)); MovieFragment moof = CreateFragment(); AddAuxInfoHeaders(20000, &moof.tracks[0]); diff --git a/media/webm/webm_cluster_parser.cc b/media/webm/webm_cluster_parser.cc index 477f668..4027f11 100644 --- a/media/webm/webm_cluster_parser.cc +++ b/media/webm/webm_cluster_parser.cc @@ -23,11 +23,11 @@ static std::string GenerateCounterBlock(const uint8* iv, int iv_size) { return counter_block; } -WebMClusterParser::WebMClusterParser(int64 timecode_scale, - int audio_track_num, - int video_track_num, - const std::string& audio_encryption_key_id, - const std::string& video_encryption_key_id) +WebMClusterParser::WebMClusterParser( + int64 timecode_scale, int audio_track_num, int video_track_num, + const std::string& audio_encryption_key_id, + const std::string& video_encryption_key_id, + const LogCB& log_cb) : timecode_multiplier_(timecode_scale / 1000.0), audio_encryption_key_id_(audio_encryption_key_id), video_encryption_key_id_(video_encryption_key_id), @@ -39,7 +39,8 @@ WebMClusterParser::WebMClusterParser(int64 timecode_scale, cluster_start_time_(kNoTimestamp()), cluster_ended_(false), audio_(audio_track_num), - video_(video_track_num) { + video_(video_track_num), + log_cb_(log_cb) { } WebMClusterParser::~WebMClusterParser() {} @@ -106,7 +107,7 @@ bool WebMClusterParser::OnListEnd(int id) { // Make sure the BlockGroup actually had a Block. if (block_data_size_ == -1) { - DVLOG(1) << "Block missing from BlockGroup."; + MEDIA_LOG(log_cb_) << "Block missing from BlockGroup."; return false; } @@ -140,7 +141,7 @@ bool WebMClusterParser::ParseBlock(const uint8* buf, int size, int duration) { // Return an error if the trackNum > 127. We just aren't // going to support large track numbers right now. if (!(buf[0] & 0x80)) { - DVLOG(1) << "TrackNumber over 127 not supported"; + MEDIA_LOG(log_cb_) << "TrackNumber over 127 not supported"; return false; } @@ -150,7 +151,7 @@ bool WebMClusterParser::ParseBlock(const uint8* buf, int size, int duration) { int lacing = (flags >> 1) & 0x3; if (lacing) { - DVLOG(1) << "Lacing " << lacing << " not supported yet."; + MEDIA_LOG(log_cb_) << "Lacing " << lacing << " is not supported yet."; return false; } @@ -171,7 +172,7 @@ bool WebMClusterParser::OnBinary(int id, const uint8* data, int size) { return true; if (block_data_.get()) { - DVLOG(1) << "More than 1 Block in a BlockGroup is not supported."; + MEDIA_LOG(log_cb_) << "More than 1 Block in a BlockGroup is not supported."; return false; } @@ -187,17 +188,19 @@ bool WebMClusterParser::OnBlock(int track_num, int timecode, const uint8* data, int size) { DCHECK_GE(size, 0); if (cluster_timecode_ == -1) { - DVLOG(1) << "Got a block before cluster timecode."; + MEDIA_LOG(log_cb_) << "Got a block before cluster timecode."; return false; } if (timecode < 0) { - DVLOG(1) << "Got a block with negative timecode offset " << timecode; + MEDIA_LOG(log_cb_) << "Got a block with negative timecode offset " + << timecode; return false; } if (last_block_timecode_ != -1 && timecode < last_block_timecode_) { - DVLOG(1) << "Got a block with a timecode before the previous block."; + MEDIA_LOG(log_cb_) + << "Got a block with a timecode before the previous block."; return false; } @@ -210,7 +213,7 @@ bool WebMClusterParser::OnBlock(int track_num, int timecode, track = &video_; encryption_key_id = video_encryption_key_id_; } else { - DVLOG(1) << "Unexpected track number " << track_num; + MEDIA_LOG(log_cb_) << "Unexpected track number " << track_num; return false; } @@ -231,7 +234,8 @@ bool WebMClusterParser::OnBlock(int track_num, int timecode, if (!encryption_key_id.empty()) { DCHECK_EQ(kWebMSignalByteSize, 1); if (size < kWebMSignalByteSize) { - DVLOG(1) << "Got a block from an encrypted stream with no data."; + MEDIA_LOG(log_cb_) + << "Got a block from an encrypted stream with no data."; return false; } uint8 signal_byte = data[0]; @@ -244,7 +248,8 @@ bool WebMClusterParser::OnBlock(int track_num, int timecode, if (signal_byte & kWebMFlagEncryptedFrame) { if (size < kWebMSignalByteSize + kWebMIvSize) { - DVLOG(1) << "Got an encrypted block with not enough data " << size; + MEDIA_LOG(log_cb_) << "Got an encrypted block with not enough data " + << size; return false; } counter_block = GenerateCounterBlock(data + data_offset, kWebMIvSize); diff --git a/media/webm/webm_cluster_parser.h b/media/webm/webm_cluster_parser.h index 6748a28..f31a0cb 100644 --- a/media/webm/webm_cluster_parser.h +++ b/media/webm/webm_cluster_parser.h @@ -10,6 +10,7 @@ #include "base/memory/scoped_ptr.h" #include "media/base/media_export.h" +#include "media/base/media_log.h" #include "media/base/stream_parser_buffer.h" #include "media/webm/webm_parser.h" @@ -23,7 +24,8 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { int audio_track_num, int video_track_num, const std::string& audio_encryption_key_id, - const std::string& video_encryption_key_id); + const std::string& video_encryption_key_id, + const LogCB& log_cb); virtual ~WebMClusterParser(); // Resets the parser state so it can accept a new cluster. @@ -92,6 +94,8 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { Track audio_; Track video_; + LogCB log_cb_; + DISALLOW_IMPLICIT_CONSTRUCTORS(WebMClusterParser); }; diff --git a/media/webm/webm_cluster_parser_unittest.cc b/media/webm/webm_cluster_parser_unittest.cc index d12979f..f89e68f 100644 --- a/media/webm/webm_cluster_parser_unittest.cc +++ b/media/webm/webm_cluster_parser_unittest.cc @@ -4,6 +4,7 @@ #include <algorithm> +#include "base/bind.h" #include "base/logging.h" #include "media/webm/cluster_builder.h" #include "media/webm/webm_cluster_parser.h" @@ -124,9 +125,8 @@ static void AppendToEnd(const WebMClusterParser::BufferQueue& src, class WebMClusterParserTest : public testing::Test { public: WebMClusterParserTest() - : parser_(new WebMClusterParser(kTimecodeScale, - kAudioTrackNum, kVideoTrackNum, - "", "")) { + : parser_(new WebMClusterParser( + kTimecodeScale, kAudioTrackNum, kVideoTrackNum, "", "", LogCB())) { } protected: diff --git a/media/webm/webm_content_encodings_client.cc b/media/webm/webm_content_encodings_client.cc index 2541e0b..bcf964e 100644 --- a/media/webm/webm_content_encodings_client.cc +++ b/media/webm/webm_content_encodings_client.cc @@ -10,8 +10,9 @@ namespace media { -WebMContentEncodingsClient::WebMContentEncodingsClient() - : content_encryption_encountered_(false), +WebMContentEncodingsClient::WebMContentEncodingsClient(const LogCB& log_cb) + : log_cb_(log_cb), + content_encryption_encountered_(false), content_encodings_ready_(false) { } @@ -43,7 +44,7 @@ WebMParserClient* WebMContentEncodingsClient::OnListStart(int id) { if (id == kWebMIdContentEncryption) { DCHECK(cur_content_encoding_.get()); if (content_encryption_encountered_) { - DVLOG(1) << "Unexpected multiple ContentEncryption."; + MEDIA_LOG(log_cb_) << "Unexpected multiple ContentEncryption."; return NULL; } content_encryption_encountered_ = true; @@ -66,7 +67,7 @@ bool WebMContentEncodingsClient::OnListEnd(int id) { if (id == kWebMIdContentEncodings) { // ContentEncoding element is mandatory. Check this! if (content_encodings_.empty()) { - DVLOG(1) << "Missing ContentEncoding."; + MEDIA_LOG(log_cb_) << "Missing ContentEncoding."; return false; } content_encodings_ready_ = true; @@ -84,7 +85,7 @@ bool WebMContentEncodingsClient::OnListEnd(int id) { // Default value of encoding order is 0, which should only be used on the // first ContentEncoding. if (!content_encodings_.empty()) { - DVLOG(1) << "Missing ContentEncodingOrder."; + MEDIA_LOG(log_cb_) << "Missing ContentEncodingOrder."; return false; } cur_content_encoding_->set_order(0); @@ -98,15 +99,15 @@ bool WebMContentEncodingsClient::OnListEnd(int id) { // Check for elements valid in spec but not supported for now. if (cur_content_encoding_->type() == ContentEncoding::kTypeCompression) { - DVLOG(1) << "ContentCompression not supported."; + MEDIA_LOG(log_cb_) << "ContentCompression not supported."; return false; } // Enforce mandatory elements without default values. DCHECK(cur_content_encoding_->type() == ContentEncoding::kTypeEncryption); if (!content_encryption_encountered_) { - DVLOG(1) << "ContentEncodingType is encryption but ContentEncryption " - "is missing."; + MEDIA_LOG(log_cb_) << "ContentEncodingType is encryption but" + << " ContentEncryption is missing."; return false; } @@ -145,13 +146,13 @@ bool WebMContentEncodingsClient::OnUInt(int id, int64 val) { if (id == kWebMIdContentEncodingOrder) { if (cur_content_encoding_->order() != ContentEncoding::kOrderInvalid) { - DVLOG(1) << "Unexpected multiple ContentEncodingOrder."; + MEDIA_LOG(log_cb_) << "Unexpected multiple ContentEncodingOrder."; return false; } if (val != static_cast<int64>(content_encodings_.size())) { // According to the spec, encoding order starts with 0 and counts upwards. - DVLOG(1) << "Unexpected ContentEncodingOrder."; + MEDIA_LOG(log_cb_) << "Unexpected ContentEncodingOrder."; return false; } @@ -161,18 +162,18 @@ bool WebMContentEncodingsClient::OnUInt(int id, int64 val) { if (id == kWebMIdContentEncodingScope) { if (cur_content_encoding_->scope() != ContentEncoding::kScopeInvalid) { - DVLOG(1) << "Unexpected multiple ContentEncodingScope."; + MEDIA_LOG(log_cb_) << "Unexpected multiple ContentEncodingScope."; return false; } if (val == ContentEncoding::kScopeInvalid || val > ContentEncoding::kScopeMax) { - DVLOG(1) << "Unexpected ContentEncodingScope."; + MEDIA_LOG(log_cb_) << "Unexpected ContentEncodingScope."; return false; } if (val & ContentEncoding::kScopeNextContentEncodingData) { - DVLOG(1) << "Encoded next ContentEncoding is not supported."; + MEDIA_LOG(log_cb_) << "Encoded next ContentEncoding is not supported."; return false; } @@ -182,17 +183,17 @@ bool WebMContentEncodingsClient::OnUInt(int id, int64 val) { if (id == kWebMIdContentEncodingType) { if (cur_content_encoding_->type() != ContentEncoding::kTypeInvalid) { - DVLOG(1) << "Unexpected multiple ContentEncodingType."; + MEDIA_LOG(log_cb_) << "Unexpected multiple ContentEncodingType."; return false; } if (val == ContentEncoding::kTypeCompression) { - DVLOG(1) << "ContentCompression not supported."; + MEDIA_LOG(log_cb_) << "ContentCompression not supported."; return false; } if (val != ContentEncoding::kTypeEncryption) { - DVLOG(1) << "Unexpected ContentEncodingType " << val << "."; + MEDIA_LOG(log_cb_) << "Unexpected ContentEncodingType " << val << "."; return false; } @@ -203,13 +204,13 @@ bool WebMContentEncodingsClient::OnUInt(int id, int64 val) { if (id == kWebMIdContentEncAlgo) { if (cur_content_encoding_->encryption_algo() != ContentEncoding::kEncAlgoInvalid) { - DVLOG(1) << "Unexpected multiple ContentEncAlgo."; + MEDIA_LOG(log_cb_) << "Unexpected multiple ContentEncAlgo."; return false; } if (val < ContentEncoding::kEncAlgoNotEncrypted || val > ContentEncoding::kEncAlgoAes) { - DVLOG(1) << "Unexpected ContentEncAlgo " << val << "."; + MEDIA_LOG(log_cb_) << "Unexpected ContentEncAlgo " << val << "."; return false; } @@ -221,12 +222,12 @@ bool WebMContentEncodingsClient::OnUInt(int id, int64 val) { if (id == kWebMIdAESSettingsCipherMode) { if (cur_content_encoding_->cipher_mode() != ContentEncoding::kCipherModeInvalid) { - DVLOG(1) << "Unexpected multiple AESSettingsCipherMode."; + MEDIA_LOG(log_cb_) << "Unexpected multiple AESSettingsCipherMode."; return false; } if (val != ContentEncoding::kCipherModeCtr) { - DVLOG(1) << "Unexpected AESSettingsCipherMode " << val << "."; + MEDIA_LOG(log_cb_) << "Unexpected AESSettingsCipherMode " << val << "."; return false; } @@ -249,7 +250,7 @@ bool WebMContentEncodingsClient::OnBinary(int id, const uint8* data, int size) { if (id == kWebMIdContentEncKeyID) { if (!cur_content_encoding_->encryption_key_id().empty()) { - DVLOG(1) << "Unexpected multiple ContentEncKeyID"; + MEDIA_LOG(log_cb_) << "Unexpected multiple ContentEncKeyID"; return false; } cur_content_encoding_->SetEncryptionKeyId(data, size); diff --git a/media/webm/webm_content_encodings_client.h b/media/webm/webm_content_encodings_client.h index 257d37d..e477fcf3 100644 --- a/media/webm/webm_content_encodings_client.h +++ b/media/webm/webm_content_encodings_client.h @@ -7,9 +7,11 @@ #include <vector> +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "media/base/media_export.h" +#include "media/base/media_log.h" #include "media/webm/webm_content_encodings.h" #include "media/webm/webm_parser.h" @@ -20,7 +22,7 @@ typedef std::vector<ContentEncoding*> ContentEncodings; // Parser for WebM ContentEncodings element. class MEDIA_EXPORT WebMContentEncodingsClient : public WebMParserClient { public: - WebMContentEncodingsClient(); + explicit WebMContentEncodingsClient(const LogCB& log_cb); virtual ~WebMContentEncodingsClient(); const ContentEncodings& content_encodings() const; @@ -32,6 +34,7 @@ class MEDIA_EXPORT WebMContentEncodingsClient : public WebMParserClient { virtual bool OnBinary(int id, const uint8* data, int size) OVERRIDE; private: + LogCB log_cb_; scoped_ptr<ContentEncoding> cur_content_encoding_; bool content_encryption_encountered_; ContentEncodings content_encodings_; diff --git a/media/webm/webm_content_encodings_client_unittest.cc b/media/webm/webm_content_encodings_client_unittest.cc index bf45bd7..bb9e694 100644 --- a/media/webm/webm_content_encodings_client_unittest.cc +++ b/media/webm/webm_content_encodings_client_unittest.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/bind.h" #include "media/webm/webm_constants.h" #include "media/webm/webm_content_encodings_client.h" #include "media/webm/webm_parser.h" @@ -12,7 +13,8 @@ namespace media { class WebMContentEncodingsClientTest : public testing::Test { public: WebMContentEncodingsClientTest() - : parser_(kWebMIdContentEncodings, &client_) {} + : client_(LogCB()), + parser_(kWebMIdContentEncodings, &client_) {} void ParseAndExpectToFail(const uint8* buf, int size) { int result = parser_.Parse(buf, size); diff --git a/media/webm/webm_stream_parser.cc b/media/webm/webm_stream_parser.cc index 89e85d7..dfa56c3 100644 --- a/media/webm/webm_stream_parser.cc +++ b/media/webm/webm_stream_parser.cc @@ -186,7 +186,8 @@ void WebMStreamParser::Init(const InitCB& init_cb, const NewBuffersCB& video_cb, const NeedKeyCB& need_key_cb, const NewMediaSegmentCB& new_segment_cb, - const base::Closure& end_of_segment_cb) { + const base::Closure& end_of_segment_cb, + const LogCB& log_cb) { DCHECK_EQ(state_, kWaitingForInit); DCHECK(init_cb_.is_null()); DCHECK(!init_cb.is_null()); @@ -204,6 +205,7 @@ void WebMStreamParser::Init(const InitCB& init_cb, need_key_cb_ = need_key_cb; new_segment_cb_ = new_segment_cb; end_of_segment_cb_ = end_of_segment_cb; + log_cb_ = log_cb; } void WebMStreamParser::Flush() { @@ -305,9 +307,10 @@ int WebMStreamParser::ParseInfoAndTracks(const uint8* data, int size) { case kWebMIdInfo: // We've found the element we are looking for. break; - default: - DVLOG(1) << "Unexpected ID 0x" << std::hex << id; + default: { + MEDIA_LOG(log_cb_) << "Unexpected element ID 0x" << std::hex << id; return -1; + } } WebMInfoParser info_parser; @@ -320,7 +323,7 @@ int WebMStreamParser::ParseInfoAndTracks(const uint8* data, int size) { cur_size -= result; bytes_parsed += result; - WebMTracksParser tracks_parser; + WebMTracksParser tracks_parser(log_cb_); result = tracks_parser.Parse(cur, cur_size); if (result <= 0) @@ -393,7 +396,8 @@ int WebMStreamParser::ParseInfoAndTracks(const uint8* data, int size) { tracks_parser.audio_track_num(), tracks_parser.video_track_num(), tracks_parser.audio_encryption_key_id(), - tracks_parser.video_encryption_key_id())); + tracks_parser.video_encryption_key_id(), + log_cb_)); ChangeState(kParsingClusters); diff --git a/media/webm/webm_stream_parser.h b/media/webm/webm_stream_parser.h index 3640151..c98805a 100644 --- a/media/webm/webm_stream_parser.h +++ b/media/webm/webm_stream_parser.h @@ -27,7 +27,8 @@ class WebMStreamParser : public StreamParser { const NewBuffersCB& video_cb, const NeedKeyCB& need_key_cb, const NewMediaSegmentCB& new_segment_cb, - const base::Closure& end_of_segment_cb) OVERRIDE; + const base::Closure& end_of_segment_cb, + const LogCB& log_cb) OVERRIDE; virtual void Flush() OVERRIDE; virtual bool Parse(const uint8* buf, int size) OVERRIDE; @@ -71,6 +72,7 @@ class WebMStreamParser : public StreamParser { NeedKeyCB need_key_cb_; NewMediaSegmentCB new_segment_cb_; base::Closure end_of_segment_cb_; + LogCB log_cb_; // True if a new cluster id has been seen, but no audio or video buffers have // been parsed yet. diff --git a/media/webm/webm_tracks_parser.cc b/media/webm/webm_tracks_parser.cc index 7232285..8a8864d 100644 --- a/media/webm/webm_tracks_parser.cc +++ b/media/webm/webm_tracks_parser.cc @@ -16,11 +16,12 @@ namespace media { static const int kWebMTrackTypeVideo = 1; static const int kWebMTrackTypeAudio = 2; -WebMTracksParser::WebMTracksParser() +WebMTracksParser::WebMTracksParser(const LogCB& log_cb) : track_type_(-1), track_num_(-1), audio_track_num_(-1), - video_track_num_(-1) { + video_track_num_(-1), + log_cb_(log_cb) { } WebMTracksParser::~WebMTracksParser() {} @@ -44,7 +45,8 @@ int WebMTracksParser::Parse(const uint8* buf, int size) { WebMParserClient* WebMTracksParser::OnListStart(int id) { if (id == kWebMIdContentEncodings) { DCHECK(!track_content_encodings_client_.get()); - track_content_encodings_client_.reset(new WebMContentEncodingsClient); + track_content_encodings_client_.reset( + new WebMContentEncodingsClient(log_cb_)); return track_content_encodings_client_->OnListStart(id); } @@ -65,15 +67,15 @@ bool WebMTracksParser::OnListEnd(int id) { if (id == kWebMIdTrackEntry) { if (track_type_ == -1 || track_num_ == -1) { - DVLOG(1) << "Missing TrackEntry data" - << " TrackType " << track_type_ - << " TrackNum " << track_num_; + MEDIA_LOG(log_cb_) << "Missing TrackEntry data for " + << " TrackType " << track_type_ + << " TrackNum " << track_num_; return false; } if (track_type_ != kWebMTrackTypeAudio && track_type_ != kWebMTrackTypeVideo) { - DVLOG(1) << "Unexpected TrackType " << track_type_; + MEDIA_LOG(log_cb_) << "Unexpected TrackType " << track_type_; return false; } @@ -118,7 +120,8 @@ bool WebMTracksParser::OnUInt(int id, int64 val) { } if (*dst != -1) { - DVLOG(1) << "Multiple values for id " << std::hex << id << " specified"; + MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id + << " specified"; return false; } @@ -136,7 +139,7 @@ bool WebMTracksParser::OnBinary(int id, const uint8* data, int size) { bool WebMTracksParser::OnString(int id, const std::string& str) { if (id == kWebMIdCodecID && str != "A_VORBIS" && str != "V_VP8") { - DVLOG(1) << "Unexpected CodecID " << str; + MEDIA_LOG(log_cb_) << "Unexpected CodecID " << str; return false; } diff --git a/media/webm/webm_tracks_parser.h b/media/webm/webm_tracks_parser.h index 02d43d6..897ef42 100644 --- a/media/webm/webm_tracks_parser.h +++ b/media/webm/webm_tracks_parser.h @@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" +#include "media/base/media_log.h" #include "media/webm/webm_content_encodings_client.h" #include "media/webm/webm_parser.h" @@ -17,7 +18,7 @@ namespace media { // Parser for WebM Tracks element. class WebMTracksParser : public WebMParserClient { public: - explicit WebMTracksParser(); + explicit WebMTracksParser(const LogCB& log_cb); virtual ~WebMTracksParser(); // Parses a WebM Tracks element in |buf|. @@ -53,6 +54,7 @@ class WebMTracksParser : public WebMParserClient { int64 video_track_num_; std::string audio_encryption_key_id_; std::string video_encryption_key_id_; + LogCB log_cb_; DISALLOW_COPY_AND_ASSIGN(WebMTracksParser); }; |