| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <limits> | 5 #include <limits> |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "services/media/audio/audio_track_impl.h" | 8 #include "services/media/audio/audio_track_impl.h" |
| 9 #include "services/media/audio/platform/generic/mixers/mixer_utils.h" | 9 #include "services/media/audio/platform/generic/mixers/mixer_utils.h" |
| 10 #include "services/media/audio/platform/generic/mixers/point_sampler.h" | 10 #include "services/media/audio/platform/generic/mixers/point_sampler.h" |
| 11 | 11 |
| 12 namespace mojo { | 12 namespace mojo { |
| 13 namespace media { | 13 namespace media { |
| 14 namespace audio { | 14 namespace audio { |
| 15 namespace mixers { | 15 namespace mixers { |
| 16 | 16 |
| 17 // Point Sample Mixer implementation. | 17 // Point Sample Mixer implementation. |
| 18 template <typename DType, | 18 template <size_t DChCount, |
| 19 size_t DChCount, | |
| 20 typename SType, | 19 typename SType, |
| 21 size_t SChCount> | 20 size_t SChCount> |
| 22 class PointSamplerImpl : public PointSampler { | 21 class PointSamplerImpl : public PointSampler { |
| 23 public: | 22 public: |
| 24 PointSamplerImpl() : PointSampler(0, FRAC_ONE - 1) {} | 23 PointSamplerImpl() : PointSampler(0, FRAC_ONE - 1) {} |
| 25 | 24 |
| 26 bool Mix(void* dst, | 25 bool Mix(int32_t* dst, |
| 27 uint32_t dst_frames, | 26 uint32_t dst_frames, |
| 28 uint32_t* dst_offset, | 27 uint32_t* dst_offset, |
| 29 const void* src, | 28 const void* src, |
| 30 uint32_t frac_src_frames, | 29 uint32_t frac_src_frames, |
| 31 int32_t* frac_src_offset, | 30 int32_t* frac_src_offset, |
| 32 uint32_t frac_step_size, | 31 uint32_t frac_step_size, |
| 33 bool accumulate) override; | 32 bool accumulate) override; |
| 34 | 33 |
| 35 private: | 34 private: |
| 36 template <bool DoAccumulate> | 35 template <bool DoAccumulate> |
| 37 static inline bool Mix(void* dst, | 36 static inline bool Mix(int32_t* dst, |
| 38 uint32_t dst_frames, | 37 uint32_t dst_frames, |
| 39 uint32_t* dst_offset, | 38 uint32_t* dst_offset, |
| 40 const void* src, | 39 const void* src, |
| 41 uint32_t frac_src_frames, | 40 uint32_t frac_src_frames, |
| 42 int32_t* frac_src_offset, | 41 int32_t* frac_src_offset, |
| 43 uint32_t frac_step_size); | 42 uint32_t frac_step_size); |
| 44 }; | 43 }; |
| 45 | 44 |
| 46 template <typename DType, | 45 template <size_t DChCount, |
| 47 size_t DChCount, | |
| 48 typename SType, | 46 typename SType, |
| 49 size_t SChCount> | 47 size_t SChCount> |
| 50 template <bool DoAccumulate> | 48 template <bool DoAccumulate> |
| 51 inline bool PointSamplerImpl<DType, DChCount, SType, SChCount>::Mix( | 49 inline bool PointSamplerImpl<DChCount, SType, SChCount>::Mix( |
| 52 void* dst_void, | 50 int32_t* dst, |
| 53 uint32_t dst_frames, | 51 uint32_t dst_frames, |
| 54 uint32_t* dst_offset, | 52 uint32_t* dst_offset, |
| 55 const void* src_void, | 53 const void* src_void, |
| 56 uint32_t frac_src_frames, | 54 uint32_t frac_src_frames, |
| 57 int32_t* frac_src_offset, | 55 int32_t* frac_src_offset, |
| 58 uint32_t frac_step_size) { | 56 uint32_t frac_step_size) { |
| 59 using SR = utils::SrcReader<SType, SChCount, DChCount>; | 57 using SR = utils::SrcReader<SType, SChCount, DChCount>; |
| 60 using DM = utils::DstMixer<DType, DoAccumulate>; | 58 using DM = utils::DstMixer<DoAccumulate>; |
| 61 | 59 |
| 62 const SType* src = static_cast<const SType*>(src_void); | 60 const SType* src = static_cast<const SType*>(src_void); |
| 63 DType* dst = static_cast<DType*>(dst_void); | |
| 64 uint32_t doff = *dst_offset; | 61 uint32_t doff = *dst_offset; |
| 65 int32_t soff = *frac_src_offset; | 62 int32_t soff = *frac_src_offset; |
| 66 | 63 |
| 67 DCHECK_LE(frac_src_frames, | 64 DCHECK_LE(frac_src_frames, |
| 68 static_cast<uint32_t>(std::numeric_limits<int32_t>::max())); | 65 static_cast<uint32_t>(std::numeric_limits<int32_t>::max())); |
| 69 DCHECK_LT(soff, static_cast<int32_t>(frac_src_frames)); | 66 DCHECK_LT(soff, static_cast<int32_t>(frac_src_frames)); |
| 70 DCHECK_GE(soff, 0); | 67 DCHECK_GE(soff, 0); |
| 71 | 68 |
| 72 while ((doff < dst_frames) && | 69 while ((doff < dst_frames) && |
| 73 (soff < static_cast<int32_t>(frac_src_frames))) { | 70 (soff < static_cast<int32_t>(frac_src_frames))) { |
| 74 uint32_t src_iter; | 71 uint32_t src_iter; |
| 75 DType* out; | 72 int32_t* out; |
| 76 | 73 |
| 77 src_iter = (soff >> AudioTrackImpl::PTS_FRACTIONAL_BITS) * SChCount; | 74 src_iter = (soff >> AudioTrackImpl::PTS_FRACTIONAL_BITS) * SChCount; |
| 78 out = dst + (doff * DChCount); | 75 out = dst + (doff * DChCount); |
| 79 | 76 |
| 80 for (size_t dst_iter = 0; dst_iter < DChCount; ++dst_iter) { | 77 for (size_t dst_iter = 0; dst_iter < DChCount; ++dst_iter) { |
| 81 int32_t sample = SR::Read(src + src_iter + (dst_iter / SR::DstPerSrc)); | 78 int32_t sample = SR::Read(src + src_iter + (dst_iter / SR::DstPerSrc)); |
| 82 out[dst_iter] = DM::Mix(out + dst_iter, sample); | 79 out[dst_iter] = DM::Mix(out[dst_iter], sample); |
| 83 } | 80 } |
| 84 | 81 |
| 85 doff += 1; | 82 doff += 1; |
| 86 soff += frac_step_size; | 83 soff += frac_step_size; |
| 87 } | 84 } |
| 88 | 85 |
| 89 *dst_offset = doff; | 86 *dst_offset = doff; |
| 90 *frac_src_offset = soff; | 87 *frac_src_offset = soff; |
| 91 | 88 |
| 92 return (soff >= static_cast<int32_t>(frac_src_frames)); | 89 return (soff >= static_cast<int32_t>(frac_src_frames)); |
| 93 } | 90 } |
| 94 | 91 |
| 95 template <typename DType, | 92 template <size_t DChCount, |
| 96 size_t DChCount, | |
| 97 typename SType, | 93 typename SType, |
| 98 size_t SChCount> | 94 size_t SChCount> |
| 99 bool PointSamplerImpl<DType, DChCount, SType, SChCount>::Mix( | 95 bool PointSamplerImpl<DChCount, SType, SChCount>::Mix( |
| 100 void* dst, | 96 int32_t* dst, |
| 101 uint32_t dst_frames, | 97 uint32_t dst_frames, |
| 102 uint32_t* dst_offset, | 98 uint32_t* dst_offset, |
| 103 const void* src, | 99 const void* src, |
| 104 uint32_t frac_src_frames, | 100 uint32_t frac_src_frames, |
| 105 int32_t* frac_src_offset, | 101 int32_t* frac_src_offset, |
| 106 uint32_t frac_step_size, | 102 uint32_t frac_step_size, |
| 107 bool accumulate) { | 103 bool accumulate) { |
| 108 return accumulate ? Mix<true>(dst, dst_frames, dst_offset, | 104 return accumulate ? Mix<true>(dst, dst_frames, dst_offset, |
| 109 src, frac_src_frames, frac_src_offset, | 105 src, frac_src_frames, frac_src_offset, |
| 110 frac_step_size) | 106 frac_step_size) |
| 111 : Mix<false>(dst, dst_frames, dst_offset, | 107 : Mix<false>(dst, dst_frames, dst_offset, |
| 112 src, frac_src_frames, frac_src_offset, | 108 src, frac_src_frames, frac_src_offset, |
| 113 frac_step_size); | 109 frac_step_size); |
| 114 } | 110 } |
| 115 | 111 |
| 116 // Templates used to expand all of the different combinations of the possible | 112 // Templates used to expand all of the different combinations of the possible |
| 117 // Point Sampler Mixer configurations. | 113 // Point Sampler Mixer configurations. |
| 118 template <typename DType, | 114 template <size_t DChCount, |
| 119 size_t DChCount, | |
| 120 typename SType, | 115 typename SType, |
| 121 size_t SChCount> | 116 size_t SChCount> |
| 122 static inline MixerPtr SelectPSM(const LpcmMediaTypeDetailsPtr& src_format, | 117 static inline MixerPtr SelectPSM(const LpcmMediaTypeDetailsPtr& src_format, |
| 123 const LpcmMediaTypeDetailsPtr& dst_format) { | 118 const LpcmMediaTypeDetailsPtr& dst_format) { |
| 124 return MixerPtr(new PointSamplerImpl<DType, DChCount, SType, SChCount>()); | 119 return MixerPtr(new PointSamplerImpl<DChCount, SType, SChCount>()); |
| 125 } | 120 } |
| 126 | 121 |
| 127 template <typename DType, | 122 template <size_t DChCount, |
| 128 size_t DChCount, | |
| 129 typename SType> | 123 typename SType> |
| 130 static inline MixerPtr SelectPSM(const LpcmMediaTypeDetailsPtr& src_format, | 124 static inline MixerPtr SelectPSM(const LpcmMediaTypeDetailsPtr& src_format, |
| 131 const LpcmMediaTypeDetailsPtr& dst_format) { | 125 const LpcmMediaTypeDetailsPtr& dst_format) { |
| 132 switch (src_format->channels) { | 126 switch (src_format->channels) { |
| 133 case 1: | 127 case 1: |
| 134 return SelectPSM<DType, DChCount, SType, 1>(src_format, dst_format); | 128 return SelectPSM<DChCount, SType, 1>(src_format, dst_format); |
| 135 case 2: | 129 case 2: |
| 136 return SelectPSM<DType, DChCount, SType, 2>(src_format, dst_format); | 130 return SelectPSM<DChCount, SType, 2>(src_format, dst_format); |
| 137 default: | 131 default: |
| 138 return nullptr; | 132 return nullptr; |
| 139 } | 133 } |
| 140 } | 134 } |
| 141 | 135 |
| 142 template <typename DType, | 136 template <size_t DChCount> |
| 143 size_t DChCount> | |
| 144 static inline MixerPtr SelectPSM(const LpcmMediaTypeDetailsPtr& src_format, | 137 static inline MixerPtr SelectPSM(const LpcmMediaTypeDetailsPtr& src_format, |
| 145 const LpcmMediaTypeDetailsPtr& dst_format) { | 138 const LpcmMediaTypeDetailsPtr& dst_format) { |
| 146 switch (src_format->sample_format) { | 139 switch (src_format->sample_format) { |
| 147 case LpcmSampleFormat::UNSIGNED_8: | 140 case LpcmSampleFormat::UNSIGNED_8: |
| 148 return SelectPSM<DType, DChCount, uint8_t>(src_format, dst_format); | 141 return SelectPSM<DChCount, uint8_t>(src_format, dst_format); |
| 149 case LpcmSampleFormat::SIGNED_16: | 142 case LpcmSampleFormat::SIGNED_16: |
| 150 return SelectPSM<DType, DChCount, int16_t>(src_format, dst_format); | 143 return SelectPSM<DChCount, int16_t>(src_format, dst_format); |
| 151 default: | |
| 152 return nullptr; | |
| 153 } | |
| 154 } | |
| 155 | |
| 156 template <typename DType> | |
| 157 static inline MixerPtr SelectPSM(const LpcmMediaTypeDetailsPtr& src_format, | |
| 158 const LpcmMediaTypeDetailsPtr& dst_format) { | |
| 159 switch (dst_format->channels) { | |
| 160 case 1: | |
| 161 return SelectPSM<DType, 1>(src_format, dst_format); | |
| 162 case 2: | |
| 163 return SelectPSM<DType, 2>(src_format, dst_format); | |
| 164 default: | 144 default: |
| 165 return nullptr; | 145 return nullptr; |
| 166 } | 146 } |
| 167 } | 147 } |
| 168 | 148 |
| 169 MixerPtr PointSampler::Select(const LpcmMediaTypeDetailsPtr& src_format, | 149 MixerPtr PointSampler::Select(const LpcmMediaTypeDetailsPtr& src_format, |
| 170 const LpcmMediaTypeDetailsPtr& dst_format) { | 150 const LpcmMediaTypeDetailsPtr& dst_format) { |
| 171 switch (dst_format->sample_format) { | 151 switch (dst_format->channels) { |
| 172 case LpcmSampleFormat::UNSIGNED_8: | 152 case 1: |
| 173 return SelectPSM<uint8_t>(src_format, dst_format); | 153 return SelectPSM<1>(src_format, dst_format); |
| 174 case LpcmSampleFormat::SIGNED_16: | 154 case 2: |
| 175 return SelectPSM<int16_t>(src_format, dst_format); | 155 return SelectPSM<2>(src_format, dst_format); |
| 176 default: | 156 default: |
| 177 return nullptr; | 157 return nullptr; |
| 178 } | 158 } |
| 179 } | 159 } |
| 180 | 160 |
| 181 } // namespace mixers | 161 } // namespace mixers |
| 182 } // namespace audio | 162 } // namespace audio |
| 183 } // namespace media | 163 } // namespace media |
| 184 } // namespace mojo | 164 } // namespace mojo |
| OLD | NEW |