media_stream_audio_track_resource.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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 3// found in the LICENSE file. 4 5#include "ppapi/proxy/media_stream_audio_track_resource.h" 6 7#include "ppapi/proxy/audio_buffer_resource.h" 8#include "ppapi/shared_impl/media_stream_buffer.h" 9#include "ppapi/shared_impl/var.h" 10 11namespace ppapi { 12namespace proxy { 13 14MediaStreamAudioTrackResource::MediaStreamAudioTrackResource( 15 Connection connection, 16 PP_Instance instance, 17 int pending_renderer_id, 18 const std::string& id) 19 : MediaStreamTrackResourceBase( 20 connection, instance, pending_renderer_id, id), 21 get_buffer_output_(NULL) { 22} 23 24MediaStreamAudioTrackResource::~MediaStreamAudioTrackResource() { 25 Close(); 26} 27 28thunk::PPB_MediaStreamAudioTrack_API* 29MediaStreamAudioTrackResource::AsPPB_MediaStreamAudioTrack_API() { 30 return this; 31} 32 33PP_Var MediaStreamAudioTrackResource::GetId() { 34 return StringVar::StringToPPVar(id()); 35} 36 37PP_Bool MediaStreamAudioTrackResource::HasEnded() { 38 return PP_FromBool(has_ended()); 39} 40 41int32_t MediaStreamAudioTrackResource::Configure( 42 const int32_t attrib_list[], 43 scoped_refptr<TrackedCallback> callback) { 44 // TODO(penghuang): Implement this function. 45 return PP_ERROR_NOTSUPPORTED; 46} 47 48int32_t MediaStreamAudioTrackResource::GetAttrib( 49 PP_MediaStreamAudioTrack_Attrib attrib, 50 int32_t* value) { 51 // TODO(penghuang): Implement this function. 52 return PP_ERROR_NOTSUPPORTED; 53} 54 55int32_t MediaStreamAudioTrackResource::GetBuffer( 56 PP_Resource* buffer, 57 scoped_refptr<TrackedCallback> callback) { 58 if (has_ended()) 59 return PP_ERROR_FAILED; 60 61 if (TrackedCallback::IsPending(get_buffer_callback_)) 62 return PP_ERROR_INPROGRESS; 63 64 *buffer = GetAudioBuffer(); 65 if (*buffer) 66 return PP_OK; 67 68 // TODO(penghuang): Use the callback as hints to determine which thread will 69 // use the resource, so we could deliver buffers to the target thread directly 70 // for better performance. 71 get_buffer_output_ = buffer; 72 get_buffer_callback_ = callback; 73 return PP_OK_COMPLETIONPENDING; 74} 75 76int32_t MediaStreamAudioTrackResource::RecycleBuffer(PP_Resource buffer) { 77 BufferMap::iterator it = buffers_.find(buffer); 78 if (it == buffers_.end()) 79 return PP_ERROR_BADRESOURCE; 80 81 scoped_refptr<AudioBufferResource> buffer_resource = it->second; 82 buffers_.erase(it); 83 84 if (has_ended()) 85 return PP_OK; 86 87 DCHECK_GE(buffer_resource->GetBufferIndex(), 0); 88 89 SendEnqueueBufferMessageToHost(buffer_resource->GetBufferIndex()); 90 buffer_resource->Invalidate(); 91 return PP_OK; 92} 93 94void MediaStreamAudioTrackResource::Close() { 95 if (has_ended()) 96 return; 97 98 if (TrackedCallback::IsPending(get_buffer_callback_)) { 99 *get_buffer_output_ = 0; 100 get_buffer_callback_->PostAbort(); 101 get_buffer_callback_ = NULL; 102 get_buffer_output_ = 0; 103 } 104 105 ReleaseBuffers(); 106 MediaStreamTrackResourceBase::CloseInternal(); 107} 108 109void MediaStreamAudioTrackResource::OnNewBufferEnqueued() { 110 if (!TrackedCallback::IsPending(get_buffer_callback_)) 111 return; 112 113 *get_buffer_output_ = GetAudioBuffer(); 114 int32_t result = *get_buffer_output_ ? PP_OK : PP_ERROR_FAILED; 115 get_buffer_output_ = NULL; 116 scoped_refptr<TrackedCallback> callback; 117 callback.swap(get_buffer_callback_); 118 callback->Run(result); 119} 120 121PP_Resource MediaStreamAudioTrackResource::GetAudioBuffer() { 122 int32_t index = buffer_manager()->DequeueBuffer(); 123 if (index < 0) 124 return 0; 125 126 MediaStreamBuffer* buffer = buffer_manager()->GetBufferPointer(index); 127 DCHECK(buffer); 128 scoped_refptr<AudioBufferResource> resource = 129 new AudioBufferResource(pp_instance(), index, buffer); 130 // Add |pp_resource()| and |resource| into |buffers_|. 131 // |buffers_| uses scoped_ptr<> to hold a ref of |resource|. It keeps the 132 // resource alive. 133 buffers_.insert(BufferMap::value_type(resource->pp_resource(), resource)); 134 return resource->GetReference(); 135} 136 137void MediaStreamAudioTrackResource::ReleaseBuffers() { 138 BufferMap::iterator it = buffers_.begin(); 139 while (it != buffers_.end()) { 140 // Just invalidate and release VideoBufferResorce, but keep PP_Resource. 141 // So plugin can still use |RecycleBuffer()|. 142 it->second->Invalidate(); 143 it->second = NULL; 144 } 145} 146 147} // namespace proxy 148} // namespace ppapi 149