Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(398)

Side by Side Diff: media/audio/audio_output_device.cc

Issue 2437863004: Make more media APIs aware of |delay| and |delay_timestamp| (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/callback_helpers.h" 13 #include "base/callback_helpers.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/metrics/histogram_macros.h" 15 #include "base/metrics/histogram_macros.h"
16 #include "base/threading/thread_restrictions.h" 16 #include "base/threading/thread_restrictions.h"
17 #include "base/time/time.h" 17 #include "base/time/time.h"
18 #include "base/timer/timer.h" 18 #include "base/timer/timer.h"
19 #include "base/trace_event/trace_event.h" 19 #include "base/trace_event/trace_event.h"
20 #include "build/build_config.h" 20 #include "build/build_config.h"
21 #include "media/audio/audio_device_description.h" 21 #include "media/audio/audio_device_description.h"
22 #include "media/audio/audio_output_controller.h" 22 #include "media/audio/audio_output_controller.h"
23 #include "media/base/audio_timestamp_helper.h"
23 #include "media/base/limits.h" 24 #include "media/base/limits.h"
24 25
25 namespace media { 26 namespace media {
26 27
27 // Takes care of invoking the render callback on the audio thread. 28 // Takes care of invoking the render callback on the audio thread.
28 // An instance of this class is created for each capture stream in 29 // An instance of this class is created for each capture stream in
29 // OnStreamCreated(). 30 // OnStreamCreated().
30 class AudioOutputDevice::AudioThreadCallback 31 class AudioOutputDevice::AudioThreadCallback
31 : public AudioDeviceThread::Callback { 32 : public AudioDeviceThread::Callback {
32 public: 33 public:
33 AudioThreadCallback(const AudioParameters& audio_parameters, 34 AudioThreadCallback(const AudioParameters& audio_parameters,
34 base::SharedMemoryHandle memory, 35 base::SharedMemoryHandle memory,
35 int memory_length, 36 int memory_length,
36 AudioRendererSink::RenderCallback* render_callback); 37 AudioRendererSink::RenderCallback* render_callback);
37 ~AudioThreadCallback() override; 38 ~AudioThreadCallback() override;
38 39
39 void MapSharedMemory() override; 40 void MapSharedMemory() override;
40 41
41 // Called whenever we receive notifications about pending data. 42 // Called whenever we receive notifications about pending data.
42 void Process(uint32_t pending_data) override; 43 void Process(int64_t pending_data, base::TimeTicks delay_timestamp) override;
43 44
44 // Returns whether the current thread is the audio device thread or not. 45 // Returns whether the current thread is the audio device thread or not.
45 // Will always return true if DCHECKs are not enabled. 46 // Will always return true if DCHECKs are not enabled.
46 bool CurrentThreadIsAudioDeviceThread(); 47 bool CurrentThreadIsAudioDeviceThread();
47 48
48 private: 49 private:
49 const int bytes_per_frame_; 50 const int frame_rate_;
50 AudioRendererSink::RenderCallback* render_callback_; 51 AudioRendererSink::RenderCallback* render_callback_;
51 std::unique_ptr<AudioBus> output_bus_; 52 std::unique_ptr<AudioBus> output_bus_;
52 uint64_t callback_num_; 53 uint64_t callback_num_;
53 54
54 DISALLOW_COPY_AND_ASSIGN(AudioThreadCallback); 55 DISALLOW_COPY_AND_ASSIGN(AudioThreadCallback);
55 }; 56 };
56 57
57 AudioOutputDevice::AudioOutputDevice( 58 AudioOutputDevice::AudioOutputDevice(
58 std::unique_ptr<AudioOutputIPC> ipc, 59 std::unique_ptr<AudioOutputIPC> ipc,
59 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, 60 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 } 425 }
425 426
426 // AudioOutputDevice::AudioThreadCallback 427 // AudioOutputDevice::AudioThreadCallback
427 428
428 AudioOutputDevice::AudioThreadCallback::AudioThreadCallback( 429 AudioOutputDevice::AudioThreadCallback::AudioThreadCallback(
429 const AudioParameters& audio_parameters, 430 const AudioParameters& audio_parameters,
430 base::SharedMemoryHandle memory, 431 base::SharedMemoryHandle memory,
431 int memory_length, 432 int memory_length,
432 AudioRendererSink::RenderCallback* render_callback) 433 AudioRendererSink::RenderCallback* render_callback)
433 : AudioDeviceThread::Callback(audio_parameters, memory, memory_length, 1), 434 : AudioDeviceThread::Callback(audio_parameters, memory, memory_length, 1),
434 bytes_per_frame_(audio_parameters.GetBytesPerFrame()), 435 frame_rate_(audio_parameters.sample_rate()),
435 render_callback_(render_callback), 436 render_callback_(render_callback),
436 callback_num_(0) {} 437 callback_num_(0) {}
437 438
438 AudioOutputDevice::AudioThreadCallback::~AudioThreadCallback() { 439 AudioOutputDevice::AudioThreadCallback::~AudioThreadCallback() {
439 } 440 }
440 441
441 void AudioOutputDevice::AudioThreadCallback::MapSharedMemory() { 442 void AudioOutputDevice::AudioThreadCallback::MapSharedMemory() {
442 CHECK_EQ(total_segments_, 1); 443 CHECK_EQ(total_segments_, 1);
443 CHECK(shared_memory_.Map(memory_length_)); 444 CHECK(shared_memory_.Map(memory_length_));
444 DCHECK_EQ(static_cast<size_t>(memory_length_), 445 DCHECK_EQ(static_cast<size_t>(memory_length_),
445 sizeof(AudioOutputBufferParameters) + 446 sizeof(AudioOutputBufferParameters) +
446 AudioBus::CalculateMemorySize(audio_parameters_)); 447 AudioBus::CalculateMemorySize(audio_parameters_));
447 448
448 AudioOutputBuffer* buffer = 449 AudioOutputBuffer* buffer =
449 reinterpret_cast<AudioOutputBuffer*>(shared_memory_.memory()); 450 reinterpret_cast<AudioOutputBuffer*>(shared_memory_.memory());
450 output_bus_ = AudioBus::WrapMemory(audio_parameters_, buffer->audio); 451 output_bus_ = AudioBus::WrapMemory(audio_parameters_, buffer->audio);
451 } 452 }
452 453
453 // Called whenever we receive notifications about pending data. 454 // Called whenever we receive notifications about pending data.
454 void AudioOutputDevice::AudioThreadCallback::Process(uint32_t pending_data) { 455 void AudioOutputDevice::AudioThreadCallback::Process(
455 // Convert the number of pending bytes in the render buffer into frames. 456 int64_t pending_data,
456 double frames_delayed = static_cast<double>(pending_data) / bytes_per_frame_; 457 base::TimeTicks delay_timestamp) {
458 base::TimeDelta delay = base::TimeDelta::FromInternalValue(pending_data);
miu 2016/10/23 01:19:16 Instead of passing pending_data as an int64_t, cou
Mikhail 2016/10/24 19:50:24 The reason for keeping this is 'AudioInputDevice::
457 459
458 callback_num_++; 460 callback_num_++;
459 TRACE_EVENT1("audio", "AudioOutputDevice::FireRenderCallback", 461 TRACE_EVENT1("audio", "AudioOutputDevice::FireRenderCallback",
460 "callback_num", callback_num_); 462 "callback_num", callback_num_);
461 463
462 // When playback starts, we get an immediate callback to Process to make sure 464 // 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 465 // 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. 466 // ingesting data, which is what we want to track with this trace.
465 if (callback_num_ == 2) { 467 if (callback_num_ == 2) {
466 TRACE_EVENT_ASYNC_END0("audio", "StartingPlayback", this); 468 TRACE_EVENT_ASYNC_END0("audio", "StartingPlayback", this);
467 } 469 }
468 470
469 // Read and reset the number of frames skipped. 471 // Read and reset the number of frames skipped.
470 AudioOutputBuffer* buffer = 472 AudioOutputBuffer* buffer =
471 reinterpret_cast<AudioOutputBuffer*>(shared_memory_.memory()); 473 reinterpret_cast<AudioOutputBuffer*>(shared_memory_.memory());
472 uint32_t frames_skipped = buffer->params.frames_skipped; 474 uint32_t frames_skipped = buffer->params.frames_skipped;
473 buffer->params.frames_skipped = 0; 475 buffer->params.frames_skipped = 0;
474 476
475 DVLOG(4) << __func__ << " pending_data:" << pending_data 477 DVLOG(4) << __func__ << " delay:" << delay
476 << " frames_delayed(pre-round):" << frames_delayed
477 << " frames_skipped:" << frames_skipped; 478 << " frames_skipped:" << frames_skipped;
478 479
480 // TODO(Mikhail) : Now all clients expect that bus duration included to
481 // |delay|. We should reconsider this.
482 const int frames = output_bus_->frames();
chcunningham 2016/10/21 18:19:47 I'm confused. Why are we doing this here instead o
Mikhail 2016/10/24 19:50:24 Indeed. Thanks for noticing!
483 delay += AudioTimestampHelper::FramesToTime(frames, frame_rate_);
484
479 // Update the audio-delay measurement, inform about the number of skipped 485 // Update the audio-delay measurement, inform about the number of skipped
480 // frames, and ask client to render audio. Since |output_bus_| is wrapping 486 // 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 487 // the shared memory the Render() call is writing directly into the shared
482 // memory. 488 // memory.
483 render_callback_->Render(output_bus_.get(), std::round(frames_delayed), 489 render_callback_->Render(output_bus_.get(), delay, delay_timestamp,
484 frames_skipped); 490 frames_skipped);
485 } 491 }
486 492
487 bool AudioOutputDevice::AudioThreadCallback:: 493 bool AudioOutputDevice::AudioThreadCallback::
488 CurrentThreadIsAudioDeviceThread() { 494 CurrentThreadIsAudioDeviceThread() {
489 return thread_checker_.CalledOnValidThread(); 495 return thread_checker_.CalledOnValidThread();
490 } 496 }
491 497
492 } // namespace media 498 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698