1 // Copyright 2015 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/cpp/video_encoder.h"
7 #include "ppapi/c/pp_errors.h"
8 #include "ppapi/c/ppb_video_encoder.h"
9 #include "ppapi/cpp/completion_callback.h"
10 #include "ppapi/cpp/instance_handle.h"
11 #include "ppapi/cpp/module.h"
12 #include "ppapi/cpp/module_impl.h"
19 const char* interface_name
<PPB_VideoEncoder_0_1
>() {
20 return PPB_VIDEOENCODER_INTERFACE_0_1
;
24 const char* interface_name
<PPB_VideoEncoder_0_2
>() {
25 return PPB_VIDEOENCODER_INTERFACE_0_2
;
28 // This struct is used to adapt
29 // CompletionCallbackWithOutput<std::vector<PP_VideoProfileDescription>>
30 // to the pre-0.2 APIs, which return PP_VideoProfileDescription_0_1.
31 // This struct is allocated on the heap, and deleted in
32 // CallbackProfileDescriptionConverter.
33 struct CallbackProfileDescription_0_1
{
34 explicit CallbackProfileDescription_0_1(const CompletionCallbackWithOutput
<
35 std::vector
<PP_VideoProfileDescription
> >& cc
)
36 : output_profiles(&profiles
),
37 original_output_profiles(cc
.output()),
38 original_callback(cc
.pp_completion_callback()) {}
39 std::vector
<PP_VideoProfileDescription_0_1
> profiles
;
40 ArrayOutputAdapter
<PP_VideoProfileDescription_0_1
> output_profiles
;
41 PP_ArrayOutput original_output_profiles
;
42 PP_CompletionCallback original_callback
;
45 // Converts data from a 0.1 style callback to 0.2 callback.
46 void CallbackProfileDescriptionConverter(void* user_data
, int32_t result
) {
47 CallbackProfileDescription_0_1
* data
=
48 static_cast<CallbackProfileDescription_0_1
*>(user_data
);
50 PP_VideoProfileDescription
* original_profiles
=
51 static_cast<PP_VideoProfileDescription
*>(
52 data
->original_output_profiles
.GetDataBuffer(
53 data
->original_output_profiles
.user_data
,
54 static_cast<uint32_t>(data
->profiles
.size()),
55 static_cast<uint32_t>(sizeof(PP_VideoProfileDescription
))));
57 for (size_t i
= 0; i
< data
->profiles
.size(); i
++) {
58 const PP_VideoProfileDescription_0_1
& profile
= data
->profiles
[i
];
60 original_profiles
[i
].profile
= profile
.profile
;
61 original_profiles
[i
].max_resolution
= profile
.max_resolution
;
62 original_profiles
[i
].max_framerate_numerator
=
63 profile
.max_framerate_numerator
;
64 original_profiles
[i
].max_framerate_denominator
=
65 profile
.max_framerate_denominator
;
66 original_profiles
[i
].hardware_accelerated
=
67 PP_FromBool(profile
.acceleration
== PP_HARDWAREACCELERATION_ONLY
);
71 // Now execute the original callback.
72 PP_RunCompletionCallback(&data
->original_callback
, result
);
78 VideoEncoder::VideoEncoder() {
81 VideoEncoder::VideoEncoder(const InstanceHandle
& instance
) {
82 if (has_interface
<PPB_VideoEncoder_0_2
>()) {
83 PassRefFromConstructor(
84 get_interface
<PPB_VideoEncoder_0_2
>()->Create(instance
.pp_instance()));
85 } else if (has_interface
<PPB_VideoEncoder_0_1
>()) {
86 PassRefFromConstructor(
87 get_interface
<PPB_VideoEncoder_0_1
>()->Create(instance
.pp_instance()));
91 VideoEncoder::VideoEncoder(const VideoEncoder
& other
) : Resource(other
) {
94 int32_t VideoEncoder::GetSupportedProfiles(const CompletionCallbackWithOutput
<
95 std::vector
<PP_VideoProfileDescription
> >& cc
) {
96 if (has_interface
<PPB_VideoEncoder_0_2
>()) {
97 return get_interface
<PPB_VideoEncoder_0_2
>()->GetSupportedProfiles(
98 pp_resource(), cc
.output(), cc
.pp_completion_callback());
99 } else if (has_interface
<PPB_VideoEncoder_0_1
>()) {
100 // Data for our callback wrapper. The callback handler will delete it.
101 CallbackProfileDescription_0_1
* data
=
102 new CallbackProfileDescription_0_1(cc
);
103 return get_interface
<PPB_VideoEncoder_0_1
>()->GetSupportedProfiles(
104 pp_resource(), data
->output_profiles
.pp_array_output(),
105 PP_MakeCompletionCallback(&CallbackProfileDescriptionConverter
, data
));
107 return cc
.MayForce(PP_ERROR_NOINTERFACE
);
110 int32_t VideoEncoder::Initialize(const PP_VideoFrame_Format
& input_format
,
111 const Size
& input_visible_size
,
112 const PP_VideoProfile
& output_profile
,
113 const uint32_t initial_bitrate
,
114 PP_HardwareAcceleration acceleration
,
115 const CompletionCallback
& cc
) {
116 if (has_interface
<PPB_VideoEncoder_0_2
>()) {
117 return get_interface
<PPB_VideoEncoder_0_2
>()->Initialize(
118 pp_resource(), input_format
, &input_visible_size
.pp_size(),
119 output_profile
, initial_bitrate
, acceleration
,
120 cc
.pp_completion_callback());
121 } else if (has_interface
<PPB_VideoEncoder_0_1
>()) {
122 return get_interface
<PPB_VideoEncoder_0_1
>()->Initialize(
123 pp_resource(), input_format
, &input_visible_size
.pp_size(),
124 output_profile
, initial_bitrate
, acceleration
,
125 cc
.pp_completion_callback());
127 return cc
.MayForce(PP_ERROR_NOINTERFACE
);
130 int32_t VideoEncoder::GetFramesRequired() {
131 if (has_interface
<PPB_VideoEncoder_0_2
>()) {
132 return get_interface
<PPB_VideoEncoder_0_2
>()->GetFramesRequired(
134 } else if (has_interface
<PPB_VideoEncoder_0_1
>()) {
135 return get_interface
<PPB_VideoEncoder_0_1
>()->GetFramesRequired(
138 return PP_ERROR_NOINTERFACE
;
141 int32_t VideoEncoder::GetFrameCodedSize(Size
* coded_size
) {
142 if (has_interface
<PPB_VideoEncoder_0_2
>()) {
143 return get_interface
<PPB_VideoEncoder_0_2
>()->GetFrameCodedSize(
144 pp_resource(), &coded_size
->pp_size());
145 } else if (has_interface
<PPB_VideoEncoder_0_1
>()) {
146 return get_interface
<PPB_VideoEncoder_0_1
>()->GetFrameCodedSize(
147 pp_resource(), &coded_size
->pp_size());
149 return PP_ERROR_NOINTERFACE
;
152 int32_t VideoEncoder::GetVideoFrame(
153 const CompletionCallbackWithOutput
<VideoFrame
>& cc
) {
154 if (has_interface
<PPB_VideoEncoder_0_2
>()) {
155 return get_interface
<PPB_VideoEncoder_0_2
>()->GetVideoFrame(
156 pp_resource(), cc
.output(), cc
.pp_completion_callback());
157 } else if (has_interface
<PPB_VideoEncoder_0_1
>()) {
158 return get_interface
<PPB_VideoEncoder_0_1
>()->GetVideoFrame(
159 pp_resource(), cc
.output(), cc
.pp_completion_callback());
161 return cc
.MayForce(PP_ERROR_NOINTERFACE
);
164 int32_t VideoEncoder::Encode(const VideoFrame
& video_frame
,
166 const CompletionCallback
& cc
) {
167 if (has_interface
<PPB_VideoEncoder_0_2
>()) {
168 return get_interface
<PPB_VideoEncoder_0_2
>()->Encode(
169 pp_resource(), video_frame
.pp_resource(), PP_FromBool(force_keyframe
),
170 cc
.pp_completion_callback());
171 } else if (has_interface
<PPB_VideoEncoder_0_1
>()) {
172 return get_interface
<PPB_VideoEncoder_0_1
>()->Encode(
173 pp_resource(), video_frame
.pp_resource(), PP_FromBool(force_keyframe
),
174 cc
.pp_completion_callback());
176 return cc
.MayForce(PP_ERROR_NOINTERFACE
);
179 int32_t VideoEncoder::GetBitstreamBuffer(
180 const CompletionCallbackWithOutput
<PP_BitstreamBuffer
>& cc
) {
181 if (has_interface
<PPB_VideoEncoder_0_2
>()) {
182 return get_interface
<PPB_VideoEncoder_0_2
>()->GetBitstreamBuffer(
183 pp_resource(), cc
.output(), cc
.pp_completion_callback());
184 } else if (has_interface
<PPB_VideoEncoder_0_1
>()) {
185 return get_interface
<PPB_VideoEncoder_0_1
>()->GetBitstreamBuffer(
186 pp_resource(), cc
.output(), cc
.pp_completion_callback());
188 return cc
.MayForce(PP_ERROR_NOINTERFACE
);
191 void VideoEncoder::RecycleBitstreamBuffer(
192 const PP_BitstreamBuffer
& bitstream_buffer
) {
193 if (has_interface
<PPB_VideoEncoder_0_2
>()) {
194 get_interface
<PPB_VideoEncoder_0_2
>()->RecycleBitstreamBuffer(
195 pp_resource(), &bitstream_buffer
);
196 } else if (has_interface
<PPB_VideoEncoder_0_1
>()) {
197 get_interface
<PPB_VideoEncoder_0_1
>()->RecycleBitstreamBuffer(
198 pp_resource(), &bitstream_buffer
);
202 void VideoEncoder::RequestEncodingParametersChange(uint32_t bitrate
,
203 uint32_t framerate
) {
204 if (has_interface
<PPB_VideoEncoder_0_2
>()) {
205 get_interface
<PPB_VideoEncoder_0_2
>()->RequestEncodingParametersChange(
206 pp_resource(), bitrate
, framerate
);
207 } else if (has_interface
<PPB_VideoEncoder_0_1
>()) {
208 get_interface
<PPB_VideoEncoder_0_1
>()->RequestEncodingParametersChange(
209 pp_resource(), bitrate
, framerate
);
213 void VideoEncoder::Close() {
214 if (has_interface
<PPB_VideoEncoder_0_2
>()) {
215 get_interface
<PPB_VideoEncoder_0_2
>()->Close(pp_resource());
216 } else if (has_interface
<PPB_VideoEncoder_0_1
>()) {
217 get_interface
<PPB_VideoEncoder_0_1
>()->Close(pp_resource());