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"
17 MediaStreamVideoTrackResource::MediaStreamVideoTrackResource(
18 Connection connection
,
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() {
31 thunk::PPB_MediaStreamVideoTrack_API
*
32 MediaStreamVideoTrackResource::AsPPB_MediaStreamVideoTrack_API() {
36 PP_Var
MediaStreamVideoTrackResource::GetId() {
37 return StringVar::StringToPPVar(id());
40 PP_Bool
MediaStreamVideoTrackResource::HasEnded() {
41 return PP_FromBool(has_ended());
44 int32_t MediaStreamVideoTrackResource::Configure(
45 const int32_t attrib_list
[],
46 scoped_refptr
<TrackedCallback
> callback
) {
48 return PP_ERROR_FAILED
;
50 if (TrackedCallback::IsPending(configure_callback_
) ||
51 TrackedCallback::IsPending(get_frame_callback_
)) {
52 return PP_ERROR_INPROGRESS
;
55 // Do not support configure, if frames are hold by plugin.
57 return PP_ERROR_INPROGRESS
;
59 MediaStreamVideoTrackShared::Attributes attributes
;
61 for (;attrib_list
[i
] != PP_MEDIASTREAMVIDEOTRACK_ATTRIB_NONE
; i
+= 2) {
62 switch (attrib_list
[i
]) {
63 case PP_MEDIASTREAMVIDEOTRACK_ATTRIB_BUFFERED_FRAMES
:
64 attributes
.buffers
= attrib_list
[i
+ 1];
66 case PP_MEDIASTREAMVIDEOTRACK_ATTRIB_WIDTH
:
67 attributes
.width
= attrib_list
[i
+ 1];
69 case PP_MEDIASTREAMVIDEOTRACK_ATTRIB_HEIGHT
:
70 attributes
.height
= attrib_list
[i
+ 1];
72 case PP_MEDIASTREAMVIDEOTRACK_ATTRIB_FORMAT
:
73 attributes
.format
= static_cast<PP_VideoFrame_Format
>(attrib_list
[i
+ 1]);
76 return PP_ERROR_BADARGUMENT
;
80 if (!MediaStreamVideoTrackShared::VerifyAttributes(attributes
))
81 return PP_ERROR_BADARGUMENT
;
83 configure_callback_
= callback
;
84 Call
<PpapiPluginMsg_MediaStreamVideoTrack_ConfigureReply
>(
86 PpapiHostMsg_MediaStreamVideoTrack_Configure(attributes
),
87 base::Bind(&MediaStreamVideoTrackResource::OnPluginMsgConfigureReply
,
88 base::Unretained(this)),
90 return PP_OK_COMPLETIONPENDING
;
93 int32_t MediaStreamVideoTrackResource::GetAttrib(
94 PP_MediaStreamVideoTrack_Attrib attrib
,
96 // TODO(penghuang): implement this function.
97 return PP_ERROR_NOTSUPPORTED
;
100 int32_t MediaStreamVideoTrackResource::GetFrame(
102 scoped_refptr
<TrackedCallback
> callback
) {
104 return PP_ERROR_FAILED
;
106 if (TrackedCallback::IsPending(configure_callback_
) ||
107 TrackedCallback::IsPending(get_frame_callback_
)) {
108 return PP_ERROR_INPROGRESS
;
111 *frame
= GetVideoFrame();
115 get_frame_output_
= frame
;
116 get_frame_callback_
= callback
;
117 return PP_OK_COMPLETIONPENDING
;
120 int32_t MediaStreamVideoTrackResource::RecycleFrame(PP_Resource frame
) {
121 FrameMap::iterator it
= frames_
.find(frame
);
122 if (it
== frames_
.end())
123 return PP_ERROR_BADRESOURCE
;
125 scoped_refptr
<VideoFrameResource
> frame_resource
= it
->second
;
131 DCHECK_GE(frame_resource
->GetBufferIndex(), 0);
133 SendEnqueueBufferMessageToHost(frame_resource
->GetBufferIndex());
134 frame_resource
->Invalidate();
138 void MediaStreamVideoTrackResource::Close() {
142 if (TrackedCallback::IsPending(get_frame_callback_
)) {
143 *get_frame_output_
= 0;
144 get_frame_callback_
->PostAbort();
145 get_frame_callback_
= NULL
;
146 get_frame_output_
= 0;
150 MediaStreamTrackResourceBase::CloseInternal();
153 void MediaStreamVideoTrackResource::OnNewBufferEnqueued() {
154 if (!TrackedCallback::IsPending(get_frame_callback_
))
157 *get_frame_output_
= GetVideoFrame();
158 int32_t result
= *get_frame_output_
? PP_OK
: PP_ERROR_FAILED
;
159 get_frame_output_
= NULL
;
160 scoped_refptr
<TrackedCallback
> callback
;
161 callback
.swap(get_frame_callback_
);
162 callback
->Run(result
);
165 PP_Resource
MediaStreamVideoTrackResource::GetVideoFrame() {
166 int32_t index
= buffer_manager()->DequeueBuffer();
170 MediaStreamBuffer
* buffer
= buffer_manager()->GetBufferPointer(index
);
172 scoped_refptr
<VideoFrameResource
> resource
=
173 new VideoFrameResource(pp_instance(), index
, buffer
);
174 // Add |pp_resource()| and |resource| into |frames_|.
175 // |frames_| uses scoped_ptr<> to hold a ref of |resource|. It keeps the
177 frames_
.insert(FrameMap::value_type(resource
->pp_resource(), resource
));
178 return resource
->GetReference();
181 void MediaStreamVideoTrackResource::ReleaseFrames() {
182 FrameMap::iterator it
= frames_
.begin();
183 while (it
!= frames_
.end()) {
184 // Just invalidate and release VideoFrameResorce, but keep PP_Resource.
185 // So plugin can still use |RecycleFrame()|.
186 it
->second
->Invalidate();
191 void MediaStreamVideoTrackResource::OnPluginMsgConfigureReply(
192 const ResourceMessageReplyParams
& params
) {
193 if (TrackedCallback::IsPending(configure_callback_
)) {
194 scoped_refptr
<TrackedCallback
> callback
;
195 callback
.swap(configure_callback_
);
196 callback
->Run(params
.result());