mac: Fix DownloadItemController unit tests on Yosemite.
[chromium-blink-merge.git] / ppapi / proxy / media_stream_video_track_resource.cc
blob2942ff574fb598021ada98cd2fadb3dd6ae06f44
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.
5 #include "ppapi/proxy/media_stream_video_track_resource.h"
7 #include "base/logging.h"
8 #include "ppapi/proxy/ppapi_messages.h"
9 #include "ppapi/proxy/video_frame_resource.h"
10 #include "ppapi/shared_impl/media_stream_buffer.h"
11 #include "ppapi/shared_impl/media_stream_video_track_shared.h"
12 #include "ppapi/shared_impl/var.h"
14 namespace ppapi {
15 namespace proxy {
17 MediaStreamVideoTrackResource::MediaStreamVideoTrackResource(
18 Connection connection,
19 PP_Instance instance,
20 int pending_renderer_id,
21 const std::string& id)
22 : MediaStreamTrackResourceBase(
23 connection, instance, pending_renderer_id, id),
24 get_frame_output_(NULL) {
27 MediaStreamVideoTrackResource::MediaStreamVideoTrackResource(
28 Connection connection,
29 PP_Instance instance)
30 : MediaStreamTrackResourceBase(connection, instance),
31 get_frame_output_(NULL) {
32 SendCreate(RENDERER, PpapiHostMsg_MediaStreamVideoTrack_Create());
35 MediaStreamVideoTrackResource::~MediaStreamVideoTrackResource() {
36 Close();
39 thunk::PPB_MediaStreamVideoTrack_API*
40 MediaStreamVideoTrackResource::AsPPB_MediaStreamVideoTrack_API() {
41 return this;
44 PP_Var MediaStreamVideoTrackResource::GetId() {
45 return StringVar::StringToPPVar(id());
48 PP_Bool MediaStreamVideoTrackResource::HasEnded() {
49 return PP_FromBool(has_ended());
52 int32_t MediaStreamVideoTrackResource::Configure(
53 const int32_t attrib_list[],
54 scoped_refptr<TrackedCallback> callback) {
55 if (has_ended())
56 return PP_ERROR_FAILED;
58 if (TrackedCallback::IsPending(configure_callback_) ||
59 TrackedCallback::IsPending(get_frame_callback_)) {
60 return PP_ERROR_INPROGRESS;
63 // Do not support configure, if frames are hold by plugin.
64 if (!frames_.empty())
65 return PP_ERROR_INPROGRESS;
67 MediaStreamVideoTrackShared::Attributes attributes;
68 int i = 0;
69 for (;attrib_list[i] != PP_MEDIASTREAMVIDEOTRACK_ATTRIB_NONE; i += 2) {
70 switch (attrib_list[i]) {
71 case PP_MEDIASTREAMVIDEOTRACK_ATTRIB_BUFFERED_FRAMES:
72 attributes.buffers = attrib_list[i + 1];
73 break;
74 case PP_MEDIASTREAMVIDEOTRACK_ATTRIB_WIDTH:
75 attributes.width = attrib_list[i + 1];
76 break;
77 case PP_MEDIASTREAMVIDEOTRACK_ATTRIB_HEIGHT:
78 attributes.height = attrib_list[i + 1];
79 break;
80 case PP_MEDIASTREAMVIDEOTRACK_ATTRIB_FORMAT:
81 attributes.format = static_cast<PP_VideoFrame_Format>(attrib_list[i + 1]);
82 break;
83 default:
84 return PP_ERROR_BADARGUMENT;
88 if (!MediaStreamVideoTrackShared::VerifyAttributes(attributes))
89 return PP_ERROR_BADARGUMENT;
91 configure_callback_ = callback;
92 Call<PpapiPluginMsg_MediaStreamVideoTrack_ConfigureReply>(
93 RENDERER,
94 PpapiHostMsg_MediaStreamVideoTrack_Configure(attributes),
95 base::Bind(&MediaStreamVideoTrackResource::OnPluginMsgConfigureReply,
96 base::Unretained(this)),
97 callback);
98 return PP_OK_COMPLETIONPENDING;
101 int32_t MediaStreamVideoTrackResource::GetAttrib(
102 PP_MediaStreamVideoTrack_Attrib attrib,
103 int32_t* value) {
104 // TODO(penghuang): implement this function.
105 return PP_ERROR_NOTSUPPORTED;
108 int32_t MediaStreamVideoTrackResource::GetFrame(
109 PP_Resource* frame,
110 scoped_refptr<TrackedCallback> callback) {
111 if (has_ended())
112 return PP_ERROR_FAILED;
114 if (TrackedCallback::IsPending(configure_callback_) ||
115 TrackedCallback::IsPending(get_frame_callback_)) {
116 return PP_ERROR_INPROGRESS;
119 *frame = GetVideoFrame();
120 if (*frame)
121 return PP_OK;
123 get_frame_output_ = frame;
124 get_frame_callback_ = callback;
125 return PP_OK_COMPLETIONPENDING;
128 int32_t MediaStreamVideoTrackResource::RecycleFrame(PP_Resource frame) {
129 FrameMap::iterator it = frames_.find(frame);
130 if (it == frames_.end())
131 return PP_ERROR_BADRESOURCE;
133 scoped_refptr<VideoFrameResource> frame_resource = it->second;
134 frames_.erase(it);
136 if (has_ended())
137 return PP_OK;
139 DCHECK_GE(frame_resource->GetBufferIndex(), 0);
141 SendEnqueueBufferMessageToHost(frame_resource->GetBufferIndex());
142 frame_resource->Invalidate();
143 return PP_OK;
146 void MediaStreamVideoTrackResource::Close() {
147 if (has_ended())
148 return;
150 if (TrackedCallback::IsPending(get_frame_callback_)) {
151 *get_frame_output_ = 0;
152 get_frame_callback_->PostAbort();
153 get_frame_callback_ = NULL;
154 get_frame_output_ = 0;
157 ReleaseFrames();
158 MediaStreamTrackResourceBase::CloseInternal();
161 int32_t MediaStreamVideoTrackResource::GetEmptyFrame(
162 PP_Resource* frame, scoped_refptr<TrackedCallback> callback) {
163 return GetFrame(frame, callback);
166 int32_t MediaStreamVideoTrackResource::PutFrame(PP_Resource frame) {
167 // TODO(ronghuawu): Consider to rename RecycleFrame to PutFrame and use
168 // one set of GetFrame and PutFrame for both input and output.
169 return RecycleFrame(frame);
172 void MediaStreamVideoTrackResource::OnNewBufferEnqueued() {
173 if (!TrackedCallback::IsPending(get_frame_callback_))
174 return;
176 *get_frame_output_ = GetVideoFrame();
177 int32_t result = *get_frame_output_ ? PP_OK : PP_ERROR_FAILED;
178 get_frame_output_ = NULL;
179 scoped_refptr<TrackedCallback> callback;
180 callback.swap(get_frame_callback_);
181 callback->Run(result);
184 PP_Resource MediaStreamVideoTrackResource::GetVideoFrame() {
185 int32_t index = buffer_manager()->DequeueBuffer();
186 if (index < 0)
187 return 0;
189 MediaStreamBuffer* buffer = buffer_manager()->GetBufferPointer(index);
190 DCHECK(buffer);
191 scoped_refptr<VideoFrameResource> resource =
192 new VideoFrameResource(pp_instance(), index, buffer);
193 // Add |pp_resource()| and |resource| into |frames_|.
194 // |frames_| uses scoped_ptr<> to hold a ref of |resource|. It keeps the
195 // resource alive.
196 frames_.insert(FrameMap::value_type(resource->pp_resource(), resource));
197 return resource->GetReference();
200 void MediaStreamVideoTrackResource::ReleaseFrames() {
201 for (FrameMap::iterator it = frames_.begin(); it != frames_.end(); ++it) {
202 // Just invalidate and release VideoFrameResorce, but keep PP_Resource.
203 // So plugin can still use |RecycleFrame()|.
204 it->second->Invalidate();
205 it->second = NULL;
209 void MediaStreamVideoTrackResource::OnPluginMsgConfigureReply(
210 const ResourceMessageReplyParams& params,
211 const std::string& track_id) {
212 if (id().empty()) {
213 set_id(track_id);
214 } else {
215 DCHECK_EQ(id(), track_id);
217 if (TrackedCallback::IsPending(configure_callback_)) {
218 scoped_refptr<TrackedCallback> callback;
219 callback.swap(configure_callback_);
220 callback->Run(params.result());
224 } // namespace proxy
225 } // namespace ppapi