1 /*
2  * Copyright (C) 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 HARDWARE_GOOGLE_MEDIA_C2_V1_0_UTILS_TYPES_H
18 #define HARDWARE_GOOGLE_MEDIA_C2_V1_0_UTILS_TYPES_H
19 
20 #include <chrono>
21 
22 #include <bufferpool/ClientManager.h>
23 #include <android/hardware/media/bufferpool/1.0/IClientManager.h>
24 #include <android/hardware/media/bufferpool/1.0/types.h>
25 #include <hardware/google/media/c2/1.0/IComponentStore.h>
26 #include <hardware/google/media/c2/1.0/types.h>
27 #include <gui/IGraphicBufferProducer.h>
28 
29 #include <C2Component.h>
30 #include <C2Param.h>
31 #include <C2ParamDef.h>
32 #include <C2Work.h>
33 
34 using namespace std::chrono_literals;
35 
36 namespace hardware {
37 namespace google {
38 namespace media {
39 namespace c2 {
40 namespace V1_0 {
41 namespace utils {
42 
43 using ::android::hardware::hidl_bitfield;
44 using ::android::hardware::hidl_handle;
45 using ::android::hardware::hidl_string;
46 using ::android::hardware::hidl_vec;
47 using ::android::status_t;
48 using ::android::sp;
49 using ::android::hardware::media::bufferpool::V1_0::implementation::
50         ConnectionId;
51 using ::android::IGraphicBufferProducer;
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 // C2SettingResult -> SettingResult
69 Status objcpy(
70         SettingResult* d,
71         const C2SettingResult& s);
72 
73 // SettingResult -> std::unique_ptr<C2SettingResult>
74 c2_status_t objcpy(
75         std::unique_ptr<C2SettingResult>* d,
76         const SettingResult& s);
77 
78 // C2ParamDescriptor -> ParamDescriptor
79 Status objcpy(
80         ParamDescriptor* d,
81         const C2ParamDescriptor& s);
82 
83 // ParamDescriptor -> std::shared_ptr<C2ParamDescriptor>
84 c2_status_t objcpy(
85         std::shared_ptr<C2ParamDescriptor>* d,
86         const ParamDescriptor& s);
87 
88 // C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery
89 Status objcpy(
90         FieldSupportedValuesQuery* d,
91         const C2FieldSupportedValuesQuery& s);
92 
93 // FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery
94 c2_status_t objcpy(
95         C2FieldSupportedValuesQuery* d,
96         const FieldSupportedValuesQuery& s);
97 
98 // C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult
99 Status objcpy(
100         FieldSupportedValuesQueryResult* d,
101         const C2FieldSupportedValuesQuery& s);
102 
103 // FieldSupportedValuesQuery, FieldSupportedValuesQueryResult -> C2FieldSupportedValuesQuery
104 c2_status_t objcpy(
105         C2FieldSupportedValuesQuery* d,
106         const FieldSupportedValuesQuery& sq,
107         const FieldSupportedValuesQueryResult& sr);
108 
109 // C2Component::Traits -> ComponentTraits
110 Status objcpy(
111         IComponentStore::ComponentTraits* d,
112         const C2Component::Traits& s);
113 
114 // ComponentTraits -> C2Component::Traits, std::unique_ptr<std::vector<std::string>>
115 // Note: The output d is only valid as long as aliasesBuffer remains alive.
116 c2_status_t objcpy(
117         C2Component::Traits* d,
118         std::unique_ptr<std::vector<std::string>>* aliasesBuffer,
119         const IComponentStore::ComponentTraits& s);
120 
121 // C2StructDescriptor -> StructDescriptor
122 Status objcpy(
123         StructDescriptor* d,
124         const C2StructDescriptor& s);
125 
126 // StructDescriptor -> C2StructDescriptor
127 c2_status_t objcpy(
128         std::unique_ptr<C2StructDescriptor>* d,
129         const StructDescriptor& s);
130 
131 // Abstract class to be used in
132 // objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle).
133 struct BufferPoolSender {
134     typedef ::android::hardware::media::bufferpool::V1_0::
135             ResultStatus ResultStatus;
136     typedef ::android::hardware::media::bufferpool::V1_0::
137             BufferStatusMessage BufferStatusMessage;
138     typedef ::android::hardware::media::bufferpool::
139             BufferPoolData BufferPoolData;
140 
141     /**
142      * Send bpData and return BufferStatusMessage that can be supplied to
143      * IClientManager::receive() in the receiving process.
144      *
145      * This function will be called from within the function
146      * objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle).
147      *
148      * \param[in] bpData BufferPoolData identifying the buffer to send.
149      * \param[out] bpMessage BufferStatusMessage of the transaction. Information
150      *    inside \p bpMessage should be passed to the receiving process by some
151      *    other means so it can call receive() properly.
152      * \return ResultStatus value that determines the success of the operation.
153      *    (See the possible values of ResultStatus in
154      *    hardware/interfaces/media/bufferpool/1.0/types.hal.)
155      */
156     virtual ResultStatus send(
157             const std::shared_ptr<BufferPoolData>& bpData,
158             BufferStatusMessage* bpMessage) = 0;
159 
160     virtual ~BufferPoolSender() = default;
161 };
162 
163 // Default implementation of BufferPoolSender.
164 //
165 // To use DefaultBufferPoolSender, the IClientManager instance of the receiving
166 // process must be set before send() can operate. DefaultBufferPoolSender will
167 // hold a strong reference to the IClientManager instance and use it to call
168 // IClientManager::registerSender() to establish the bufferpool connection when
169 // send() is called.
170 struct DefaultBufferPoolSender : BufferPoolSender {
171     typedef ::android::hardware::media::bufferpool::V1_0::implementation::
172             ClientManager ClientManager;
173     typedef ::android::hardware::media::bufferpool::V1_0::
174             IClientManager IClientManager;
175 
176     // Set the IClientManager instance of the receiving process and the refresh
177     // interval for the connection. The default interval is 4.5 seconds, which
178     // is slightly shorter than the amount of time the bufferpool will keep an
179     // inactive connection for.
180     DefaultBufferPoolSender(
181             const sp<IClientManager>& receiverManager = nullptr,
182             std::chrono::steady_clock::duration refreshInterval = 4500ms);
183 
184     // Set the IClientManager instance of the receiving process and the refresh
185     // interval for the connection. The default interval is 4.5 seconds, which
186     // is slightly shorter than the amount of time the bufferpool will keep an
187     // inactive connection for.
188     void setReceiver(
189             const sp<IClientManager>& receiverManager,
190             std::chrono::steady_clock::duration refreshInterval = 4500ms);
191 
192     // Implementation of BufferPoolSender::send(). send() will establish a
193     // bufferpool connection if needed, then send the bufferpool data over to
194     // the receiving process.
195     virtual ResultStatus send(
196             const std::shared_ptr<BufferPoolData>& bpData,
197             BufferStatusMessage* bpMessage) override;
198 
199 private:
200     std::mutex mMutex;
201     sp<ClientManager> mSenderManager;
202     sp<IClientManager> mReceiverManager;
203     int64_t mReceiverConnectionId;
204     int64_t mSourceConnectionId;
205     std::chrono::steady_clock::time_point mLastSent;
206     std::chrono::steady_clock::duration mRefreshInterval;
207 };
208 
209 // std::list<std::unique_ptr<C2Work>> -> WorkBundle
210 // Note: If bufferpool will be used, bpSender must not be null.
211 Status objcpy(
212         WorkBundle* d,
213         const std::list<std::unique_ptr<C2Work>>& s,
214         BufferPoolSender* bpSender = nullptr);
215 
216 // WorkBundle -> std::list<std::unique_ptr<C2Work>>
217 c2_status_t objcpy(
218         std::list<std::unique_ptr<C2Work>>* d,
219         const WorkBundle& s);
220 
221 /**
222  * Parses a params blob and returns C2Param pointers to its params.
223  * \param[out] params target vector of C2Param pointers
224  * \param[in] blob parameter blob to parse
225  * \retval C2_OK if the full blob was parsed
226  * \retval C2_BAD_VALUE otherwise
227  */
228 c2_status_t parseParamsBlob(
229         std::vector<C2Param*> *params,
230         const hidl_vec<uint8_t> &blob);
231 
232 /**
233  * Concatenates a list of C2Params into a params blob.
234  * \param[out] blob target blob
235  * \param[in] params parameters to concatenate
236  * \retval C2_OK if the blob was successfully created
237  * \retval C2_BAD_VALUE if the blob was not successful (this only happens if the parameters were
238  *         not const)
239  */
240 Status createParamsBlob(
241         hidl_vec<uint8_t> *blob,
242         const std::vector<C2Param*> &params);
243 Status createParamsBlob(
244         hidl_vec<uint8_t> *blob,
245         const std::vector<std::unique_ptr<C2Param>> &params);
246 Status createParamsBlob(
247         hidl_vec<uint8_t> *blob,
248         const std::vector<std::shared_ptr<const C2Info>> &params);
249 Status createParamsBlob(
250         hidl_vec<uint8_t> *blob,
251         const std::vector<std::unique_ptr<C2Tuning>> &params);
252 
253 /**
254  * Parses a params blob and create a vector of C2Params whose members are copies
255  * of the params in the blob.
256  * \param[out] params the resulting vector
257  * \param[in] blob parameter blob to parse
258  * \retval C2_OK if the full blob was parsed and params was constructed
259  * \retval C2_BAD_VALUE otherwise
260  */
261 c2_status_t copyParamsFromBlob(
262         std::vector<std::unique_ptr<C2Param>>* params,
263         Params blob);
264 
265 /**
266  * Parses a params blob and applies updates to params
267  * \param[in,out] params params to be updated
268  * \param[in] blob parameter blob containing updates
269  * \retval C2_OK if the full blob was parsed and params was updated
270  * \retval C2_BAD_VALUE otherwise
271  */
272 c2_status_t updateParamsFromBlob(
273         const std::vector<C2Param*>& params,
274         const Params& blob);
275 
276 /**
277  * Converts a BufferPool status value to c2_status_t.
278  * \param BufferPool status
279  * \return Corresponding c2_status_t
280  */
281 c2_status_t toC2Status(::android::hardware::media::bufferpool::V1_0::
282         ResultStatus rs);
283 
284 // BufferQueue-Based Block Operations
285 // ==================================
286 
287 // Create a GraphicBuffer object from a graphic block and attach it to an
288 // IGraphicBufferProducer.
289 status_t attachToBufferQueue(const C2ConstGraphicBlock& block,
290                              const sp<IGraphicBufferProducer>& igbp,
291                              uint32_t generation,
292                              int32_t* bqSlot);
293 
294 // Return false if block does not come from a bufferqueue-based blockpool.
295 // Otherwise, extract generation, bqId and bqSlot and return true.
296 bool getBufferQueueAssignment(const C2ConstGraphicBlock& block,
297                               uint32_t* generation,
298                               uint64_t* bqId,
299                               int32_t* bqSlot);
300 
301 // Disassociate the given block with its designated bufferqueue so that
302 // cancelBuffer() will not be called when the block is destroyed. If the block
303 // does not have a designated bufferqueue, the function returns false.
304 // Otherwise, it returns true.
305 //
306 // Note: This function should be called after attachBuffer() or queueBuffer() is
307 // called manually.
308 bool yieldBufferQueueBlock(const C2ConstGraphicBlock& block);
309 
310 // Call yieldBufferQueueBlock() on blocks in the given workList. processInput
311 // determines whether input blocks are yielded. processOutput works similarly on
312 // output blocks. (The default value of processInput is false while the default
313 // value of processOutput is true. This implies that in most cases, only output
314 // buffers contain bufferqueue-based blocks.)
315 //
316 // Note: This function should be called after WorkBundle has been successfully
317 // sent over the Treble boundary to another process.
318 void yieldBufferQueueBlocks(const std::list<std::unique_ptr<C2Work>>& workList,
319                             bool processInput = false,
320                             bool processOutput = true);
321 
322 // Assign the given block to a bufferqueue so that when the block is destroyed,
323 // cancelBuffer() will be called.
324 //
325 // If the block does not come from a bufferqueue-based blockpool, this function
326 // returns false.
327 //
328 // If the block already has a bufferqueue assignment that matches the given one,
329 // the function returns true.
330 //
331 // If the block already has a bufferqueue assignment that does not match the
332 // given one, the block will be reassigned to the given bufferqueue. This
333 // will call attachBuffer() on the given igbp. The function then returns true on
334 // success or false on any failure during the operation.
335 //
336 // Note: This function should be called after detachBuffer() or dequeueBuffer()
337 // is called manually.
338 bool holdBufferQueueBlock(const C2ConstGraphicBlock& block,
339                           const sp<IGraphicBufferProducer>& igbp,
340                           uint64_t bqId,
341                           uint32_t generation);
342 
343 // Call holdBufferQueueBlock() on input or output blocks in the given workList.
344 // Since the bufferqueue assignment for input and output buffers can be
345 // different, this function takes forInput to determine whether the given
346 // bufferqueue is for input buffers or output buffers. (The default value of
347 // forInput is false.)
348 //
349 // In the (rare) case that both input and output buffers are bufferqueue-based,
350 // this function must be called twice, once for the input buffers and once for
351 // the output buffers.
352 //
353 // Note: This function should be called after WorkBundle has been received from
354 // another process.
355 void holdBufferQueueBlocks(const std::list<std::unique_ptr<C2Work>>& workList,
356                            const sp<IGraphicBufferProducer>& igbp,
357                            uint64_t bqId,
358                            uint32_t generation,
359                            bool forInput = false);
360 
361 }  // namespace utils
362 }  // namespace V1_0
363 }  // namespace c2
364 }  // namespace media
365 }  // namespace google
366 }  // namespace hardware
367 
368 #endif  // HARDWARE_GOOGLE_MEDIA_C2_V1_0_UTILS_TYPES_H
369