/* * Copyright 2015 Rockchip Electronics Co. LTD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __MPP_TASK_H__ #define __MPP_TASK_H__ #include "mpp_meta.h" /* * Advanced task flow * Advanced task flow introduces three concepts: port, task and item * * Port is from OpenMAX * Port has two type: input port and output port which are all for data transaction. * Port work like a queue. task will be dequeue from or enqueue to one port. * On input side user will dequeue task from input port, setup task and enqueue task * back to input port. * On output side user will dequeue task from output port, get the information from * and then enqueue task back to output port. * * Task indicates one transaction on the port. * Task has two working mode: async mode and sync mode * If mpp is work in sync mode on task enqueue function return the task has been done * If mpp is work in async mode on task enqueue function return the task is just put * on the task queue for process. * Task can carry different items. Task just like a container of items * * Item indicates MppPacket or MppFrame which is contained in one task */ /* * One mpp task queue has two ports: input and output * * The whole picture is: * Top layer mpp has two ports: mpp_input_port and mpp_output_port * But internally these two ports belongs to two task queue. * The mpp_input_port is the mpp_input_task_queue's input port. * The mpp_output_port is the mpp_output_task_queue's output port. * * Each port uses its task queue to communication */ typedef enum { MPP_PORT_INPUT, MPP_PORT_OUTPUT, MPP_PORT_BUTT, } MppPortType; /* * Advance task work flow mode: ****************************************************************************** * 1. async mode (default_val) * * mpp_init(type, coding, MPP_WORK_ASYNC) * * input thread * a - poll(input) * b - dequeue(input, *task) * c - task_set_item(packet/frame) * d - enqueue(input, task) // when enqueue return the task is not done yet * * output thread * a - poll(output) * b - dequeue(output, *task) * c - task_get_item(frame/packet) * d - enqueue(output, task) ****************************************************************************** * 2. sync mode * * mpp_init(type, coding, MPP_WORK_SYNC) * * a - poll(input) * b - dequeue(input, *task) * c - task_set_item(packet/frame) * d - enqueue(task) // when enqueue return the task is finished ****************************************************************************** */ typedef enum { MPP_TASK_ASYNC, MPP_TASK_SYNC, MPP_TASK_WORK_MODE_BUTT, } MppTaskWorkMode; /* * Mpp port poll type * * MPP_POLL_BLOCK - for block poll * MPP_POLL_NON_BLOCK - for non-block poll * small than MPP_POLL_MAX - for poll with timeout in ms * small than MPP_POLL_BUTT or larger than MPP_POLL_MAX is invalid value */ typedef enum { MPP_POLL_BUTT = -2, MPP_POLL_BLOCK = -1, MPP_POLL_NON_BLOCK = 0, MPP_POLL_MAX = 8000, } MppPollType; /* * Mpp timeout define * MPP_TIMEOUT_BLOCK - for block poll * MPP_TIMEOUT_NON_BLOCK - for non-block poll * small than MPP_TIMEOUT_MAX - for poll with timeout in ms * small than MPP_TIMEOUT_BUTT or larger than MPP_TIMEOUT_MAX is invalid value */ #define MPP_TIMEOUT_BUTT (-2L) #define MPP_TIMEOUT_BLOCK (-1L) #define MPP_TIMEOUT_NON_BLOCK (0L) #define MPP_TIMEOUT_MAX (8000L) /* * MppTask is descriptor of a task which send to mpp for process * mpp can support different type of work mode, for example: * * decoder: * * 1. typical decoder mode: * input - MppPacket (normal cpu buffer, need cpu copy) * output - MppFrame (ion/drm buffer in external/internal mode) * 2. secure decoder mode: * input - MppPacket (externel ion/drm buffer, cpu can not access) * output - MppFrame (ion/drm buffer in external/internal mode, cpu can not access) * * interface usage: * * typical flow * input side: * task_dequeue(ctx, PORT_INPUT, &task); * task_put_item(task, MODE_INPUT, packet) * task_enqueue(ctx, PORT_INPUT, task); * output side: * task_dequeue(ctx, PORT_OUTPUT, &task); * task_get_item(task, MODE_OUTPUT, &frame) * task_enqueue(ctx, PORT_OUTPUT, task); * * secure flow * input side: * task_dequeue(ctx, PORT_INPUT, &task); * task_put_item(task, MODE_INPUT, packet) * task_put_item(task, MODE_OUTPUT, frame) // buffer will be specified here * task_enqueue(ctx, PORT_INPUT, task); * output side: * task_dequeue(ctx, PORT_OUTPUT, &task); * task_get_item(task, MODE_OUTPUT, &frame) * task_enqueue(ctx, PORT_OUTPUT, task); * * encoder: * * 1. typical encoder mode: * input - MppFrame (ion/drm buffer in external mode) * output - MppPacket (normal cpu buffer, need cpu copy) * 2. user input encoder mode: * input - MppFrame (normal cpu buffer, need to build hardware table for this buffer) * output - MppPacket (normal cpu buffer, need cpu copy) * 3. secure encoder mode: * input - MppFrame (ion/drm buffer in external mode, cpu can not access) * output - MppPacket (externel ion/drm buffer, cpu can not access) * * typical / user input flow * input side: * task_dequeue(ctx, PORT_INPUT, &task); * task_put_item(task, MODE_INPUT, frame) * task_enqueue(ctx, PORT_INPUT, task); * output side: * task_dequeue(ctx, PORT_OUTPUT, &task); * task_get_item(task, MODE_OUTPUT, &packet) * task_enqueue(ctx, PORT_OUTPUT, task); * * secure flow * input side: * task_dequeue(ctx, PORT_INPUT, &task); * task_put_item(task, MODE_OUTPUT, packet) // buffer will be specified here * task_put_item(task, MODE_INPUT, frame) * task_enqueue(ctx, PORT_INPUT, task); * output side: * task_dequeue(ctx, PORT_OUTPUT, &task); * task_get_item(task, MODE_OUTPUT, &packet) * task_get_item(task, MODE_OUTPUT, &frame) * task_enqueue(ctx, PORT_OUTPUT, task); * * NOTE: this flow can specify the output frame. User will setup both intput frame and output packet * buffer at the input side. Then at output side when user gets a finished task user can get the output * packet and corresponding released input frame. * * image processing * * 1. typical image process mode: * input - MppFrame (ion/drm buffer in external mode) * output - MppFrame (ion/drm buffer in external mode) * * typical / user input flow * input side: * task_dequeue(ctx, PORT_INPUT, &task); * task_put_item(task, MODE_INPUT, frame) * task_enqueue(ctx, PORT_INPUT, task); * output side: * task_dequeue(ctx, PORT_OUTPUT, &task); * task_get_item(task, MODE_OUTPUT, &frame) * task_enqueue(ctx, PORT_OUTPUT, task); */ /* NOTE: use index rather then handle to descripbe task */ #ifdef __cplusplus extern "C" { #endif MPP_RET mpp_task_meta_set_s32(MppTask task, MppMetaKey key, RK_S32 val); MPP_RET mpp_task_meta_set_s64(MppTask task, MppMetaKey key, RK_S64 val); MPP_RET mpp_task_meta_set_ptr(MppTask task, MppMetaKey key, void *val); MPP_RET mpp_task_meta_set_frame (MppTask task, MppMetaKey key, MppFrame frame); MPP_RET mpp_task_meta_set_packet(MppTask task, MppMetaKey key, MppPacket packet); MPP_RET mpp_task_meta_set_buffer(MppTask task, MppMetaKey key, MppBuffer buffer); MPP_RET mpp_task_meta_get_s32(MppTask task, MppMetaKey key, RK_S32 *val, RK_S32 default_val); MPP_RET mpp_task_meta_get_s64(MppTask task, MppMetaKey key, RK_S64 *val, RK_S64 default_val); MPP_RET mpp_task_meta_get_ptr(MppTask task, MppMetaKey key, void **val, void *default_val); MPP_RET mpp_task_meta_get_frame (MppTask task, MppMetaKey key, MppFrame *frame); MPP_RET mpp_task_meta_get_packet(MppTask task, MppMetaKey key, MppPacket *packet); MPP_RET mpp_task_meta_get_buffer(MppTask task, MppMetaKey key, MppBuffer *buffer); #ifdef __cplusplus } #endif #endif /*__MPP_QUEUE_H__*/