15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/client/audio_decode_scheduler.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/single_thread_task_runner.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/client/audio_player.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/codec/audio_decoder.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/proto/audio.pb.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AudioDecodeScheduler::Core : public base::RefCountedThreadSafe<Core> { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Core(scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner, 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPlayer> audio_player); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Initialize(const protocol::SessionConfig& config); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ProcessAudioPacket(scoped_ptr<AudioPacket> packet, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& done); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by AudioDecodeScheduler when it is destroyed. 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Detach(); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCountedThreadSafe<Core>; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Core(); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called on the audio decoder thread. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DecodePacket(scoped_ptr<AudioPacket> packet, const base::Closure& done); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called on the main thread. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ProcessDecodedPacket(scoped_ptr<AudioPacket> packet, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& done); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner_; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioDecoder> decoder_; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPlayer> audio_player_; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Core); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioDecodeScheduler::Core::Core( 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPlayer> audio_player) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : main_task_runner_(main_task_runner), 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_decode_task_runner_(audio_decode_task_runner), 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_player_(audio_player.Pass()) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioDecodeScheduler::Core::~Core() { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioDecodeScheduler::Core::Initialize( 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const protocol::SessionConfig& config) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(main_task_runner_->BelongsToCurrentThread()); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_.reset(AudioDecoder::CreateAudioDecoder(config).release()); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioDecodeScheduler::Core::ProcessAudioPacket( 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& done) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(main_task_runner_->BelongsToCurrentThread()); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_decode_task_runner_->PostTask(FROM_HERE, base::Bind( 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AudioDecodeScheduler::Core::DecodePacket, this, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Passed(&packet), done)); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioDecodeScheduler::Core::Detach() { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(main_task_runner_->BelongsToCurrentThread()); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_player_.reset(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioDecodeScheduler::Core::DecodePacket( 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& done) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(audio_decode_task_runner_->BelongsToCurrentThread()); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> decoded_packet = decoder_->Decode(packet.Pass()); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) main_task_runner_->PostTask(FROM_HERE, base::Bind( 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AudioDecodeScheduler::Core::ProcessDecodedPacket, this, 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&decoded_packet), done)); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioDecodeScheduler::Core::ProcessDecodedPacket( 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& done) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(main_task_runner_->BelongsToCurrentThread()); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only process |packet| if it is non-NULL. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (packet.get() && audio_player_.get()) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_player_->ProcessAudioPacket(packet.Pass()); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done.Run(); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioDecodeScheduler::AudioDecodeScheduler( 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPlayer> audio_player) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : core_(new Core(main_task_runner, audio_decode_task_runner, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_player.Pass())) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioDecodeScheduler::~AudioDecodeScheduler() { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_->Detach(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioDecodeScheduler::Initialize(const protocol::SessionConfig& config) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_->Initialize(config); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioDecodeScheduler::ProcessAudioPacket(scoped_ptr<AudioPacket> packet, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& done) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_->ProcessAudioPacket(packet.Pass(), done); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 124