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

Side by Side Diff: media/cast/receiver/audio_decoder.cc

Issue 1905763002: Convert //media/cast from scoped_ptr to std::unique_ptr (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « media/cast/receiver/audio_decoder.h ('k') | media/cast/receiver/audio_decoder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/cast/receiver/audio_decoder.h" 5 #include "media/cast/receiver/audio_decoder.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8
8 #include <utility> 9 #include <utility>
9 10
10 #include "base/bind.h" 11 #include "base/bind.h"
11 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
12 #include "base/location.h" 13 #include "base/location.h"
13 #include "base/logging.h" 14 #include "base/logging.h"
14 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/ptr_util.h"
15 #include "base/sys_byteorder.h" 17 #include "base/sys_byteorder.h"
16 #include "build/build_config.h" 18 #include "build/build_config.h"
17 #include "third_party/opus/src/include/opus.h" 19 #include "third_party/opus/src/include/opus.h"
18 20
19 namespace media { 21 namespace media {
20 namespace cast { 22 namespace cast {
21 23
22 // Base class that handles the common problem of detecting dropped frames, and 24 // Base class that handles the common problem of detecting dropped frames, and
23 // then invoking the Decode() method implemented by the subclasses to convert 25 // then invoking the Decode() method implemented by the subclasses to convert
24 // the encoded payload data into usable audio data. 26 // the encoded payload data into usable audio data.
(...skipping 10 matching lines...) Expand all
35 operational_status_(STATUS_UNINITIALIZED), 37 operational_status_(STATUS_UNINITIALIZED),
36 seen_first_frame_(false) { 38 seen_first_frame_(false) {
37 if (num_channels_ <= 0 || sampling_rate <= 0 || sampling_rate % 100 != 0) 39 if (num_channels_ <= 0 || sampling_rate <= 0 || sampling_rate % 100 != 0)
38 operational_status_ = STATUS_INVALID_CONFIGURATION; 40 operational_status_ = STATUS_INVALID_CONFIGURATION;
39 } 41 }
40 42
41 OperationalStatus InitializationResult() const { 43 OperationalStatus InitializationResult() const {
42 return operational_status_; 44 return operational_status_;
43 } 45 }
44 46
45 void DecodeFrame(scoped_ptr<EncodedFrame> encoded_frame, 47 void DecodeFrame(std::unique_ptr<EncodedFrame> encoded_frame,
46 const DecodeFrameCallback& callback) { 48 const DecodeFrameCallback& callback) {
47 DCHECK_EQ(operational_status_, STATUS_INITIALIZED); 49 DCHECK_EQ(operational_status_, STATUS_INITIALIZED);
48 50
49 static_assert(sizeof(encoded_frame->frame_id) == sizeof(last_frame_id_), 51 static_assert(sizeof(encoded_frame->frame_id) == sizeof(last_frame_id_),
50 "size of frame_id types do not match"); 52 "size of frame_id types do not match");
51 bool is_continuous = true; 53 bool is_continuous = true;
52 if (seen_first_frame_) { 54 if (seen_first_frame_) {
53 const uint32_t frames_ahead = encoded_frame->frame_id - last_frame_id_; 55 const uint32_t frames_ahead = encoded_frame->frame_id - last_frame_id_;
54 if (frames_ahead > 1) { 56 if (frames_ahead > 1) {
55 RecoverBecauseFramesWereDropped(); 57 RecoverBecauseFramesWereDropped();
56 is_continuous = false; 58 is_continuous = false;
57 } 59 }
58 } else { 60 } else {
59 seen_first_frame_ = true; 61 seen_first_frame_ = true;
60 } 62 }
61 last_frame_id_ = encoded_frame->frame_id; 63 last_frame_id_ = encoded_frame->frame_id;
62 64
63 scoped_ptr<AudioBus> decoded_audio = Decode( 65 std::unique_ptr<AudioBus> decoded_audio =
64 encoded_frame->mutable_bytes(), 66 Decode(encoded_frame->mutable_bytes(),
65 static_cast<int>(encoded_frame->data.size())); 67 static_cast<int>(encoded_frame->data.size()));
66 68
67 scoped_ptr<FrameEvent> event(new FrameEvent()); 69 std::unique_ptr<FrameEvent> event(new FrameEvent());
68 event->timestamp = cast_environment_->Clock()->NowTicks(); 70 event->timestamp = cast_environment_->Clock()->NowTicks();
69 event->type = FRAME_DECODED; 71 event->type = FRAME_DECODED;
70 event->media_type = AUDIO_EVENT; 72 event->media_type = AUDIO_EVENT;
71 event->rtp_timestamp = encoded_frame->rtp_timestamp; 73 event->rtp_timestamp = encoded_frame->rtp_timestamp;
72 event->frame_id = encoded_frame->frame_id; 74 event->frame_id = encoded_frame->frame_id;
73 cast_environment_->logger()->DispatchFrameEvent(std::move(event)); 75 cast_environment_->logger()->DispatchFrameEvent(std::move(event));
74 76
75 cast_environment_->PostTask(CastEnvironment::MAIN, 77 cast_environment_->PostTask(CastEnvironment::MAIN,
76 FROM_HERE, 78 FROM_HERE,
77 base::Bind(callback, 79 base::Bind(callback,
78 base::Passed(&decoded_audio), 80 base::Passed(&decoded_audio),
79 is_continuous)); 81 is_continuous));
80 } 82 }
81 83
82 protected: 84 protected:
83 friend class base::RefCountedThreadSafe<ImplBase>; 85 friend class base::RefCountedThreadSafe<ImplBase>;
84 virtual ~ImplBase() {} 86 virtual ~ImplBase() {}
85 87
86 virtual void RecoverBecauseFramesWereDropped() {} 88 virtual void RecoverBecauseFramesWereDropped() {}
87 89
88 // Note: Implementation of Decode() is allowed to mutate |data|. 90 // Note: Implementation of Decode() is allowed to mutate |data|.
89 virtual scoped_ptr<AudioBus> Decode(uint8_t* data, int len) = 0; 91 virtual std::unique_ptr<AudioBus> Decode(uint8_t* data, int len) = 0;
90 92
91 const scoped_refptr<CastEnvironment> cast_environment_; 93 const scoped_refptr<CastEnvironment> cast_environment_;
92 const Codec codec_; 94 const Codec codec_;
93 const int num_channels_; 95 const int num_channels_;
94 96
95 // Subclass' ctor is expected to set this to STATUS_INITIALIZED. 97 // Subclass' ctor is expected to set this to STATUS_INITIALIZED.
96 OperationalStatus operational_status_; 98 OperationalStatus operational_status_;
97 99
98 private: 100 private:
99 bool seen_first_frame_; 101 bool seen_first_frame_;
(...skipping 30 matching lines...) Expand all
130 ~OpusImpl() final {} 132 ~OpusImpl() final {}
131 133
132 void RecoverBecauseFramesWereDropped() final { 134 void RecoverBecauseFramesWereDropped() final {
133 // Passing NULL for the input data notifies the decoder of frame loss. 135 // Passing NULL for the input data notifies the decoder of frame loss.
134 const opus_int32 result = 136 const opus_int32 result =
135 opus_decode_float( 137 opus_decode_float(
136 opus_decoder_, NULL, 0, buffer_.get(), max_samples_per_frame_, 0); 138 opus_decoder_, NULL, 0, buffer_.get(), max_samples_per_frame_, 0);
137 DCHECK_GE(result, 0); 139 DCHECK_GE(result, 0);
138 } 140 }
139 141
140 scoped_ptr<AudioBus> Decode(uint8_t* data, int len) final { 142 std::unique_ptr<AudioBus> Decode(uint8_t* data, int len) final {
141 scoped_ptr<AudioBus> audio_bus; 143 std::unique_ptr<AudioBus> audio_bus;
142 const opus_int32 num_samples_decoded = opus_decode_float( 144 const opus_int32 num_samples_decoded = opus_decode_float(
143 opus_decoder_, data, len, buffer_.get(), max_samples_per_frame_, 0); 145 opus_decoder_, data, len, buffer_.get(), max_samples_per_frame_, 0);
144 if (num_samples_decoded <= 0) 146 if (num_samples_decoded <= 0)
145 return audio_bus; // Decode error. 147 return audio_bus; // Decode error.
146 148
147 // Copy interleaved samples from |buffer_| into a new AudioBus (where 149 // Copy interleaved samples from |buffer_| into a new AudioBus (where
148 // samples are stored in planar format, for each channel). 150 // samples are stored in planar format, for each channel).
149 audio_bus = AudioBus::Create(num_channels_, num_samples_decoded); 151 audio_bus = AudioBus::Create(num_channels_, num_samples_decoded);
150 // TODO(miu): This should be moved into AudioBus::FromInterleaved(). 152 // TODO(miu): This should be moved into AudioBus::FromInterleaved().
151 for (int ch = 0; ch < num_channels_; ++ch) { 153 for (int ch = 0; ch < num_channels_; ++ch) {
152 const float* src = buffer_.get() + ch; 154 const float* src = buffer_.get() + ch;
153 const float* const src_end = src + num_samples_decoded * num_channels_; 155 const float* const src_end = src + num_samples_decoded * num_channels_;
154 float* dest = audio_bus->channel(ch); 156 float* dest = audio_bus->channel(ch);
155 for (; src < src_end; src += num_channels_, ++dest) 157 for (; src < src_end; src += num_channels_, ++dest)
156 *dest = *src; 158 *dest = *src;
157 } 159 }
158 return audio_bus; 160 return audio_bus;
159 } 161 }
160 162
161 const scoped_ptr<uint8_t[]> decoder_memory_; 163 const std::unique_ptr<uint8_t[]> decoder_memory_;
162 OpusDecoder* const opus_decoder_; 164 OpusDecoder* const opus_decoder_;
163 const int max_samples_per_frame_; 165 const int max_samples_per_frame_;
164 const scoped_ptr<float[]> buffer_; 166 const std::unique_ptr<float[]> buffer_;
165 167
166 // According to documentation in third_party/opus/src/include/opus.h, we must 168 // According to documentation in third_party/opus/src/include/opus.h, we must
167 // provide enough space in |buffer_| to contain 120ms of samples. At 48 kHz, 169 // provide enough space in |buffer_| to contain 120ms of samples. At 48 kHz,
168 // then, that means 5760 samples times the number of channels. 170 // then, that means 5760 samples times the number of channels.
169 static const int kOpusMaxFrameDurationMillis = 120; 171 static const int kOpusMaxFrameDurationMillis = 120;
170 172
171 DISALLOW_COPY_AND_ASSIGN(OpusImpl); 173 DISALLOW_COPY_AND_ASSIGN(OpusImpl);
172 }; 174 };
173 175
174 class AudioDecoder::Pcm16Impl : public AudioDecoder::ImplBase { 176 class AudioDecoder::Pcm16Impl : public AudioDecoder::ImplBase {
175 public: 177 public:
176 Pcm16Impl(const scoped_refptr<CastEnvironment>& cast_environment, 178 Pcm16Impl(const scoped_refptr<CastEnvironment>& cast_environment,
177 int num_channels, 179 int num_channels,
178 int sampling_rate) 180 int sampling_rate)
179 : ImplBase(cast_environment, 181 : ImplBase(cast_environment,
180 CODEC_AUDIO_PCM16, 182 CODEC_AUDIO_PCM16,
181 num_channels, 183 num_channels,
182 sampling_rate) { 184 sampling_rate) {
183 if (ImplBase::operational_status_ != STATUS_UNINITIALIZED) 185 if (ImplBase::operational_status_ != STATUS_UNINITIALIZED)
184 return; 186 return;
185 ImplBase::operational_status_ = STATUS_INITIALIZED; 187 ImplBase::operational_status_ = STATUS_INITIALIZED;
186 } 188 }
187 189
188 private: 190 private:
189 ~Pcm16Impl() final {} 191 ~Pcm16Impl() final {}
190 192
191 scoped_ptr<AudioBus> Decode(uint8_t* data, int len) final { 193 std::unique_ptr<AudioBus> Decode(uint8_t* data, int len) final {
192 scoped_ptr<AudioBus> audio_bus; 194 std::unique_ptr<AudioBus> audio_bus;
193 const int num_samples = len / sizeof(int16_t) / num_channels_; 195 const int num_samples = len / sizeof(int16_t) / num_channels_;
194 if (num_samples <= 0) 196 if (num_samples <= 0)
195 return audio_bus; 197 return audio_bus;
196 198
197 int16_t* const pcm_data = reinterpret_cast<int16_t*>(data); 199 int16_t* const pcm_data = reinterpret_cast<int16_t*>(data);
198 #if defined(ARCH_CPU_LITTLE_ENDIAN) 200 #if defined(ARCH_CPU_LITTLE_ENDIAN)
199 // Convert endianness. 201 // Convert endianness.
200 const int num_elements = num_samples * num_channels_; 202 const int num_elements = num_samples * num_channels_;
201 for (int i = 0; i < num_elements; ++i) 203 for (int i = 0; i < num_elements; ++i)
202 pcm_data[i] = static_cast<int16_t>(base::NetToHost16(pcm_data[i])); 204 pcm_data[i] = static_cast<int16_t>(base::NetToHost16(pcm_data[i]));
(...skipping 26 matching lines...) Expand all
229 } 231 }
230 232
231 AudioDecoder::~AudioDecoder() {} 233 AudioDecoder::~AudioDecoder() {}
232 234
233 OperationalStatus AudioDecoder::InitializationResult() const { 235 OperationalStatus AudioDecoder::InitializationResult() const {
234 if (impl_.get()) 236 if (impl_.get())
235 return impl_->InitializationResult(); 237 return impl_->InitializationResult();
236 return STATUS_UNSUPPORTED_CODEC; 238 return STATUS_UNSUPPORTED_CODEC;
237 } 239 }
238 240
239 void AudioDecoder::DecodeFrame( 241 void AudioDecoder::DecodeFrame(std::unique_ptr<EncodedFrame> encoded_frame,
240 scoped_ptr<EncodedFrame> encoded_frame, 242 const DecodeFrameCallback& callback) {
241 const DecodeFrameCallback& callback) {
242 DCHECK(encoded_frame.get()); 243 DCHECK(encoded_frame.get());
243 DCHECK(!callback.is_null()); 244 DCHECK(!callback.is_null());
244 if (!impl_.get() || impl_->InitializationResult() != STATUS_INITIALIZED) { 245 if (!impl_.get() || impl_->InitializationResult() != STATUS_INITIALIZED) {
245 callback.Run(make_scoped_ptr<AudioBus>(NULL), false); 246 callback.Run(base::WrapUnique<AudioBus>(NULL), false);
246 return; 247 return;
247 } 248 }
248 cast_environment_->PostTask(CastEnvironment::AUDIO, 249 cast_environment_->PostTask(CastEnvironment::AUDIO,
249 FROM_HERE, 250 FROM_HERE,
250 base::Bind(&AudioDecoder::ImplBase::DecodeFrame, 251 base::Bind(&AudioDecoder::ImplBase::DecodeFrame,
251 impl_, 252 impl_,
252 base::Passed(&encoded_frame), 253 base::Passed(&encoded_frame),
253 callback)); 254 callback));
254 } 255 }
255 256
256 } // namespace cast 257 } // namespace cast
257 } // namespace media 258 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/receiver/audio_decoder.h ('k') | media/cast/receiver/audio_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698