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     std::chrono::steady_clock::duration mRefreshInterval;
210 
211     struct Connection {
212         int64_t receiverConnectionId;
213         std::chrono::steady_clock::time_point lastSent;
ConnectionDefaultBufferPoolSender::Connection214         Connection(int64_t receiverConnectionId,
215                    std::chrono::steady_clock::time_point lastSent)
216               : receiverConnectionId(receiverConnectionId),
217                 lastSent(lastSent) {
218         }
219     };
220 
221     // Map of connections.
222     //
223     // The key is the connection id. One sender-receiver pair may have multiple
224     // connections.
225     std::map<int64_t, Connection> mConnections;
226 };
227 
228 // std::list<std::unique_ptr<C2Work>> -> WorkBundle
229 // Note: If bufferpool will be used, bpSender must not be null.
230 bool objcpy(
231         WorkBundle* d,
232         const std::list<std::unique_ptr<C2Work>>& s,
233         BufferPoolSender* bpSender = nullptr);
234 
235 // WorkBundle -> std::list<std::unique_ptr<C2Work>>
236 bool objcpy(
237         std::list<std::unique_ptr<C2Work>>* d,
238         const WorkBundle& s);
239 
240 /**
241  * Parses a params blob and returns C2Param pointers to its params. The pointers
242  * point to locations inside the underlying buffer of \p blob. If \p blob is
243  * destroyed, the pointers become invalid.
244  *
245  * \param[out] params target vector of C2Param pointers
246  * \param[in] blob parameter blob to parse
247  * \retval true if the full blob was parsed
248  * \retval false otherwise
249  */
250 bool parseParamsBlob(
251         std::vector<C2Param*> *params,
252         const hidl_vec<uint8_t> &blob);
253 
254 /**
255  * Concatenates a list of C2Params into a params blob.
256  *
257  * \param[out] blob target blob
258  * \param[in] params parameters to concatenate
259  * \retval true if the blob was successfully created
260  * \retval false if the blob was not successful (this only happens if the
261  *         parameters were not const)
262  */
263 bool createParamsBlob(
264         hidl_vec<uint8_t> *blob,
265         const std::vector<C2Param*> &params);
266 bool createParamsBlob(
267         hidl_vec<uint8_t> *blob,
268         const std::vector<std::unique_ptr<C2Param>> &params);
269 bool createParamsBlob(
270         hidl_vec<uint8_t> *blob,
271         const std::vector<std::shared_ptr<const C2Info>> &params);
272 bool createParamsBlob(
273         hidl_vec<uint8_t> *blob,
274         const std::vector<std::unique_ptr<C2Tuning>> &params);
275 
276 /**
277  * Parses a params blob and create a vector of C2Params whose members are copies
278  * of the params in the blob.
279  *
280  * \param[out] params the resulting vector
281  * \param[in] blob parameter blob to parse
282  * \retval true if the full blob was parsed and params was constructed
283  * \retval false otherwise
284  */
285 bool copyParamsFromBlob(
286         std::vector<std::unique_ptr<C2Param>>* params,
287         Params blob);
288 bool copyParamsFromBlob(
289         std::vector<std::unique_ptr<C2Tuning>>* params,
290         Params blob);
291 
292 /**
293  * Parses a params blob and applies updates to params.
294  *
295  * \param[in,out] params params to be updated
296  * \param[in] blob parameter blob containing updates
297  * \retval true if the full blob was parsed and params was updated
298  * \retval false otherwise
299  */
300 bool updateParamsFromBlob(
301         const std::vector<C2Param*>& params,
302         const Params& blob);
303 
304 /**
305  * Converts a BufferPool status value to c2_status_t.
306  * \param BufferPool status
307  * \return Corresponding c2_status_t
308  */
309 c2_status_t toC2Status(::android::hardware::media::bufferpool::V2_0::
310         ResultStatus rs);
311 
312 // BufferQueue-Based Block Operations
313 // ==================================
314 
315 // Call before transferring block to other processes.
316 //
317 // The given block is ready to transfer to other processes. This will guarantee
318 // the given block data is not mutated by bufferqueue migration.
319 bool beginTransferBufferQueueBlock(const C2ConstGraphicBlock& block);
320 
321 // Call beginTransferBufferQueueBlock() on blocks in the given workList.
322 // processInput determines whether input blocks are yielded. processOutput
323 // works similarly on output blocks. (The default value of processInput is
324 // false while the default value of processOutput is true. This implies that in
325 // most cases, only output buffers contain bufferqueue-based blocks.)
326 void beginTransferBufferQueueBlocks(
327         const std::list<std::unique_ptr<C2Work>>& workList,
328         bool processInput = false,
329         bool processOutput = true);
330 
331 // Call after transferring block is finished and make sure that
332 // beginTransferBufferQueueBlock() is called before.
333 //
334 // The transfer of given block is finished. If transfer is successful the given
335 // block is not owned by process anymore. Since transfer is finished the given
336 // block data is OK to mutate by bufferqueue migration after this call.
337 bool endTransferBufferQueueBlock(const C2ConstGraphicBlock& block,
338                                  bool transfer);
339 
340 // Call endTransferBufferQueueBlock() on blocks in the given workList.
341 // processInput determines whether input blocks are yielded. processOutput
342 // works similarly on output blocks. (The default value of processInput is
343 // false while the default value of processOutput is true. This implies that in
344 // most cases, only output buffers contain bufferqueue-based blocks.)
345 void endTransferBufferQueueBlocks(
346         const std::list<std::unique_ptr<C2Work>>& workList,
347         bool transfer,
348         bool processInput = false,
349         bool processOutput = true);
350 
351 // The given block is ready to be rendered. the given block is not owned by
352 // process anymore. If migration is in progress, this returns false in order
353 // not to render.
354 bool displayBufferQueueBlock(const C2ConstGraphicBlock& block);
355 
356 }  // namespace utils
357 }  // namespace V1_0
358 }  // namespace c2
359 }  // namespace media
360 }  // namespace hardware
361 }  // namespace android
362 
363 #endif  // CODEC2_HIDL_V1_0_UTILS_TYPES_H
364