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