1/*
2 * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef __MPP_TASK_H__
17#define __MPP_TASK_H__
18
19#include "mpp_meta.h"
20
21/*
22 * Advanced task flow
23 * Advanced task flow introduces three concepts: port, task and item
24 *
25 * Port is from OpenMAX
26 * Port has two type: input port and output port which are all for data transaction.
27 * Port work like a queue. task will be dequeue from or enqueue to one port.
28 * On input side user will dequeue task from input port, setup task and enqueue task
29 * back to input port.
30 * On output side user will dequeue task from output port, get the information from
31 * and then enqueue task back to output port.
32 *
33 * Task indicates one transaction on the port.
34 * Task has two working mode: async mode and sync mode
35 * If mpp is work in sync mode on task enqueue function return the task has been done
36 * If mpp is work in async mode on task enqueue function return the task is just put
37 * on the task queue for process.
38 * Task can carry different items. Task just like a container of items
39 *
40 * Item indicates MppPacket or MppFrame which is contained in one task
41 */
42
43/*
44 * One mpp task queue has two ports: input and output
45 *
46 * The whole picture is:
47 * Top layer mpp has two ports: mpp_input_port and mpp_output_port
48 * But internally these two ports belongs to two task queue.
49 * The mpp_input_port is the mpp_input_task_queue's input port.
50 * The mpp_output_port is the mpp_output_task_queue's output port.
51 *
52 * Each port uses its task queue to communication
53 */
54typedef enum {
55    MPP_PORT_INPUT,
56    MPP_PORT_OUTPUT,
57    MPP_PORT_BUTT,
58} MppPortType;
59
60/*
61 * Advance task work flow mode:
62 ******************************************************************************
63 * 1. async mode (default_val)
64 *
65 * mpp_init(type, coding, MPP_WORK_ASYNC)
66 *
67 * input thread
68 * a - poll(input)
69 * b - dequeue(input, *task)
70 * c - task_set_item(packet/frame)
71 * d - enqueue(input, task)     // when enqueue return the task is not done yet
72 *
73 * output thread
74 * a - poll(output)
75 * b - dequeue(output, *task)
76 * c - task_get_item(frame/packet)
77 * d - enqueue(output, task)
78 ******************************************************************************
79 * 2. sync mode
80 *
81 * mpp_init(type, coding, MPP_WORK_SYNC)
82 *
83 * a - poll(input)
84 * b - dequeue(input, *task)
85 * c - task_set_item(packet/frame)
86 * d - enqueue(task)            // when enqueue return the task is finished
87 ******************************************************************************
88 */
89typedef enum {
90    MPP_TASK_ASYNC,
91    MPP_TASK_SYNC,
92    MPP_TASK_WORK_MODE_BUTT,
93} MppTaskWorkMode;
94
95/*
96 * Mpp port poll type
97 *
98 * MPP_POLL_BLOCK           - for block poll
99 * MPP_POLL_NON_BLOCK       - for non-block poll
100 * small than MPP_POLL_MAX  - for poll with timeout in ms
101 * small than MPP_POLL_BUTT or larger than MPP_POLL_MAX is invalid value
102 */
103typedef enum {
104    MPP_POLL_BUTT = -2,
105    MPP_POLL_BLOCK = -1,
106    MPP_POLL_NON_BLOCK = 0,
107    MPP_POLL_MAX = 8000,
108} MppPollType;
109
110/*
111 * Mpp timeout define
112 * MPP_TIMEOUT_BLOCK            - for block poll
113 * MPP_TIMEOUT_NON_BLOCK        - for non-block poll
114 * small than MPP_TIMEOUT_MAX   - for poll with timeout in ms
115 * small than MPP_TIMEOUT_BUTT or larger than MPP_TIMEOUT_MAX is invalid value
116 */
117#define MPP_TIMEOUT_BUTT (-2L)
118#define MPP_TIMEOUT_BLOCK (-1L)
119#define MPP_TIMEOUT_NON_BLOCK (0L)
120#define MPP_TIMEOUT_MAX (8000L)
121
122/*
123 * MppTask is descriptor of a task which send to mpp for process
124 * mpp can support different type of work mode, for example:
125 *
126 * decoder:
127 *
128 * 1. typical decoder mode:
129 * input    - MppPacket     (normal cpu buffer, need cpu copy)
130 * output   - MppFrame      (ion/drm buffer in external/internal mode)
131 * 2. secure decoder mode:
132 * input    - MppPacket     (externel ion/drm buffer, cpu can not access)
133 * output   - MppFrame      (ion/drm buffer in external/internal mode, cpu can not access)
134 *
135 * interface usage:
136 *
137 * typical flow
138 * input side:
139 * task_dequeue(ctx, PORT_INPUT, &task);
140 * task_put_item(task, MODE_INPUT, packet)
141 * task_enqueue(ctx, PORT_INPUT, task);
142 * output side:
143 * task_dequeue(ctx, PORT_OUTPUT, &task);
144 * task_get_item(task, MODE_OUTPUT, &frame)
145 * task_enqueue(ctx, PORT_OUTPUT, task);
146 *
147 * secure flow
148 * input side:
149 * task_dequeue(ctx, PORT_INPUT, &task);
150 * task_put_item(task, MODE_INPUT, packet)
151 * task_put_item(task, MODE_OUTPUT, frame)  // buffer will be specified here
152 * task_enqueue(ctx, PORT_INPUT, task);
153 * output side:
154 * task_dequeue(ctx, PORT_OUTPUT, &task);
155 * task_get_item(task, MODE_OUTPUT, &frame)
156 * task_enqueue(ctx, PORT_OUTPUT, task);
157 *
158 * encoder:
159 *
160 * 1. typical encoder mode:
161 * input    - MppFrame      (ion/drm buffer in external mode)
162 * output   - MppPacket     (normal cpu buffer, need cpu copy)
163 * 2. user input encoder mode:
164 * input    - MppFrame      (normal cpu buffer, need to build hardware table for this buffer)
165 * output   - MppPacket     (normal cpu buffer, need cpu copy)
166 * 3. secure encoder mode:
167 * input    - MppFrame      (ion/drm buffer in external mode, cpu can not access)
168 * output   - MppPacket     (externel ion/drm buffer, cpu can not access)
169 *
170 * typical / user input flow
171 * input side:
172 * task_dequeue(ctx, PORT_INPUT, &task);
173 * task_put_item(task, MODE_INPUT, frame)
174 * task_enqueue(ctx, PORT_INPUT, task);
175 * output side:
176 * task_dequeue(ctx, PORT_OUTPUT, &task);
177 * task_get_item(task, MODE_OUTPUT, &packet)
178 * task_enqueue(ctx, PORT_OUTPUT, task);
179 *
180 * secure flow
181 * input side:
182 * task_dequeue(ctx, PORT_INPUT, &task);
183 * task_put_item(task, MODE_OUTPUT, packet)  // buffer will be specified here
184 * task_put_item(task, MODE_INPUT, frame)
185 * task_enqueue(ctx, PORT_INPUT, task);
186 * output side:
187 * task_dequeue(ctx, PORT_OUTPUT, &task);
188 * task_get_item(task, MODE_OUTPUT, &packet)
189 * task_get_item(task, MODE_OUTPUT, &frame)
190 * task_enqueue(ctx, PORT_OUTPUT, task);
191 *
192 * NOTE: this flow can specify the output frame. User will setup both intput frame and output packet
193 * buffer at the input side. Then at output side when user gets a finished task user can get the output
194 * packet and corresponding released input frame.
195 *
196 * image processing
197 *
198 * 1. typical image process mode:
199 * input    - MppFrame      (ion/drm buffer in external mode)
200 * output   - MppFrame      (ion/drm buffer in external mode)
201 *
202 * typical / user input flow
203 * input side:
204 * task_dequeue(ctx, PORT_INPUT, &task);
205 * task_put_item(task, MODE_INPUT, frame)
206 * task_enqueue(ctx, PORT_INPUT, task);
207 * output side:
208 * task_dequeue(ctx, PORT_OUTPUT, &task);
209 * task_get_item(task, MODE_OUTPUT, &frame)
210 * task_enqueue(ctx, PORT_OUTPUT, task);
211 */
212/* NOTE: use index rather then handle to descripbe task */
213
214#ifdef __cplusplus
215extern "C" {
216#endif
217
218MPP_RET mpp_task_meta_set_s32(MppTask task, MppMetaKey key, signed int val);
219MPP_RET mpp_task_meta_set_s64(MppTask task, MppMetaKey key, RK_S64 val);
220MPP_RET mpp_task_meta_set_ptr(MppTask task, MppMetaKey key, void *val);
221MPP_RET mpp_task_meta_set_frame(MppTask task, MppMetaKey key, MppFrame frame);
222MPP_RET mpp_task_meta_set_packet(MppTask task, MppMetaKey key, MppPacket packet);
223MPP_RET mpp_task_meta_set_buffer(MppTask task, MppMetaKey key, MppBuffer buffer);
224
225MPP_RET mpp_task_meta_get_s32(MppTask task, MppMetaKey key, signed int *val, signed int default_val);
226MPP_RET mpp_task_meta_get_s64(MppTask task, MppMetaKey key, RK_S64 *val, RK_S64 default_val);
227MPP_RET mpp_task_meta_get_ptr(MppTask task, MppMetaKey key, void **val, void *default_val);
228MPP_RET mpp_task_meta_get_frame(MppTask task, MppMetaKey key, MppFrame *frame);
229MPP_RET mpp_task_meta_get_packet(MppTask task, MppMetaKey key, MppPacket *packet);
230MPP_RET mpp_task_meta_get_buffer(MppTask task, MppMetaKey key, MppBuffer *buffer);
231
232#ifdef __cplusplus
233}
234#endif
235
236#endif /* __MPP_QUEUE_H__ */