1 /* 2 * Copyright 2015 Rockchip Electronics Co. LTD 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 __MPP_TASK_IMPL_H__ 18 #define __MPP_TASK_IMPL_H__ 19 20 #include "mpp_list.h" 21 #include "mpp_task.h" 22 23 typedef void* MppPort; 24 typedef void* MppTaskQueue; 25 26 /* 27 * mpp task status transaction 28 * 29 * mpp task is generated from mpp port. When create a mpp port the corresponding task 30 * will be created, too. Then external user will dequeue task from port and enqueue to 31 * mpp port for process. 32 * 33 * input port task work flow: 34 * 35 * description | call | status transaction 36 * 1. input port init | enqueue(external) | -> external_queue 37 * 2. input port user dequeue | dequeue(external) | external_queue -> external_hold 38 * 3. user setup task for processing| | 39 * 4. input port user enqueue | enqueue(external) | external_hold -> internal_queue 40 * 5. input port mpp start process | dequeue(internal) | internal_queue -> internal_hold 41 * 6. mpp process task | | 42 * 7. input port mpp task finish | enqueue(internal) | internal_hold -> external_queue 43 * loop to 2 44 * 45 * output port task work flow: 46 * description | call | status transaction 47 * 1. output port init | enqueue(internal) | -> internal_queue 48 * 2. output port mpp task dequeue | dequeue(internal) | internal_queue -> internal_hold 49 * 3. mpp setup task by processed frame/packet | 50 * 4. output port mpp task enqueue | enqueue(internal) | internal_hold -> external_queue 51 * 5. output port user task dequeue | dequeue(external) | external_queue -> external_hold 52 * 6. user get task as output | | 53 * 7. output port user release task | enqueue(external) | external_hold -> external_queue 54 * loop to 2 55 * 56 */ 57 typedef enum MppTaskStatus_e { 58 MPP_INPUT_PORT, /* in external queue and ready for external dequeue */ 59 MPP_INPUT_HOLD, /* dequeued and hold by external user, user will config */ 60 MPP_OUTPUT_PORT, /* in mpp internal work queue and ready for mpp dequeue */ 61 MPP_OUTPUT_HOLD, /* dequeued and hold by mpp internal worker, mpp is processing */ 62 MPP_TASK_STATUS_BUTT, 63 } MppTaskStatus; 64 65 typedef struct MppTaskImpl_t { 66 const char *name; 67 struct list_head list; 68 MppTaskQueue queue; 69 RK_S32 index; 70 MppTaskStatus status; 71 72 MppMeta meta; 73 } MppTaskImpl; 74 75 #ifdef __cplusplus 76 extern "C" { 77 #endif 78 79 MPP_RET check_mpp_task_name(MppTask task); 80 81 /* 82 * Mpp task queue function: 83 * 84 * mpp_task_queue_init - create task queue structure 85 * mpp_task_queue_deinit - destory task queue structure 86 * mpp_task_queue_get_port - return input or output port of task queue 87 * 88 * Typical work flow, task mpp_dec for example: 89 * 90 * 1. Mpp layer creates one task queue in order to connect mpp input and mpp_dec input. 91 * 2. Mpp layer setups the task count in task queue input port. 92 * 3. Get input port from the task queue and assign to mpp input as mpp_input_port. 93 * 4. Get output port from the task queue and assign to mpp_dec input as dec_input_port. 94 * 5. Let the loop start. 95 * a. mpi user will dequeue task from mpp_input_port. 96 * b. mpi user will setup task. 97 * c. mpi user will enqueue task back to mpp_input_port. 98 * d. task will automatically transfer to dec_input_port. 99 * e. mpp_dec will dequeue task from dec_input_port. 100 * f. mpp_dec will process task. 101 * g. mpp_dec will enqueue task back to dec_input_port. 102 * h. task will automatically transfer to mpp_input_port. 103 * 6. Stop the loop. All tasks must be return to input port with idle status. 104 * 6. Mpp layer destory the task queue. 105 */ 106 MPP_RET mpp_task_queue_init(MppTaskQueue *queue, void *mpp, const char *name); 107 MPP_RET mpp_task_queue_setup(MppTaskQueue queue, RK_S32 task_count); 108 MPP_RET mpp_task_queue_deinit(MppTaskQueue queue); 109 MppPort mpp_task_queue_get_port(MppTaskQueue queue, MppPortType type); 110 111 #define mpp_port_poll(port, timeout) _mpp_port_poll(__FUNCTION__, port, timeout) 112 #define mpp_port_dequeue(port, task) _mpp_port_dequeue(__FUNCTION__, port, task) 113 #define mpp_port_enqueue(port, task) _mpp_port_enqueue(__FUNCTION__, port, task) 114 #define mpp_port_awake(port) _mpp_port_awake(__FUNCTION__, port) 115 #define mpp_port_move(port, task, status) _mpp_port_move(__FUNCTION__, port, task, status) 116 117 MPP_RET _mpp_port_poll(const char *caller, MppPort port, MppPollType timeout); 118 MPP_RET _mpp_port_dequeue(const char *caller, MppPort port, MppTask *task); 119 MPP_RET _mpp_port_enqueue(const char *caller, MppPort port, MppTask task); 120 MPP_RET _mpp_port_awake(const char *caller, MppPort port); 121 MPP_RET _mpp_port_move(const char *caller, MppPort port, MppTask task, MppTaskStatus status); 122 123 MppMeta mpp_task_get_meta(MppTask task); 124 125 #ifdef __cplusplus 126 } 127 #endif 128 129 #endif /*__MPP_TASK_IMPL_H__*/ 130