1 /* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 // System dependencies
31 #include <pthread.h>
32
33 // JPEG dependencies
34 #include "mm_jpeg_dbg.h"
35 #include "mm_jpeg_interface.h"
36 #include "mm_jpeg.h"
37 #include "mm_jpeg_inlines.h"
38
39 OMX_ERRORTYPE mm_jpegdec_ebd(OMX_HANDLETYPE hComponent,
40 OMX_PTR pAppData,
41 OMX_BUFFERHEADERTYPE *pBuffer);
42 OMX_ERRORTYPE mm_jpegdec_fbd(OMX_HANDLETYPE hComponent,
43 OMX_PTR pAppData,
44 OMX_BUFFERHEADERTYPE* pBuffer);
45 OMX_ERRORTYPE mm_jpegdec_event_handler(OMX_HANDLETYPE hComponent,
46 OMX_PTR pAppData,
47 OMX_EVENTTYPE eEvent,
48 OMX_U32 nData1,
49 OMX_U32 nData2,
50 OMX_PTR pEventData);
51
52
53 /** mm_jpegdec_destroy_job
54 *
55 * Arguments:
56 * @p_session: Session obj
57 *
58 * Return:
59 * 0 for success else failure
60 *
61 * Description:
62 * Destroy the job based paramenters
63 *
64 **/
mm_jpegdec_destroy_job(mm_jpeg_job_session_t * p_session)65 static int32_t mm_jpegdec_destroy_job(mm_jpeg_job_session_t *p_session)
66 {
67 int32_t rc = 0;
68
69 return rc;
70 }
71
72 /** mm_jpeg_job_done:
73 *
74 * Arguments:
75 * @p_session: decode session
76 *
77 * Return:
78 * OMX_ERRORTYPE
79 *
80 * Description:
81 * Finalize the job
82 *
83 **/
mm_jpegdec_job_done(mm_jpeg_job_session_t * p_session)84 static void mm_jpegdec_job_done(mm_jpeg_job_session_t *p_session)
85 {
86 mm_jpeg_obj *my_obj = (mm_jpeg_obj *)p_session->jpeg_obj;
87 mm_jpeg_job_q_node_t *node = NULL;
88
89 /*Destroy job related params*/
90 mm_jpegdec_destroy_job(p_session);
91
92 /*remove the job*/
93 node = mm_jpeg_queue_remove_job_by_job_id(&my_obj->ongoing_job_q,
94 p_session->jobId);
95 if (node) {
96 free(node);
97 }
98 p_session->encoding = OMX_FALSE;
99
100 /* wake up jobMgr thread to work on new job if there is any */
101 cam_sem_post(&my_obj->job_mgr.job_sem);
102 }
103
104
105 /** mm_jpegdec_session_send_buffers:
106 *
107 * Arguments:
108 * @data: job session
109 *
110 * Return:
111 * OMX error values
112 *
113 * Description:
114 * Send the buffers to OMX layer
115 *
116 **/
mm_jpegdec_session_send_buffers(void * data)117 OMX_ERRORTYPE mm_jpegdec_session_send_buffers(void *data)
118 {
119 uint32_t i = 0;
120 mm_jpeg_job_session_t* p_session = (mm_jpeg_job_session_t *)data;
121 OMX_ERRORTYPE ret = OMX_ErrorNone;
122 QOMX_BUFFER_INFO lbuffer_info;
123 mm_jpeg_decode_params_t *p_params = &p_session->dec_params;
124
125 memset(&lbuffer_info, 0x0, sizeof(QOMX_BUFFER_INFO));
126 for (i = 0; i < p_params->num_src_bufs; i++) {
127 LOGD("Source buffer %d", i);
128 lbuffer_info.fd = (OMX_U32)p_params->src_main_buf[i].fd;
129 ret = OMX_UseBuffer(p_session->omx_handle, &(p_session->p_in_omx_buf[i]), 0,
130 &lbuffer_info, p_params->src_main_buf[i].buf_size,
131 p_params->src_main_buf[i].buf_vaddr);
132 if (ret) {
133 LOGE("Error %d", ret);
134 return ret;
135 }
136 }
137
138 LOGD("Exit");
139 return ret;
140 }
141
142 /** mm_jpeg_session_free_buffers:
143 *
144 * Arguments:
145 * @data: job session
146 *
147 * Return:
148 * OMX error values
149 *
150 * Description:
151 * Free the buffers from OMX layer
152 *
153 **/
mm_jpegdec_session_free_buffers(void * data)154 OMX_ERRORTYPE mm_jpegdec_session_free_buffers(void *data)
155 {
156 OMX_ERRORTYPE ret = OMX_ErrorNone;
157 uint32_t i = 0;
158 mm_jpeg_job_session_t* p_session = (mm_jpeg_job_session_t *)data;
159 mm_jpeg_decode_params_t *p_params = &p_session->dec_params;
160
161 for (i = 0; i < p_params->num_src_bufs; i++) {
162 LOGD("Source buffer %d", i);
163 ret = OMX_FreeBuffer(p_session->omx_handle, 0, p_session->p_in_omx_buf[i]);
164 if (ret) {
165 LOGE("Error %d", ret);
166 return ret;
167 }
168 }
169
170 for (i = 0; i < p_params->num_dst_bufs; i++) {
171 LOGD("Dest buffer %d", i);
172 ret = OMX_FreeBuffer(p_session->omx_handle, 1, p_session->p_out_omx_buf[i]);
173 if (ret) {
174 LOGE("Error");
175 return ret;
176 }
177 }
178 LOGD("Exit");
179 return ret;
180 }
181
182 /** mm_jpegdec_session_create:
183 *
184 * Arguments:
185 * @p_session: job session
186 *
187 * Return:
188 * OMX error types
189 *
190 * Description:
191 * Create a jpeg encode session
192 *
193 **/
mm_jpegdec_session_create(mm_jpeg_job_session_t * p_session)194 OMX_ERRORTYPE mm_jpegdec_session_create(mm_jpeg_job_session_t* p_session)
195 {
196 OMX_ERRORTYPE rc = OMX_ErrorNone;
197
198 pthread_mutex_init(&p_session->lock, NULL);
199 pthread_cond_init(&p_session->cond, NULL);
200 cirq_reset(&p_session->cb_q);
201 p_session->state_change_pending = OMX_FALSE;
202 p_session->abort_state = MM_JPEG_ABORT_NONE;
203 p_session->error_flag = OMX_ErrorNone;
204 p_session->ebd_count = 0;
205 p_session->fbd_count = 0;
206 p_session->encode_pid = -1;
207 p_session->config = OMX_FALSE;
208
209 p_session->omx_callbacks.EmptyBufferDone = mm_jpegdec_ebd;
210 p_session->omx_callbacks.FillBufferDone = mm_jpegdec_fbd;
211 p_session->omx_callbacks.EventHandler = mm_jpegdec_event_handler;
212 p_session->exif_count_local = 0;
213
214 rc = OMX_GetHandle(&p_session->omx_handle,
215 "OMX.qcom.image.jpeg.decoder",
216 (void *)p_session,
217 &p_session->omx_callbacks);
218
219 if (OMX_ErrorNone != rc) {
220 LOGE("OMX_GetHandle failed (%d)", rc);
221 return rc;
222 }
223 return rc;
224 }
225
226 /** mm_jpegdec_session_destroy:
227 *
228 * Arguments:
229 * @p_session: job session
230 *
231 * Return:
232 * none
233 *
234 * Description:
235 * Destroy a jpeg encode session
236 *
237 **/
mm_jpegdec_session_destroy(mm_jpeg_job_session_t * p_session)238 void mm_jpegdec_session_destroy(mm_jpeg_job_session_t* p_session)
239 {
240 OMX_ERRORTYPE rc = OMX_ErrorNone;
241
242 LOGD("E");
243 if (NULL == p_session->omx_handle) {
244 LOGE("invalid handle");
245 return;
246 }
247
248 rc = mm_jpeg_session_change_state(p_session, OMX_StateIdle, NULL);
249 if (rc) {
250 LOGE("Error");
251 }
252
253 rc = mm_jpeg_session_change_state(p_session, OMX_StateLoaded,
254 mm_jpegdec_session_free_buffers);
255 if (rc) {
256 LOGE("Error");
257 }
258
259 rc = OMX_FreeHandle(p_session->omx_handle);
260 if (0 != rc) {
261 LOGE("OMX_FreeHandle failed (%d)", rc);
262 }
263 p_session->omx_handle = NULL;
264
265
266 pthread_mutex_destroy(&p_session->lock);
267 pthread_cond_destroy(&p_session->cond);
268 LOGD("X");
269 }
270
271 /** mm_jpeg_session_config_port:
272 *
273 * Arguments:
274 * @p_session: job session
275 *
276 * Return:
277 * OMX error values
278 *
279 * Description:
280 * Configure OMX ports
281 *
282 **/
mm_jpegdec_session_config_ports(mm_jpeg_job_session_t * p_session)283 OMX_ERRORTYPE mm_jpegdec_session_config_ports(mm_jpeg_job_session_t* p_session)
284 {
285 OMX_ERRORTYPE ret = OMX_ErrorNone;
286 mm_jpeg_decode_params_t *p_params = &p_session->dec_params;
287 mm_jpeg_decode_job_t *p_jobparams = &p_session->decode_job;
288
289 mm_jpeg_buf_t *p_src_buf =
290 &p_params->src_main_buf[p_jobparams->src_index];
291
292 p_session->inputPort.nPortIndex = 0;
293 p_session->outputPort.nPortIndex = 1;
294
295
296 ret = OMX_GetParameter(p_session->omx_handle, OMX_IndexParamPortDefinition,
297 &p_session->inputPort);
298 if (ret) {
299 LOGE("failed");
300 return ret;
301 }
302
303 ret = OMX_GetParameter(p_session->omx_handle, OMX_IndexParamPortDefinition,
304 &p_session->outputPort);
305 if (ret) {
306 LOGE("failed");
307 return ret;
308 }
309
310 p_session->inputPort.format.image.nFrameWidth =
311 (OMX_U32)p_jobparams->main_dim.src_dim.width;
312 p_session->inputPort.format.image.nFrameHeight =
313 (OMX_U32)p_jobparams->main_dim.src_dim.height;
314 p_session->inputPort.format.image.nStride =
315 p_src_buf->offset.mp[0].stride;
316 p_session->inputPort.format.image.nSliceHeight =
317 (OMX_U32)p_src_buf->offset.mp[0].scanline;
318 p_session->inputPort.format.image.eColorFormat =
319 map_jpeg_format(p_params->color_format);
320 p_session->inputPort.nBufferSize =
321 p_params->src_main_buf[p_jobparams->src_index].buf_size;
322 p_session->inputPort.nBufferCountActual = (OMX_U32)p_params->num_src_bufs;
323 ret = OMX_SetParameter(p_session->omx_handle, OMX_IndexParamPortDefinition,
324 &p_session->inputPort);
325 if (ret) {
326 LOGE("failed");
327 return ret;
328 }
329
330 return ret;
331 }
332
333
334 /** mm_jpegdec_session_config_main:
335 *
336 * Arguments:
337 * @p_session: job session
338 *
339 * Return:
340 * OMX error values
341 *
342 * Description:
343 * Configure main image
344 *
345 **/
mm_jpegdec_session_config_main(mm_jpeg_job_session_t * p_session)346 OMX_ERRORTYPE mm_jpegdec_session_config_main(mm_jpeg_job_session_t *p_session)
347 {
348 OMX_ERRORTYPE rc = OMX_ErrorNone;
349
350 /* config port */
351 LOGD("config port");
352 rc = mm_jpegdec_session_config_ports(p_session);
353 if (OMX_ErrorNone != rc) {
354 LOGE("config port failed");
355 return rc;
356 }
357
358
359 /* TODO: config crop */
360
361 return rc;
362 }
363
364 /** mm_jpeg_session_configure:
365 *
366 * Arguments:
367 * @data: encode session
368 *
369 * Return:
370 * none
371 *
372 * Description:
373 * Configure the session
374 *
375 **/
mm_jpegdec_session_configure(mm_jpeg_job_session_t * p_session)376 static OMX_ERRORTYPE mm_jpegdec_session_configure(mm_jpeg_job_session_t *p_session)
377 {
378 OMX_ERRORTYPE ret = OMX_ErrorNone;
379
380 LOGD("E ");
381
382 MM_JPEG_CHK_ABORT(p_session, ret, error);
383
384 /* config main img */
385 ret = mm_jpegdec_session_config_main(p_session);
386 if (OMX_ErrorNone != ret) {
387 LOGE("config main img failed");
388 goto error;
389 }
390
391 /* TODO: common config (if needed) */
392
393 ret = mm_jpeg_session_change_state(p_session, OMX_StateIdle,
394 mm_jpegdec_session_send_buffers);
395 if (ret) {
396 LOGE("change state to idle failed %d", ret);
397 goto error;
398 }
399
400 ret = mm_jpeg_session_change_state(p_session, OMX_StateExecuting,
401 NULL);
402 if (ret) {
403 LOGE("change state to executing failed %d", ret);
404 goto error;
405 }
406
407 error:
408 LOGD("X ret %d", ret);
409 return ret;
410 }
411
mm_jpeg_session_port_enable(mm_jpeg_job_session_t * p_session,OMX_U32 nPortIndex,OMX_BOOL wait)412 static OMX_ERRORTYPE mm_jpeg_session_port_enable(
413 mm_jpeg_job_session_t *p_session,
414 OMX_U32 nPortIndex,
415 OMX_BOOL wait)
416 {
417 OMX_ERRORTYPE ret = OMX_ErrorNone;
418 OMX_EVENTTYPE lEvent;
419
420 pthread_mutex_lock(&p_session->lock);
421 p_session->event_pending = OMX_TRUE;
422 pthread_mutex_unlock(&p_session->lock);
423
424 ret = OMX_SendCommand(p_session->omx_handle, OMX_CommandPortEnable,
425 nPortIndex, NULL);
426
427 if (ret) {
428 LOGE("failed");
429 return ret;
430 }
431
432 if (wait == OMX_TRUE) {
433 // Wait for cmd complete
434 pthread_mutex_lock(&p_session->lock);
435 if (p_session->event_pending == OMX_TRUE) {
436 LOGD("before wait");
437 pthread_cond_wait(&p_session->cond, &p_session->lock);
438 lEvent = p_session->omxEvent;
439 LOGD("after wait");
440 }
441 lEvent = p_session->omxEvent;
442 pthread_mutex_unlock(&p_session->lock);
443
444 if (lEvent != OMX_EventCmdComplete) {
445 LOGD("Unexpected event %d",lEvent);
446 return OMX_ErrorUndefined;
447 }
448 }
449 return OMX_ErrorNone;
450 }
451
mm_jpeg_session_port_disable(mm_jpeg_job_session_t * p_session,OMX_U32 nPortIndex,OMX_BOOL wait)452 static OMX_ERRORTYPE mm_jpeg_session_port_disable(
453 mm_jpeg_job_session_t *p_session,
454 OMX_U32 nPortIndex,
455 OMX_BOOL wait)
456 {
457 OMX_ERRORTYPE ret = OMX_ErrorNone;
458 OMX_EVENTTYPE lEvent;
459
460 pthread_mutex_lock(&p_session->lock);
461 p_session->event_pending = OMX_TRUE;
462 pthread_mutex_unlock(&p_session->lock);
463
464 ret = OMX_SendCommand(p_session->omx_handle, OMX_CommandPortDisable,
465 nPortIndex, NULL);
466
467 if (ret) {
468 LOGE("failed");
469 return ret;
470 }
471 if (wait == OMX_TRUE) {
472 // Wait for cmd complete
473 pthread_mutex_lock(&p_session->lock);
474 if (p_session->event_pending == OMX_TRUE) {
475 LOGD("before wait");
476 pthread_cond_wait(&p_session->cond, &p_session->lock);
477
478 LOGD("after wait");
479 }
480 lEvent = p_session->omxEvent;
481 pthread_mutex_unlock(&p_session->lock);
482
483 if (lEvent != OMX_EventCmdComplete) {
484 LOGD("Unexpected event %d",lEvent);
485 return OMX_ErrorUndefined;
486 }
487 }
488 return OMX_ErrorNone;
489 }
490
491
492 /** mm_jpegdec_session_decode:
493 *
494 * Arguments:
495 * @p_session: encode session
496 *
497 * Return:
498 * OMX_ERRORTYPE
499 *
500 * Description:
501 * Start the encoding
502 *
503 **/
mm_jpegdec_session_decode(mm_jpeg_job_session_t * p_session)504 static OMX_ERRORTYPE mm_jpegdec_session_decode(mm_jpeg_job_session_t *p_session)
505 {
506 OMX_ERRORTYPE ret = OMX_ErrorNone;
507 mm_jpeg_decode_params_t *p_params = &p_session->dec_params;
508 mm_jpeg_decode_job_t *p_jobparams = &p_session->decode_job;
509 OMX_EVENTTYPE lEvent;
510 uint32_t i;
511 QOMX_BUFFER_INFO lbuffer_info;
512
513 pthread_mutex_lock(&p_session->lock);
514 p_session->abort_state = MM_JPEG_ABORT_NONE;
515 p_session->encoding = OMX_FALSE;
516 pthread_mutex_unlock(&p_session->lock);
517
518 if (OMX_FALSE == p_session->config) {
519 ret = mm_jpegdec_session_configure(p_session);
520 if (ret) {
521 LOGE("Error");
522 goto error;
523 }
524 p_session->config = OMX_TRUE;
525 }
526
527 pthread_mutex_lock(&p_session->lock);
528 p_session->encoding = OMX_TRUE;
529 pthread_mutex_unlock(&p_session->lock);
530
531 MM_JPEG_CHK_ABORT(p_session, ret, error);
532
533 p_session->event_pending = OMX_TRUE;
534
535 ret = OMX_EmptyThisBuffer(p_session->omx_handle,
536 p_session->p_in_omx_buf[p_jobparams->src_index]);
537 if (ret) {
538 LOGE("Error");
539 goto error;
540 }
541
542 // Wait for port settings changed
543 pthread_mutex_lock(&p_session->lock);
544 if (p_session->event_pending == OMX_TRUE) {
545 LOGD("before wait");
546 pthread_cond_wait(&p_session->cond, &p_session->lock);
547 }
548 lEvent = p_session->omxEvent;
549 LOGD("after wait");
550 pthread_mutex_unlock(&p_session->lock);
551
552 if (lEvent != OMX_EventPortSettingsChanged) {
553 LOGD("Unexpected event %d",lEvent);
554 goto error;
555 }
556
557 // Disable output port (wait)
558 mm_jpeg_session_port_disable(p_session,
559 p_session->outputPort.nPortIndex,
560 OMX_TRUE);
561
562 // Get port definition
563 ret = OMX_GetParameter(p_session->omx_handle, OMX_IndexParamPortDefinition,
564 &p_session->outputPort);
565 if (ret) {
566 LOGE("failed");
567 return ret;
568 }
569
570 // Set port definition
571 p_session->outputPort.format.image.nFrameWidth =
572 (OMX_U32)p_jobparams->main_dim.dst_dim.width;
573 p_session->outputPort.format.image.nFrameHeight =
574 (OMX_U32)p_jobparams->main_dim.dst_dim.height;
575 p_session->outputPort.format.image.eColorFormat =
576 map_jpeg_format(p_params->color_format);
577
578 p_session->outputPort.nBufferSize =
579 p_params->dest_buf[p_jobparams->dst_index].buf_size;
580 p_session->outputPort.nBufferCountActual = (OMX_U32)p_params->num_dst_bufs;
581
582 p_session->outputPort.format.image.nSliceHeight =
583 (OMX_U32)
584 p_params->dest_buf[p_jobparams->dst_index].offset.mp[0].scanline;
585 p_session->outputPort.format.image.nStride =
586 p_params->dest_buf[p_jobparams->dst_index].offset.mp[0].stride;
587
588 ret = OMX_SetParameter(p_session->omx_handle, OMX_IndexParamPortDefinition,
589 &p_session->outputPort);
590 if (ret) {
591 LOGE("failed");
592 return ret;
593 }
594
595 // Enable port (no wait)
596 mm_jpeg_session_port_enable(p_session,
597 p_session->outputPort.nPortIndex,
598 OMX_FALSE);
599
600 memset(&lbuffer_info, 0x0, sizeof(QOMX_BUFFER_INFO));
601 // Use buffers
602 for (i = 0; i < p_params->num_dst_bufs; i++) {
603 lbuffer_info.fd = (OMX_U32)p_params->dest_buf[i].fd;
604 LOGD("Dest buffer %d", (unsigned int)i);
605 ret = OMX_UseBuffer(p_session->omx_handle, &(p_session->p_out_omx_buf[i]),
606 1, &lbuffer_info, p_params->dest_buf[i].buf_size,
607 p_params->dest_buf[i].buf_vaddr);
608 if (ret) {
609 LOGE("Error");
610 return ret;
611 }
612 }
613
614 // Wait for port enable completion
615 pthread_mutex_lock(&p_session->lock);
616 if (p_session->event_pending == OMX_TRUE) {
617 LOGD("before wait");
618 pthread_cond_wait(&p_session->cond, &p_session->lock);
619 lEvent = p_session->omxEvent;
620 LOGD("after wait");
621 }
622 lEvent = p_session->omxEvent;
623 pthread_mutex_unlock(&p_session->lock);
624
625 if (lEvent != OMX_EventCmdComplete) {
626 LOGD("Unexpected event %d",lEvent);
627 goto error;
628 }
629
630 ret = OMX_FillThisBuffer(p_session->omx_handle,
631 p_session->p_out_omx_buf[p_jobparams->dst_index]);
632 if (ret) {
633 LOGE("Error");
634 goto error;
635 }
636
637 MM_JPEG_CHK_ABORT(p_session, ret, error);
638
639 error:
640
641 LOGD("X ");
642 return ret;
643 }
644
645 /** mm_jpegdec_process_decoding_job:
646 *
647 * Arguments:
648 * @my_obj: jpeg client
649 * @job_node: job node
650 *
651 * Return:
652 * 0 for success -1 otherwise
653 *
654 * Description:
655 * Start the encoding job
656 *
657 **/
mm_jpegdec_process_decoding_job(mm_jpeg_obj * my_obj,mm_jpeg_job_q_node_t * job_node)658 int32_t mm_jpegdec_process_decoding_job(mm_jpeg_obj *my_obj, mm_jpeg_job_q_node_t* job_node)
659 {
660 mm_jpeg_q_data_t qdata;
661 int32_t rc = 0;
662 OMX_ERRORTYPE ret = OMX_ErrorNone;
663 mm_jpeg_job_session_t *p_session = NULL;
664
665 /* check if valid session */
666 p_session = mm_jpeg_get_session(my_obj, job_node->dec_info.job_id);
667 if (NULL == p_session) {
668 LOGE("invalid job id %x",
669 job_node->dec_info.job_id);
670 return -1;
671 }
672
673 /* sent encode cmd to OMX, queue job into ongoing queue */
674 qdata.p = job_node;
675 rc = mm_jpeg_queue_enq(&my_obj->ongoing_job_q, qdata);
676 if (rc) {
677 LOGE("jpeg enqueue failed %d", ret);
678 goto error;
679 }
680
681 p_session->decode_job = job_node->dec_info.decode_job;
682 p_session->jobId = job_node->dec_info.job_id;
683 ret = mm_jpegdec_session_decode(p_session);
684 if (ret) {
685 LOGE("encode session failed");
686 goto error;
687 }
688
689 LOGD("Success X ");
690 return rc;
691
692 error:
693
694 if ((OMX_ErrorNone != ret) &&
695 (NULL != p_session->dec_params.jpeg_cb)) {
696 p_session->job_status = JPEG_JOB_STATUS_ERROR;
697 LOGD("send jpeg error callback %d",
698 p_session->job_status);
699 p_session->dec_params.jpeg_cb(p_session->job_status,
700 p_session->client_hdl,
701 p_session->jobId,
702 NULL,
703 p_session->dec_params.userdata);
704 }
705
706 /*remove the job*/
707 mm_jpegdec_job_done(p_session);
708 LOGD("Error X ");
709
710 return rc;
711 }
712
713 /** mm_jpeg_start_decode_job:
714 *
715 * Arguments:
716 * @my_obj: jpeg object
717 * @client_hdl: client handle
718 * @job: pointer to encode job
719 * @jobId: job id
720 *
721 * Return:
722 * 0 for success else failure
723 *
724 * Description:
725 * Start the encoding job
726 *
727 **/
mm_jpegdec_start_decode_job(mm_jpeg_obj * my_obj,mm_jpeg_job_t * job,uint32_t * job_id)728 int32_t mm_jpegdec_start_decode_job(mm_jpeg_obj *my_obj,
729 mm_jpeg_job_t *job,
730 uint32_t *job_id)
731 {
732 mm_jpeg_q_data_t qdata;
733 int32_t rc = -1;
734 uint8_t session_idx = 0;
735 uint8_t client_idx = 0;
736 mm_jpeg_job_q_node_t* node = NULL;
737 mm_jpeg_job_session_t *p_session = NULL;
738 mm_jpeg_decode_job_t *p_jobparams = &job->decode_job;
739
740 *job_id = 0;
741
742 /* check if valid session */
743 session_idx = GET_SESSION_IDX(p_jobparams->session_id);
744 client_idx = GET_CLIENT_IDX(p_jobparams->session_id);
745 LOGD("session_idx %d client idx %d",
746 session_idx, client_idx);
747
748 if ((session_idx >= MM_JPEG_MAX_SESSION) ||
749 (client_idx >= MAX_JPEG_CLIENT_NUM)) {
750 LOGE("invalid session id %x",
751 job->decode_job.session_id);
752 return rc;
753 }
754
755 p_session = &my_obj->clnt_mgr[client_idx].session[session_idx];
756 if (OMX_FALSE == p_session->active) {
757 LOGE("session not active %x",
758 job->decode_job.session_id);
759 return rc;
760 }
761
762 if ((p_jobparams->src_index >= (int32_t)p_session->dec_params.num_src_bufs) ||
763 (p_jobparams->dst_index >= (int32_t)p_session->dec_params.num_dst_bufs)) {
764 LOGE("invalid buffer indices");
765 return rc;
766 }
767
768 /* enqueue new job into todo job queue */
769 node = (mm_jpeg_job_q_node_t *)malloc(sizeof(mm_jpeg_job_q_node_t));
770 if (NULL == node) {
771 LOGE("No memory for mm_jpeg_job_q_node_t");
772 return -1;
773 }
774
775 *job_id = job->decode_job.session_id |
776 ((p_session->job_hist++ % JOB_HIST_MAX) << 16);
777
778 memset(node, 0, sizeof(mm_jpeg_job_q_node_t));
779 node->dec_info.decode_job = job->decode_job;
780 node->dec_info.job_id = *job_id;
781 node->dec_info.client_handle = p_session->client_hdl;
782 node->type = MM_JPEG_CMD_TYPE_DECODE_JOB;
783
784 qdata.p = node;
785 rc = mm_jpeg_queue_enq(&my_obj->job_mgr.job_queue, qdata);
786 if (0 == rc) {
787 cam_sem_post(&my_obj->job_mgr.job_sem);
788 }
789
790 return rc;
791 }
792
793 /** mm_jpegdec_create_session:
794 *
795 * Arguments:
796 * @my_obj: jpeg object
797 * @client_hdl: client handle
798 * @p_params: pointer to encode params
799 * @p_session_id: session id
800 *
801 * Return:
802 * 0 for success else failure
803 *
804 * Description:
805 * Start the encoding session
806 *
807 **/
mm_jpegdec_create_session(mm_jpeg_obj * my_obj,uint32_t client_hdl,mm_jpeg_decode_params_t * p_params,uint32_t * p_session_id)808 int32_t mm_jpegdec_create_session(mm_jpeg_obj *my_obj,
809 uint32_t client_hdl,
810 mm_jpeg_decode_params_t *p_params,
811 uint32_t* p_session_id)
812 {
813 int32_t rc = 0;
814 OMX_ERRORTYPE ret = OMX_ErrorNone;
815 uint8_t clnt_idx = 0;
816 int session_idx = -1;
817 mm_jpeg_job_session_t *p_session = NULL;
818 *p_session_id = 0;
819
820 /* validate the parameters */
821 if ((p_params->num_src_bufs > MM_JPEG_MAX_BUF)
822 || (p_params->num_dst_bufs > MM_JPEG_MAX_BUF)) {
823 LOGE("invalid num buffers");
824 return rc;
825 }
826
827 /* check if valid client */
828 clnt_idx = mm_jpeg_util_get_index_by_handler(client_hdl);
829 if (clnt_idx >= MAX_JPEG_CLIENT_NUM) {
830 LOGE("invalid client with handler (%d)", client_hdl);
831 return rc;
832 }
833
834 session_idx = mm_jpeg_get_new_session_idx(my_obj, clnt_idx, &p_session);
835 if (session_idx < 0) {
836 LOGE("invalid session id (%d)", session_idx);
837 return rc;
838 }
839
840 ret = mm_jpegdec_session_create(p_session);
841 if (OMX_ErrorNone != ret) {
842 p_session->active = OMX_FALSE;
843 LOGE("jpeg session create failed");
844 return rc;
845 }
846
847 *p_session_id = (JOB_ID_MAGICVAL << 24) |
848 ((unsigned)session_idx << 8) | clnt_idx;
849
850 /*copy the params*/
851 p_session->dec_params = *p_params;
852 p_session->client_hdl = client_hdl;
853 p_session->sessionId = *p_session_id;
854 p_session->jpeg_obj = (void*)my_obj; /* save a ptr to jpeg_obj */
855 LOGD("session id %x", *p_session_id);
856
857 return rc;
858 }
859
860 /** mm_jpegdec_destroy_session:
861 *
862 * Arguments:
863 * @my_obj: jpeg object
864 * @session_id: session index
865 *
866 * Return:
867 * 0 for success else failure
868 *
869 * Description:
870 * Destroy the encoding session
871 *
872 **/
mm_jpegdec_destroy_session(mm_jpeg_obj * my_obj,mm_jpeg_job_session_t * p_session)873 int32_t mm_jpegdec_destroy_session(mm_jpeg_obj *my_obj,
874 mm_jpeg_job_session_t *p_session)
875 {
876 int32_t rc = 0;
877 mm_jpeg_job_q_node_t *node = NULL;
878
879 if (NULL == p_session) {
880 LOGE("invalid session");
881 return rc;
882 }
883 uint32_t session_id = p_session->sessionId;
884 pthread_mutex_lock(&my_obj->job_lock);
885
886 /* abort job if in todo queue */
887 LOGD("abort todo jobs");
888 node = mm_jpeg_queue_remove_job_by_session_id(&my_obj->job_mgr.job_queue, session_id);
889 while (NULL != node) {
890 free(node);
891 node = mm_jpeg_queue_remove_job_by_session_id(&my_obj->job_mgr.job_queue, session_id);
892 }
893
894 /* abort job if in ongoing queue */
895 LOGD("abort ongoing jobs");
896 node = mm_jpeg_queue_remove_job_by_session_id(&my_obj->ongoing_job_q, session_id);
897 while (NULL != node) {
898 free(node);
899 node = mm_jpeg_queue_remove_job_by_session_id(&my_obj->ongoing_job_q, session_id);
900 }
901
902 /* abort the current session */
903 mm_jpeg_session_abort(p_session);
904 mm_jpegdec_session_destroy(p_session);
905 mm_jpeg_remove_session_idx(my_obj, session_id);
906 pthread_mutex_unlock(&my_obj->job_lock);
907
908 /* wake up jobMgr thread to work on new job if there is any */
909 cam_sem_post(&my_obj->job_mgr.job_sem);
910 LOGD("X");
911
912 return rc;
913 }
914
915 /** mm_jpegdec_destroy_session_by_id:
916 *
917 * Arguments:
918 * @my_obj: jpeg object
919 * @session_id: session index
920 *
921 * Return:
922 * 0 for success else failure
923 *
924 * Description:
925 * Destroy the encoding session
926 *
927 **/
mm_jpegdec_destroy_session_by_id(mm_jpeg_obj * my_obj,uint32_t session_id)928 int32_t mm_jpegdec_destroy_session_by_id(mm_jpeg_obj *my_obj, uint32_t session_id)
929 {
930 int32_t rc = 0;
931 mm_jpeg_job_session_t *p_session = mm_jpeg_get_session(my_obj, session_id);
932
933 if (NULL == p_session) {
934 LOGE("session is not valid");
935 return rc;
936 }
937
938 return mm_jpegdec_destroy_session(my_obj, p_session);
939 }
940
941
942
mm_jpegdec_ebd(OMX_HANDLETYPE hComponent,OMX_PTR pAppData,OMX_BUFFERHEADERTYPE * pBuffer)943 OMX_ERRORTYPE mm_jpegdec_ebd(OMX_HANDLETYPE hComponent,
944 OMX_PTR pAppData,
945 OMX_BUFFERHEADERTYPE *pBuffer)
946 {
947 mm_jpeg_job_session_t *p_session = (mm_jpeg_job_session_t *) pAppData;
948
949 LOGD("count %d ", p_session->ebd_count);
950 pthread_mutex_lock(&p_session->lock);
951 p_session->ebd_count++;
952 pthread_mutex_unlock(&p_session->lock);
953 return 0;
954 }
955
mm_jpegdec_fbd(OMX_HANDLETYPE hComponent,OMX_PTR pAppData,OMX_BUFFERHEADERTYPE * pBuffer)956 OMX_ERRORTYPE mm_jpegdec_fbd(OMX_HANDLETYPE hComponent,
957 OMX_PTR pAppData,
958 OMX_BUFFERHEADERTYPE *pBuffer)
959 {
960 OMX_ERRORTYPE ret = OMX_ErrorNone;
961 mm_jpeg_job_session_t *p_session = (mm_jpeg_job_session_t *) pAppData;
962 mm_jpeg_output_t output_buf;
963
964 LOGD("count %d ", p_session->fbd_count);
965
966 pthread_mutex_lock(&p_session->lock);
967
968 if (MM_JPEG_ABORT_NONE != p_session->abort_state) {
969 pthread_mutex_unlock(&p_session->lock);
970 return ret;
971 }
972
973 p_session->fbd_count++;
974 if (NULL != p_session->dec_params.jpeg_cb) {
975 p_session->job_status = JPEG_JOB_STATUS_DONE;
976 output_buf.buf_filled_len = (uint32_t)pBuffer->nFilledLen;
977 output_buf.buf_vaddr = pBuffer->pBuffer;
978 output_buf.fd = -1;
979 LOGD("send jpeg callback %d",
980 p_session->job_status);
981 p_session->dec_params.jpeg_cb(p_session->job_status,
982 p_session->client_hdl,
983 p_session->jobId,
984 &output_buf,
985 p_session->dec_params.userdata);
986
987 /* remove from ready queue */
988 mm_jpegdec_job_done(p_session);
989 }
990 pthread_mutex_unlock(&p_session->lock);
991 LOGD("Exit");
992
993 return ret;
994 }
995
mm_jpegdec_event_handler(OMX_HANDLETYPE hComponent,OMX_PTR pAppData,OMX_EVENTTYPE eEvent,OMX_U32 nData1,OMX_U32 nData2,OMX_PTR pEventData)996 OMX_ERRORTYPE mm_jpegdec_event_handler(OMX_HANDLETYPE hComponent,
997 OMX_PTR pAppData,
998 OMX_EVENTTYPE eEvent,
999 OMX_U32 nData1,
1000 OMX_U32 nData2,
1001 OMX_PTR pEventData)
1002 {
1003 mm_jpeg_job_session_t *p_session = (mm_jpeg_job_session_t *) pAppData;
1004
1005 LOGD("%d %d %d state %d", eEvent, (int)nData1,
1006 (int)nData2, p_session->abort_state);
1007
1008 LOGD("AppData=%p ", pAppData);
1009
1010 pthread_mutex_lock(&p_session->lock);
1011 p_session->omxEvent = eEvent;
1012 if (MM_JPEG_ABORT_INIT == p_session->abort_state) {
1013 p_session->abort_state = MM_JPEG_ABORT_DONE;
1014 pthread_cond_signal(&p_session->cond);
1015 pthread_mutex_unlock(&p_session->lock);
1016 return OMX_ErrorNone;
1017 }
1018
1019 if (eEvent == OMX_EventError) {
1020 if (p_session->encoding == OMX_TRUE) {
1021 LOGD("Error during encoding");
1022
1023 /* send jpeg callback */
1024 if (NULL != p_session->dec_params.jpeg_cb) {
1025 p_session->job_status = JPEG_JOB_STATUS_ERROR;
1026 LOGD("send jpeg error callback %d",
1027 p_session->job_status);
1028 p_session->dec_params.jpeg_cb(p_session->job_status,
1029 p_session->client_hdl,
1030 p_session->jobId,
1031 NULL,
1032 p_session->dec_params.userdata);
1033 }
1034
1035 /* remove from ready queue */
1036 mm_jpegdec_job_done(p_session);
1037 }
1038 pthread_cond_signal(&p_session->cond);
1039 } else if (eEvent == OMX_EventCmdComplete) {
1040 p_session->state_change_pending = OMX_FALSE;
1041 p_session->event_pending = OMX_FALSE;
1042 pthread_cond_signal(&p_session->cond);
1043 } else if (eEvent == OMX_EventPortSettingsChanged) {
1044 p_session->event_pending = OMX_FALSE;
1045 pthread_cond_signal(&p_session->cond);
1046 }
1047
1048 pthread_mutex_unlock(&p_session->lock);
1049 LOGD("Exit");
1050 return OMX_ErrorNone;
1051 }
1052
1053 /** mm_jpegdec_abort_job:
1054 *
1055 * Arguments:
1056 * @my_obj: jpeg object
1057 * @client_hdl: client handle
1058 * @jobId: job id
1059 *
1060 * Return:
1061 * 0 for success else failure
1062 *
1063 * Description:
1064 * Abort the encoding session
1065 *
1066 **/
mm_jpegdec_abort_job(mm_jpeg_obj * my_obj,uint32_t jobId)1067 int32_t mm_jpegdec_abort_job(mm_jpeg_obj *my_obj,
1068 uint32_t jobId)
1069 {
1070 int32_t rc = -1;
1071 mm_jpeg_job_q_node_t *node = NULL;
1072 mm_jpeg_job_session_t *p_session = NULL;
1073
1074 LOGD("Enter");
1075 pthread_mutex_lock(&my_obj->job_lock);
1076
1077 /* abort job if in todo queue */
1078 node = mm_jpeg_queue_remove_job_by_job_id(&my_obj->job_mgr.job_queue, jobId);
1079 if (NULL != node) {
1080 free(node);
1081 goto abort_done;
1082 }
1083
1084 /* abort job if in ongoing queue */
1085 node = mm_jpeg_queue_remove_job_by_job_id(&my_obj->ongoing_job_q, jobId);
1086 if (NULL != node) {
1087 /* find job that is OMX ongoing, ask OMX to abort the job */
1088 p_session = mm_jpeg_get_session(my_obj, node->dec_info.job_id);
1089 if (p_session) {
1090 mm_jpeg_session_abort(p_session);
1091 } else {
1092 LOGE("Invalid job id 0x%x",
1093 node->dec_info.job_id);
1094 }
1095 free(node);
1096 goto abort_done;
1097 }
1098
1099 abort_done:
1100 pthread_mutex_unlock(&my_obj->job_lock);
1101
1102 return rc;
1103 }
1104 /** mm_jpegdec_init:
1105 *
1106 * Arguments:
1107 * @my_obj: jpeg object
1108 *
1109 * Return:
1110 * 0 for success else failure
1111 *
1112 * Description:
1113 * Initializes the jpeg client
1114 *
1115 **/
mm_jpegdec_init(mm_jpeg_obj * my_obj)1116 int32_t mm_jpegdec_init(mm_jpeg_obj *my_obj)
1117 {
1118 int32_t rc = 0;
1119
1120 /* init locks */
1121 pthread_mutex_init(&my_obj->job_lock, NULL);
1122
1123 /* init ongoing job queue */
1124 rc = mm_jpeg_queue_init(&my_obj->ongoing_job_q);
1125 if (0 != rc) {
1126 LOGE("Error");
1127 return -1;
1128 }
1129
1130 /* init job semaphore and launch jobmgr thread */
1131 LOGD("Launch jobmgr thread rc %d", rc);
1132 rc = mm_jpeg_jobmgr_thread_launch(my_obj);
1133 if (0 != rc) {
1134 LOGE("Error");
1135 return -1;
1136 }
1137
1138 /* load OMX */
1139 if (OMX_ErrorNone != OMX_Init()) {
1140 /* roll back in error case */
1141 LOGE("OMX_Init failed (%d)", rc);
1142 mm_jpeg_jobmgr_thread_release(my_obj);
1143 mm_jpeg_queue_deinit(&my_obj->ongoing_job_q);
1144 pthread_mutex_destroy(&my_obj->job_lock);
1145 }
1146
1147 return rc;
1148 }
1149
1150 /** mm_jpegdec_deinit:
1151 *
1152 * Arguments:
1153 * @my_obj: jpeg object
1154 *
1155 * Return:
1156 * 0 for success else failure
1157 *
1158 * Description:
1159 * Deinits the jpeg client
1160 *
1161 **/
mm_jpegdec_deinit(mm_jpeg_obj * my_obj)1162 int32_t mm_jpegdec_deinit(mm_jpeg_obj *my_obj)
1163 {
1164 int32_t rc = 0;
1165
1166 /* release jobmgr thread */
1167 rc = mm_jpeg_jobmgr_thread_release(my_obj);
1168 if (0 != rc) {
1169 LOGE("Error");
1170 }
1171
1172 /* unload OMX engine */
1173 OMX_Deinit();
1174
1175 /* deinit ongoing job and cb queue */
1176 rc = mm_jpeg_queue_deinit(&my_obj->ongoing_job_q);
1177 if (0 != rc) {
1178 LOGE("Error");
1179 }
1180
1181 /* destroy locks */
1182 pthread_mutex_destroy(&my_obj->job_lock);
1183
1184 return rc;
1185 }
1186