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