diff options
author | tyoverby@chromium.org <tyoverby@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-06 21:30:29 +0000 |
---|---|---|
committer | tyoverby@chromium.org <tyoverby@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-06 21:30:29 +0000 |
commit | 36499f88cef6febccaa85f61f3b5345728013314 (patch) | |
tree | 92977687e003c29b1a0136722791fb01a915bd86 /media | |
parent | 2beccf710cafa61a163e44fa01e114c3f2694e62 (diff) | |
download | chromium_src-36499f88cef6febccaa85f61f3b5345728013314.zip chromium_src-36499f88cef6febccaa85f61f3b5345728013314.tar.gz chromium_src-36499f88cef6febccaa85f61f3b5345728013314.tar.bz2 |
Added logging calls to FFmpegDemuxer.
BUG=260005
Review URL: https://chromiumcodereview.appspot.com/21953003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@215982 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/base/media_log.cc | 30 | ||||
-rw-r--r-- | media/base/media_log.h | 6 | ||||
-rw-r--r-- | media/base/media_log_event.h | 3 | ||||
-rw-r--r-- | media/base/sample_format.cc | 23 | ||||
-rw-r--r-- | media/base/sample_format.h | 3 | ||||
-rw-r--r-- | media/base/video_frame.cc | 28 | ||||
-rw-r--r-- | media/base/video_frame.h | 3 | ||||
-rw-r--r-- | media/filters/ffmpeg_demuxer.cc | 77 |
8 files changed, 164 insertions, 9 deletions
diff --git a/media/base/media_log.cc b/media/base/media_log.cc index 0f2e182..8a07b02 100644 --- a/media/base/media_log.cc +++ b/media/base/media_log.cc @@ -56,6 +56,8 @@ const char* MediaLog::EventTypeToString(MediaLogEvent::Type type) { return "BUFFERED_EXTENTS_CHANGED"; case MediaLogEvent::MEDIA_SOURCE_ERROR: return "MEDIA_SOURCE_ERROR"; + case MediaLogEvent::PROPERTY_CHANGE: + return "PROPERTY_CHANGE"; } NOTREACHED(); return NULL; @@ -198,4 +200,32 @@ scoped_ptr<MediaLogEvent> MediaLog::CreateMediaSourceErrorEvent( return event.Pass(); } +void MediaLog::SetStringProperty( + const char* key, const std::string& value) { + scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PROPERTY_CHANGE)); + event->params.SetString(key, value); + AddEvent(event.Pass()); +} + +void MediaLog::SetIntegerProperty( + const char* key, int value) { + scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PROPERTY_CHANGE)); + event->params.SetInteger(key, value); + AddEvent(event.Pass()); +} + +void MediaLog::SetDoubleProperty( + const char* key, double value) { + scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PROPERTY_CHANGE)); + event->params.SetDouble(key, value); + AddEvent(event.Pass()); +} + +void MediaLog::SetBooleanProperty( + const char* key, bool value) { + scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PROPERTY_CHANGE)); + event->params.SetBoolean(key, value); + AddEvent(event.Pass()); +} + } //namespace media diff --git a/media/base/media_log.h b/media/base/media_log.h index 191de33..1d25c09 100644 --- a/media/base/media_log.h +++ b/media/base/media_log.h @@ -68,6 +68,12 @@ class MEDIA_EXPORT MediaLog : public base::RefCountedThreadSafe<MediaLog> { scoped_ptr<MediaLogEvent> CreateMediaSourceErrorEvent( const std::string& error); + // Report a property change without an accompanying event. + void SetStringProperty(const char* key, const std::string& value); + void SetIntegerProperty(const char* key, int value); + void SetDoubleProperty(const char* key, double value); + void SetBooleanProperty(const char* key, bool value); + protected: friend class base::RefCountedThreadSafe<MediaLog>; virtual ~MediaLog(); diff --git a/media/base/media_log_event.h b/media/base/media_log_event.h index 142626b..811d113 100644 --- a/media/base/media_log_event.h +++ b/media/base/media_log_event.h @@ -87,6 +87,9 @@ struct MediaLogEvent { // Errors reported by Media Source Extensions code. MEDIA_SOURCE_ERROR, // params: "error": Error string describing the error detected. + + // A property has changed without any special event occurring. + PROPERTY_CHANGE, }; int32 id; diff --git a/media/base/sample_format.cc b/media/base/sample_format.cc index 3fdcf101..a4791cd 100644 --- a/media/base/sample_format.cc +++ b/media/base/sample_format.cc @@ -29,4 +29,27 @@ int SampleFormatToBytesPerChannel(SampleFormat sample_format) { return 0; } +const char* SampleFormatToString(SampleFormat sample_format) { + switch(sample_format) { + case kUnknownSampleFormat: + return "Unknown sample format"; + case kSampleFormatU8: + return "Unsigned 8-bit with bias of 128"; + case kSampleFormatS16: + return "Signed 16-bit"; + case kSampleFormatS32: + return "Signed 32-bit"; + case kSampleFormatF32: + return "Float 32-bit"; + case kSampleFormatPlanarS16: + return "Signed 16-bit planar"; + case kSampleFormatPlanarF32: + return "Float 32-bit planar"; + case kSampleFormatMax: + break; + } + NOTREACHED() << "Invalid sample format provided: " << sample_format; + return ""; +} + } // namespace media diff --git a/media/base/sample_format.h b/media/base/sample_format.h index bcaa5b2..3d2799f 100644 --- a/media/base/sample_format.h +++ b/media/base/sample_format.h @@ -29,6 +29,9 @@ enum SampleFormat { // |sample_format|. MEDIA_EXPORT int SampleFormatToBytesPerChannel(SampleFormat sample_format); +// Returns the name of the sample format as a string +MEDIA_EXPORT const char* SampleFormatToString(SampleFormat sample_format); + } // namespace media #endif // MEDIA_BASE_SAMPLE_FORMAT_H diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index de7440a..10ad051 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc @@ -43,6 +43,34 @@ scoped_refptr<VideoFrame> VideoFrame::CreateFrame( } // static +std::string VideoFrame::FormatToString(VideoFrame::Format format) { + switch (format) { + case VideoFrame::INVALID: + return "INVALID"; + case VideoFrame::RGB32: + return "RGB32"; + case VideoFrame::YV12: + return "YV12"; + case VideoFrame::YV16: + return "YV16"; + case VideoFrame::EMPTY: + return "EMPTY"; + case VideoFrame::I420: + return "I420"; + case VideoFrame::NATIVE_TEXTURE: + return "NATIVE_TEXTURE"; +#if defined(GOOGLE_TV) + case VideoFrame::HOLE: + return "HOLE"; +#endif + case VideoFrame::YV12A: + return "YV12A"; + } + NOTREACHED() << "Invalid videoframe format provided: " << format; + return ""; +} + +// static bool VideoFrame::IsValidConfig(VideoFrame::Format format, const gfx::Size& coded_size, const gfx::Rect& visible_rect, diff --git a/media/base/video_frame.h b/media/base/video_frame.h index 128143c..8207d9b 100644 --- a/media/base/video_frame.h +++ b/media/base/video_frame.h @@ -53,6 +53,9 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { YV12A = 14, // 20bpp YUVA planar 1x1 Y, 2x2 VU, 1x1 A samples. }; + // Returns the name of a Format as a string. + static std::string FormatToString(Format format); + // This class calls the TextureNoLongerNeededCallback when the last reference // on the class is destroyed. The VideoFrame holds a reference to the mailbox // but anyone else who queries the mailbox should also hold a reference while diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index 70c5596..14b1fff 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc @@ -17,6 +17,7 @@ #include "base/metrics/sparse_histogram.h" #include "base/stl_util.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/task_runner_util.h" #include "base/time/time.h" #include "media/base/audio_decoder_config.h" @@ -491,8 +492,12 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, // partial playback. At least one audio or video stream must be playable. AVFormatContext* format_context = glue_->format_context(); streams_.resize(format_context->nb_streams); - bool found_audio_stream = false; - bool found_video_stream = false; + + AVStream* audio_stream = NULL; + AudioDecoderConfig audio_config; + + AVStream* video_stream = NULL; + VideoDecoderConfig video_config; base::TimeDelta max_duration; for (size_t i = 0; i < format_context->nb_streams; ++i) { @@ -501,31 +506,32 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, AVMediaType codec_type = codec_context->codec_type; if (codec_type == AVMEDIA_TYPE_AUDIO) { - if (found_audio_stream) + if (audio_stream) continue; + // Log the codec detected, whether it is supported or not. UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedAudioCodec", codec_context->codec_id); // Ensure the codec is supported. IsValidConfig() also checks that the // channel layout and sample format are valid. - AudioDecoderConfig audio_config; AVStreamToAudioDecoderConfig(stream, &audio_config, false); if (!audio_config.IsValidConfig()) continue; - found_audio_stream = true; + audio_stream = stream; } else if (codec_type == AVMEDIA_TYPE_VIDEO) { - if (found_video_stream) + if (video_stream) continue; + // Log the codec detected, whether it is supported or not. UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedVideoCodec", codec_context->codec_id); // Ensure the codec is supported. IsValidConfig() also checks that the // frame size and visible size are valid. - VideoDecoderConfig video_config; AVStreamToVideoDecoderConfig(stream, &video_config, false); + if (!video_config.IsValidConfig()) continue; - found_video_stream = true; + video_stream = stream; } else { continue; } @@ -541,7 +547,7 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, } } - if (!found_audio_stream && !found_video_stream) { + if (!audio_stream && !video_stream) { status_cb.Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); return; } @@ -579,6 +585,59 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, if (bitrate_ > 0) data_source_->SetBitrate(bitrate_); + // Audio logging + if (audio_stream) { + AVCodecContext* audio_codec = audio_stream->codec; + media_log_->SetBooleanProperty("found_audio_stream", true); + + SampleFormat sample_format = audio_config.sample_format(); + std::string sample_name = SampleFormatToString(sample_format); + + media_log_->SetStringProperty("audio_sample_format", sample_name); + + media_log_->SetStringProperty("audio_codec_name", + audio_codec->codec_name); + media_log_->SetIntegerProperty("audio_sample_rate", + audio_codec->sample_rate); + media_log_->SetIntegerProperty("audio_channels_count", + audio_codec->channels); + media_log_->SetIntegerProperty("audio_samples_per_second", + audio_config.samples_per_second()); + } else { + media_log_->SetBooleanProperty("found_audio_stream", false); + } + + // Video logging + if (video_stream) { + AVCodecContext* video_codec = video_stream->codec; + media_log_->SetBooleanProperty("found_video_stream", true); + media_log_->SetStringProperty("video_codec_name", video_codec->codec_name); + media_log_->SetIntegerProperty("width", video_codec->width); + media_log_->SetIntegerProperty("height", video_codec->height); + media_log_->SetIntegerProperty("coded_width", + video_codec->coded_width); + media_log_->SetIntegerProperty("coded_height", + video_codec->coded_height); + media_log_->SetStringProperty( + "time_base", + base::StringPrintf("%d/%d", + video_codec->time_base.num, + video_codec->time_base.den)); + media_log_->SetStringProperty( + "video_format", VideoFrame::FormatToString(video_config.format())); + media_log_->SetBooleanProperty("video_is_encrypted", + video_config.is_encrypted()); + } else { + media_log_->SetBooleanProperty("found_video_stream", false); + } + + + media_log_->SetDoubleProperty("max_duration", max_duration.InSecondsF()); + media_log_->SetDoubleProperty("start_time", start_time_.InSecondsF()); + media_log_->SetDoubleProperty("filesize_in_bytes", + static_cast<double>(filesize_in_bytes)); + media_log_->SetIntegerProperty("bitrate", bitrate_); + status_cb.Run(PIPELINE_OK); } |