xref: /rockchip-linux_mpp/mpp/base/inc/mpp_task_impl.h (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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