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