Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / ppapi / proxy / media_stream_audio_track_resource.cc
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
11 namespace ppapi {
12 namespace proxy {
13
14 MediaStreamAudioTrackResource::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
24 MediaStreamAudioTrackResource::~MediaStreamAudioTrackResource() {
25   Close();
26 }
27
28 thunk::PPB_MediaStreamAudioTrack_API*
29 MediaStreamAudioTrackResource::AsPPB_MediaStreamAudioTrack_API() {
30   return this;
31 }
32
33 PP_Var MediaStreamAudioTrackResource::GetId() {
34   return StringVar::StringToPPVar(id());
35 }
36
37 PP_Bool MediaStreamAudioTrackResource::HasEnded() {
38   return PP_FromBool(has_ended());
39 }
40
41 int32_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
48 int32_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
55 int32_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
76 int32_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
94 void 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
109 void 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
121 PP_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
137 void 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