1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CODEC2_HIDL_V1_0_UTILS_TYPES_H
18 #define CODEC2_HIDL_V1_0_UTILS_TYPES_H
19 
20 #include <bufferpool/ClientManager.h>
21 #include <android/hardware/media/bufferpool/2.0/IClientManager.h>
22 #include <android/hardware/media/bufferpool/2.0/types.h>
23 #include <android/hardware/media/c2/1.0/IComponentStore.h>
24 #include <android/hardware/media/c2/1.0/types.h>
25 #include <android/hidl/safe_union/1.0/types.h>
26 
27 #include <C2Component.h>
28 #include <C2Param.h>
29 #include <C2ParamDef.h>
30 #include <C2Work.h>
31 #include <util/C2Debug-base.h>
32 
33 #include <chrono>
34 
35 using namespace std::chrono_literals;
36 
37 namespace android {
38 namespace hardware {
39 namespace media {
40 namespace c2 {
41 namespace V1_0 {
42 namespace utils {
43 
44 using ::android::hardware::hidl_bitfield;
45 using ::android::hardware::hidl_handle;
46 using ::android::hardware::hidl_string;
47 using ::android::hardware::hidl_vec;
48 using ::android::status_t;
49 using ::android::sp;
50 using ::android::hardware::media::bufferpool::V2_0::implementation::
51         ConnectionId;
52 
53 // Types of metadata for Blocks.
54 struct C2Hidl_Range {
55     uint32_t offset;
56     uint32_t length; // Do not use "size" because the name collides with C2Info::size().
57 };
58 typedef C2GlobalParam<C2Info, C2Hidl_Range, 0> C2Hidl_RangeInfo;
59 
60 struct C2Hidl_Rect {
61     uint32_t left;
62     uint32_t top;
63     uint32_t width;
64     uint32_t height;
65 };
66 typedef C2GlobalParam<C2Info, C2Hidl_Rect, 1> C2Hidl_RectInfo;
67 
68 // Make asString() and operator<< work with Status as well as c2_status_t.
69 C2_DECLARE_AS_STRING_AND_DEFINE_STREAM_OUT(Status);
70 
71 /**
72  * All objcpy() functions will return a boolean value indicating whether the
73  * conversion succeeds or not.
74  */
75 
76 // C2SettingResult -> SettingResult
77 bool objcpy(
78         SettingResult* d,
79         const C2SettingResult& s);
80 
81 // SettingResult -> std::unique_ptr<C2SettingResult>
82 bool objcpy(
83         std::unique_ptr<C2SettingResult>* d,
84         const SettingResult& s);
85 
86 // C2ParamDescriptor -> ParamDescriptor
87 bool objcpy(
88         ParamDescriptor* d,
89         const C2ParamDescriptor& s);
90 
91 // ParamDescriptor -> std::shared_ptr<C2ParamDescriptor>
92 bool objcpy(
93         std::shared_ptr<C2ParamDescriptor>* d,
94         const ParamDescriptor& s);
95 
96 // C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery
97 bool objcpy(
98         FieldSupportedValuesQuery* d,
99         const C2FieldSupportedValuesQuery& s);
100 
101 // FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery
102 bool objcpy(
103         C2FieldSupportedValuesQuery* d,
104         const FieldSupportedValuesQuery& s);
105 
106 // C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult
107 bool objcpy(
108         FieldSupportedValuesQueryResult* d,
109         const C2FieldSupportedValuesQuery& s);
110 
111 // FieldSupportedValuesQuery, FieldSupportedValuesQueryResult -> C2FieldSupportedValuesQuery
112 bool objcpy(
113         C2FieldSupportedValuesQuery* d,
114         const FieldSupportedValuesQuery& sq,
115         const FieldSupportedValuesQueryResult& sr);
116 
117 // C2Component::Traits -> ComponentTraits
118 bool objcpy(
119         IComponentStore::ComponentTraits* d,
120         const C2Component::Traits& s);
121 
122 // ComponentTraits -> C2Component::Traits
123 bool objcpy(
124         C2Component::Traits* d,
125         const IComponentStore::ComponentTraits& s);
126 
127 // C2StructDescriptor -> StructDescriptor
128 bool objcpy(
129         StructDescriptor* d,
130         const C2StructDescriptor& s);
131 
132 // StructDescriptor -> C2StructDescriptor
133 bool objcpy(
134         std::unique_ptr<C2StructDescriptor>* d,
135         const StructDescriptor& s);
136 
137 // Abstract class to be used in
138 // objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle).
139 struct BufferPoolSender {
140     typedef ::android::hardware::media::bufferpool::V2_0::
141             ResultStatus ResultStatus;
142     typedef ::android::hardware::media::bufferpool::V2_0::
143             BufferStatusMessage BufferStatusMessage;
144     typedef ::android::hardware::media::bufferpool::
145             BufferPoolData BufferPoolData;
146 
147     /**
148      * Send bpData and return BufferStatusMessage that can be supplied to
149      * IClientManager::receive() in the receiving process.
150      *
151      * This function will be called from within the function
152      * objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle).
153      *
154      * \param[in] bpData BufferPoolData identifying the buffer to send.
155      * \param[out] bpMessage BufferStatusMessage of the transaction. Information
156      *    inside \p bpMessage should be passed to the receiving process by some
157      *    other means so it can call receive() properly.
158      * \return ResultStatus value that determines the success of the operation.
159      *    (See the possible values of ResultStatus in
160      *    hardware/interfaces/media/bufferpool/2.0/types.hal.)
161      */
162     virtual ResultStatus send(
163             const std::shared_ptr<BufferPoolData>& bpData,
164             BufferStatusMessage* bpMessage) = 0;
165 
166     virtual ~BufferPoolSender() = default;
167 };
168 
169 // Default implementation of BufferPoolSender.
170 //
171 // To use DefaultBufferPoolSender, the IClientManager instance of the receiving
172 // process must be set before send() can operate. DefaultBufferPoolSender will
173 // hold a strong reference to the IClientManager instance and use it to call
174 // IClientManager::registerSender() to establish the bufferpool connection when
175 // send() is called.
176 struct DefaultBufferPoolSender : BufferPoolSender {
177     typedef ::android::hardware::media::bufferpool::V2_0::implementation::
178             ClientManager ClientManager;
179     typedef ::android::hardware::media::bufferpool::V2_0::
180             IClientManager IClientManager;
181 
182     // Set the IClientManager instance of the receiving process and the refresh
183     // interval for the connection. The default interval is 4.5 seconds, which
184     // is slightly shorter than the amount of time the bufferpool will keep an
185     // inactive connection for.
186     DefaultBufferPoolSender(
187             const sp<IClientManager>& receiverManager = nullptr,
188             std::chrono::steady_clock::duration refreshInterval = 4500ms);
189 
190     // Set the IClientManager instance of the receiving process and the refresh
191     // interval for the connection. The default interval is 4.5 seconds, which
192     // is slightly shorter than the amount of time the bufferpool will keep an
193     // inactive connection for.
194     void setReceiver(
195             const sp<IClientManager>& receiverManager,
196             std::chrono::steady_clock::duration refreshInterval = 4500ms);
197 
198     // Implementation of BufferPoolSender::send(). send() will establish a
199     // bufferpool connection if needed, then send the bufferpool data over to
200     // the receiving process.
201     virtual ResultStatus send(
202             const std::shared_ptr<BufferPoolData>& bpData,
203             BufferStatusMessage* bpMessage) override;
204 
205 private:
206     std::mutex mMutex;
207     sp<ClientManager> mSenderManager;
208     sp<IClientManager> mReceiverManager;
209     int64_t mReceiverConnectionId;
210     int64_t mSourceConnectionId;
211     std::chrono::steady_clock::time_point mLastSent;
212     std::chrono::steady_clock::duration mRefreshInterval;
213 };
214 
215 // std::list<std::unique_ptr<C2Work>> -> WorkBundle
216 // Note: If bufferpool will be used, bpSender must not be null.
217 bool objcpy(
218         WorkBundle* d,
219         const std::list<std::unique_ptr<C2Work>>& s,
220         BufferPoolSender* bpSender = nullptr);
221 
222 // WorkBundle -> std::list<std::unique_ptr<C2Work>>
223 bool objcpy(
224         std::list<std::unique_ptr<C2Work>>* d,
225         const WorkBundle& s);
226 
227 /**
228  * Parses a params blob and returns C2Param pointers to its params. The pointers
229  * point to locations inside the underlying buffer of \p blob. If \p blob is
230  * destroyed, the pointers become invalid.
231  *
232  * \param[out] params target vector of C2Param pointers
233  * \param[in] blob parameter blob to parse
234  * \retval true if the full blob was parsed
235  * \retval false otherwise
236  */
237 bool parseParamsBlob(
238         std::vector<C2Param*> *params,
239         const hidl_vec<uint8_t> &blob);
240 
241 /**
242  * Concatenates a list of C2Params into a params blob.
243  *
244  * \param[out] blob target blob
245  * \param[in] params parameters to concatenate
246  * \retval true if the blob was successfully created
247  * \retval false if the blob was not successful (this only happens if the
248  *         parameters were not const)
249  */
250 bool createParamsBlob(
251         hidl_vec<uint8_t> *blob,
252         const std::vector<C2Param*> &params);
253 bool createParamsBlob(
254         hidl_vec<uint8_t> *blob,
255         const std::vector<std::unique_ptr<C2Param>> &params);
256 bool createParamsBlob(
257         hidl_vec<uint8_t> *blob,
258         const std::vector<std::shared_ptr<const C2Info>> &params);
259 bool createParamsBlob(
260         hidl_vec<uint8_t> *blob,
261         const std::vector<std::unique_ptr<C2Tuning>> &params);
262 
263 /**
264  * Parses a params blob and create a vector of C2Params whose members are copies
265  * of the params in the blob.
266  *
267  * \param[out] params the resulting vector
268  * \param[in] blob parameter blob to parse
269  * \retval true if the full blob was parsed and params was constructed
270  * \retval false otherwise
271  */
272 bool copyParamsFromBlob(
273         std::vector<std::unique_ptr<C2Param>>* params,
274         Params blob);
275 bool copyParamsFromBlob(
276         std::vector<std::unique_ptr<C2Tuning>>* params,
277         Params blob);
278 
279 /**
280  * Parses a params blob and applies updates to params.
281  *
282  * \param[in,out] params params to be updated
283  * \param[in] blob parameter blob containing updates
284  * \retval true if the full blob was parsed and params was updated
285  * \retval false otherwise
286  */
287 bool updateParamsFromBlob(
288         const std::vector<C2Param*>& params,
289         const Params& blob);
290 
291 /**
292  * Converts a BufferPool status value to c2_status_t.
293  * \param BufferPool status
294  * \return Corresponding c2_status_t
295  */
296 c2_status_t toC2Status(::android::hardware::media::bufferpool::V2_0::
297         ResultStatus rs);
298 
299 // BufferQueue-Based Block Operations
300 // ==================================
301 
302 // Call before transferring block to other processes.
303 //
304 // The given block is ready to transfer to other processes. This will guarantee
305 // the given block data is not mutated by bufferqueue migration.
306 bool beginTransferBufferQueueBlock(const C2ConstGraphicBlock& block);
307 
308 // Call beginTransferBufferQueueBlock() on blocks in the given workList.
309 // processInput determines whether input blocks are yielded. processOutput
310 // works similarly on output blocks. (The default value of processInput is
311 // false while the default value of processOutput is true. This implies that in
312 // most cases, only output buffers contain bufferqueue-based blocks.)
313 void beginTransferBufferQueueBlocks(
314         const std::list<std::unique_ptr<C2Work>>& workList,
315         bool processInput = false,
316         bool processOutput = true);
317 
318 // Call after transferring block is finished and make sure that
319 // beginTransferBufferQueueBlock() is called before.
320 //
321 // The transfer of given block is finished. If transfer is successful the given
322 // block is not owned by process anymore. Since transfer is finished the given
323 // block data is OK to mutate by bufferqueue migration after this call.
324 bool endTransferBufferQueueBlock(const C2ConstGraphicBlock& block,
325                                  bool transfer);
326 
327 // Call endTransferBufferQueueBlock() on blocks in the given workList.
328 // processInput determines whether input blocks are yielded. processOutput
329 // works similarly on output blocks. (The default value of processInput is
330 // false while the default value of processOutput is true. This implies that in
331 // most cases, only output buffers contain bufferqueue-based blocks.)
332 void endTransferBufferQueueBlocks(
333         const std::list<std::unique_ptr<C2Work>>& workList,
334         bool transfer,
335         bool processInput = false,
336         bool processOutput = true);
337 
338 // The given block is ready to be rendered. the given block is not owned by
339 // process anymore. If migration is in progress, this returns false in order
340 // not to render.
341 bool displayBufferQueueBlock(const C2ConstGraphicBlock& block);
342 
343 }  // namespace utils
344 }  // namespace V1_0
345 }  // namespace c2
346 }  // namespace media
347 }  // namespace hardware
348 }  // namespace android
349 
350 #endif  // CODEC2_HIDL_V1_0_UTILS_TYPES_H
351