| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "webkit/plugins/ppapi/ppb_audio_impl.h" | 5 #include "webkit/plugins/ppapi/ppb_audio_impl.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "ppapi/c/pp_completion_callback.h" | 8 #include "ppapi/c/pp_completion_callback.h" |
| 9 #include "ppapi/c/ppb_audio.h" | 9 #include "ppapi/c/ppb_audio.h" |
| 10 #include "ppapi/c/ppb_audio_config.h" | 10 #include "ppapi/c/ppb_audio_config.h" |
| 11 #include "ppapi/c/trusted/ppb_audio_trusted.h" | 11 #include "ppapi/c/trusted/ppb_audio_trusted.h" |
| 12 #include "ppapi/shared_impl/resource_tracker.h" |
| 13 #include "ppapi/shared_impl/tracker_base.h" |
| 12 #include "ppapi/thunk/enter.h" | 14 #include "ppapi/thunk/enter.h" |
| 13 #include "ppapi/thunk/ppb_audio_config_api.h" | 15 #include "ppapi/thunk/ppb_audio_config_api.h" |
| 14 #include "ppapi/thunk/thunk.h" | 16 #include "ppapi/thunk/thunk.h" |
| 15 #include "webkit/plugins/ppapi/common.h" | 17 #include "webkit/plugins/ppapi/common.h" |
| 18 #include "webkit/plugins/ppapi/resource_helper.h" |
| 16 | 19 |
| 17 using ppapi::thunk::EnterResourceNoLock; | 20 using ppapi::thunk::EnterResourceNoLock; |
| 18 using ppapi::thunk::PPB_Audio_API; | 21 using ppapi::thunk::PPB_Audio_API; |
| 19 using ppapi::thunk::PPB_AudioConfig_API; | 22 using ppapi::thunk::PPB_AudioConfig_API; |
| 20 | 23 |
| 21 namespace webkit { | 24 namespace webkit { |
| 22 namespace ppapi { | 25 namespace ppapi { |
| 23 | 26 |
| 24 // PPB_AudioConfig ------------------------------------------------------------- | 27 // PPB_AudioConfig ------------------------------------------------------------- |
| 25 | 28 |
| 26 PPB_AudioConfig_Impl::PPB_AudioConfig_Impl(PluginInstance* instance) | 29 PPB_AudioConfig_Impl::PPB_AudioConfig_Impl(PP_Instance instance) |
| 27 : Resource(instance) { | 30 : Resource(instance) { |
| 28 } | 31 } |
| 29 | 32 |
| 30 PPB_AudioConfig_Impl::~PPB_AudioConfig_Impl() { | 33 PPB_AudioConfig_Impl::~PPB_AudioConfig_Impl() { |
| 31 } | 34 } |
| 32 | 35 |
| 33 // static | 36 // static |
| 34 PP_Resource PPB_AudioConfig_Impl::Create(PluginInstance* instance, | 37 PP_Resource PPB_AudioConfig_Impl::Create(PP_Instance instance, |
| 35 PP_AudioSampleRate sample_rate, | 38 PP_AudioSampleRate sample_rate, |
| 36 uint32_t sample_frame_count) { | 39 uint32_t sample_frame_count) { |
| 37 scoped_refptr<PPB_AudioConfig_Impl> config( | 40 scoped_refptr<PPB_AudioConfig_Impl> config( |
| 38 new PPB_AudioConfig_Impl(instance)); | 41 new PPB_AudioConfig_Impl(instance)); |
| 39 if (!config->Init(sample_rate, sample_frame_count)) | 42 if (!config->Init(sample_rate, sample_frame_count)) |
| 40 return 0; | 43 return 0; |
| 41 return config->GetReference(); | 44 return config->GetReference(); |
| 42 } | 45 } |
| 43 | 46 |
| 44 PPB_AudioConfig_API* PPB_AudioConfig_Impl::AsPPB_AudioConfig_API() { | 47 PPB_AudioConfig_API* PPB_AudioConfig_Impl::AsPPB_AudioConfig_API() { |
| 45 return this; | 48 return this; |
| 46 } | 49 } |
| 47 | 50 |
| 48 // PPB_Audio_Impl -------------------------------------------------------------- | 51 // PPB_Audio_Impl -------------------------------------------------------------- |
| 49 | 52 |
| 50 PPB_Audio_Impl::PPB_Audio_Impl(PluginInstance* instance) | 53 PPB_Audio_Impl::PPB_Audio_Impl(PP_Instance instance) |
| 51 : Resource(instance), | 54 : Resource(instance), |
| 52 config_id_(0), | |
| 53 audio_(NULL), | 55 audio_(NULL), |
| 54 create_callback_pending_(false), | 56 create_callback_pending_(false), |
| 55 shared_memory_size_for_create_callback_(0) { | 57 shared_memory_size_for_create_callback_(0) { |
| 56 create_callback_ = PP_MakeCompletionCallback(NULL, NULL); | 58 create_callback_ = PP_MakeCompletionCallback(NULL, NULL); |
| 57 } | 59 } |
| 58 | 60 |
| 59 PPB_Audio_Impl::~PPB_Audio_Impl() { | 61 PPB_Audio_Impl::~PPB_Audio_Impl() { |
| 60 if (config_id_) | |
| 61 ResourceTracker::Get()->ReleaseResource(config_id_); | |
| 62 | |
| 63 // Calling ShutDown() makes sure StreamCreated cannot be called anymore and | 62 // Calling ShutDown() makes sure StreamCreated cannot be called anymore and |
| 64 // releases the audio data associated with the pointer. Note however, that | 63 // releases the audio data associated with the pointer. Note however, that |
| 65 // until ShutDown returns, StreamCreated may still be called. This will be | 64 // until ShutDown returns, StreamCreated may still be called. This will be |
| 66 // OK since we'll just immediately clean up the data it stored later in this | 65 // OK since we'll just immediately clean up the data it stored later in this |
| 67 // destructor. | 66 // destructor. |
| 68 if (audio_) { | 67 if (audio_) { |
| 69 audio_->ShutDown(); | 68 audio_->ShutDown(); |
| 70 audio_ = NULL; | 69 audio_ = NULL; |
| 71 } | 70 } |
| 72 | 71 |
| 73 // If the completion callback hasn't fired yet, do so here | 72 // If the completion callback hasn't fired yet, do so here |
| 74 // with an error condition. | 73 // with an error condition. |
| 75 if (create_callback_pending_) { | 74 if (create_callback_pending_) { |
| 76 PP_RunCompletionCallback(&create_callback_, PP_ERROR_ABORTED); | 75 PP_RunCompletionCallback(&create_callback_, PP_ERROR_ABORTED); |
| 77 create_callback_pending_ = false; | 76 create_callback_pending_ = false; |
| 78 } | 77 } |
| 79 } | 78 } |
| 80 | 79 |
| 81 // static | 80 // static |
| 82 PP_Resource PPB_Audio_Impl::Create(PluginInstance* instance, | 81 PP_Resource PPB_Audio_Impl::Create(PP_Instance instance, |
| 83 PP_Resource config_id, | 82 PP_Resource config, |
| 84 PPB_Audio_Callback audio_callback, | 83 PPB_Audio_Callback audio_callback, |
| 85 void* user_data) { | 84 void* user_data) { |
| 86 scoped_refptr<PPB_Audio_Impl> audio(new PPB_Audio_Impl(instance)); | 85 scoped_refptr<PPB_Audio_Impl> audio(new PPB_Audio_Impl(instance)); |
| 87 if (!audio->Init(config_id, audio_callback, user_data)) | 86 if (!audio->Init(config, audio_callback, user_data)) |
| 88 return 0; | 87 return 0; |
| 89 return audio->GetReference(); | 88 return audio->GetReference(); |
| 90 } | 89 } |
| 91 | 90 |
| 92 PPB_Audio_API* PPB_Audio_Impl::AsPPB_Audio_API() { | 91 PPB_Audio_API* PPB_Audio_Impl::AsPPB_Audio_API() { |
| 93 return this; | 92 return this; |
| 94 } | 93 } |
| 95 | 94 |
| 96 bool PPB_Audio_Impl::Init(PP_Resource config_id, | 95 bool PPB_Audio_Impl::Init(PP_Resource config, |
| 97 PPB_Audio_Callback callback, void* user_data) { | 96 PPB_Audio_Callback callback, void* user_data) { |
| 98 // Validate the config and keep a reference to it. | 97 // Validate the config and keep a reference to it. |
| 99 EnterResourceNoLock<PPB_AudioConfig_API> enter(config_id, true); | 98 EnterResourceNoLock<PPB_AudioConfig_API> enter(config, true); |
| 100 if (enter.failed()) | 99 if (enter.failed()) |
| 101 return false; | 100 return false; |
| 102 config_id_ = config_id; | 101 config_ = config; |
| 103 ResourceTracker::Get()->AddRefResource(config_id); | |
| 104 | 102 |
| 105 if (!callback) | 103 if (!callback) |
| 106 return false; | 104 return false; |
| 107 SetCallback(callback, user_data); | 105 SetCallback(callback, user_data); |
| 108 | 106 |
| 107 PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this); |
| 108 if (!plugin_delegate) |
| 109 return false; |
| 110 |
| 109 // When the stream is created, we'll get called back on StreamCreated(). | 111 // When the stream is created, we'll get called back on StreamCreated(). |
| 110 CHECK(!audio_); | 112 CHECK(!audio_); |
| 111 audio_ = instance()->delegate()->CreateAudio( | 113 audio_ = plugin_delegate->CreateAudio(enter.object()->GetSampleRate(), |
| 112 enter.object()->GetSampleRate(), | 114 enter.object()->GetSampleFrameCount(), |
| 113 enter.object()->GetSampleFrameCount(), | 115 this); |
| 114 this); | |
| 115 return audio_ != NULL; | 116 return audio_ != NULL; |
| 116 } | 117 } |
| 117 | 118 |
| 118 PP_Resource PPB_Audio_Impl::GetCurrentConfig() { | 119 PP_Resource PPB_Audio_Impl::GetCurrentConfig() { |
| 119 // AddRef on behalf of caller. | 120 // AddRef on behalf of caller, while keeping a ref for ourselves. |
| 120 ResourceTracker::Get()->AddRefResource(config_id_); | 121 ::ppapi::TrackerBase::Get()->GetResourceTracker()->AddRefResource(config_); |
| 121 return config_id_; | 122 return config_; |
| 122 } | 123 } |
| 123 | 124 |
| 124 PP_Bool PPB_Audio_Impl::StartPlayback() { | 125 PP_Bool PPB_Audio_Impl::StartPlayback() { |
| 125 if (!audio_) | 126 if (!audio_) |
| 126 return PP_FALSE; | 127 return PP_FALSE; |
| 127 if (playing()) | 128 if (playing()) |
| 128 return PP_TRUE; | 129 return PP_TRUE; |
| 129 SetStartPlaybackState(); | 130 SetStartPlaybackState(); |
| 130 return BoolToPPBool(audio_->StartPlayback()); | 131 return BoolToPPBool(audio_->StartPlayback()); |
| 131 } | 132 } |
| 132 | 133 |
| 133 PP_Bool PPB_Audio_Impl::StopPlayback() { | 134 PP_Bool PPB_Audio_Impl::StopPlayback() { |
| 134 if (!audio_) | 135 if (!audio_) |
| 135 return PP_FALSE; | 136 return PP_FALSE; |
| 136 if (!playing()) | 137 if (!playing()) |
| 137 return PP_TRUE; | 138 return PP_TRUE; |
| 138 if (!audio_->StopPlayback()) | 139 if (!audio_->StopPlayback()) |
| 139 return PP_FALSE; | 140 return PP_FALSE; |
| 140 SetStopPlaybackState(); | 141 SetStopPlaybackState(); |
| 141 return PP_TRUE; | 142 return PP_TRUE; |
| 142 } | 143 } |
| 143 | 144 |
| 144 int32_t PPB_Audio_Impl::OpenTrusted(PP_Resource config_id, | 145 int32_t PPB_Audio_Impl::OpenTrusted(PP_Resource config, |
| 145 PP_CompletionCallback create_callback) { | 146 PP_CompletionCallback create_callback) { |
| 147 // Validate the config and keep a reference to it. |
| 148 EnterResourceNoLock<PPB_AudioConfig_API> enter(config, true); |
| 149 if (enter.failed()) |
| 150 return PP_ERROR_FAILED; |
| 151 config_ = config; |
| 146 | 152 |
| 147 // Validate the config and keep a reference to it. | 153 PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this); |
| 148 EnterResourceNoLock<PPB_AudioConfig_API> enter(config_id, true); | 154 if (!plugin_delegate) |
| 149 if (enter.failed()) | 155 return PP_ERROR_FAILED; |
| 150 return false; | |
| 151 config_id_ = config_id; | |
| 152 ResourceTracker::Get()->AddRefResource(config_id); | |
| 153 | 156 |
| 154 // When the stream is created, we'll get called back on StreamCreated(). | 157 // When the stream is created, we'll get called back on StreamCreated(). |
| 155 DCHECK(!audio_); | 158 DCHECK(!audio_); |
| 156 audio_ = instance()->delegate()->CreateAudio( | 159 audio_ = plugin_delegate->CreateAudio(enter.object()->GetSampleRate(), |
| 157 enter.object()->GetSampleRate(), | 160 enter.object()->GetSampleFrameCount(), |
| 158 enter.object()->GetSampleFrameCount(), | 161 this); |
| 159 this); | |
| 160 if (!audio_) | 162 if (!audio_) |
| 161 return PP_ERROR_FAILED; | 163 return PP_ERROR_FAILED; |
| 162 | 164 |
| 163 // At this point, we are guaranteeing ownership of the completion | 165 // At this point, we are guaranteeing ownership of the completion |
| 164 // callback. Audio promises to fire the completion callback | 166 // callback. Audio promises to fire the completion callback |
| 165 // once and only once. | 167 // once and only once. |
| 166 create_callback_ = create_callback; | 168 create_callback_ = create_callback; |
| 167 create_callback_pending_ = true; | 169 create_callback_pending_ = true; |
| 168 return PP_OK_COMPLETIONPENDING; | 170 return PP_OK_COMPLETIONPENDING; |
| 169 } | 171 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 // something more elaborate like an ACK from the plugin or post a task to | 223 // something more elaborate like an ACK from the plugin or post a task to |
| 222 // the I/O thread and back, but this extra complexity doesn't seem worth it | 224 // the I/O thread and back, but this extra complexity doesn't seem worth it |
| 223 // just to clean up these handles faster. | 225 // just to clean up these handles faster. |
| 224 } else { | 226 } else { |
| 225 SetStreamInfo(shared_memory_handle, shared_memory_size, socket_handle); | 227 SetStreamInfo(shared_memory_handle, shared_memory_size, socket_handle); |
| 226 } | 228 } |
| 227 } | 229 } |
| 228 | 230 |
| 229 } // namespace ppapi | 231 } // namespace ppapi |
| 230 } // namespace webkit | 232 } // namespace webkit |
| OLD | NEW |