| 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/mac/audio_low_latency_input_mac.h" | 5 #include "media/audio/mac/audio_low_latency_input_mac.h" |
| 6 #include <CoreServices/CoreServices.h> | 6 #include <CoreServices/CoreServices.h> |
| 7 #include <mach/mach.h> | 7 #include <mach/mach.h> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/mac/mac_logging.h" | 12 #include "base/mac/mac_logging.h" |
| 13 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
| 14 #include "base/metrics/sparse_histogram.h" | 14 #include "base/metrics/sparse_histogram.h" |
| 15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 16 #include "base/sys_info.h" | 16 #include "base/sys_info.h" |
| 17 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 18 #include "base/trace_event/trace_event.h" |
| 18 #include "media/audio/mac/audio_manager_mac.h" | 19 #include "media/audio/mac/audio_manager_mac.h" |
| 19 #include "media/base/audio_bus.h" | 20 #include "media/base/audio_bus.h" |
| 20 #include "media/base/data_buffer.h" | 21 #include "media/base/data_buffer.h" |
| 21 | 22 |
| 22 namespace media { | 23 namespace media { |
| 23 | 24 |
| 24 // Number of blocks of buffers used in the |fifo_|. | 25 // Number of blocks of buffers used in the |fifo_|. |
| 25 const int kNumberOfBlocksBufferInFifo = 2; | 26 const int kNumberOfBlocksBufferInFifo = 2; |
| 26 | 27 |
| 27 // Max length of sequence of TooManyFramesToProcessError errors. | 28 // Max length of sequence of TooManyFramesToProcessError errors. |
| (...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 // is received from the input device via the output scope of the audio unit. | 824 // is received from the input device via the output scope of the audio unit. |
| 824 return self->OnDataIsAvailable(flags, time_stamp, bus_number, | 825 return self->OnDataIsAvailable(flags, time_stamp, bus_number, |
| 825 number_of_frames); | 826 number_of_frames); |
| 826 } | 827 } |
| 827 | 828 |
| 828 OSStatus AUAudioInputStream::OnDataIsAvailable( | 829 OSStatus AUAudioInputStream::OnDataIsAvailable( |
| 829 AudioUnitRenderActionFlags* flags, | 830 AudioUnitRenderActionFlags* flags, |
| 830 const AudioTimeStamp* time_stamp, | 831 const AudioTimeStamp* time_stamp, |
| 831 UInt32 bus_number, | 832 UInt32 bus_number, |
| 832 UInt32 number_of_frames) { | 833 UInt32 number_of_frames) { |
| 834 TRACE_EVENT0("audio", "AUAudioInputStream::OnDataIsAvailable"); |
| 833 // Update |last_callback_time_| on the main browser thread. Its value is used | 835 // Update |last_callback_time_| on the main browser thread. Its value is used |
| 834 // by CheckIfInputStreamIsAlive() to detect if the stream is dead or alive. | 836 // by CheckIfInputStreamIsAlive() to detect if the stream is dead or alive. |
| 835 manager_->GetTaskRunner()->PostTask( | 837 manager_->GetTaskRunner()->PostTask( |
| 836 FROM_HERE, | 838 FROM_HERE, |
| 837 base::Bind(&AUAudioInputStream::UpdateDataCallbackTimeOnMainThread, | 839 base::Bind(&AUAudioInputStream::UpdateDataCallbackTimeOnMainThread, |
| 838 weak_factory_.GetWeakPtr(), base::TimeTicks::Now())); | 840 weak_factory_.GetWeakPtr(), base::TimeTicks::Now())); |
| 839 | 841 |
| 840 // Indicate that input callbacks have started on the internal AUHAL IO | 842 // Indicate that input callbacks have started on the internal AUHAL IO |
| 841 // thread. The |input_callback_is_active_| member is read from the creating | 843 // thread. The |input_callback_is_active_| member is read from the creating |
| 842 // thread when a timer fires once and set to false in Stop() on the same | 844 // thread when a timer fires once and set to false in Stop() on the same |
| (...skipping 28 matching lines...) Expand all Loading... |
| 871 } | 873 } |
| 872 | 874 |
| 873 // Update the |mDataByteSize| to match |number_of_frames|. | 875 // Update the |mDataByteSize| to match |number_of_frames|. |
| 874 audio_buffer->mDataByteSize = new_size; | 876 audio_buffer->mDataByteSize = new_size; |
| 875 } | 877 } |
| 876 | 878 |
| 877 // Obtain the recorded audio samples by initiating a rendering cycle. | 879 // Obtain the recorded audio samples by initiating a rendering cycle. |
| 878 // Since it happens on the input bus, the |&audio_buffer_list_| parameter is | 880 // Since it happens on the input bus, the |&audio_buffer_list_| parameter is |
| 879 // a reference to the preallocated audio buffer list that the audio unit | 881 // a reference to the preallocated audio buffer list that the audio unit |
| 880 // renders into. | 882 // renders into. |
| 883 TRACE_EVENT_BEGIN0("audio", "AudioUnitRender"); |
| 881 OSStatus result = AudioUnitRender(audio_unit_, flags, time_stamp, bus_number, | 884 OSStatus result = AudioUnitRender(audio_unit_, flags, time_stamp, bus_number, |
| 882 number_of_frames, &audio_buffer_list_); | 885 number_of_frames, &audio_buffer_list_); |
| 886 TRACE_EVENT_END0("audio", "AudioUnitRender"); |
| 883 if (result == noErr) { | 887 if (result == noErr) { |
| 884 audio_unit_render_has_worked_ = true; | 888 audio_unit_render_has_worked_ = true; |
| 885 } | 889 } |
| 886 if (result) { | 890 if (result) { |
| 891 TRACE_EVENT_INSTANT0("audio", "AudioUnitRender error", |
| 892 TRACE_EVENT_SCOPE_THREAD); |
| 887 // Only upload UMA histograms for the case when AGC is enabled. The reason | 893 // Only upload UMA histograms for the case when AGC is enabled. The reason |
| 888 // is that we want to compare these stats with others in this class and | 894 // is that we want to compare these stats with others in this class and |
| 889 // they are only stored for "AGC streams", e.g. WebRTC audio streams. | 895 // they are only stored for "AGC streams", e.g. WebRTC audio streams. |
| 890 const bool add_uma_histogram = GetAutomaticGainControl(); | 896 const bool add_uma_histogram = GetAutomaticGainControl(); |
| 891 if (add_uma_histogram) { | 897 if (add_uma_histogram) { |
| 892 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.AudioInputCbErrorMac", result); | 898 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.AudioInputCbErrorMac", result); |
| 893 } | 899 } |
| 894 OSSTATUS_LOG(ERROR, result) << "AudioUnitRender() failed "; | 900 OSSTATUS_LOG(ERROR, result) << "AudioUnitRender() failed "; |
| 895 if (result == kAudioUnitErr_TooManyFramesToProcess || | 901 if (result == kAudioUnitErr_TooManyFramesToProcess || |
| 896 result == kAudioUnitErr_CannotDoInCurrentContext) { | 902 result == kAudioUnitErr_CannotDoInCurrentContext) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 // Update time of successful call to AudioUnitRender(). | 941 // Update time of successful call to AudioUnitRender(). |
| 936 last_success_time_ = base::TimeTicks::Now(); | 942 last_success_time_ = base::TimeTicks::Now(); |
| 937 | 943 |
| 938 // Deliver recorded data to the consumer as a callback. | 944 // Deliver recorded data to the consumer as a callback. |
| 939 return Provide(number_of_frames, &audio_buffer_list_, time_stamp); | 945 return Provide(number_of_frames, &audio_buffer_list_, time_stamp); |
| 940 } | 946 } |
| 941 | 947 |
| 942 OSStatus AUAudioInputStream::Provide(UInt32 number_of_frames, | 948 OSStatus AUAudioInputStream::Provide(UInt32 number_of_frames, |
| 943 AudioBufferList* io_data, | 949 AudioBufferList* io_data, |
| 944 const AudioTimeStamp* time_stamp) { | 950 const AudioTimeStamp* time_stamp) { |
| 951 TRACE_EVENT1("audio", "AUAudioInputStream::Provide", "number_of_frames", |
| 952 number_of_frames); |
| 945 UpdateCaptureTimestamp(time_stamp); | 953 UpdateCaptureTimestamp(time_stamp); |
| 946 last_number_of_frames_ = number_of_frames; | 954 last_number_of_frames_ = number_of_frames; |
| 947 | 955 |
| 948 // TODO(grunell): We'll only care about the first buffer size change, any | 956 // TODO(grunell): We'll only care about the first buffer size change, any |
| 949 // further changes will be ignored. This is in line with output side stats. | 957 // further changes will be ignored. This is in line with output side stats. |
| 950 // It would be nice to have all changes reflected in UMA stats. | 958 // It would be nice to have all changes reflected in UMA stats. |
| 951 if (number_of_frames != number_of_frames_ && number_of_frames_provided_ == 0) | 959 if (number_of_frames != number_of_frames_ && number_of_frames_provided_ == 0) |
| 952 number_of_frames_provided_ = number_of_frames; | 960 number_of_frames_provided_ = number_of_frames; |
| 953 | 961 |
| 954 // Update the capture latency. | 962 // Update the capture latency. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 973 // when the Display Audio is used as capture source and the cable is first | 981 // when the Display Audio is used as capture source and the cable is first |
| 974 // remove and then inserted again. | 982 // remove and then inserted again. |
| 975 // See http://www.crbug.com/434681 for details. | 983 // See http://www.crbug.com/434681 for details. |
| 976 if (static_cast<int>(number_of_frames) > fifo_.GetUnfilledFrames()) { | 984 if (static_cast<int>(number_of_frames) > fifo_.GetUnfilledFrames()) { |
| 977 // Derive required increase in number of FIFO blocks. The increase is | 985 // Derive required increase in number of FIFO blocks. The increase is |
| 978 // typically one block. | 986 // typically one block. |
| 979 const int blocks = | 987 const int blocks = |
| 980 static_cast<int>((number_of_frames - fifo_.GetUnfilledFrames()) / | 988 static_cast<int>((number_of_frames - fifo_.GetUnfilledFrames()) / |
| 981 number_of_frames_) + 1; | 989 number_of_frames_) + 1; |
| 982 DLOG(WARNING) << "Increasing FIFO capacity by " << blocks << " blocks"; | 990 DLOG(WARNING) << "Increasing FIFO capacity by " << blocks << " blocks"; |
| 991 TRACE_EVENT_INSTANT1("audio", "Increasing FIFO capacity", |
| 992 TRACE_EVENT_SCOPE_THREAD, "increased by", blocks); |
| 983 fifo_.IncreaseCapacity(blocks); | 993 fifo_.IncreaseCapacity(blocks); |
| 984 } | 994 } |
| 985 | 995 |
| 986 // Copy captured (and interleaved) data into FIFO. | 996 // Copy captured (and interleaved) data into FIFO. |
| 987 fifo_.Push(audio_data, number_of_frames, format_.mBitsPerChannel / 8); | 997 fifo_.Push(audio_data, number_of_frames, format_.mBitsPerChannel / 8); |
| 988 | 998 |
| 989 // Consume and deliver the data when the FIFO has a block of available data. | 999 // Consume and deliver the data when the FIFO has a block of available data. |
| 990 while (fifo_.available_blocks()) { | 1000 while (fifo_.available_blocks()) { |
| 991 const AudioBus* audio_bus = fifo_.Consume(); | 1001 const AudioBus* audio_bus = fifo_.Consume(); |
| 992 DCHECK_EQ(audio_bus->frames(), static_cast<int>(number_of_frames_)); | 1002 DCHECK_EQ(audio_bus->frames(), static_cast<int>(number_of_frames_)); |
| (...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1671 | 1681 |
| 1672 number_of_frames_provided_ = 0; | 1682 number_of_frames_provided_ = 0; |
| 1673 glitches_detected_ = 0; | 1683 glitches_detected_ = 0; |
| 1674 last_sample_time_ = 0; | 1684 last_sample_time_ = 0; |
| 1675 last_number_of_frames_ = 0; | 1685 last_number_of_frames_ = 0; |
| 1676 total_lost_frames_ = 0; | 1686 total_lost_frames_ = 0; |
| 1677 largest_glitch_frames_ = 0; | 1687 largest_glitch_frames_ = 0; |
| 1678 } | 1688 } |
| 1679 | 1689 |
| 1680 } // namespace media | 1690 } // namespace media |
| OLD | NEW |