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 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 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 103 LogHelper::LogHelper(const LogCB& log_cb) : log_cb_(log_cb) {} 104 105 LogHelper::~LogHelper() { 106 if (log_cb_.is_null()) 107 return; 108 log_cb_.Run(stream_.str()); 109 } 110 111 MediaLog::MediaLog() : id_(g_media_log_count.GetNext()) {} 112 113 MediaLog::~MediaLog() {} 114 115 void MediaLog::AddEvent(scoped_ptr<MediaLogEvent> event) {} 116 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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