Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / media / base / media_log.cc
blob754a5f924cee03f1dd8476993660f47165aeb199
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/base/media_log.h"
7 #include "base/atomic_sequence_num.h"
8 #include "base/json/json_writer.h"
9 #include "base/values.h"
11 namespace media {
13 // A count of all MediaLogs created in the current process. Used to generate
14 // unique IDs.
15 static base::StaticAtomicSequenceNumber g_media_log_count;
17 std::string MediaLog::MediaLogLevelToString(MediaLogLevel level) {
18 switch (level) {
19 case MEDIALOG_ERROR:
20 return "error";
21 case MEDIALOG_INFO:
22 return "info";
23 case MEDIALOG_DEBUG:
24 return "debug";
26 NOTREACHED();
27 return NULL;
30 MediaLogEvent::Type MediaLog::MediaLogLevelToEventType(MediaLogLevel level) {
31 switch (level) {
32 case MEDIALOG_ERROR:
33 return MediaLogEvent::MEDIA_ERROR_LOG_ENTRY;
34 case MEDIALOG_INFO:
35 return MediaLogEvent::MEDIA_INFO_LOG_ENTRY;
36 case MEDIALOG_DEBUG:
37 return MediaLogEvent::MEDIA_DEBUG_LOG_ENTRY;
39 NOTREACHED();
40 return MediaLogEvent::MEDIA_ERROR_LOG_ENTRY;
43 std::string MediaLog::EventTypeToString(MediaLogEvent::Type type) {
44 switch (type) {
45 case MediaLogEvent::WEBMEDIAPLAYER_CREATED:
46 return "WEBMEDIAPLAYER_CREATED";
47 case MediaLogEvent::WEBMEDIAPLAYER_DESTROYED:
48 return "WEBMEDIAPLAYER_DESTROYED";
49 case MediaLogEvent::LOAD:
50 return "LOAD";
51 case MediaLogEvent::SEEK:
52 return "SEEK";
53 case MediaLogEvent::PLAY:
54 return "PLAY";
55 case MediaLogEvent::PAUSE:
56 return "PAUSE";
57 case MediaLogEvent::PIPELINE_STATE_CHANGED:
58 return "PIPELINE_STATE_CHANGED";
59 case MediaLogEvent::PIPELINE_ERROR:
60 return "PIPELINE_ERROR";
61 case MediaLogEvent::VIDEO_SIZE_SET:
62 return "VIDEO_SIZE_SET";
63 case MediaLogEvent::DURATION_SET:
64 return "DURATION_SET";
65 case MediaLogEvent::TOTAL_BYTES_SET:
66 return "TOTAL_BYTES_SET";
67 case MediaLogEvent::NETWORK_ACTIVITY_SET:
68 return "NETWORK_ACTIVITY_SET";
69 case MediaLogEvent::ENDED:
70 return "ENDED";
71 case MediaLogEvent::TEXT_ENDED:
72 return "TEXT_ENDED";
73 case MediaLogEvent::BUFFERED_EXTENTS_CHANGED:
74 return "BUFFERED_EXTENTS_CHANGED";
75 case MediaLogEvent::MEDIA_ERROR_LOG_ENTRY:
76 return "MEDIA_ERROR_LOG_ENTRY";
77 case MediaLogEvent::MEDIA_INFO_LOG_ENTRY:
78 return "MEDIA_INFO_LOG_ENTRY";
79 case MediaLogEvent::MEDIA_DEBUG_LOG_ENTRY:
80 return "MEDIA_DEBUG_LOG_ENTRY";
81 case MediaLogEvent::PROPERTY_CHANGE:
82 return "PROPERTY_CHANGE";
84 NOTREACHED();
85 return NULL;
88 std::string MediaLog::PipelineStatusToString(PipelineStatus status) {
89 switch (status) {
90 case PIPELINE_OK:
91 return "pipeline: ok";
92 case PIPELINE_ERROR_URL_NOT_FOUND:
93 return "pipeline: url not found";
94 case PIPELINE_ERROR_NETWORK:
95 return "pipeline: network error";
96 case PIPELINE_ERROR_DECODE:
97 return "pipeline: decode error";
98 case PIPELINE_ERROR_ABORT:
99 return "pipeline: abort";
100 case PIPELINE_ERROR_INITIALIZATION_FAILED:
101 return "pipeline: initialization failed";
102 case PIPELINE_ERROR_COULD_NOT_RENDER:
103 return "pipeline: could not render";
104 case PIPELINE_ERROR_READ:
105 return "pipeline: read error";
106 case PIPELINE_ERROR_OPERATION_PENDING:
107 return "pipeline: operation pending";
108 case PIPELINE_ERROR_INVALID_STATE:
109 return "pipeline: invalid state";
110 case DEMUXER_ERROR_COULD_NOT_OPEN:
111 return "demuxer: could not open";
112 case DEMUXER_ERROR_COULD_NOT_PARSE:
113 return "demuxer: could not parse";
114 case DEMUXER_ERROR_NO_SUPPORTED_STREAMS:
115 return "demuxer: no supported streams";
116 case DECODER_ERROR_NOT_SUPPORTED:
117 return "decoder: not supported";
119 NOTREACHED();
120 return NULL;
123 std::string MediaLog::MediaEventToLogString(const MediaLogEvent& event) {
124 // Special case for PIPELINE_ERROR, since that's by far the most useful
125 // event for figuring out media pipeline failures, and just reporting
126 // pipeline status as numeric code is not very helpful/user-friendly.
127 int error_code = 0;
128 if (event.type == MediaLogEvent::PIPELINE_ERROR &&
129 event.params.GetInteger("pipeline_error", &error_code)) {
130 PipelineStatus status = static_cast<PipelineStatus>(error_code);
131 return EventTypeToString(event.type) + " " +
132 media::MediaLog::PipelineStatusToString(status);
134 std::string params_json;
135 base::JSONWriter::Write(event.params, &params_json);
136 return EventTypeToString(event.type) + " " + params_json;
139 MediaLog::MediaLog() : id_(g_media_log_count.GetNext()) {}
141 MediaLog::~MediaLog() {}
143 void MediaLog::AddEvent(scoped_ptr<MediaLogEvent> event) {}
145 scoped_ptr<MediaLogEvent> MediaLog::CreateEvent(MediaLogEvent::Type type) {
146 scoped_ptr<MediaLogEvent> event(new MediaLogEvent);
147 event->id = id_;
148 event->type = type;
149 event->time = base::TimeTicks::Now();
150 return event.Pass();
153 scoped_ptr<MediaLogEvent> MediaLog::CreateBooleanEvent(
154 MediaLogEvent::Type type,
155 const std::string& property,
156 bool value) {
157 scoped_ptr<MediaLogEvent> event(CreateEvent(type));
158 event->params.SetBoolean(property, value);
159 return event.Pass();
162 scoped_ptr<MediaLogEvent> MediaLog::CreateStringEvent(
163 MediaLogEvent::Type type,
164 const std::string& property,
165 const std::string& value) {
166 scoped_ptr<MediaLogEvent> event(CreateEvent(type));
167 event->params.SetString(property, value);
168 return event.Pass();
171 scoped_ptr<MediaLogEvent> MediaLog::CreateTimeEvent(
172 MediaLogEvent::Type type,
173 const std::string& property,
174 base::TimeDelta value) {
175 scoped_ptr<MediaLogEvent> event(CreateEvent(type));
176 if (value.is_max())
177 event->params.SetString(property, "unknown");
178 else
179 event->params.SetDouble(property, value.InSecondsF());
180 return event.Pass();
183 scoped_ptr<MediaLogEvent> MediaLog::CreateLoadEvent(const std::string& url) {
184 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::LOAD));
185 event->params.SetString("url", url);
186 return event.Pass();
189 scoped_ptr<MediaLogEvent> MediaLog::CreateSeekEvent(float seconds) {
190 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::SEEK));
191 event->params.SetDouble("seek_target", seconds);
192 return event.Pass();
195 scoped_ptr<MediaLogEvent> MediaLog::CreatePipelineStateChangedEvent(
196 Pipeline::State state) {
197 scoped_ptr<MediaLogEvent> event(
198 CreateEvent(MediaLogEvent::PIPELINE_STATE_CHANGED));
199 event->params.SetString("pipeline_state", Pipeline::GetStateString(state));
200 return event.Pass();
203 scoped_ptr<MediaLogEvent> MediaLog::CreatePipelineErrorEvent(
204 PipelineStatus error) {
205 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PIPELINE_ERROR));
206 event->params.SetInteger("pipeline_error", error);
207 return event.Pass();
210 scoped_ptr<MediaLogEvent> MediaLog::CreateVideoSizeSetEvent(
211 size_t width, size_t height) {
212 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::VIDEO_SIZE_SET));
213 event->params.SetInteger("width", width);
214 event->params.SetInteger("height", height);
215 return event.Pass();
218 scoped_ptr<MediaLogEvent> MediaLog::CreateBufferedExtentsChangedEvent(
219 int64 start, int64 current, int64 end) {
220 scoped_ptr<MediaLogEvent> event(
221 CreateEvent(MediaLogEvent::BUFFERED_EXTENTS_CHANGED));
222 // These values are headed to JS where there is no int64 so we use a double
223 // and accept loss of precision above 2^53 bytes (8 Exabytes).
224 event->params.SetDouble("buffer_start", start);
225 event->params.SetDouble("buffer_current", current);
226 event->params.SetDouble("buffer_end", end);
227 return event.Pass();
230 void MediaLog::AddLogEvent(MediaLogLevel level, const std::string& message) {
231 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogLevelToEventType(level)));
232 event->params.SetString(MediaLogLevelToString(level), message);
233 AddEvent(event.Pass());
236 void MediaLog::SetStringProperty(
237 const std::string& key, const std::string& value) {
238 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PROPERTY_CHANGE));
239 event->params.SetString(key, value);
240 AddEvent(event.Pass());
243 void MediaLog::SetIntegerProperty(
244 const std::string& key, int value) {
245 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PROPERTY_CHANGE));
246 event->params.SetInteger(key, value);
247 AddEvent(event.Pass());
250 void MediaLog::SetDoubleProperty(
251 const std::string& key, double value) {
252 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PROPERTY_CHANGE));
253 event->params.SetDouble(key, value);
254 AddEvent(event.Pass());
257 void MediaLog::SetBooleanProperty(
258 const std::string& key, bool value) {
259 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PROPERTY_CHANGE));
260 event->params.SetBoolean(key, value);
261 AddEvent(event.Pass());
264 void MediaLog::SetTimeProperty(
265 const std::string& key, base::TimeDelta value) {
266 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PROPERTY_CHANGE));
267 if (value.is_max())
268 event->params.SetString(key, "unknown");
269 else
270 event->params.SetDouble(key, value.InSecondsF());
271 AddEvent(event.Pass());
274 LogHelper::LogHelper(MediaLog::MediaLogLevel level,
275 const scoped_refptr<MediaLog>& media_log)
276 : level_(level), media_log_(media_log) {
277 DCHECK(media_log_.get());
280 LogHelper::~LogHelper() {
281 media_log_->AddLogEvent(level_, stream_.str());
284 } //namespace media