Home | History | Annotate | Download | only in base
      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