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)#ifndef PPAPI_SHARED_IMPL_PPB_AUDIO_SHARED_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_SHARED_IMPL_PPB_AUDIO_SHARED_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/memory/shared_memory.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sync_socket.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/simple_thread.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/audio_bus.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_audio.h" 1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ppapi/c/ppb_audio_config.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/resource.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/ppb_audio_api.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_NACL) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/untrusted/irt/irt_ppapi.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class PPAPI_SHARED_EXPORT AudioCallbackCombined { 2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public: 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AudioCallbackCombined(); 2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) explicit AudioCallbackCombined(PPB_Audio_Callback_1_0 callback_1_0); 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) explicit AudioCallbackCombined(PPB_Audio_Callback callback); 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ~AudioCallbackCombined(); 3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool IsValid() const; 3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void Run(void* sample_buffer, 3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) uint32_t buffer_size_in_bytes, 3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) PP_TimeDelta latency, 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void* user_data) const; 3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private: 4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) PPB_Audio_Callback_1_0 callback_1_0_; 4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) PPB_Audio_Callback callback_; 4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implements the logic to map shared memory and run the audio thread signaled 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from the sync socket. Both the proxy and the renderer implementation use 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this code. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPAPI_SHARED_EXPORT PPB_Audio_Shared 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public thunk::PPB_Audio_API, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::DelegateSimpleThread::Delegate { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PPB_Audio_Shared(); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~PPB_Audio_Shared(); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool playing() const { return playing_; } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets the callback information that the background thread will use. This 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is optional. Without a callback, the thread will not be run. This 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // non-callback mode is used in the renderer with the proxy, since the proxy 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // handles the callback entirely within the plugin process. 6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void SetCallback(const AudioCallbackCombined& callback, void* user_data); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Configures the current state to be playing or not. The caller is 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // responsible for ensuring the new state is the opposite of the current one. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the implementation for PPB_Audio.Start/StopPlayback, except that 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it does not actually notify the audio system to stop playback, it just 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // configures our object to stop generating callbacks. The actual stop 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // playback request will be done in the derived classes and will be different 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the proxy and the renderer. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetStartPlaybackState(); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetStopPlaybackState(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets the shared memory and socket handles. This will automatically start 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // playback if we're currently set to play. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetStreamInfo(PP_Instance instance, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle shared_memory_handle, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t shared_memory_size, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SyncSocket::Handle socket_handle, 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) PP_AudioSampleRate sample_rate, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sample_frame_count); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_NACL) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NaCl has a special API for IRT code to create threads that can call back 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // into user code. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void SetThreadFunctions(const struct PP_ThreadFunctions* functions); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Starts execution of the audio thread. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartThread(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop execution of the audio thread. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StopThread(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DelegateSimpleThread::Delegate implementation. Run on the audio thread. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Run(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // True if playing the stream. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool playing_; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Socket used to notify us when audio is ready to accept new samples. This 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pointer is created in StreamCreated(). 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::CancelableSyncSocket> socket_; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sample buffer in shared memory. This pointer is created in 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // StreamCreated(). The memory is only mapped when the audio thread is 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // created. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::SharedMemory> shared_memory_; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The size of the sample buffer in bytes. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t shared_memory_size_; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_NACL) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When the callback is set, this thread is spawned for calling it. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::DelegateSimpleThread> audio_thread_; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uintptr_t thread_id_; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool thread_active_; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void CallRun(void* self); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callback to call when audio is ready to accept new samples. 12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AudioCallbackCombined callback_; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // User data pointer passed verbatim to the callback function. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* user_data_; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AudioBus for shuttling data across the shared memory. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<media::AudioBus> audio_bus_; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Internal buffer for client's integer audio data. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int client_buffer_size_bytes_; 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<uint8_t[]> client_buffer_; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The size (in bytes) of one second of audio data. Used to calculate latency. 13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) size_t bytes_per_second_; 13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Buffer index used to coordinate with the browser side audio receiver. 1400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) uint32_t buffer_index_; 1410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PPB_Audio_Shared); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // PPAPI_SHARED_IMPL_PPB_AUDIO_SHARED_H_ 148