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) {
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
......@@ -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();
......
......@@ -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;
......
......@@ -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
......@@ -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
......@@ -42,6 +42,34 @@ scoped_refptr<VideoFrame> VideoFrame::CreateFrame(
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
bool VideoFrame::IsValidConfig(VideoFrame::Format format,
const gfx::Size& coded_size,
......
......@@ -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
......
......@@ -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);
}
......
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