| OLD | NEW | 
|    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |    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 |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "media/audio/audio_output_device.h" |    5 #include "media/audio/audio_output_device.h" | 
|    6  |    6  | 
|    7 #include <stddef.h> |    7 #include <stddef.h> | 
|    8 #include <stdint.h> |    8 #include <stdint.h> | 
|    9  |    9  | 
|   10 #include <cmath> |   10 #include <cmath> | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
|   32  public: |   32  public: | 
|   33   AudioThreadCallback(const AudioParameters& audio_parameters, |   33   AudioThreadCallback(const AudioParameters& audio_parameters, | 
|   34                       base::SharedMemoryHandle memory, |   34                       base::SharedMemoryHandle memory, | 
|   35                       int memory_length, |   35                       int memory_length, | 
|   36                       AudioRendererSink::RenderCallback* render_callback); |   36                       AudioRendererSink::RenderCallback* render_callback); | 
|   37   ~AudioThreadCallback() override; |   37   ~AudioThreadCallback() override; | 
|   38  |   38  | 
|   39   void MapSharedMemory() override; |   39   void MapSharedMemory() override; | 
|   40  |   40  | 
|   41   // Called whenever we receive notifications about pending data. |   41   // Called whenever we receive notifications about pending data. | 
|   42   void Process(uint32_t pending_data) override; |   42   void Process(uint32_t control_signal) override; | 
|   43  |   43  | 
|   44   // Returns whether the current thread is the audio device thread or not. |   44   // Returns whether the current thread is the audio device thread or not. | 
|   45   // Will always return true if DCHECKs are not enabled. |   45   // Will always return true if DCHECKs are not enabled. | 
|   46   bool CurrentThreadIsAudioDeviceThread(); |   46   bool CurrentThreadIsAudioDeviceThread(); | 
|   47  |   47  | 
|   48  private: |   48  private: | 
|   49   const int bytes_per_frame_; |  | 
|   50   AudioRendererSink::RenderCallback* render_callback_; |   49   AudioRendererSink::RenderCallback* render_callback_; | 
|   51   std::unique_ptr<AudioBus> output_bus_; |   50   std::unique_ptr<AudioBus> output_bus_; | 
|   52   uint64_t callback_num_; |   51   uint64_t callback_num_; | 
|   53  |   52  | 
|   54   DISALLOW_COPY_AND_ASSIGN(AudioThreadCallback); |   53   DISALLOW_COPY_AND_ASSIGN(AudioThreadCallback); | 
|   55 }; |   54 }; | 
|   56  |   55  | 
|   57 AudioOutputDevice::AudioOutputDevice( |   56 AudioOutputDevice::AudioOutputDevice( | 
|   58     std::unique_ptr<AudioOutputIPC> ipc, |   57     std::unique_ptr<AudioOutputIPC> ipc, | 
|   59     const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, |   58     const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, | 
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  424 } |  423 } | 
|  425  |  424  | 
|  426 // AudioOutputDevice::AudioThreadCallback |  425 // AudioOutputDevice::AudioThreadCallback | 
|  427  |  426  | 
|  428 AudioOutputDevice::AudioThreadCallback::AudioThreadCallback( |  427 AudioOutputDevice::AudioThreadCallback::AudioThreadCallback( | 
|  429     const AudioParameters& audio_parameters, |  428     const AudioParameters& audio_parameters, | 
|  430     base::SharedMemoryHandle memory, |  429     base::SharedMemoryHandle memory, | 
|  431     int memory_length, |  430     int memory_length, | 
|  432     AudioRendererSink::RenderCallback* render_callback) |  431     AudioRendererSink::RenderCallback* render_callback) | 
|  433     : AudioDeviceThread::Callback(audio_parameters, memory, memory_length, 1), |  432     : AudioDeviceThread::Callback(audio_parameters, memory, memory_length, 1), | 
|  434       bytes_per_frame_(audio_parameters.GetBytesPerFrame()), |  | 
|  435       render_callback_(render_callback), |  433       render_callback_(render_callback), | 
|  436       callback_num_(0) {} |  434       callback_num_(0) {} | 
|  437  |  435  | 
|  438 AudioOutputDevice::AudioThreadCallback::~AudioThreadCallback() { |  436 AudioOutputDevice::AudioThreadCallback::~AudioThreadCallback() { | 
|  439 } |  437 } | 
|  440  |  438  | 
|  441 void AudioOutputDevice::AudioThreadCallback::MapSharedMemory() { |  439 void AudioOutputDevice::AudioThreadCallback::MapSharedMemory() { | 
|  442   CHECK_EQ(total_segments_, 1); |  440   CHECK_EQ(total_segments_, 1); | 
|  443   CHECK(shared_memory_.Map(memory_length_)); |  441   CHECK(shared_memory_.Map(memory_length_)); | 
|  444   DCHECK_EQ(static_cast<size_t>(memory_length_), |  442   DCHECK_EQ(static_cast<size_t>(memory_length_), | 
|  445             sizeof(AudioOutputBufferParameters) + |  443             sizeof(AudioOutputBufferParameters) + | 
|  446                 AudioBus::CalculateMemorySize(audio_parameters_)); |  444                 AudioBus::CalculateMemorySize(audio_parameters_)); | 
|  447  |  445  | 
|  448   AudioOutputBuffer* buffer = |  446   AudioOutputBuffer* buffer = | 
|  449       reinterpret_cast<AudioOutputBuffer*>(shared_memory_.memory()); |  447       reinterpret_cast<AudioOutputBuffer*>(shared_memory_.memory()); | 
|  450   output_bus_ = AudioBus::WrapMemory(audio_parameters_, buffer->audio); |  448   output_bus_ = AudioBus::WrapMemory(audio_parameters_, buffer->audio); | 
|  451 } |  449 } | 
|  452  |  450  | 
|  453 // Called whenever we receive notifications about pending data. |  451 // Called whenever we receive notifications about pending data. | 
|  454 void AudioOutputDevice::AudioThreadCallback::Process(uint32_t pending_data) { |  452 void AudioOutputDevice::AudioThreadCallback::Process(uint32_t control_signal) { | 
|  455   // Convert the number of pending bytes in the render buffer into frames. |  | 
|  456   double frames_delayed = static_cast<double>(pending_data) / bytes_per_frame_; |  | 
|  457  |  | 
|  458   callback_num_++; |  453   callback_num_++; | 
|  459   TRACE_EVENT1("audio", "AudioOutputDevice::FireRenderCallback", |  454   TRACE_EVENT1("audio", "AudioOutputDevice::FireRenderCallback", | 
|  460                "callback_num", callback_num_); |  455                "callback_num", callback_num_); | 
|  461  |  456  | 
|  462   // When playback starts, we get an immediate callback to Process to make sure |  457   // When playback starts, we get an immediate callback to Process to make sure | 
|  463   // that we have some data, we'll get another one after the device is awake and |  458   // that we have some data, we'll get another one after the device is awake and | 
|  464   // ingesting data, which is what we want to track with this trace. |  459   // ingesting data, which is what we want to track with this trace. | 
|  465   if (callback_num_ == 2) { |  460   if (callback_num_ == 2) { | 
|  466     TRACE_EVENT_ASYNC_END0("audio", "StartingPlayback", this); |  461     TRACE_EVENT_ASYNC_END0("audio", "StartingPlayback", this); | 
|  467   } |  462   } | 
|  468  |  463  | 
|  469   // Read and reset the number of frames skipped. |  464   // Read and reset the number of frames skipped. | 
|  470   AudioOutputBuffer* buffer = |  465   AudioOutputBuffer* buffer = | 
|  471       reinterpret_cast<AudioOutputBuffer*>(shared_memory_.memory()); |  466       reinterpret_cast<AudioOutputBuffer*>(shared_memory_.memory()); | 
|  472   uint32_t frames_skipped = buffer->params.frames_skipped; |  467   uint32_t frames_skipped = buffer->params.frames_skipped; | 
|  473   buffer->params.frames_skipped = 0; |  468   buffer->params.frames_skipped = 0; | 
|  474  |  469  | 
|  475   DVLOG(4) << __func__ << " pending_data:" << pending_data |  470   base::TimeDelta delay = | 
|  476            << " frames_delayed(pre-round):" << frames_delayed |  471       base::TimeDelta::FromMicroseconds(buffer->params.delay); | 
 |  472  | 
 |  473   base::TimeTicks delay_timestamp = | 
 |  474       base::TimeTicks() + | 
 |  475       base::TimeDelta::FromMicroseconds(buffer->params.delay_timestamp); | 
 |  476  | 
 |  477   DVLOG(4) << __func__ << " delay:" << delay << " delay_timestamp:" << delay | 
|  477            << " frames_skipped:" << frames_skipped; |  478            << " frames_skipped:" << frames_skipped; | 
|  478  |  479  | 
|  479   // Update the audio-delay measurement, inform about the number of skipped |  480   // Update the audio-delay measurement, inform about the number of skipped | 
|  480   // frames, and ask client to render audio.  Since |output_bus_| is wrapping |  481   // frames, and ask client to render audio.  Since |output_bus_| is wrapping | 
|  481   // the shared memory the Render() call is writing directly into the shared |  482   // the shared memory the Render() call is writing directly into the shared | 
|  482   // memory. |  483   // memory. | 
|  483   render_callback_->Render(output_bus_.get(), std::round(frames_delayed), |  484   render_callback_->Render(delay, delay_timestamp, frames_skipped, | 
|  484                            frames_skipped); |  485                            output_bus_.get()); | 
|  485 } |  486 } | 
|  486  |  487  | 
|  487 bool AudioOutputDevice::AudioThreadCallback:: |  488 bool AudioOutputDevice::AudioThreadCallback:: | 
|  488     CurrentThreadIsAudioDeviceThread() { |  489     CurrentThreadIsAudioDeviceThread() { | 
|  489   return thread_checker_.CalledOnValidThread(); |  490   return thread_checker_.CalledOnValidThread(); | 
|  490 } |  491 } | 
|  491  |  492  | 
|  492 }  // namespace media |  493 }  // namespace media | 
| OLD | NEW |