diff options
Diffstat (limited to 'nodes/ti_semseg_cnn/src/semseg_cnn_manage_graph.cpp')
-rw-r--r-- | nodes/ti_semseg_cnn/src/semseg_cnn_manage_graph.cpp | 1188 |
1 files changed, 1188 insertions, 0 deletions
diff --git a/nodes/ti_semseg_cnn/src/semseg_cnn_manage_graph.cpp b/nodes/ti_semseg_cnn/src/semseg_cnn_manage_graph.cpp new file mode 100644 index 0000000..7b3cca3 --- /dev/null +++ b/nodes/ti_semseg_cnn/src/semseg_cnn_manage_graph.cpp | |||
@@ -0,0 +1,1188 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Copyright (c) 2021 Texas Instruments Incorporated | ||
4 | * | ||
5 | * All rights reserved not granted herein. | ||
6 | * | ||
7 | * Limited License. | ||
8 | * | ||
9 | * Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive | ||
10 | * license under copyrights and patents it now or hereafter owns or controls to make, | ||
11 | * have made, use, import, offer to sell and sell ("Utilize") this software subject to the | ||
12 | * terms herein. With respect to the foregoing patent license, such license is granted | ||
13 | * solely to the extent that any such patent is necessary to Utilize the software alone. | ||
14 | * The patent license shall not apply to any combinations which include this software, | ||
15 | * other than combinations with devices manufactured by or for TI ("TI Devices"). | ||
16 | * No hardware patent is licensed hereunder. | ||
17 | * | ||
18 | * Redistributions must preserve existing copyright notices and reproduce this license | ||
19 | * (including the above copyright notice and the disclaimer and (if applicable) source | ||
20 | * code license limitations below) in the documentation and/or other materials provided | ||
21 | * with the distribution | ||
22 | * | ||
23 | * Redistribution and use in binary form, without modification, are permitted provided | ||
24 | * that the following conditions are met: | ||
25 | * | ||
26 | * * No reverse engineering, decompilation, or disassembly of this software is | ||
27 | * permitted with respect to any software provided in binary form. | ||
28 | * | ||
29 | * * any redistribution and use are licensed by TI for use only with TI Devices. | ||
30 | * | ||
31 | * * Nothing shall obligate TI to provide you with source code for the software | ||
32 | * licensed and provided to you in appCntxtect code. | ||
33 | * | ||
34 | * If software source code is provided to you, modification and redistribution of the | ||
35 | * source code are permitted provided that the following conditions are met: | ||
36 | * | ||
37 | * * any redistribution and use of the source code, including any resulting derivative | ||
38 | * works, are licensed by TI for use only with TI Devices. | ||
39 | * | ||
40 | * * any redistribution and use of any appCntxtect code compiled from the source code | ||
41 | * and any resulting derivative works, are licensed by TI for use only with TI Devices. | ||
42 | * | ||
43 | * Neither the name of Texas Instruments Incorporated nor the names of its suppliers | ||
44 | * | ||
45 | * may be used to endorse or promote products derived from this software without | ||
46 | * specific prior written permission. | ||
47 | * | ||
48 | * DISCLAIMER. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY TI AND TI'S LICENSORS "AS IS" AND ANY EXPRESS | ||
51 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
52 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
53 | * IN NO EVENT SHALL TI AND TI'S LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
54 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
55 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
56 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | ||
57 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
58 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
59 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
60 | * | ||
61 | */ | ||
62 | |||
63 | #include <signal.h> | ||
64 | #include <stdio.h> | ||
65 | #include <stdlib.h> | ||
66 | |||
67 | #include <app_ptk_demo_common.h> | ||
68 | #include <cm_common.h> | ||
69 | #include <cm_postproc_node_cntxt.h> | ||
70 | |||
71 | #include "semseg_cnn.h" | ||
72 | |||
73 | #define SEMSEG_CNN_MAX_OUT_TENSOR_DIMS (3U) | ||
74 | #define SEMSEG_CNN_NUM_GRAPH_PARAMS (3U) | ||
75 | |||
76 | |||
77 | |||
78 | vx_status SEMSEG_CNN_init_SS(SEMSEG_CNN_Context *appCntxt) | ||
79 | { | ||
80 | int32_t i; | ||
81 | int32_t vxStatus = VX_SUCCESS; | ||
82 | vx_image scalerInput; | ||
83 | CM_LdcNodeCntxt *ldcObj; | ||
84 | CM_ScalerNodeCntxt *scalerObj; | ||
85 | CM_DLRNodeCntxt *dlrObj; | ||
86 | |||
87 | ldcObj = &appCntxt->ldcObj; | ||
88 | scalerObj = &appCntxt->scalerObj; | ||
89 | dlrObj = &appCntxt->dlrObj; | ||
90 | |||
91 | |||
92 | // Create input image object | ||
93 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
94 | { | ||
95 | for (i = 0; i < appCntxt->pipelineDepth; i++) | ||
96 | { | ||
97 | // create objects | ||
98 | appCntxt->vxInputImage[i] = vxCreateImage(appCntxt->vxContext, | ||
99 | appCntxt->inputImageWidth, | ||
100 | appCntxt->inputImageHeight, | ||
101 | VX_DF_IMAGE_UYVY); | ||
102 | |||
103 | if (appCntxt->vxInputImage[i] == NULL) | ||
104 | { | ||
105 | PTK_printf("[%s:%d] vxCreateImage() failed\n", | ||
106 | __FUNCTION__, __LINE__); | ||
107 | |||
108 | vxStatus = VX_FAILURE; | ||
109 | break; | ||
110 | } | ||
111 | |||
112 | vxSetReferenceName((vx_reference)appCntxt->vxInputImage[i], | ||
113 | "InputImage"); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | // Create rectified image object | ||
118 | if ((vxStatus == (vx_status)VX_SUCCESS) && appCntxt->enableLdcNode) | ||
119 | { | ||
120 | for (i = 0; i < appCntxt->pipelineDepth; i++) | ||
121 | { | ||
122 | appCntxt->vxRectifiedImage[i] = | ||
123 | vxCreateImage(appCntxt->vxContext, | ||
124 | appCntxt->inputImageWidth, | ||
125 | appCntxt->inputImageHeight, | ||
126 | VX_DF_IMAGE_NV12); | ||
127 | |||
128 | if (appCntxt->vxRectifiedImage[i] == NULL) | ||
129 | { | ||
130 | PTK_printf("[%s:%d] vxCreateImage() failed\n", | ||
131 | __FUNCTION__, __LINE__); | ||
132 | |||
133 | vxStatus = VX_FAILURE; | ||
134 | break; | ||
135 | } | ||
136 | |||
137 | vxSetReferenceName((vx_reference)appCntxt->vxRectifiedImage[i], | ||
138 | "RectifiedImage_NV12"); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
143 | { | ||
144 | vx_size tensorDims[SEMSEG_CNN_MAX_OUT_TENSOR_DIMS]; | ||
145 | |||
146 | /* DIM 0 - Width. */ | ||
147 | tensorDims[0] = appCntxt->tidlImageWidth; | ||
148 | |||
149 | /* DIM 1 - Height. */ | ||
150 | tensorDims[1] = appCntxt->tidlImageHeight; | ||
151 | |||
152 | /* DIM 2 - Number of channels. */ | ||
153 | tensorDims[2] = 1; | ||
154 | |||
155 | for (i = 0; i < appCntxt->pipelineDepth; i++) | ||
156 | { | ||
157 | appCntxt->vxOutTensor[i] = | ||
158 | vxCreateTensor(appCntxt->vxContext, | ||
159 | SEMSEG_CNN_MAX_OUT_TENSOR_DIMS, | ||
160 | tensorDims, | ||
161 | VX_TYPE_UINT8, | ||
162 | 0); | ||
163 | |||
164 | if (appCntxt->vxOutTensor[i] == NULL) | ||
165 | { | ||
166 | PTK_printf("[%s:%d] vxCreateTensor() failed\n", | ||
167 | __FUNCTION__, __LINE__); | ||
168 | |||
169 | vxStatus = VX_FAILURE; | ||
170 | break; | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | |||
175 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
176 | { | ||
177 | int32_t numDims; | ||
178 | |||
179 | #if 0 | ||
180 | CM_DLRCreateParams params; | ||
181 | int32_t status; | ||
182 | |||
183 | params.modelPath = appCntxt->dlrModelPath; | ||
184 | params.devType = DLR_DEVTYPE_CPU; | ||
185 | params.devId = 0; | ||
186 | |||
187 | status = CM_dlrNodeCntxtInit(dlrObj, ¶ms); | ||
188 | |||
189 | if (status < 0) | ||
190 | { | ||
191 | PTK_printf("[%s:%d] CM_dlrNodeCntxtInit() failed.\n", | ||
192 | __FUNCTION__, __LINE__); | ||
193 | |||
194 | vxStatus = VX_FAILURE; | ||
195 | } | ||
196 | #endif | ||
197 | |||
198 | numDims = dlrObj->input.info[0].dim - 1; | ||
199 | if (dlrObj->input.numInfo != CM_PREPROC_NUM_OUTPUT_TENSORS) | ||
200 | { | ||
201 | PTK_printf("[%s:%d] Number of DLR inputs [%d] does not match the " | ||
202 | "number of tensors [%d] output by the pre-processing " | ||
203 | "node.\n", | ||
204 | __FUNCTION__, | ||
205 | __LINE__, | ||
206 | dlrObj->input.numInfo, | ||
207 | CM_PREPROC_NUM_OUTPUT_TENSORS); | ||
208 | |||
209 | vxStatus = VX_FAILURE; | ||
210 | } | ||
211 | else if (numDims != CM_PREPROC_OUTPUT_TENSORS_DIMS) | ||
212 | { | ||
213 | PTK_printf("[%s:%d] Number of DLR input dims [%d] does not match the " | ||
214 | "number of tensor dims [%d] output by the pre-processing " | ||
215 | "node.\n", | ||
216 | __FUNCTION__, | ||
217 | __LINE__, | ||
218 | numDims, | ||
219 | CM_PREPROC_OUTPUT_TENSORS_DIMS); | ||
220 | |||
221 | vxStatus = VX_FAILURE; | ||
222 | } | ||
223 | else | ||
224 | { | ||
225 | CM_DLRIfInfo *info; | ||
226 | |||
227 | /* Allocate DLR input buffers. Currenly, the input buffers are held | ||
228 | * for each pipelined outputs so we need pipeline number of input | ||
229 | * buffers. | ||
230 | */ | ||
231 | info = &dlrObj->input.info[0]; | ||
232 | for (i = 0; i < appCntxt->pipelineDepth; i++) | ||
233 | { | ||
234 | /* Allocate the input buffer. */ | ||
235 | appCntxt->dlrInputBuff[i] = (float *) | ||
236 | tivxMemAlloc(info->size * sizeof(float), TIVX_MEM_EXTERNAL); | ||
237 | |||
238 | if (appCntxt->dlrInputBuff[i] == NULL) | ||
239 | { | ||
240 | PTK_printf("[%s:%d] Failed to allocate input (%d) " | ||
241 | "of size (%d) bytes.\n", | ||
242 | __FUNCTION__, __LINE__, i, info->size); | ||
243 | vxStatus = VX_FAILURE; | ||
244 | break; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | /* Allocate DLR input buffer. Curently, the output buffer is not | ||
249 | * held across frames so just one istance is sufficient. | ||
250 | */ | ||
251 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
252 | { | ||
253 | /* Allocate the output buffer. */ | ||
254 | info = &dlrObj->output.info[0]; | ||
255 | for (i = 0; i < appCntxt->pipelineDepth; i++) | ||
256 | { | ||
257 | /* Allocate the input buffer. */ | ||
258 | appCntxt->dlrOutputBuff[i] = (int32_t *) | ||
259 | tivxMemAlloc(info->size * sizeof(int32_t), TIVX_MEM_EXTERNAL); | ||
260 | |||
261 | if (appCntxt->dlrOutputBuff[i] == NULL) | ||
262 | { | ||
263 | PTK_printf("[%s:%d] Failed to allocate output (%d) " | ||
264 | "of size (%d) bytes.\n", | ||
265 | __FUNCTION__, __LINE__, i, info->size); | ||
266 | vxStatus = VX_FAILURE; | ||
267 | break; | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | } | ||
272 | } | ||
273 | |||
274 | /* Input image will be the scaler default input. */ | ||
275 | scalerInput = appCntxt->vxInputImage[0]; | ||
276 | |||
277 | /************************/ | ||
278 | /* LDC node */ | ||
279 | /************************/ | ||
280 | if ((appCntxt->enableLdcNode) && (vxStatus == (vx_status)VX_SUCCESS)) | ||
281 | { | ||
282 | CM_LdcCreateParams params; | ||
283 | |||
284 | params.width = appCntxt->inputImageWidth; | ||
285 | params.height = appCntxt->inputImageHeight; | ||
286 | params.ssFactor = appCntxt->ldcSsFactor; | ||
287 | params.blockWidth = appCntxt->ldcBlockWidth; | ||
288 | params.blockHeight = appCntxt->ldcBlockHeight; | ||
289 | params.pixelPad = appCntxt->ldcPixelPad; | ||
290 | params.lutFilePath = appCntxt->ldcLutFilePath; | ||
291 | |||
292 | vxStatus = CM_ldcNodeCntxtInit(&appCntxt->ldcObj, | ||
293 | appCntxt->vxContext, | ||
294 | ¶ms); | ||
295 | |||
296 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
297 | { | ||
298 | PTK_printf("[%s:%d] CM_ldcNodeCntxtInit() failed\n", | ||
299 | __FUNCTION__, __LINE__); | ||
300 | } | ||
301 | else | ||
302 | { | ||
303 | vxStatus = CM_ldcNodeCntxtSetup(ldcObj, | ||
304 | appCntxt->vxContext, | ||
305 | appCntxt->vxGraph, | ||
306 | appCntxt->vxInputImage[0], | ||
307 | appCntxt->vxRectifiedImage[0]); | ||
308 | |||
309 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
310 | { | ||
311 | PTK_printf("[%s:%d] CM_ldcNodeCntxtSetup() failed\n", | ||
312 | __FUNCTION__, __LINE__); | ||
313 | |||
314 | vxStatus = VX_FAILURE; | ||
315 | } | ||
316 | else | ||
317 | { | ||
318 | /* LDC output will be the scaler input. */ | ||
319 | scalerInput = appCntxt->vxRectifiedImage[0]; | ||
320 | } | ||
321 | } | ||
322 | } | ||
323 | |||
324 | /************************/ | ||
325 | /* Scaler node */ | ||
326 | /************************/ | ||
327 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
328 | { | ||
329 | CM_ScalerCreateParams params; | ||
330 | |||
331 | params.width = appCntxt->tidlImageWidth; | ||
332 | params.height = appCntxt->tidlImageHeight; | ||
333 | params.imageType = VX_DF_IMAGE_NV12; | ||
334 | params.interpolation = VX_INTERPOLATION_BILINEAR; | ||
335 | params.pipelineDepth = appCntxt->pipelineDepth; | ||
336 | |||
337 | vxStatus = CM_scalerNodeCntxtInit(&appCntxt->scalerObj, | ||
338 | appCntxt->vxContext, | ||
339 | ¶ms); | ||
340 | |||
341 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
342 | { | ||
343 | PTK_printf("[%s:%d] CM_scalerNodeCntxtInit() failed\n", | ||
344 | __FUNCTION__, __LINE__); | ||
345 | } | ||
346 | else | ||
347 | { | ||
348 | vxStatus = CM_scalerNodeCntxtSetup(scalerObj, | ||
349 | appCntxt->vxContext, | ||
350 | appCntxt->vxGraph, | ||
351 | scalerInput); | ||
352 | |||
353 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
354 | { | ||
355 | PTK_printf("[%s:%d] CM_scalerNodeCntxtSetup() failed\n", | ||
356 | __FUNCTION__, __LINE__); | ||
357 | |||
358 | vxStatus = VX_FAILURE; | ||
359 | } | ||
360 | } | ||
361 | } | ||
362 | |||
363 | return vxStatus; | ||
364 | } | ||
365 | |||
366 | vx_status SEMSEG_CNN_deinit_SS(SEMSEG_CNN_Context *appCntxt) | ||
367 | { | ||
368 | CM_DLRNodeCntxt *dlrObj; | ||
369 | CM_DLRIfInfo *info; | ||
370 | int32_t i; | ||
371 | vx_status vxStatus = VX_SUCCESS; | ||
372 | |||
373 | dlrObj = &appCntxt->dlrObj; | ||
374 | |||
375 | |||
376 | for (i = 0; i < appCntxt->pipelineDepth; i++) | ||
377 | { | ||
378 | if (appCntxt->vxInputImage[i] != NULL) | ||
379 | { | ||
380 | vxReleaseImage(&appCntxt->vxInputImage[i]); | ||
381 | } | ||
382 | } | ||
383 | |||
384 | if (appCntxt->enableLdcNode) | ||
385 | { | ||
386 | for (i = 0; i < appCntxt->pipelineDepth; i++) | ||
387 | { | ||
388 | if (appCntxt->vxRectifiedImage[i] != NULL) | ||
389 | { | ||
390 | vxReleaseImage(&appCntxt->vxRectifiedImage[i]); | ||
391 | } | ||
392 | } | ||
393 | |||
394 | CM_ldcNodeCntxtDeInit(&appCntxt->ldcObj); | ||
395 | } | ||
396 | |||
397 | |||
398 | /* Scaler node. */ | ||
399 | CM_scalerNodeCntxtDeInit(&appCntxt->scalerObj); | ||
400 | |||
401 | // vxOutTensor is always created | ||
402 | { | ||
403 | for (i = 0; i < appCntxt->pipelineDepth; i++) | ||
404 | { | ||
405 | if (appCntxt->vxOutTensor[i] != NULL) | ||
406 | { | ||
407 | vxReleaseTensor(&appCntxt->vxOutTensor[i]); | ||
408 | } | ||
409 | } | ||
410 | } | ||
411 | |||
412 | /* De-allocate the input buffer. */ | ||
413 | info = &dlrObj->input.info[0]; | ||
414 | for (i = 0; i < appCntxt->pipelineDepth; i++) | ||
415 | { | ||
416 | if (appCntxt->dlrInputBuff[i] != NULL) | ||
417 | { | ||
418 | tivxMemFree(appCntxt->dlrInputBuff[i], | ||
419 | info->size * sizeof(float), | ||
420 | TIVX_MEM_EXTERNAL); | ||
421 | } | ||
422 | } | ||
423 | |||
424 | /* De-allocate the DLR output buffer. */ | ||
425 | info = &dlrObj->output.info[0]; | ||
426 | for (i = 0; i < appCntxt->pipelineDepth; i++) | ||
427 | { | ||
428 | if (appCntxt->dlrOutputBuff[i] != NULL) | ||
429 | { | ||
430 | tivxMemFree(appCntxt->dlrOutputBuff[i], | ||
431 | info->size * sizeof(int32_t), | ||
432 | TIVX_MEM_EXTERNAL); | ||
433 | } | ||
434 | } | ||
435 | |||
436 | return vxStatus; | ||
437 | } | ||
438 | |||
439 | vx_status SEMSEG_CNN_setupPipeline(SEMSEG_CNN_Context * appCntxt) | ||
440 | { | ||
441 | CM_LdcNodeCntxt *ldcObj; | ||
442 | CM_ScalerNodeCntxt *scalerObj; | ||
443 | SEMSEG_CNN_graphParams *paramDesc; | ||
444 | vx_graph_parameter_queue_params_t q[SEMSEG_CNN_NUM_GRAPH_PARAMS]; | ||
445 | |||
446 | vx_status vxStatus; | ||
447 | uint32_t appValue; | ||
448 | uint32_t i; | ||
449 | uint32_t cnt; | ||
450 | |||
451 | ldcObj = &appCntxt->ldcObj; | ||
452 | scalerObj = &appCntxt->scalerObj; | ||
453 | cnt = 0; | ||
454 | |||
455 | appCntxt->numGraphParams = 3; | ||
456 | |||
457 | /* LDC node Param 6 ==> graph param 0. */ | ||
458 | vxStatus = ptkdemo_addParamByNodeIndex(appCntxt->vxGraph, | ||
459 | ldcObj->vxNode, | ||
460 | 6); | ||
461 | |||
462 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
463 | { | ||
464 | PTK_printf("[%s:%d] ptkdemo_addParamByNodeIndex() failed\n", | ||
465 | __FUNCTION__, __LINE__); | ||
466 | } | ||
467 | else | ||
468 | { | ||
469 | q[cnt++].refs_list = (vx_reference*)appCntxt->vxInputImage; | ||
470 | } | ||
471 | |||
472 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
473 | { | ||
474 | /* LDC node Param 7 ==> graph param 1. */ | ||
475 | vxStatus = ptkdemo_addParamByNodeIndex(appCntxt->vxGraph, | ||
476 | ldcObj->vxNode, | ||
477 | 7); | ||
478 | |||
479 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
480 | { | ||
481 | PTK_printf("[%s:%d] ptkdemo_addParamByNodeIndex() failed\n", | ||
482 | __FUNCTION__, __LINE__); | ||
483 | } | ||
484 | else | ||
485 | { | ||
486 | q[cnt++].refs_list = (vx_reference*)appCntxt->vxRectifiedImage; | ||
487 | } | ||
488 | } | ||
489 | |||
490 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
491 | { | ||
492 | /* Scaler node Param 1 ==> graph param 1/2. */ | ||
493 | vxStatus = ptkdemo_addParamByNodeIndex(appCntxt->vxGraph, | ||
494 | scalerObj->vxNode, | ||
495 | 1); | ||
496 | |||
497 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
498 | { | ||
499 | PTK_printf("[%s:%d] ptkdemo_addParamByNodeIndex() failed\n", | ||
500 | __FUNCTION__, __LINE__); | ||
501 | } | ||
502 | else | ||
503 | { | ||
504 | q[cnt++].refs_list = (vx_reference*)scalerObj->outImage; | ||
505 | } | ||
506 | } | ||
507 | |||
508 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
509 | { | ||
510 | for (i = 0; i < cnt; i++) | ||
511 | { | ||
512 | q[i].graph_parameter_index = i; | ||
513 | q[i].refs_list_size = appCntxt->pipelineDepth; | ||
514 | } | ||
515 | |||
516 | // allocate free Q | ||
517 | for (i = 0; i < appCntxt->pipelineDepth; i++) | ||
518 | { | ||
519 | paramDesc = &appCntxt->paramDesc[i]; | ||
520 | paramDesc->vxInputImage = appCntxt->vxInputImage[i]; | ||
521 | paramDesc->vxOutTensor = appCntxt->vxOutTensor[i]; | ||
522 | paramDesc->timestamp = &appCntxt->timestamp[i]; | ||
523 | paramDesc->dlrInputBuff = appCntxt->dlrInputBuff[i]; | ||
524 | paramDesc->dlrOutputBuff = appCntxt->dlrOutputBuff[i]; | ||
525 | paramDesc->vxScalerOut = scalerObj->outImage[i]; | ||
526 | paramDesc->vxRectifiedImage = appCntxt->vxRectifiedImage[i]; | ||
527 | |||
528 | SEMSEG_CNN_enqueInputDesc(appCntxt, paramDesc); | ||
529 | } | ||
530 | |||
531 | vxStatus = vxSetGraphScheduleConfig(appCntxt->vxGraph, | ||
532 | VX_GRAPH_SCHEDULE_MODE_QUEUE_AUTO, | ||
533 | cnt, | ||
534 | q); | ||
535 | |||
536 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
537 | { | ||
538 | PTK_printf("[%s:%d] vxSetGraphScheduleConfig() failed\n", | ||
539 | __FUNCTION__, __LINE__); | ||
540 | } | ||
541 | } | ||
542 | |||
543 | if (vxStatus == VX_SUCCESS) | ||
544 | { | ||
545 | /* explicitly set graph pipeline depth */ | ||
546 | vxStatus = tivxSetGraphPipelineDepth(appCntxt->vxGraph, | ||
547 | appCntxt->pipelineDepth); | ||
548 | |||
549 | if (vxStatus != VX_SUCCESS) | ||
550 | { | ||
551 | PTK_printf("[%s:%d] tivxSetGraphPipelineDepth() failed\n", | ||
552 | __FUNCTION__, __LINE__); | ||
553 | } | ||
554 | } | ||
555 | |||
556 | if (vxStatus == VX_SUCCESS) | ||
557 | { | ||
558 | appValue = appCntxt->vxEvtAppValBase + SEMSEG_CNN_SCALER_NODE_COMPLETE_EVENT; | ||
559 | |||
560 | vxStatus = vxRegisterEvent((vx_reference)scalerObj->vxNode, | ||
561 | VX_EVENT_NODE_COMPLETED, | ||
562 | 0, | ||
563 | appValue); | ||
564 | |||
565 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
566 | { | ||
567 | PTK_printf("[%s:%d] vxRegisterEvent() failed\n", | ||
568 | __FUNCTION__, __LINE__); | ||
569 | } | ||
570 | } | ||
571 | |||
572 | |||
573 | return vxStatus; | ||
574 | } | ||
575 | |||
576 | |||
577 | void SEMSEG_CNN_printStats(SEMSEG_CNN_Context * appCntxt) | ||
578 | { | ||
579 | tivx_utils_graph_perf_print(appCntxt->vxGraph); | ||
580 | |||
581 | appPerfPointPrint(&appCntxt->semsegPerf); | ||
582 | PTK_printf("\n"); | ||
583 | appPerfPointPrintFPS(&appCntxt->semsegPerf); | ||
584 | PTK_printf("\n"); | ||
585 | } | ||
586 | |||
587 | |||
588 | vx_status SEMSEG_CNN_exportStats(SEMSEG_CNN_Context * appCntxt, FILE *fp, bool exportAll) | ||
589 | { | ||
590 | vx_status vxStatus = tivx_utils_graph_perf_export(fp, appCntxt->vxGraph); | ||
591 | |||
592 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
593 | { | ||
594 | PTK_printf("[%s:%d] tivx_utils_graph_perf_export() failed\n", | ||
595 | __FUNCTION__, __LINE__); | ||
596 | } | ||
597 | |||
598 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
599 | { | ||
600 | if (exportAll == true) | ||
601 | { | ||
602 | app_perf_point_t *perfArr[1] = {&appCntxt->semsegPerf}; | ||
603 | appPerfStatsExportAll(fp, perfArr, 1); | ||
604 | } | ||
605 | } | ||
606 | |||
607 | return vxStatus; | ||
608 | } | ||
609 | |||
610 | |||
611 | vx_status SEMSEG_CNN_waitGraph(SEMSEG_CNN_Context * appCntxt) | ||
612 | { | ||
613 | vx_status vxStatus; | ||
614 | |||
615 | vxStatus = vxWaitGraph(appCntxt->vxGraph); | ||
616 | |||
617 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
618 | { | ||
619 | PTK_printf("[%s:%d] vxWaitGraph() failed\n", | ||
620 | __FUNCTION__, __LINE__); | ||
621 | |||
622 | vxStatus = VX_FAILURE; | ||
623 | } | ||
624 | |||
625 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
626 | { | ||
627 | /* Wait for the output queue to get flushed. */ | ||
628 | while (appCntxt->freeQ.size() != appCntxt->pipelineDepth) | ||
629 | { | ||
630 | std::this_thread::sleep_for(std::chrono::milliseconds(50)); | ||
631 | } | ||
632 | } | ||
633 | |||
634 | return vxStatus; | ||
635 | } | ||
636 | |||
637 | |||
638 | vx_status SEMSEG_CNN_process(SEMSEG_CNN_Context * appCntxt, | ||
639 | SEMSEG_CNN_graphParams * gpDesc, | ||
640 | uint64_t timestamp) | ||
641 | { | ||
642 | vx_status vxStatus = VX_SUCCESS; | ||
643 | uint16_t i; | ||
644 | uint8_t cnt = 0; | ||
645 | |||
646 | vx_reference obj[SEMSEG_CNN_NUM_GRAPH_PARAMS]; | ||
647 | |||
648 | // set timestamp of input image | ||
649 | *gpDesc->timestamp = timestamp; | ||
650 | |||
651 | obj[cnt++] = (vx_reference)gpDesc->vxInputImage; | ||
652 | if (appCntxt->enableLdcNode) | ||
653 | { | ||
654 | obj[cnt++] = (vx_reference)gpDesc->vxRectifiedImage; | ||
655 | } | ||
656 | obj[cnt++] = (vx_reference)gpDesc->vxScalerOut; | ||
657 | |||
658 | // Enqueue buffers | ||
659 | // Enqueue vxOutTensor after DLR is completed | ||
660 | for (i = 0; i < appCntxt->numGraphParams; i++) | ||
661 | { | ||
662 | vxStatus = vxGraphParameterEnqueueReadyRef(appCntxt->vxGraph, | ||
663 | i, | ||
664 | &obj[i], | ||
665 | 1); | ||
666 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
667 | { | ||
668 | PTK_printf("[%s:%d] vxGraphParameterEnqueueReadyRef(%d) " | ||
669 | "failed\n", __FUNCTION__, __LINE__, i); | ||
670 | break; | ||
671 | } | ||
672 | } | ||
673 | |||
674 | /* Push the descriptor to the DLR input queue. */ | ||
675 | SEMSEG_CNN_enquePreprocInputDesc(appCntxt, gpDesc); | ||
676 | |||
677 | return vxStatus; | ||
678 | } | ||
679 | |||
680 | |||
681 | vx_status SEMSEG_CNN_preProcess(SEMSEG_CNN_Context * appCntxt, | ||
682 | vx_image vxScalerOut, | ||
683 | float * dlrInputBuff) | ||
684 | { | ||
685 | vx_rectangle_t rect; | ||
686 | vx_imagepatch_addressing_t imgAddr; | ||
687 | uint8_t *srcPtr[2]; | ||
688 | vx_map_id mapId[2]; | ||
689 | bool mapped[2] = {false, false}; | ||
690 | vx_status vxStatus; | ||
691 | |||
692 | rect.start_x = 0; | ||
693 | rect.start_y = 0; | ||
694 | rect.end_x = appCntxt->tidlImageWidth; | ||
695 | rect.end_y = appCntxt->tidlImageHeight; | ||
696 | |||
697 | /* Map the image planes. */ | ||
698 | for (uint32_t i = 0; i < 2; i++) | ||
699 | { | ||
700 | /* Get the pointer to the YUV data plans. */ | ||
701 | vxStatus = vxMapImagePatch(vxScalerOut, | ||
702 | &rect, | ||
703 | i, | ||
704 | &mapId[i], | ||
705 | &imgAddr, | ||
706 | (void **)&srcPtr[i], | ||
707 | VX_WRITE_ONLY, | ||
708 | VX_MEMORY_TYPE_HOST, | ||
709 | VX_NOGAP_X); | ||
710 | |||
711 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
712 | { | ||
713 | PTK_printf("[%s:%d] vxMapImagePatch() failed.", | ||
714 | __FUNCTION__, __LINE__); | ||
715 | } | ||
716 | else | ||
717 | { | ||
718 | mapped[i] = true; | ||
719 | } | ||
720 | |||
721 | /* UV plane has half the height. */ | ||
722 | rect.end_y /= 2; | ||
723 | } | ||
724 | |||
725 | /* Take thr output image from the scaler which is in NV12 format and do | ||
726 | * the following: | ||
727 | * - Color convert the image from YUV420 to BGR format | ||
728 | * - Convert to float and write to the DLR input buffer | ||
729 | */ | ||
730 | |||
731 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
732 | { | ||
733 | vxStatus = | ||
734 | CM_SEMSEG_CNN_convertYUV2RGB(dlrInputBuff, | ||
735 | (const uint8_t**)srcPtr, | ||
736 | appCntxt->preProcMean, | ||
737 | appCntxt->preProcScale, | ||
738 | appCntxt->tidlImageWidth, | ||
739 | appCntxt->tidlImageHeight); | ||
740 | |||
741 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
742 | { | ||
743 | PTK_printf("[%s:%d] CM_SEMSEG_CNN_convertYUV2RGB() failed.", | ||
744 | __FUNCTION__, __LINE__); | ||
745 | } | ||
746 | } | ||
747 | |||
748 | /* Unmap the image planes. */ | ||
749 | for (uint32_t i = 0; i < 2; i++) | ||
750 | { | ||
751 | if (mapped[i] == true) | ||
752 | { | ||
753 | vxUnmapImagePatch(vxScalerOut, mapId[i]); | ||
754 | } | ||
755 | } | ||
756 | |||
757 | return vxStatus; | ||
758 | } | ||
759 | |||
760 | vx_status SEMSEG_CNN_postProcess(SEMSEG_CNN_Context * appCntxt, | ||
761 | vx_image vxScalerOut, | ||
762 | int32_t * dlrOutputBuff) | ||
763 | { | ||
764 | vx_rectangle_t rect; | ||
765 | vx_imagepatch_addressing_t imgAddr; | ||
766 | vx_map_id mapId; | ||
767 | uint8_t *dPtr; | ||
768 | vx_status vxStatus; | ||
769 | |||
770 | /* Get the pointer to the UV plane in the output image. */ | ||
771 | rect.start_x = 0; | ||
772 | rect.start_y = 0; | ||
773 | rect.end_x = appCntxt->tidlImageWidth; | ||
774 | rect.end_y = appCntxt->tidlImageHeight/2; // Chroma is UV interleaved | ||
775 | |||
776 | /* Get the pointer to the UV data plans. */ | ||
777 | vxStatus = vxMapImagePatch(vxScalerOut, | ||
778 | &rect, | ||
779 | 1, // UV plane | ||
780 | &mapId, | ||
781 | &imgAddr, | ||
782 | (void **)&dPtr, | ||
783 | VX_WRITE_ONLY, | ||
784 | VX_MEMORY_TYPE_HOST, | ||
785 | VX_NOGAP_X); | ||
786 | |||
787 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
788 | { | ||
789 | PTK_printf("[%s:%d] vxMapImagePatch() failed.", | ||
790 | __FUNCTION__, __LINE__); | ||
791 | } | ||
792 | else | ||
793 | { | ||
794 | int32_t *classId; | ||
795 | uint8_t *p; | ||
796 | float alpha; | ||
797 | float alphaC; | ||
798 | int32_t widthInByte; | ||
799 | |||
800 | alpha = 0.5; | ||
801 | alphaC = 1.0f - alpha; | ||
802 | |||
803 | classId = dlrOutputBuff; | ||
804 | widthInByte = imgAddr.dim_x/2; | ||
805 | |||
806 | /* Blend the input image data with the DLR output tensor and generate | ||
807 | * the output image. | ||
808 | */ | ||
809 | for (uint32_t i = 0; i < imgAddr.dim_y; i++) | ||
810 | { | ||
811 | p = dPtr; | ||
812 | |||
813 | for (int32_t j = 0; j < widthInByte; j++) | ||
814 | { | ||
815 | uint8_t c = (uint8_t)*classId; | ||
816 | |||
817 | p[0] = (uint8_t)((p[0] * alpha) + yuvColMap[c].u * alphaC); | ||
818 | p[1] = (uint8_t)((p[1] * alpha) + yuvColMap[c].v * alphaC); | ||
819 | |||
820 | /* Move to the next pain of UV pixels. */ | ||
821 | p += 2; | ||
822 | |||
823 | /* We use one class Id for a pair of UV pixels, so skip one | ||
824 | * class value. | ||
825 | */ | ||
826 | classId += 2; | ||
827 | } | ||
828 | |||
829 | /* Move to the next line in the image. */ | ||
830 | dPtr += imgAddr.stride_y; | ||
831 | |||
832 | /* Skip the next line in the tensor data. */ | ||
833 | classId += appCntxt->tidlImageWidth; | ||
834 | } | ||
835 | |||
836 | vxUnmapImagePatch(vxScalerOut, mapId); | ||
837 | } | ||
838 | |||
839 | return vxStatus; | ||
840 | |||
841 | } | ||
842 | |||
843 | vx_status SEMSEG_CNN_createOutTensor(SEMSEG_CNN_Context * appCntxt, | ||
844 | vx_tensor vxOutTensor, | ||
845 | int32_t * dlrOutputBuff) | ||
846 | { | ||
847 | uint8_t *dPtr; | ||
848 | vx_size start[SEMSEG_CNN_MAX_OUT_TENSOR_DIMS]; | ||
849 | vx_size strides[SEMSEG_CNN_MAX_OUT_TENSOR_DIMS]; | ||
850 | vx_size tensorDims[SEMSEG_CNN_MAX_OUT_TENSOR_DIMS]; | ||
851 | vx_map_id mapId; | ||
852 | vx_status vxStatus; | ||
853 | |||
854 | start[0] = 0; | ||
855 | start[1] = 0; | ||
856 | start[2] = 0; | ||
857 | |||
858 | /* DIM 0 - Width. */ | ||
859 | tensorDims[0] = appCntxt->tidlImageWidth; | ||
860 | |||
861 | /* DIM 1 - Height. */ | ||
862 | tensorDims[1] = appCntxt->tidlImageHeight; | ||
863 | |||
864 | /* DIM 2 - Number of channels. */ | ||
865 | tensorDims[2] = 1; | ||
866 | |||
867 | /* Strides */ | ||
868 | strides[0] = 1; | ||
869 | strides[1] = tensorDims[0]; | ||
870 | strides[2] = strides[1]*tensorDims[1]; | ||
871 | |||
872 | vxStatus = tivxMapTensorPatch(vxOutTensor, | ||
873 | SEMSEG_CNN_MAX_OUT_TENSOR_DIMS, | ||
874 | start, | ||
875 | tensorDims, | ||
876 | &mapId, | ||
877 | strides, | ||
878 | (void **)&dPtr, | ||
879 | VX_READ_AND_WRITE, | ||
880 | VX_MEMORY_TYPE_HOST); | ||
881 | |||
882 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
883 | { | ||
884 | PTK_printf("[%s:%d] tivxMapTensorPatch() failed.", | ||
885 | __FUNCTION__, __LINE__); | ||
886 | } | ||
887 | else | ||
888 | { | ||
889 | int32_t *sPtr; | ||
890 | uint32_t size; | ||
891 | |||
892 | sPtr = dlrOutputBuff; | ||
893 | size = tensorDims[0] * tensorDims[1]; | ||
894 | |||
895 | for (uint32_t i = 0; i < size; i++) | ||
896 | { | ||
897 | *dPtr++ = (uint8_t)*sPtr++; | ||
898 | } | ||
899 | |||
900 | vxStatus = tivxUnmapTensorPatch(vxOutTensor, mapId); | ||
901 | |||
902 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
903 | { | ||
904 | PTK_printf("[%s:%d] tivxUnmapTensorPatch() failed.", | ||
905 | __FUNCTION__, __LINE__); | ||
906 | } | ||
907 | } | ||
908 | |||
909 | return vxStatus; | ||
910 | } | ||
911 | |||
912 | |||
913 | |||
914 | vx_status SEMSEG_CNN_popFreeInputDesc(SEMSEG_CNN_Context *appCntxt, | ||
915 | SEMSEG_CNN_graphParams **gpDesc) | ||
916 | { | ||
917 | vx_status vxStatus = VX_SUCCESS; | ||
918 | |||
919 | *gpDesc = appCntxt->freeQ.pop(); | ||
920 | |||
921 | if (*gpDesc == nullptr) | ||
922 | { | ||
923 | vxStatus = VX_FAILURE; | ||
924 | } | ||
925 | |||
926 | return vxStatus; | ||
927 | } | ||
928 | |||
929 | |||
930 | vx_status SEMSEG_CNN_popPreprocInputDesc(SEMSEG_CNN_Context *appCntxt, | ||
931 | SEMSEG_CNN_graphParams **gpDesc) | ||
932 | { | ||
933 | vx_status vxStatus = VX_SUCCESS; | ||
934 | |||
935 | *gpDesc = appCntxt->preProcQ.pop(); | ||
936 | |||
937 | if (*gpDesc == nullptr) | ||
938 | { | ||
939 | vxStatus = VX_FAILURE; | ||
940 | } | ||
941 | |||
942 | return vxStatus; | ||
943 | } | ||
944 | |||
945 | |||
946 | vx_status SEMSEG_CNN_popDLRInputDesc(SEMSEG_CNN_Context *appCntxt, | ||
947 | SEMSEG_CNN_graphParams **gpDesc) | ||
948 | { | ||
949 | vx_status vxStatus = VX_SUCCESS; | ||
950 | |||
951 | *gpDesc = appCntxt->dlrQ.pop(); | ||
952 | |||
953 | if (*gpDesc == nullptr) | ||
954 | { | ||
955 | vxStatus = VX_FAILURE; | ||
956 | } | ||
957 | |||
958 | return vxStatus; | ||
959 | } | ||
960 | |||
961 | vx_status SEMSEG_CNN_popPostprocInputDesc(SEMSEG_CNN_Context *appCntxt, | ||
962 | SEMSEG_CNN_graphParams **gpDesc) | ||
963 | { | ||
964 | vx_status vxStatus = VX_SUCCESS; | ||
965 | |||
966 | *gpDesc = appCntxt->postProcQ.pop(); | ||
967 | |||
968 | if (*gpDesc == nullptr) | ||
969 | { | ||
970 | vxStatus = VX_FAILURE; | ||
971 | } | ||
972 | |||
973 | return vxStatus; | ||
974 | } | ||
975 | |||
976 | vx_status SEMSEG_CNN_getOutputDesc(SEMSEG_CNN_Context *appCntxt, | ||
977 | SEMSEG_CNN_graphParams *gpDesc) | ||
978 | { | ||
979 | SEMSEG_CNN_graphParams *desc; | ||
980 | vx_status vxStatus = VX_SUCCESS; | ||
981 | |||
982 | desc = appCntxt->outputQ.peek(); | ||
983 | |||
984 | if (desc == nullptr) | ||
985 | { | ||
986 | vxStatus = VX_FAILURE; | ||
987 | } | ||
988 | else | ||
989 | { | ||
990 | *gpDesc = *desc; | ||
991 | } | ||
992 | |||
993 | return vxStatus; | ||
994 | } | ||
995 | |||
996 | vx_status SEMSEG_CNN_popOutputDesc(SEMSEG_CNN_Context *appCntxt, | ||
997 | SEMSEG_CNN_graphParams **gpDesc) | ||
998 | { | ||
999 | vx_status vxStatus = VX_SUCCESS; | ||
1000 | |||
1001 | *gpDesc = appCntxt->outputQ.pop(); | ||
1002 | |||
1003 | if (*gpDesc == nullptr) | ||
1004 | { | ||
1005 | vxStatus = VX_FAILURE; | ||
1006 | } | ||
1007 | |||
1008 | return vxStatus; | ||
1009 | } | ||
1010 | |||
1011 | |||
1012 | void SEMSEG_CNN_enqueInputDesc(SEMSEG_CNN_Context *appCntxt, | ||
1013 | SEMSEG_CNN_graphParams *desc) | ||
1014 | { | ||
1015 | appCntxt->freeQ.push(desc); | ||
1016 | } | ||
1017 | |||
1018 | |||
1019 | void SEMSEG_CNN_enquePreprocInputDesc(SEMSEG_CNN_Context *appCntxt, | ||
1020 | SEMSEG_CNN_graphParams *desc) | ||
1021 | { | ||
1022 | appCntxt->preProcQ.push(desc); | ||
1023 | } | ||
1024 | |||
1025 | void SEMSEG_CNN_enqueDLRInputDesc(SEMSEG_CNN_Context *appCntxt, | ||
1026 | SEMSEG_CNN_graphParams *desc) | ||
1027 | { | ||
1028 | appCntxt->dlrQ.push(desc); | ||
1029 | } | ||
1030 | |||
1031 | void SEMSEG_CNN_enquePostprocInputDesc(SEMSEG_CNN_Context *appCntxt, | ||
1032 | SEMSEG_CNN_graphParams *desc) | ||
1033 | { | ||
1034 | appCntxt->postProcQ.push(desc); | ||
1035 | } | ||
1036 | |||
1037 | |||
1038 | void SEMSEG_CNN_enqueOutputDesc(SEMSEG_CNN_Context *appCntxt, | ||
1039 | SEMSEG_CNN_graphParams *desc) | ||
1040 | { | ||
1041 | appCntxt->outputQ.push(desc); | ||
1042 | } | ||
1043 | |||
1044 | |||
1045 | vx_status SEMSEG_CNN_processEvent(SEMSEG_CNN_Context * appCntxt, vx_event_t * event) | ||
1046 | { | ||
1047 | vx_reference ref; | ||
1048 | uint8_t i; | ||
1049 | uint32_t numRefs; | ||
1050 | uint32_t index; | ||
1051 | vx_status vxStatus; | ||
1052 | |||
1053 | // For profiling | ||
1054 | float diff; | ||
1055 | |||
1056 | ref = NULL; | ||
1057 | vxStatus = (vx_status)VX_SUCCESS; | ||
1058 | |||
1059 | if(event->type == VX_EVENT_NODE_COMPLETED) | ||
1060 | { | ||
1061 | uint32_t appValue = appCntxt->vxEvtAppValBase + | ||
1062 | SEMSEG_CNN_SCALER_NODE_COMPLETE_EVENT; | ||
1063 | |||
1064 | if (event->app_value != appValue) | ||
1065 | { | ||
1066 | /* Something wrong. We did not register for this event. */ | ||
1067 | PTK_printf("[%s:%d] Unknown App Value [%d].\n", | ||
1068 | __FUNCTION__, __LINE__, event->app_value); | ||
1069 | |||
1070 | vxStatus = VX_FAILURE; | ||
1071 | } | ||
1072 | |||
1073 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
1074 | { | ||
1075 | if (appCntxt->startPerfCapt == false) | ||
1076 | { | ||
1077 | appCntxt->startPerfCapt = true; | ||
1078 | } | ||
1079 | else | ||
1080 | { | ||
1081 | appPerfPointEnd(&appCntxt->semsegPerf); | ||
1082 | |||
1083 | appCntxt->profileEnd = GET_TIME(); | ||
1084 | diff = GET_DIFF(appCntxt->profileStart, appCntxt->profileEnd); | ||
1085 | CM_reportProctime("Inter_frame_interval", diff); | ||
1086 | } | ||
1087 | |||
1088 | appPerfPointBegin(&appCntxt->semsegPerf); | ||
1089 | appCntxt->profileStart = GET_TIME(); | ||
1090 | |||
1091 | /* Node execution is complete. Deque all the parameters | ||
1092 | * for this node. | ||
1093 | */ | ||
1094 | for (i = 0; i < appCntxt->numGraphParams; i++) | ||
1095 | { | ||
1096 | vxStatus = vxGraphParameterDequeueDoneRef(appCntxt->vxGraph, | ||
1097 | i, | ||
1098 | &ref, | ||
1099 | 1, | ||
1100 | &numRefs); | ||
1101 | if (vxStatus != (vx_status)VX_SUCCESS) | ||
1102 | { | ||
1103 | PTK_printf("[%s:%d] vxGraphParameterDequeueDoneRef() failed\n", | ||
1104 | __FUNCTION__, __LINE__); | ||
1105 | |||
1106 | break; | ||
1107 | } | ||
1108 | } | ||
1109 | |||
1110 | } | ||
1111 | |||
1112 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
1113 | { | ||
1114 | /* Wakeup the pre-process thread. The pre-process thread will | ||
1115 | * process the descriptor at the head of the queue. | ||
1116 | */ | ||
1117 | appCntxt->preProcSem->notify(); | ||
1118 | } | ||
1119 | } | ||
1120 | |||
1121 | |||
1122 | |||
1123 | return vxStatus; | ||
1124 | } | ||
1125 | |||
1126 | |||
1127 | vx_status SEMSEG_CNN_getOutBuff(SEMSEG_CNN_Context * appCntxt, | ||
1128 | vx_image * inputImage, | ||
1129 | vx_reference * output, | ||
1130 | vx_uint64 * timestamp) | ||
1131 | { | ||
1132 | vx_status vxStatus; | ||
1133 | SEMSEG_CNN_graphParams desc; | ||
1134 | |||
1135 | vxStatus = SEMSEG_CNN_getOutputDesc(appCntxt, &desc); | ||
1136 | |||
1137 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
1138 | { | ||
1139 | |||
1140 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
1141 | { | ||
1142 | if (appCntxt->enableLdcNode) | ||
1143 | { | ||
1144 | *inputImage = desc.vxRectifiedImage; | ||
1145 | } | ||
1146 | else | ||
1147 | { | ||
1148 | *inputImage = desc.vxInputImage; | ||
1149 | } | ||
1150 | |||
1151 | if (appCntxt->enablePostProcNode) | ||
1152 | { | ||
1153 | *output = (vx_reference)desc.vxScalerOut; | ||
1154 | } | ||
1155 | else | ||
1156 | { | ||
1157 | *output = (vx_reference)desc.vxOutTensor; | ||
1158 | } | ||
1159 | |||
1160 | *timestamp = *desc.timestamp; | ||
1161 | } | ||
1162 | else | ||
1163 | { | ||
1164 | PTK_printf("[%s:%d] SEMSEG_CNN_getOutputDesc() failed\n", | ||
1165 | __FUNCTION__, __LINE__); | ||
1166 | } | ||
1167 | } | ||
1168 | |||
1169 | return vxStatus; | ||
1170 | |||
1171 | } | ||
1172 | |||
1173 | vx_status SEMSEG_CNN_releaseOutBuff(SEMSEG_CNN_Context * appCntxt) | ||
1174 | { | ||
1175 | vx_status vxStatus; | ||
1176 | SEMSEG_CNN_graphParams * desc; | ||
1177 | |||
1178 | /* Pop the output descriptor. */ | ||
1179 | vxStatus = SEMSEG_CNN_popOutputDesc(appCntxt, &desc); | ||
1180 | |||
1181 | if (vxStatus == (vx_status)VX_SUCCESS) | ||
1182 | { | ||
1183 | /* Enqueue the descriptor to the free descriptor queue. */ | ||
1184 | SEMSEG_CNN_enqueInputDesc(appCntxt, desc); | ||
1185 | } | ||
1186 | |||
1187 | return vxStatus; | ||
1188 | } | ||