13d0407baSopenharmony_ci/*
23d0407baSopenharmony_ci * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
33d0407baSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43d0407baSopenharmony_ci * you may not use this file except in compliance with the License.
53d0407baSopenharmony_ci * You may obtain a copy of the License at
63d0407baSopenharmony_ci *
73d0407baSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83d0407baSopenharmony_ci *
93d0407baSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103d0407baSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113d0407baSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123d0407baSopenharmony_ci * See the License for the specific language governing permissions and
133d0407baSopenharmony_ci * limitations under the License.
143d0407baSopenharmony_ci */
153d0407baSopenharmony_ci
163d0407baSopenharmony_ci#ifndef __MPP_TASK_H__
173d0407baSopenharmony_ci#define __MPP_TASK_H__
183d0407baSopenharmony_ci
193d0407baSopenharmony_ci#include "mpp_meta.h"
203d0407baSopenharmony_ci
213d0407baSopenharmony_ci/*
223d0407baSopenharmony_ci * Advanced task flow
233d0407baSopenharmony_ci * Advanced task flow introduces three concepts: port, task and item
243d0407baSopenharmony_ci *
253d0407baSopenharmony_ci * Port is from OpenMAX
263d0407baSopenharmony_ci * Port has two type: input port and output port which are all for data transaction.
273d0407baSopenharmony_ci * Port work like a queue. task will be dequeue from or enqueue to one port.
283d0407baSopenharmony_ci * On input side user will dequeue task from input port, setup task and enqueue task
293d0407baSopenharmony_ci * back to input port.
303d0407baSopenharmony_ci * On output side user will dequeue task from output port, get the information from
313d0407baSopenharmony_ci * and then enqueue task back to output port.
323d0407baSopenharmony_ci *
333d0407baSopenharmony_ci * Task indicates one transaction on the port.
343d0407baSopenharmony_ci * Task has two working mode: async mode and sync mode
353d0407baSopenharmony_ci * If mpp is work in sync mode on task enqueue function return the task has been done
363d0407baSopenharmony_ci * If mpp is work in async mode on task enqueue function return the task is just put
373d0407baSopenharmony_ci * on the task queue for process.
383d0407baSopenharmony_ci * Task can carry different items. Task just like a container of items
393d0407baSopenharmony_ci *
403d0407baSopenharmony_ci * Item indicates MppPacket or MppFrame which is contained in one task
413d0407baSopenharmony_ci */
423d0407baSopenharmony_ci
433d0407baSopenharmony_ci/*
443d0407baSopenharmony_ci * One mpp task queue has two ports: input and output
453d0407baSopenharmony_ci *
463d0407baSopenharmony_ci * The whole picture is:
473d0407baSopenharmony_ci * Top layer mpp has two ports: mpp_input_port and mpp_output_port
483d0407baSopenharmony_ci * But internally these two ports belongs to two task queue.
493d0407baSopenharmony_ci * The mpp_input_port is the mpp_input_task_queue's input port.
503d0407baSopenharmony_ci * The mpp_output_port is the mpp_output_task_queue's output port.
513d0407baSopenharmony_ci *
523d0407baSopenharmony_ci * Each port uses its task queue to communication
533d0407baSopenharmony_ci */
543d0407baSopenharmony_citypedef enum {
553d0407baSopenharmony_ci    MPP_PORT_INPUT,
563d0407baSopenharmony_ci    MPP_PORT_OUTPUT,
573d0407baSopenharmony_ci    MPP_PORT_BUTT,
583d0407baSopenharmony_ci} MppPortType;
593d0407baSopenharmony_ci
603d0407baSopenharmony_ci/*
613d0407baSopenharmony_ci * Advance task work flow mode:
623d0407baSopenharmony_ci ******************************************************************************
633d0407baSopenharmony_ci * 1. async mode (default_val)
643d0407baSopenharmony_ci *
653d0407baSopenharmony_ci * mpp_init(type, coding, MPP_WORK_ASYNC)
663d0407baSopenharmony_ci *
673d0407baSopenharmony_ci * input thread
683d0407baSopenharmony_ci * a - poll(input)
693d0407baSopenharmony_ci * b - dequeue(input, *task)
703d0407baSopenharmony_ci * c - task_set_item(packet/frame)
713d0407baSopenharmony_ci * d - enqueue(input, task)     // when enqueue return the task is not done yet
723d0407baSopenharmony_ci *
733d0407baSopenharmony_ci * output thread
743d0407baSopenharmony_ci * a - poll(output)
753d0407baSopenharmony_ci * b - dequeue(output, *task)
763d0407baSopenharmony_ci * c - task_get_item(frame/packet)
773d0407baSopenharmony_ci * d - enqueue(output, task)
783d0407baSopenharmony_ci ******************************************************************************
793d0407baSopenharmony_ci * 2. sync mode
803d0407baSopenharmony_ci *
813d0407baSopenharmony_ci * mpp_init(type, coding, MPP_WORK_SYNC)
823d0407baSopenharmony_ci *
833d0407baSopenharmony_ci * a - poll(input)
843d0407baSopenharmony_ci * b - dequeue(input, *task)
853d0407baSopenharmony_ci * c - task_set_item(packet/frame)
863d0407baSopenharmony_ci * d - enqueue(task)            // when enqueue return the task is finished
873d0407baSopenharmony_ci ******************************************************************************
883d0407baSopenharmony_ci */
893d0407baSopenharmony_citypedef enum {
903d0407baSopenharmony_ci    MPP_TASK_ASYNC,
913d0407baSopenharmony_ci    MPP_TASK_SYNC,
923d0407baSopenharmony_ci    MPP_TASK_WORK_MODE_BUTT,
933d0407baSopenharmony_ci} MppTaskWorkMode;
943d0407baSopenharmony_ci
953d0407baSopenharmony_ci/*
963d0407baSopenharmony_ci * Mpp port poll type
973d0407baSopenharmony_ci *
983d0407baSopenharmony_ci * MPP_POLL_BLOCK           - for block poll
993d0407baSopenharmony_ci * MPP_POLL_NON_BLOCK       - for non-block poll
1003d0407baSopenharmony_ci * small than MPP_POLL_MAX  - for poll with timeout in ms
1013d0407baSopenharmony_ci * small than MPP_POLL_BUTT or larger than MPP_POLL_MAX is invalid value
1023d0407baSopenharmony_ci */
1033d0407baSopenharmony_citypedef enum {
1043d0407baSopenharmony_ci    MPP_POLL_BUTT = -2,
1053d0407baSopenharmony_ci    MPP_POLL_BLOCK = -1,
1063d0407baSopenharmony_ci    MPP_POLL_NON_BLOCK = 0,
1073d0407baSopenharmony_ci    MPP_POLL_MAX = 8000,
1083d0407baSopenharmony_ci} MppPollType;
1093d0407baSopenharmony_ci
1103d0407baSopenharmony_ci/*
1113d0407baSopenharmony_ci * Mpp timeout define
1123d0407baSopenharmony_ci * MPP_TIMEOUT_BLOCK            - for block poll
1133d0407baSopenharmony_ci * MPP_TIMEOUT_NON_BLOCK        - for non-block poll
1143d0407baSopenharmony_ci * small than MPP_TIMEOUT_MAX   - for poll with timeout in ms
1153d0407baSopenharmony_ci * small than MPP_TIMEOUT_BUTT or larger than MPP_TIMEOUT_MAX is invalid value
1163d0407baSopenharmony_ci */
1173d0407baSopenharmony_ci#define MPP_TIMEOUT_BUTT (-2L)
1183d0407baSopenharmony_ci#define MPP_TIMEOUT_BLOCK (-1L)
1193d0407baSopenharmony_ci#define MPP_TIMEOUT_NON_BLOCK (0L)
1203d0407baSopenharmony_ci#define MPP_TIMEOUT_MAX (8000L)
1213d0407baSopenharmony_ci
1223d0407baSopenharmony_ci/*
1233d0407baSopenharmony_ci * MppTask is descriptor of a task which send to mpp for process
1243d0407baSopenharmony_ci * mpp can support different type of work mode, for example:
1253d0407baSopenharmony_ci *
1263d0407baSopenharmony_ci * decoder:
1273d0407baSopenharmony_ci *
1283d0407baSopenharmony_ci * 1. typical decoder mode:
1293d0407baSopenharmony_ci * input    - MppPacket     (normal cpu buffer, need cpu copy)
1303d0407baSopenharmony_ci * output   - MppFrame      (ion/drm buffer in external/internal mode)
1313d0407baSopenharmony_ci * 2. secure decoder mode:
1323d0407baSopenharmony_ci * input    - MppPacket     (externel ion/drm buffer, cpu can not access)
1333d0407baSopenharmony_ci * output   - MppFrame      (ion/drm buffer in external/internal mode, cpu can not access)
1343d0407baSopenharmony_ci *
1353d0407baSopenharmony_ci * interface usage:
1363d0407baSopenharmony_ci *
1373d0407baSopenharmony_ci * typical flow
1383d0407baSopenharmony_ci * input side:
1393d0407baSopenharmony_ci * task_dequeue(ctx, PORT_INPUT, &task);
1403d0407baSopenharmony_ci * task_put_item(task, MODE_INPUT, packet)
1413d0407baSopenharmony_ci * task_enqueue(ctx, PORT_INPUT, task);
1423d0407baSopenharmony_ci * output side:
1433d0407baSopenharmony_ci * task_dequeue(ctx, PORT_OUTPUT, &task);
1443d0407baSopenharmony_ci * task_get_item(task, MODE_OUTPUT, &frame)
1453d0407baSopenharmony_ci * task_enqueue(ctx, PORT_OUTPUT, task);
1463d0407baSopenharmony_ci *
1473d0407baSopenharmony_ci * secure flow
1483d0407baSopenharmony_ci * input side:
1493d0407baSopenharmony_ci * task_dequeue(ctx, PORT_INPUT, &task);
1503d0407baSopenharmony_ci * task_put_item(task, MODE_INPUT, packet)
1513d0407baSopenharmony_ci * task_put_item(task, MODE_OUTPUT, frame)  // buffer will be specified here
1523d0407baSopenharmony_ci * task_enqueue(ctx, PORT_INPUT, task);
1533d0407baSopenharmony_ci * output side:
1543d0407baSopenharmony_ci * task_dequeue(ctx, PORT_OUTPUT, &task);
1553d0407baSopenharmony_ci * task_get_item(task, MODE_OUTPUT, &frame)
1563d0407baSopenharmony_ci * task_enqueue(ctx, PORT_OUTPUT, task);
1573d0407baSopenharmony_ci *
1583d0407baSopenharmony_ci * encoder:
1593d0407baSopenharmony_ci *
1603d0407baSopenharmony_ci * 1. typical encoder mode:
1613d0407baSopenharmony_ci * input    - MppFrame      (ion/drm buffer in external mode)
1623d0407baSopenharmony_ci * output   - MppPacket     (normal cpu buffer, need cpu copy)
1633d0407baSopenharmony_ci * 2. user input encoder mode:
1643d0407baSopenharmony_ci * input    - MppFrame      (normal cpu buffer, need to build hardware table for this buffer)
1653d0407baSopenharmony_ci * output   - MppPacket     (normal cpu buffer, need cpu copy)
1663d0407baSopenharmony_ci * 3. secure encoder mode:
1673d0407baSopenharmony_ci * input    - MppFrame      (ion/drm buffer in external mode, cpu can not access)
1683d0407baSopenharmony_ci * output   - MppPacket     (externel ion/drm buffer, cpu can not access)
1693d0407baSopenharmony_ci *
1703d0407baSopenharmony_ci * typical / user input flow
1713d0407baSopenharmony_ci * input side:
1723d0407baSopenharmony_ci * task_dequeue(ctx, PORT_INPUT, &task);
1733d0407baSopenharmony_ci * task_put_item(task, MODE_INPUT, frame)
1743d0407baSopenharmony_ci * task_enqueue(ctx, PORT_INPUT, task);
1753d0407baSopenharmony_ci * output side:
1763d0407baSopenharmony_ci * task_dequeue(ctx, PORT_OUTPUT, &task);
1773d0407baSopenharmony_ci * task_get_item(task, MODE_OUTPUT, &packet)
1783d0407baSopenharmony_ci * task_enqueue(ctx, PORT_OUTPUT, task);
1793d0407baSopenharmony_ci *
1803d0407baSopenharmony_ci * secure flow
1813d0407baSopenharmony_ci * input side:
1823d0407baSopenharmony_ci * task_dequeue(ctx, PORT_INPUT, &task);
1833d0407baSopenharmony_ci * task_put_item(task, MODE_OUTPUT, packet)  // buffer will be specified here
1843d0407baSopenharmony_ci * task_put_item(task, MODE_INPUT, frame)
1853d0407baSopenharmony_ci * task_enqueue(ctx, PORT_INPUT, task);
1863d0407baSopenharmony_ci * output side:
1873d0407baSopenharmony_ci * task_dequeue(ctx, PORT_OUTPUT, &task);
1883d0407baSopenharmony_ci * task_get_item(task, MODE_OUTPUT, &packet)
1893d0407baSopenharmony_ci * task_get_item(task, MODE_OUTPUT, &frame)
1903d0407baSopenharmony_ci * task_enqueue(ctx, PORT_OUTPUT, task);
1913d0407baSopenharmony_ci *
1923d0407baSopenharmony_ci * NOTE: this flow can specify the output frame. User will setup both intput frame and output packet
1933d0407baSopenharmony_ci * buffer at the input side. Then at output side when user gets a finished task user can get the output
1943d0407baSopenharmony_ci * packet and corresponding released input frame.
1953d0407baSopenharmony_ci *
1963d0407baSopenharmony_ci * image processing
1973d0407baSopenharmony_ci *
1983d0407baSopenharmony_ci * 1. typical image process mode:
1993d0407baSopenharmony_ci * input    - MppFrame      (ion/drm buffer in external mode)
2003d0407baSopenharmony_ci * output   - MppFrame      (ion/drm buffer in external mode)
2013d0407baSopenharmony_ci *
2023d0407baSopenharmony_ci * typical / user input flow
2033d0407baSopenharmony_ci * input side:
2043d0407baSopenharmony_ci * task_dequeue(ctx, PORT_INPUT, &task);
2053d0407baSopenharmony_ci * task_put_item(task, MODE_INPUT, frame)
2063d0407baSopenharmony_ci * task_enqueue(ctx, PORT_INPUT, task);
2073d0407baSopenharmony_ci * output side:
2083d0407baSopenharmony_ci * task_dequeue(ctx, PORT_OUTPUT, &task);
2093d0407baSopenharmony_ci * task_get_item(task, MODE_OUTPUT, &frame)
2103d0407baSopenharmony_ci * task_enqueue(ctx, PORT_OUTPUT, task);
2113d0407baSopenharmony_ci */
2123d0407baSopenharmony_ci/* NOTE: use index rather then handle to descripbe task */
2133d0407baSopenharmony_ci
2143d0407baSopenharmony_ci#ifdef __cplusplus
2153d0407baSopenharmony_ciextern "C" {
2163d0407baSopenharmony_ci#endif
2173d0407baSopenharmony_ci
2183d0407baSopenharmony_ciMPP_RET mpp_task_meta_set_s32(MppTask task, MppMetaKey key, signed int val);
2193d0407baSopenharmony_ciMPP_RET mpp_task_meta_set_s64(MppTask task, MppMetaKey key, RK_S64 val);
2203d0407baSopenharmony_ciMPP_RET mpp_task_meta_set_ptr(MppTask task, MppMetaKey key, void *val);
2213d0407baSopenharmony_ciMPP_RET mpp_task_meta_set_frame(MppTask task, MppMetaKey key, MppFrame frame);
2223d0407baSopenharmony_ciMPP_RET mpp_task_meta_set_packet(MppTask task, MppMetaKey key, MppPacket packet);
2233d0407baSopenharmony_ciMPP_RET mpp_task_meta_set_buffer(MppTask task, MppMetaKey key, MppBuffer buffer);
2243d0407baSopenharmony_ci
2253d0407baSopenharmony_ciMPP_RET mpp_task_meta_get_s32(MppTask task, MppMetaKey key, signed int *val, signed int default_val);
2263d0407baSopenharmony_ciMPP_RET mpp_task_meta_get_s64(MppTask task, MppMetaKey key, RK_S64 *val, RK_S64 default_val);
2273d0407baSopenharmony_ciMPP_RET mpp_task_meta_get_ptr(MppTask task, MppMetaKey key, void **val, void *default_val);
2283d0407baSopenharmony_ciMPP_RET mpp_task_meta_get_frame(MppTask task, MppMetaKey key, MppFrame *frame);
2293d0407baSopenharmony_ciMPP_RET mpp_task_meta_get_packet(MppTask task, MppMetaKey key, MppPacket *packet);
2303d0407baSopenharmony_ciMPP_RET mpp_task_meta_get_buffer(MppTask task, MppMetaKey key, MppBuffer *buffer);
2313d0407baSopenharmony_ci
2323d0407baSopenharmony_ci#ifdef __cplusplus
2333d0407baSopenharmony_ci}
2343d0407baSopenharmony_ci#endif
2353d0407baSopenharmony_ci
2363d0407baSopenharmony_ci#endif /* __MPP_QUEUE_H__ */