Commit 36499f88 authored by tyoverby@chromium.org's avatar tyoverby@chromium.org

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
parent 2beccf71
...@@ -56,6 +56,8 @@ const char* MediaLog::EventTypeToString(MediaLogEvent::Type type) { ...@@ -56,6 +56,8 @@ const char* MediaLog::EventTypeToString(MediaLogEvent::Type type) {
return "BUFFERED_EXTENTS_CHANGED"; return "BUFFERED_EXTENTS_CHANGED";
case MediaLogEvent::MEDIA_SOURCE_ERROR: case MediaLogEvent::MEDIA_SOURCE_ERROR:
return "MEDIA_SOURCE_ERROR"; return "MEDIA_SOURCE_ERROR";
case MediaLogEvent::PROPERTY_CHANGE:
return "PROPERTY_CHANGE";
} }
NOTREACHED(); NOTREACHED();
return NULL; return NULL;
...@@ -198,4 +200,32 @@ scoped_ptr<MediaLogEvent> MediaLog::CreateMediaSourceErrorEvent( ...@@ -198,4 +200,32 @@ scoped_ptr<MediaLogEvent> MediaLog::CreateMediaSourceErrorEvent(
return event.Pass(); 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 } //namespace media
...@@ -68,6 +68,12 @@ class MEDIA_EXPORT MediaLog : public base::RefCountedThreadSafe<MediaLog> { ...@@ -68,6 +68,12 @@ class MEDIA_EXPORT MediaLog : public base::RefCountedThreadSafe<MediaLog> {
scoped_ptr<MediaLogEvent> CreateMediaSourceErrorEvent( scoped_ptr<MediaLogEvent> CreateMediaSourceErrorEvent(
const std::string& error); 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: protected:
friend class base::RefCountedThreadSafe<MediaLog>; friend class base::RefCountedThreadSafe<MediaLog>;
virtual ~MediaLog(); virtual ~MediaLog();
......
...@@ -87,6 +87,9 @@ struct MediaLogEvent { ...@@ -87,6 +87,9 @@ struct MediaLogEvent {
// Errors reported by Media Source Extensions code. // Errors reported by Media Source Extensions code.
MEDIA_SOURCE_ERROR, MEDIA_SOURCE_ERROR,
// params: "error": Error string describing the error detected. // params: "error": Error string describing the error detected.
// A property has changed without any special event occurring.
PROPERTY_CHANGE,
}; };
int32 id; int32 id;
......
...@@ -29,4 +29,27 @@ int SampleFormatToBytesPerChannel(SampleFormat sample_format) { ...@@ -29,4 +29,27 @@ int SampleFormatToBytesPerChannel(SampleFormat sample_format) {
return 0; 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 } // namespace media
...@@ -29,6 +29,9 @@ enum SampleFormat { ...@@ -29,6 +29,9 @@ enum SampleFormat {
// |sample_format|. // |sample_format|.
MEDIA_EXPORT int SampleFormatToBytesPerChannel(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 } // namespace media
#endif // MEDIA_BASE_SAMPLE_FORMAT_H #endif // MEDIA_BASE_SAMPLE_FORMAT_H
...@@ -42,6 +42,34 @@ scoped_refptr<VideoFrame> VideoFrame::CreateFrame( ...@@ -42,6 +42,34 @@ scoped_refptr<VideoFrame> VideoFrame::CreateFrame(
return frame; return frame;
} }
// 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 // static
bool VideoFrame::IsValidConfig(VideoFrame::Format format, bool VideoFrame::IsValidConfig(VideoFrame::Format format,
const gfx::Size& coded_size, const gfx::Size& coded_size,
......
...@@ -53,6 +53,9 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { ...@@ -53,6 +53,9 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
YV12A = 14, // 20bpp YUVA planar 1x1 Y, 2x2 VU, 1x1 A samples. 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 // This class calls the TextureNoLongerNeededCallback when the last reference
// on the class is destroyed. The VideoFrame holds a reference to the mailbox // 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 // but anyone else who queries the mailbox should also hold a reference while
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "base/metrics/sparse_histogram.h" #include "base/metrics/sparse_histogram.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task_runner_util.h" #include "base/task_runner_util.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "media/base/audio_decoder_config.h" #include "media/base/audio_decoder_config.h"
...@@ -491,8 +492,12 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, ...@@ -491,8 +492,12 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
// partial playback. At least one audio or video stream must be playable. // partial playback. At least one audio or video stream must be playable.
AVFormatContext* format_context = glue_->format_context(); AVFormatContext* format_context = glue_->format_context();
streams_.resize(format_context->nb_streams); 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; base::TimeDelta max_duration;
for (size_t i = 0; i < format_context->nb_streams; ++i) { for (size_t i = 0; i < format_context->nb_streams; ++i) {
...@@ -501,31 +506,32 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, ...@@ -501,31 +506,32 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
AVMediaType codec_type = codec_context->codec_type; AVMediaType codec_type = codec_context->codec_type;
if (codec_type == AVMEDIA_TYPE_AUDIO) { if (codec_type == AVMEDIA_TYPE_AUDIO) {
if (found_audio_stream) if (audio_stream)
continue; continue;
// Log the codec detected, whether it is supported or not. // Log the codec detected, whether it is supported or not.
UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedAudioCodec", UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedAudioCodec",
codec_context->codec_id); codec_context->codec_id);
// Ensure the codec is supported. IsValidConfig() also checks that the // Ensure the codec is supported. IsValidConfig() also checks that the
// channel layout and sample format are valid. // channel layout and sample format are valid.
AudioDecoderConfig audio_config;
AVStreamToAudioDecoderConfig(stream, &audio_config, false); AVStreamToAudioDecoderConfig(stream, &audio_config, false);
if (!audio_config.IsValidConfig()) if (!audio_config.IsValidConfig())
continue; continue;
found_audio_stream = true; audio_stream = stream;
} else if (codec_type == AVMEDIA_TYPE_VIDEO) { } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
if (found_video_stream) if (video_stream)
continue; continue;
// Log the codec detected, whether it is supported or not. // Log the codec detected, whether it is supported or not.
UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedVideoCodec", UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedVideoCodec",
codec_context->codec_id); codec_context->codec_id);
// Ensure the codec is supported. IsValidConfig() also checks that the // Ensure the codec is supported. IsValidConfig() also checks that the
// frame size and visible size are valid. // frame size and visible size are valid.
VideoDecoderConfig video_config;
AVStreamToVideoDecoderConfig(stream, &video_config, false); AVStreamToVideoDecoderConfig(stream, &video_config, false);
if (!video_config.IsValidConfig()) if (!video_config.IsValidConfig())
continue; continue;
found_video_stream = true; video_stream = stream;
} else { } else {
continue; continue;
} }
...@@ -541,7 +547,7 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, ...@@ -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); status_cb.Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
return; return;
} }
...@@ -579,6 +585,59 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, ...@@ -579,6 +585,59 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
if (bitrate_ > 0) if (bitrate_ > 0)
data_source_->SetBitrate(bitrate_); 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); status_cb.Run(PIPELINE_OK);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment