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 "content/browser/renderer_host/media/audio_sync_reader.h" | 5 #include "content/browser/renderer_host/media/audio_sync_reader.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/memory/shared_memory.h" | 10 #include "base/memory/shared_memory.h" |
11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
13 #include "content/browser/renderer_host/media/media_stream_manager.h" | 13 #include "content/browser/renderer_host/media/media_stream_manager.h" |
14 #include "content/public/common/content_switches.h" | 14 #include "content/public/common/content_switches.h" |
15 #include "media/audio/audio_parameters.h" | 15 #include "media/audio/audio_parameters.h" |
16 | 16 |
17 using media::AudioBus; | 17 using media::AudioBus; |
18 using media::AudioOutputBuffer; | |
19 | 18 |
20 namespace { | 19 namespace { |
21 | 20 |
22 // Used to log if any audio glitches have been detected during an audio session. | 21 // Used to log if any audio glitches have been detected during an audio session. |
23 // Elements in this enum should not be added, deleted or rearranged. | 22 // Elements in this enum should not be added, deleted or rearranged. |
24 enum AudioGlitchResult { | 23 enum AudioGlitchResult { |
25 AUDIO_RENDERER_NO_AUDIO_GLITCHES = 0, | 24 AUDIO_RENDERER_NO_AUDIO_GLITCHES = 0, |
26 AUDIO_RENDERER_AUDIO_GLITCHES = 1, | 25 AUDIO_RENDERER_AUDIO_GLITCHES = 1, |
27 AUDIO_RENDERER_AUDIO_GLITCHES_MAX = AUDIO_RENDERER_AUDIO_GLITCHES | 26 AUDIO_RENDERER_AUDIO_GLITCHES_MAX = AUDIO_RENDERER_AUDIO_GLITCHES |
28 }; | 27 }; |
(...skipping 16 matching lines...) Expand all Loading... |
45 packet_size_(shared_memory_->requested_size()), | 44 packet_size_(shared_memory_->requested_size()), |
46 renderer_callback_count_(0), | 45 renderer_callback_count_(0), |
47 renderer_missed_callback_count_(0), | 46 renderer_missed_callback_count_(0), |
48 #if defined(OS_MACOSX) | 47 #if defined(OS_MACOSX) |
49 maximum_wait_time_(params.GetBufferDuration() / 2), | 48 maximum_wait_time_(params.GetBufferDuration() / 2), |
50 #else | 49 #else |
51 // TODO(dalecurtis): Investigate if we can reduce this on all platforms. | 50 // TODO(dalecurtis): Investigate if we can reduce this on all platforms. |
52 maximum_wait_time_(base::TimeDelta::FromMilliseconds(20)), | 51 maximum_wait_time_(base::TimeDelta::FromMilliseconds(20)), |
53 #endif | 52 #endif |
54 buffer_index_(0) { | 53 buffer_index_(0) { |
55 DCHECK_EQ(static_cast<size_t>(packet_size_), | 54 DCHECK_EQ(packet_size_, AudioBus::CalculateMemorySize(params)); |
56 sizeof(media::AudioOutputBufferParameters) + | 55 output_bus_ = AudioBus::WrapMemory(params, shared_memory->memory()); |
57 AudioBus::CalculateMemorySize(params)); | |
58 AudioOutputBuffer* buffer = | |
59 reinterpret_cast<AudioOutputBuffer*>(shared_memory_->memory()); | |
60 output_bus_ = AudioBus::WrapMemory(params, buffer->audio); | |
61 output_bus_->Zero(); | 56 output_bus_->Zero(); |
62 } | 57 } |
63 | 58 |
64 AudioSyncReader::~AudioSyncReader() { | 59 AudioSyncReader::~AudioSyncReader() { |
65 if (!renderer_callback_count_) | 60 if (!renderer_callback_count_) |
66 return; | 61 return; |
67 | 62 |
68 // Recording the percentage of deadline misses gives us a rough overview of | 63 // Recording the percentage of deadline misses gives us a rough overview of |
69 // how many users might be running into audio glitches. | 64 // how many users might be running into audio glitches. |
70 int percentage_missed = | 65 int percentage_missed = |
71 100.0 * renderer_missed_callback_count_ / renderer_callback_count_; | 66 100.0 * renderer_missed_callback_count_ / renderer_callback_count_; |
72 UMA_HISTOGRAM_PERCENTAGE( | 67 UMA_HISTOGRAM_PERCENTAGE( |
73 "Media.AudioRendererMissedDeadline", percentage_missed); | 68 "Media.AudioRendererMissedDeadline", percentage_missed); |
74 | 69 |
75 // Add more detailed information regarding detected audio glitches where | 70 // Add more detailed information regarding detected audio glitches where |
76 // a non-zero value of |renderer_missed_callback_count_| is added to the | 71 // a non-zero value of |renderer_missed_callback_count_| is added to the |
77 // AUDIO_RENDERER_AUDIO_GLITCHES bin. | 72 // AUDIO_RENDERER_AUDIO_GLITCHES bin. |
78 renderer_missed_callback_count_ > 0 ? | 73 renderer_missed_callback_count_ > 0 ? |
79 LogAudioGlitchResult(AUDIO_RENDERER_AUDIO_GLITCHES) : | 74 LogAudioGlitchResult(AUDIO_RENDERER_AUDIO_GLITCHES) : |
80 LogAudioGlitchResult(AUDIO_RENDERER_NO_AUDIO_GLITCHES); | 75 LogAudioGlitchResult(AUDIO_RENDERER_NO_AUDIO_GLITCHES); |
81 std::string log_string = | 76 std::string log_string = |
82 base::StringPrintf("ASR: number of detected audio glitches=%d", | 77 base::StringPrintf("ASR: number of detected audio glitches=%d", |
83 static_cast<int>(renderer_missed_callback_count_)); | 78 static_cast<int>(renderer_missed_callback_count_)); |
84 MediaStreamManager::SendMessageToNativeLog(log_string); | 79 MediaStreamManager::SendMessageToNativeLog(log_string); |
85 DVLOG(1) << log_string; | 80 DVLOG(1) << log_string; |
86 } | 81 } |
87 | 82 |
88 // media::AudioOutputController::SyncReader implementations. | 83 // media::AudioOutputController::SyncReader implementations. |
89 void AudioSyncReader::UpdatePendingBytes(uint32_t bytes, | 84 void AudioSyncReader::UpdatePendingBytes(uint32 bytes) { |
90 uint32_t frames_skipped) { | |
91 // Increase the number of skipped frames stored in shared memory. We don't | |
92 // send it over the socket since sending more than 4 bytes might lead to being | |
93 // descheduled. The reading side will zero it when consumed. | |
94 AudioOutputBuffer* buffer = | |
95 reinterpret_cast<AudioOutputBuffer*>(shared_memory_->memory()); | |
96 buffer->params.frames_skipped += frames_skipped; | |
97 | |
98 // Zero out the entire output buffer to avoid stuttering/repeating-buffers | 85 // Zero out the entire output buffer to avoid stuttering/repeating-buffers |
99 // in the anomalous case if the renderer is unable to keep up with real-time. | 86 // in the anomalous case if the renderer is unable to keep up with real-time. |
100 output_bus_->Zero(); | 87 output_bus_->Zero(); |
101 | |
102 socket_->Send(&bytes, sizeof(bytes)); | 88 socket_->Send(&bytes, sizeof(bytes)); |
103 ++buffer_index_; | 89 ++buffer_index_; |
104 } | 90 } |
105 | 91 |
106 void AudioSyncReader::Read(AudioBus* dest) { | 92 void AudioSyncReader::Read(AudioBus* dest) { |
107 ++renderer_callback_count_; | 93 ++renderer_callback_count_; |
108 if (!WaitUntilDataIsReady()) { | 94 if (!WaitUntilDataIsReady()) { |
109 ++renderer_missed_callback_count_; | 95 ++renderer_missed_callback_count_; |
110 if (renderer_missed_callback_count_ <= 100) { | 96 if (renderer_missed_callback_count_ <= 100) { |
111 LOG(WARNING) << "AudioSyncReader::Read timed out, audio glitch count=" | 97 LOG(WARNING) << "AudioSyncReader::Read timed out, audio glitch count=" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 base::TimeDelta::FromMilliseconds(1), | 172 base::TimeDelta::FromMilliseconds(1), |
187 base::TimeDelta::FromMilliseconds(1000), | 173 base::TimeDelta::FromMilliseconds(1000), |
188 50); | 174 50); |
189 return false; | 175 return false; |
190 } | 176 } |
191 | 177 |
192 return true; | 178 return true; |
193 } | 179 } |
194 | 180 |
195 } // namespace content | 181 } // namespace content |
OLD | NEW |