/* * 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 */ /* * mpp has two ports: input and output * 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 - dequeue(input, *task) * b - task_set_item(packet/frame) * c - enqueue(input, task) // when enqueue return the task is not done yet * * output thread * a - dequeue(output, *task) * b - task_get_item(frame/packet) * c - enqueue(output, task) ****************************************************************************** * 2. sync mode * * mpp_init(type, coding, MPP_WORK_SYNC) * * a - dequeue(input, *task) * b - task_set_item(packet/frame) * c - enqueue(task) // when enqueue return the task is finished ****************************************************************************** */ typedef enum { MPP_TASK_ASYNC, MPP_TASK_SYNC, MPP_TASK_WORK_MODE_BUTT, } MppTaskWorkMode; /* * 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 */ typedef RK_S32 MppTask; #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__*/