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.
4
5 #include "media/base/media_log.h"
6
7 #include <string>
8
9 #include "base/atomic_sequence_num.h"
10 #include "base/logging.h"
11 #include "base/values.h"
12
13 namespace media {
14
15 // A count of all MediaLogs created in the current process. Used to generate
16 // unique IDs.
17 static base::StaticAtomicSequenceNumber g_media_log_count;
18
EventTypeToString(MediaLogEvent::Type type)19 const char* MediaLog::EventTypeToString(MediaLogEvent::Type type) {
20 switch (type) {
21 case MediaLogEvent::WEBMEDIAPLAYER_CREATED:
22 return "WEBMEDIAPLAYER_CREATED";
23 case MediaLogEvent::WEBMEDIAPLAYER_DESTROYED:
24 return "WEBMEDIAPLAYER_DESTROYED";
25 case MediaLogEvent::PIPELINE_CREATED:
26 return "PIPELINE_CREATED";
27 case MediaLogEvent::PIPELINE_DESTROYED:
28 return "PIPELINE_DESTROYED";
29 case MediaLogEvent::LOAD:
30 return "LOAD";
31 case MediaLogEvent::SEEK:
32 return "SEEK";
33 case MediaLogEvent::PLAY:
34 return "PLAY";
35 case MediaLogEvent::PAUSE:
36 return "PAUSE";
37 case MediaLogEvent::PIPELINE_STATE_CHANGED:
38 return "PIPELINE_STATE_CHANGED";
39 case MediaLogEvent::PIPELINE_ERROR:
40 return "PIPELINE_ERROR";
41 case MediaLogEvent::VIDEO_SIZE_SET:
42 return "VIDEO_SIZE_SET";
43 case MediaLogEvent::DURATION_SET:
44 return "DURATION_SET";
45 case MediaLogEvent::TOTAL_BYTES_SET:
46 return "TOTAL_BYTES_SET";
47 case MediaLogEvent::NETWORK_ACTIVITY_SET:
48 return "NETWORK_ACTIVITY_SET";
49 case MediaLogEvent::ENDED:
50 return "ENDED";
51 case MediaLogEvent::TEXT_ENDED:
52 return "TEXT_ENDED";
53 case MediaLogEvent::BUFFERED_EXTENTS_CHANGED:
54 return "BUFFERED_EXTENTS_CHANGED";
55 case MediaLogEvent::MEDIA_SOURCE_ERROR:
56 return "MEDIA_SOURCE_ERROR";
57 case MediaLogEvent::PROPERTY_CHANGE:
58 return "PROPERTY_CHANGE";
59 }
60 NOTREACHED();
61 return NULL;
62 }
63
PipelineStatusToString(PipelineStatus status)64 const char* MediaLog::PipelineStatusToString(PipelineStatus status) {
65 switch (status) {
66 case PIPELINE_OK:
67 return "pipeline: ok";
68 case PIPELINE_ERROR_URL_NOT_FOUND:
69 return "pipeline: url not found";
70 case PIPELINE_ERROR_NETWORK:
71 return "pipeline: network error";
72 case PIPELINE_ERROR_DECODE:
73 return "pipeline: decode error";
74 case PIPELINE_ERROR_DECRYPT:
75 return "pipeline: decrypt error";
76 case PIPELINE_ERROR_ABORT:
77 return "pipeline: abort";
78 case PIPELINE_ERROR_INITIALIZATION_FAILED:
79 return "pipeline: initialization failed";
80 case PIPELINE_ERROR_COULD_NOT_RENDER:
81 return "pipeline: could not render";
82 case PIPELINE_ERROR_READ:
83 return "pipeline: read error";
84 case PIPELINE_ERROR_OPERATION_PENDING:
85 return "pipeline: operation pending";
86 case PIPELINE_ERROR_INVALID_STATE:
87 return "pipeline: invalid state";
88 case DEMUXER_ERROR_COULD_NOT_OPEN:
89 return "demuxer: could not open";
90 case DEMUXER_ERROR_COULD_NOT_PARSE:
91 return "dumuxer: could not parse";
92 case DEMUXER_ERROR_NO_SUPPORTED_STREAMS:
93 return "demuxer: no supported streams";
94 case DECODER_ERROR_NOT_SUPPORTED:
95 return "decoder: not supported";
96 }
97 NOTREACHED();
98 return NULL;
99 }
100
LogHelper(const LogCB & log_cb)101 LogHelper::LogHelper(const LogCB& log_cb) : log_cb_(log_cb) {}
102
~LogHelper()103 LogHelper::~LogHelper() {
104 if (log_cb_.is_null())
105 return;
106 log_cb_.Run(stream_.str());
107 }
108
MediaLog()109 MediaLog::MediaLog() : id_(g_media_log_count.GetNext()) {}
110
~MediaLog()111 MediaLog::~MediaLog() {}
112
AddEvent(scoped_ptr<MediaLogEvent> event)113 void MediaLog::AddEvent(scoped_ptr<MediaLogEvent> event) {}
114
CreateEvent(MediaLogEvent::Type type)115 scoped_ptr<MediaLogEvent> MediaLog::CreateEvent(MediaLogEvent::Type type) {
116 scoped_ptr<MediaLogEvent> event(new MediaLogEvent);
117 event->id = id_;
118 event->type = type;
119 event->time = base::TimeTicks::Now();
120 return event.Pass();
121 }
122
CreateBooleanEvent(MediaLogEvent::Type type,const char * property,bool value)123 scoped_ptr<MediaLogEvent> MediaLog::CreateBooleanEvent(
124 MediaLogEvent::Type type, const char* property, bool value) {
125 scoped_ptr<MediaLogEvent> event(CreateEvent(type));
126 event->params.SetBoolean(property, value);
127 return event.Pass();
128 }
129
CreateStringEvent(MediaLogEvent::Type type,const char * property,const std::string & value)130 scoped_ptr<MediaLogEvent> MediaLog::CreateStringEvent(
131 MediaLogEvent::Type type, const char* property, const std::string& value) {
132 scoped_ptr<MediaLogEvent> event(CreateEvent(type));
133 event->params.SetString(property, value);
134 return event.Pass();
135 }
136
CreateTimeEvent(MediaLogEvent::Type type,const char * property,base::TimeDelta value)137 scoped_ptr<MediaLogEvent> MediaLog::CreateTimeEvent(
138 MediaLogEvent::Type type, const char* property, base::TimeDelta value) {
139 scoped_ptr<MediaLogEvent> event(CreateEvent(type));
140 if (value.is_max())
141 event->params.SetString(property, "unknown");
142 else
143 event->params.SetDouble(property, value.InSecondsF());
144 return event.Pass();
145 }
146
CreateLoadEvent(const std::string & url)147 scoped_ptr<MediaLogEvent> MediaLog::CreateLoadEvent(const std::string& url) {
148 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::LOAD));
149 event->params.SetString("url", url);
150 return event.Pass();
151 }
152
CreateSeekEvent(float seconds)153 scoped_ptr<MediaLogEvent> MediaLog::CreateSeekEvent(float seconds) {
154 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::SEEK));
155 event->params.SetDouble("seek_target", seconds);
156 return event.Pass();
157 }
158
CreatePipelineStateChangedEvent(Pipeline::State state)159 scoped_ptr<MediaLogEvent> MediaLog::CreatePipelineStateChangedEvent(
160 Pipeline::State state) {
161 scoped_ptr<MediaLogEvent> event(
162 CreateEvent(MediaLogEvent::PIPELINE_STATE_CHANGED));
163 event->params.SetString("pipeline_state", Pipeline::GetStateString(state));
164 return event.Pass();
165 }
166
CreatePipelineErrorEvent(PipelineStatus error)167 scoped_ptr<MediaLogEvent> MediaLog::CreatePipelineErrorEvent(
168 PipelineStatus error) {
169 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PIPELINE_ERROR));
170 event->params.SetString("pipeline_error", PipelineStatusToString(error));
171 return event.Pass();
172 }
173
CreateVideoSizeSetEvent(size_t width,size_t height)174 scoped_ptr<MediaLogEvent> MediaLog::CreateVideoSizeSetEvent(
175 size_t width, size_t height) {
176 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::VIDEO_SIZE_SET));
177 event->params.SetInteger("width", width);
178 event->params.SetInteger("height", height);
179 return event.Pass();
180 }
181
CreateBufferedExtentsChangedEvent(int64 start,int64 current,int64 end)182 scoped_ptr<MediaLogEvent> MediaLog::CreateBufferedExtentsChangedEvent(
183 int64 start, int64 current, int64 end) {
184 scoped_ptr<MediaLogEvent> event(
185 CreateEvent(MediaLogEvent::BUFFERED_EXTENTS_CHANGED));
186 // These values are headed to JS where there is no int64 so we use a double
187 // and accept loss of precision above 2^53 bytes (8 Exabytes).
188 event->params.SetDouble("buffer_start", start);
189 event->params.SetDouble("buffer_current", current);
190 event->params.SetDouble("buffer_end", end);
191 return event.Pass();
192 }
193
CreateMediaSourceErrorEvent(const std::string & error)194 scoped_ptr<MediaLogEvent> MediaLog::CreateMediaSourceErrorEvent(
195 const std::string& error) {
196 scoped_ptr<MediaLogEvent> event(
197 CreateEvent(MediaLogEvent::MEDIA_SOURCE_ERROR));
198 event->params.SetString("error", error);
199 return event.Pass();
200 }
201
SetStringProperty(const char * key,const std::string & value)202 void MediaLog::SetStringProperty(
203 const char* key, const std::string& value) {
204 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PROPERTY_CHANGE));
205 event->params.SetString(key, value);
206 AddEvent(event.Pass());
207 }
208
SetIntegerProperty(const char * key,int value)209 void MediaLog::SetIntegerProperty(
210 const char* key, int value) {
211 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PROPERTY_CHANGE));
212 event->params.SetInteger(key, value);
213 AddEvent(event.Pass());
214 }
215
SetDoubleProperty(const char * key,double value)216 void MediaLog::SetDoubleProperty(
217 const char* key, double value) {
218 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PROPERTY_CHANGE));
219 event->params.SetDouble(key, value);
220 AddEvent(event.Pass());
221 }
222
SetBooleanProperty(const char * key,bool value)223 void MediaLog::SetBooleanProperty(
224 const char* key, bool value) {
225 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PROPERTY_CHANGE));
226 event->params.SetBoolean(key, value);
227 AddEvent(event.Pass());
228 }
229
SetTimeProperty(const char * key,base::TimeDelta value)230 void MediaLog::SetTimeProperty(
231 const char* key, base::TimeDelta value) {
232 scoped_ptr<MediaLogEvent> event(CreateEvent(MediaLogEvent::PROPERTY_CHANGE));
233 if (value.is_max())
234 event->params.SetString(key, "unknown");
235 else
236 event->params.SetDouble(key, value.InSecondsF());
237 AddEvent(event.Pass());
238 }
239
240 } //namespace media
241