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

Unified Diff: media/cast/audio_receiver/audio_decoder.cc

Issue 308043006: [Cast] Clean-up: Merge RtpReceiver+AudioReceiver+VideoReceiver-->FrameReceiver. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed hclam's comments. Created 6 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/cast/audio_receiver/audio_decoder.h ('k') | media/cast/audio_receiver/audio_decoder_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/cast/audio_receiver/audio_decoder.cc
diff --git a/media/cast/audio_receiver/audio_decoder.cc b/media/cast/audio_receiver/audio_decoder.cc
deleted file mode 100644
index e4e9a1453eb68d71b96cb90a560de9698e97e874..0000000000000000000000000000000000000000
--- a/media/cast/audio_receiver/audio_decoder.cc
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/cast/audio_receiver/audio_decoder.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "base/sys_byteorder.h"
-#include "media/cast/cast_defines.h"
-#include "third_party/opus/src/include/opus.h"
-
-namespace media {
-namespace cast {
-
-// Base class that handles the common problem of detecting dropped frames, and
-// then invoking the Decode() method implemented by the subclasses to convert
-// the encoded payload data into usable audio data.
-class AudioDecoder::ImplBase
- : public base::RefCountedThreadSafe<AudioDecoder::ImplBase> {
- public:
- ImplBase(const scoped_refptr<CastEnvironment>& cast_environment,
- transport::AudioCodec codec,
- int num_channels,
- int sampling_rate)
- : cast_environment_(cast_environment),
- codec_(codec),
- num_channels_(num_channels),
- cast_initialization_status_(STATUS_AUDIO_UNINITIALIZED),
- seen_first_frame_(false) {
- if (num_channels_ <= 0 || sampling_rate <= 0 || sampling_rate % 100 != 0)
- cast_initialization_status_ = STATUS_INVALID_AUDIO_CONFIGURATION;
- }
-
- CastInitializationStatus InitializationResult() const {
- return cast_initialization_status_;
- }
-
- void DecodeFrame(scoped_ptr<transport::EncodedFrame> encoded_frame,
- const DecodeFrameCallback& callback) {
- DCHECK_EQ(cast_initialization_status_, STATUS_AUDIO_INITIALIZED);
-
- COMPILE_ASSERT(sizeof(encoded_frame->frame_id) == sizeof(last_frame_id_),
- size_of_frame_id_types_do_not_match);
- bool is_continuous = true;
- if (seen_first_frame_) {
- const uint32 frames_ahead = encoded_frame->frame_id - last_frame_id_;
- if (frames_ahead > 1) {
- RecoverBecauseFramesWereDropped();
- is_continuous = false;
- }
- } else {
- seen_first_frame_ = true;
- }
- last_frame_id_ = encoded_frame->frame_id;
-
- scoped_ptr<AudioBus> decoded_audio = Decode(
- encoded_frame->mutable_bytes(),
- static_cast<int>(encoded_frame->data.size()));
- cast_environment_->PostTask(CastEnvironment::MAIN,
- FROM_HERE,
- base::Bind(callback,
- base::Passed(&decoded_audio),
- is_continuous));
- }
-
- protected:
- friend class base::RefCountedThreadSafe<ImplBase>;
- virtual ~ImplBase() {}
-
- virtual void RecoverBecauseFramesWereDropped() {}
-
- // Note: Implementation of Decode() is allowed to mutate |data|.
- virtual scoped_ptr<AudioBus> Decode(uint8* data, int len) = 0;
-
- const scoped_refptr<CastEnvironment> cast_environment_;
- const transport::AudioCodec codec_;
- const int num_channels_;
-
- // Subclass' ctor is expected to set this to STATUS_AUDIO_INITIALIZED.
- CastInitializationStatus cast_initialization_status_;
-
- private:
- bool seen_first_frame_;
- uint32 last_frame_id_;
-
- DISALLOW_COPY_AND_ASSIGN(ImplBase);
-};
-
-class AudioDecoder::OpusImpl : public AudioDecoder::ImplBase {
- public:
- OpusImpl(const scoped_refptr<CastEnvironment>& cast_environment,
- int num_channels,
- int sampling_rate)
- : ImplBase(cast_environment,
- transport::kOpus,
- num_channels,
- sampling_rate),
- decoder_memory_(new uint8[opus_decoder_get_size(num_channels)]),
- opus_decoder_(reinterpret_cast<OpusDecoder*>(decoder_memory_.get())),
- max_samples_per_frame_(
- kOpusMaxFrameDurationMillis * sampling_rate / 1000),
- buffer_(new float[max_samples_per_frame_ * num_channels]) {
- if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED)
- return;
- if (opus_decoder_init(opus_decoder_, sampling_rate, num_channels) !=
- OPUS_OK) {
- ImplBase::cast_initialization_status_ =
- STATUS_INVALID_AUDIO_CONFIGURATION;
- return;
- }
- ImplBase::cast_initialization_status_ = STATUS_AUDIO_INITIALIZED;
- }
-
- private:
- virtual ~OpusImpl() {}
-
- virtual void RecoverBecauseFramesWereDropped() OVERRIDE {
- // Passing NULL for the input data notifies the decoder of frame loss.
- const opus_int32 result =
- opus_decode_float(
- opus_decoder_, NULL, 0, buffer_.get(), max_samples_per_frame_, 0);
- DCHECK_GE(result, 0);
- }
-
- virtual scoped_ptr<AudioBus> Decode(uint8* data, int len) OVERRIDE {
- scoped_ptr<AudioBus> audio_bus;
- const opus_int32 num_samples_decoded = opus_decode_float(
- opus_decoder_, data, len, buffer_.get(), max_samples_per_frame_, 0);
- if (num_samples_decoded <= 0)
- return audio_bus.Pass(); // Decode error.
-
- // Copy interleaved samples from |buffer_| into a new AudioBus (where
- // samples are stored in planar format, for each channel).
- audio_bus = AudioBus::Create(num_channels_, num_samples_decoded).Pass();
- // TODO(miu): This should be moved into AudioBus::FromInterleaved().
- for (int ch = 0; ch < num_channels_; ++ch) {
- const float* src = buffer_.get() + ch;
- const float* const src_end = src + num_samples_decoded * num_channels_;
- float* dest = audio_bus->channel(ch);
- for (; src < src_end; src += num_channels_, ++dest)
- *dest = *src;
- }
- return audio_bus.Pass();
- }
-
- const scoped_ptr<uint8[]> decoder_memory_;
- OpusDecoder* const opus_decoder_;
- const int max_samples_per_frame_;
- const scoped_ptr<float[]> buffer_;
-
- // According to documentation in third_party/opus/src/include/opus.h, we must
- // provide enough space in |buffer_| to contain 120ms of samples. At 48 kHz,
- // then, that means 5760 samples times the number of channels.
- static const int kOpusMaxFrameDurationMillis = 120;
-
- DISALLOW_COPY_AND_ASSIGN(OpusImpl);
-};
-
-class AudioDecoder::Pcm16Impl : public AudioDecoder::ImplBase {
- public:
- Pcm16Impl(const scoped_refptr<CastEnvironment>& cast_environment,
- int num_channels,
- int sampling_rate)
- : ImplBase(cast_environment,
- transport::kPcm16,
- num_channels,
- sampling_rate) {
- if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED)
- return;
- ImplBase::cast_initialization_status_ = STATUS_AUDIO_INITIALIZED;
- }
-
- private:
- virtual ~Pcm16Impl() {}
-
- virtual scoped_ptr<AudioBus> Decode(uint8* data, int len) OVERRIDE {
- scoped_ptr<AudioBus> audio_bus;
- const int num_samples = len / sizeof(int16) / num_channels_;
- if (num_samples <= 0)
- return audio_bus.Pass();
-
- int16* const pcm_data = reinterpret_cast<int16*>(data);
-#if defined(ARCH_CPU_LITTLE_ENDIAN)
- // Convert endianness.
- const int num_elements = num_samples * num_channels_;
- for (int i = 0; i < num_elements; ++i)
- pcm_data[i] = static_cast<int16>(base::NetToHost16(pcm_data[i]));
-#endif
- audio_bus = AudioBus::Create(num_channels_, num_samples).Pass();
- audio_bus->FromInterleaved(pcm_data, num_samples, sizeof(int16));
- return audio_bus.Pass();
- }
-
- DISALLOW_COPY_AND_ASSIGN(Pcm16Impl);
-};
-
-AudioDecoder::AudioDecoder(
- const scoped_refptr<CastEnvironment>& cast_environment,
- const FrameReceiverConfig& audio_config)
- : cast_environment_(cast_environment) {
- switch (audio_config.codec.audio) {
- case transport::kOpus:
- impl_ = new OpusImpl(cast_environment,
- audio_config.channels,
- audio_config.frequency);
- break;
- case transport::kPcm16:
- impl_ = new Pcm16Impl(cast_environment,
- audio_config.channels,
- audio_config.frequency);
- break;
- default:
- NOTREACHED() << "Unknown or unspecified codec.";
- break;
- }
-}
-
-AudioDecoder::~AudioDecoder() {}
-
-CastInitializationStatus AudioDecoder::InitializationResult() const {
- if (impl_)
- return impl_->InitializationResult();
- return STATUS_UNSUPPORTED_AUDIO_CODEC;
-}
-
-void AudioDecoder::DecodeFrame(
- scoped_ptr<transport::EncodedFrame> encoded_frame,
- const DecodeFrameCallback& callback) {
- DCHECK(encoded_frame.get());
- DCHECK(!callback.is_null());
- if (!impl_ || impl_->InitializationResult() != STATUS_AUDIO_INITIALIZED) {
- callback.Run(make_scoped_ptr<AudioBus>(NULL), false);
- return;
- }
- cast_environment_->PostTask(CastEnvironment::AUDIO,
- FROM_HERE,
- base::Bind(&AudioDecoder::ImplBase::DecodeFrame,
- impl_,
- base::Passed(&encoded_frame),
- callback));
-}
-
-} // namespace cast
-} // namespace media
« no previous file with comments | « media/cast/audio_receiver/audio_decoder.h ('k') | media/cast/audio_receiver/audio_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698