[mpp_enc]: success on Android camera flow, encode_put_frame and encode_get_packet functions are ready

git-svn-id: https://10.10.10.66:8443/svn/MediaProcessPlatform/trunk/mpp@1064 6e48237b-75ef-9749-8fc9-41990f28c85a
This commit is contained in:
ChenHengming
2016-07-21 10:41:18 +00:00
parent 6eeec0b515
commit d0e59132b1
8 changed files with 502 additions and 252 deletions

View File

@@ -82,6 +82,7 @@ typedef enum {
MPP_CMD_BASE = CMD_MODULE_MPP, MPP_CMD_BASE = CMD_MODULE_MPP,
MPP_ENABLE_DEINTERLACE, MPP_ENABLE_DEINTERLACE,
MPP_SET_INPUT_BLOCK,
MPP_SET_OUTPUT_BLOCK, MPP_SET_OUTPUT_BLOCK,
MPP_CMD_END, MPP_CMD_END,
@@ -135,6 +136,10 @@ typedef struct MppEncConfig_t {
RK_S32 height; RK_S32 height;
RK_S32 format; RK_S32 format;
/*
* Encoder does not support scaling and output data only support yuv420 so far
*/
/* /*
* rate control parameter * rate control parameter
* *

View File

@@ -22,6 +22,7 @@
#define MPP_PACKET_FLAG_EOS (0x00000001) #define MPP_PACKET_FLAG_EOS (0x00000001)
#define MPP_PACKET_FLAG_EXTRA_DATA (0x00000002) #define MPP_PACKET_FLAG_EXTRA_DATA (0x00000002)
#define MPP_PACKET_FLAG_INTERNAL (0x00000004) #define MPP_PACKET_FLAG_INTERNAL (0x00000004)
#define MPP_PACKET_FLAG_INTRA (0x00000008)
/* /*
* mpp_packet_imp structure * mpp_packet_imp structure

View File

@@ -63,7 +63,7 @@ typedef struct EncTask_t {
MppBuffer ctrl_frm_buf_in; MppBuffer ctrl_frm_buf_in;
MppBuffer ctrl_pkt_buf_out; MppBuffer ctrl_pkt_buf_out;
h264e_syntax syntax_data; h264e_syntax syntax_data;
HalTaskInfo info; HalTaskInfo info;
} EncTask; } EncTask;

View File

@@ -31,12 +31,13 @@
void *mpp_enc_control_thread(void *data) void *mpp_enc_control_thread(void *data)
{ {
Mpp *mpp = (Mpp*)data; Mpp *mpp = (Mpp*)data;
MppEnc *enc = mpp->mEnc;
MppThread *thd_enc = mpp->mThreadCodec; MppThread *thd_enc = mpp->mThreadCodec;
EncTask task; // TODO EncTask task; // TODO
HalTaskInfo task_info; HalTaskInfo task_info;
MppPort input = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_OUTPUT); MppPort input = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_OUTPUT);
MppPort output = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_INPUT); MppPort output = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_INPUT);
MppTask mpp_task = NULL; MppTask mpp_task = NULL;
MPP_RET ret = MPP_OK; MPP_RET ret = MPP_OK;
memset(&task_info, 0, sizeof(HalTaskInfo)); memset(&task_info, 0, sizeof(HalTaskInfo));
@@ -48,38 +49,79 @@ void *mpp_enc_control_thread(void *data)
thd_enc->wait(); thd_enc->wait();
} }
thd_enc->unlock(); thd_enc->unlock();
if (mpp_task != NULL) {
MppFrame mpp_frame = NULL;
MppPacket mpp_packet = NULL;
// task process here
if (mpp_task != NULL) {
MppFrame frame = NULL;
MppPacket packet = NULL;
mpp_task_meta_get_frame (mpp_task, MPP_META_KEY_INPUT_FRM, &frame);
mpp_task_meta_get_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, &packet);
mpp_assert(frame);
memset(&task, 0, sizeof(EncTask));
if (mpp_frame_get_buffer(frame)) {
/*
* if there is available buffer in the input frame do encoding
*/
if (NULL == packet) {
RK_U32 width = enc->encCfg.width;
RK_U32 height = enc->encCfg.height;
RK_U32 size = width * height;
MppBuffer buffer = NULL;
mpp_buffer_get(mpp->mPacketGroup, &buffer, size);
mpp_log("create buffer size %d fd %d\n", size, mpp_buffer_get_fd(buffer));
mpp_packet_init_with_buffer(&packet, buffer);
mpp_buffer_put(buffer);
}
mpp_assert(packet);
mpp_packet_set_pts(packet, mpp_frame_get_pts(frame));
task.ctrl_frm_buf_in = mpp_frame_get_buffer(frame);
task.ctrl_pkt_buf_out = mpp_packet_get_buffer(packet);
controller_encode(mpp->mEnc->controller, &task);
task_info.enc.syntax.data = (void *)(&(task.syntax_data));
mpp_hal_reg_gen((mpp->mEnc->hal), &task_info);
mpp_hal_hw_start((mpp->mEnc->hal), &task_info);
/*vpuWaitResult = */mpp_hal_hw_wait((mpp->mEnc->hal), &task_info); // TODO need to check the return value
RK_U32 outputStreamSize = 0;
controller_config(mpp->mEnc->controller, GET_OUTPUT_STREAM_SIZE, (void*)&outputStreamSize);
mpp_packet_set_length(packet, outputStreamSize);
} else {
/*
* else init a empty packet for output
*/
mpp_packet_new(&packet);
}
if (mpp_frame_get_eos(frame))
mpp_packet_set_eos(packet);
// enqueue task back to input input // enqueue task back to input input
mpp_task_meta_get_frame (mpp_task, MPP_META_KEY_INPUT_FRM, &mpp_frame);
mpp_task_meta_get_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, &mpp_packet);
mpp_port_enqueue(input, mpp_task); mpp_port_enqueue(input, mpp_task);
mpp_task = NULL; mpp_task = NULL;
memset(&task, 0, sizeof(EncTask));
task.ctrl_frm_buf_in = mpp_frame_get_buffer(mpp_frame);
task.ctrl_pkt_buf_out = mpp_packet_get_buffer(mpp_packet);
controller_encode(mpp->mEnc->controller, &task);
task_info.enc.syntax.data = (void *)(&(task.syntax_data));
mpp_hal_reg_gen((mpp->mEnc->hal), &task_info);
mpp_hal_hw_start((mpp->mEnc->hal), &task_info);
/*vpuWaitResult = */mpp_hal_hw_wait((mpp->mEnc->hal), &task_info); // TODO need to check the return value
RK_U32 outputStreamSize = 0;
controller_config(mpp->mEnc->controller, GET_OUTPUT_STREAM_SIZE, (void*)&outputStreamSize);
mpp_packet_set_length(mpp_packet, outputStreamSize);
// send finished task to output port // send finished task to output port
mpp_port_dequeue(output, &mpp_task); mpp_port_dequeue(output, &mpp_task);
mpp_task_meta_set_frame(mpp_task, MPP_META_KEY_INPUT_FRM, mpp_frame); mpp_task_meta_set_frame(mpp_task, MPP_META_KEY_INPUT_FRM, frame);
mpp_task_meta_set_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, mpp_packet); mpp_task_meta_set_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, packet);
{
RK_S32 is_intra = task.syntax_data.frame_coding_type;
RK_U32 flag = mpp_packet_get_flag(packet);
mpp_task_meta_set_s32(mpp_task, MPP_META_KEY_OUTPUT_INTRA, is_intra);
if (is_intra) {
mpp_packet_set_flag(packet, flag | MPP_PACKET_FLAG_INTRA);
}
}
// setup output task here // setup output task here
mpp_port_enqueue(output, mpp_task); mpp_port_enqueue(output, mpp_task);
mpp_task = NULL; mpp_task = NULL;

View File

@@ -16,19 +16,21 @@
#define MODULE_TAG "vpu_api_legacy" #define MODULE_TAG "vpu_api_legacy"
#include "mpp_log.h"
#include "mpp_frame.h"
#include "vpu_api_legacy.h"
#include "mpp_mem.h"
#include "string.h" #include "string.h"
#include "mpp_common.h"
#include "mpp_env.h"
#define VPU_API_DBG_OUTPUT (0x00000001) #include "mpp_log.h"
#define VPU_API_DBG_DUMP_YUV (0x00000002) #include "mpp_mem.h"
#define VPU_API_DBG_DUMP_LOG (0x00000004) #include "mpp_env.h"
#define MAX_WRITE_HEIGHT (480) #include "mpp_common.h"
#define MAX_WRITE_WIDTH (960)
#include "vpu_api_legacy.h"
#include "mpp_packet_impl.h"
#define MAX_WRITE_HEIGHT (480)
#define MAX_WRITE_WIDTH (960)
RK_U32 vpu_api_debug = 0;
VpuApiLegacy::VpuApiLegacy() : VpuApiLegacy::VpuApiLegacy() :
mpp_ctx(NULL), mpp_ctx(NULL),
@@ -36,33 +38,32 @@ VpuApiLegacy::VpuApiLegacy() :
init_ok(0), init_ok(0),
frame_count(0), frame_count(0),
set_eos(0), set_eos(0),
vpu_api_debug(0),
fp(NULL), fp(NULL),
fp_buf(NULL), fp_buf(NULL),
memGroup(NULL), memGroup(NULL),
pictureMem(NULL), pictureMem(NULL),
outbufMem(NULL), outbufMem(NULL),
inputFrame(NULL),
outputPakcet(NULL),
outData(NULL), outData(NULL),
use_fd_flag(0), use_fd_flag(0),
task(NULL) mEosSet(0)
{ {
mpp_log_f("in\n"); mpp_env_get_u32("vpu_api_debug", &vpu_api_debug, 0);
vpu_api_dbg_func("enter\n");
mpp_create(&mpp_ctx, &mpi); mpp_create(&mpp_ctx, &mpi);
mpp_env_get_u32("vpu_api_debug", &vpu_api_debug, 0);
if (vpu_api_debug & VPU_API_DBG_DUMP_YUV) { if (vpu_api_debug & VPU_API_DBG_DUMP_YUV) {
fp = fopen("/sdcard/rk_mpp_dump.yuv", "wb"); fp = fopen("/sdcard/rk_mpp_dump.yuv", "wb");
fp_buf = mpp_malloc(RK_U8, (MAX_WRITE_HEIGHT * MAX_WRITE_WIDTH * 2)); fp_buf = mpp_malloc(RK_U8, (MAX_WRITE_HEIGHT * MAX_WRITE_WIDTH * 2));
} }
mpp_log_f("ok\n"); vpu_api_dbg_func("leave\n");
} }
VpuApiLegacy::~VpuApiLegacy() VpuApiLegacy::~VpuApiLegacy()
{ {
mpp_log_f("in\n"); vpu_api_dbg_func("enter\n");
if (fp) { if (fp) {
fclose(fp); fclose(fp);
fp = NULL; fp = NULL;
@@ -80,12 +81,14 @@ VpuApiLegacy::~VpuApiLegacy()
outData = NULL; outData = NULL;
} }
mpp_destroy(mpp_ctx); mpp_destroy(mpp_ctx);
mpp_log_f("ok\n");
vpu_api_dbg_func("leave\n");
} }
RK_S32 VpuApiLegacy::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size) RK_S32 VpuApiLegacy::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size)
{ {
mpp_log_f("in\n"); vpu_api_dbg_func("enter\n");
MPP_RET ret = MPP_OK; MPP_RET ret = MPP_OK;
MppCtxType type; MppCtxType type;
MppPacket pkt = NULL; MppPacket pkt = NULL;
@@ -102,8 +105,13 @@ RK_S32 VpuApiLegacy::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_s
} }
// TODO set control cmd // TODO set control cmd
MppParam param = NULL; MppParam param = NULL;
RK_U32 output_block = 1; RK_U32 block = 1;
param = &output_block; param = █
ret = mpi->control(mpp_ctx, MPP_SET_INPUT_BLOCK, param);
if (MPP_OK != ret) {
mpp_err("mpi->control MPP_SET_INPUT_BLOCK failed\n");
}
block = 0;
ret = mpi->control(mpp_ctx, MPP_SET_OUTPUT_BLOCK, param); ret = mpi->control(mpp_ctx, MPP_SET_OUTPUT_BLOCK, param);
if (MPP_OK != ret) { if (MPP_OK != ret) {
mpp_err("mpi->control MPP_SET_OUTPUT_BLOCK failed\n"); mpp_err("mpi->control MPP_SET_OUTPUT_BLOCK failed\n");
@@ -169,34 +177,40 @@ RK_S32 VpuApiLegacy::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_s
mpp_packet_deinit(&pkt); mpp_packet_deinit(&pkt);
} }
init_ok = 1; init_ok = 1;
mpp_log_f("ok\n");
vpu_api_dbg_func("leave\n");
return ret; return ret;
} }
RK_S32 VpuApiLegacy::flush(VpuCodecContext *ctx) RK_S32 VpuApiLegacy::flush(VpuCodecContext *ctx)
{ {
(void)ctx; (void)ctx;
mpp_log_f("in\n"); vpu_api_dbg_func("enter\n");
if (mpi && mpi->reset && init_ok) { if (mpi && mpi->reset && init_ok) {
mpi->reset(mpp_ctx); mpi->reset(mpp_ctx);
set_eos = 0; set_eos = 0;
} }
mpp_log_f("ok\n"); vpu_api_dbg_func("leave\n");
return 0; return 0;
} }
RK_S32 VpuApiLegacy::decode(VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut) RK_S32 VpuApiLegacy::decode(VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut)
{ {
mpp_log_f("in\n"); RK_S32 ret = 0;
vpu_api_dbg_func("enter\n");
(void)ctx; (void)ctx;
(void)pkt; (void)pkt;
(void)aDecOut; (void)aDecOut;
mpp_log_f("ok\n");
return 0; vpu_api_dbg_func("leave ret %d\n", ret);
return ret;
} }
RK_S32 VpuApiLegacy::decode_sendstream(VideoPacket_t *pkt) RK_S32 VpuApiLegacy::decode_sendstream(VideoPacket_t *pkt)
{ {
vpu_api_dbg_func("enter\n");
RK_S32 ret = MPP_OK; RK_S32 ret = MPP_OK;
MppPacket mpkt = NULL; MppPacket mpkt = NULL;
@@ -214,6 +228,8 @@ RK_S32 VpuApiLegacy::decode_sendstream(VideoPacket_t *pkt)
pkt->size = 0; pkt->size = 0;
} }
mpp_packet_deinit(&mpkt); mpp_packet_deinit(&mpkt);
vpu_api_dbg_func("leave ret %d\n", ret);
return ret; return ret;
} }
@@ -376,194 +392,291 @@ RK_S32 VpuApiLegacy:: decode_getoutframe(DecoderOut_t *aDecOut)
RK_S32 VpuApiLegacy::encode(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm, EncoderOut_t *aEncOut) RK_S32 VpuApiLegacy::encode(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm, EncoderOut_t *aEncOut)
{ {
MPP_RET ret = MPP_OK; MPP_RET ret = MPP_OK;
mpp_log_f("in\n"); MppTask task = NULL;
vpu_api_dbg_func("enter\n");
if (!init_ok) { if (!init_ok)
return VPU_API_ERR_VPU_CODEC_INIT; return VPU_API_ERR_VPU_CODEC_INIT;
/* try import input buffer and output buffer */
MppBufferInfo inputCommit;
MppBufferInfo outputCommit;
memset(&inputCommit, 0, sizeof(inputCommit));
memset(&outputCommit, 0, sizeof(outputCommit));
RK_U32 width = ctx->width;
RK_U32 height = ctx->height;
RK_U32 hor_stride = MPP_ALIGN(width, 16);
RK_U32 ver_stride = MPP_ALIGN(height, 16);
MppFrame frame;
MppPacket packet;
ret = mpp_frame_init(&frame);
if (MPP_OK != ret) {
mpp_err("mpp_frame_init failed\n");
goto ENCODE_FAIL;
} }
// TODO mpp_frame_set_width(frame, width);
if (1) { mpp_frame_set_height(frame, height);
ret = mpp_frame_init(&inputFrame); mpp_frame_set_hor_stride(frame, hor_stride);
if (MPP_OK != ret) { mpp_frame_set_ver_stride(frame, ver_stride);
mpp_err("mpp_frame_init failed\n");
goto ENCODE_FAIL; if (!use_fd_flag) {
RK_U32 outputBufferSize = hor_stride * ver_stride;
ret = mpp_buffer_get(memGroup, &pictureMem, aEncInStrm->size);
if (ret != MPP_OK) {
mpp_err( "Failed to allocate pictureMem buffer!\n");
pictureMem = NULL;
return ret;
} }
RK_U32 width = ctx->width; memcpy((RK_U8*) mpp_buffer_get_ptr(pictureMem), aEncInStrm->buf, aEncInStrm->size);
RK_U32 height = ctx->height; ret = mpp_buffer_get(memGroup, &outbufMem, outputBufferSize);
RK_U32 horStride = MPP_ALIGN(width, 16); if (ret != MPP_OK) {
RK_U32 verStride = MPP_ALIGN(height, 16); mpp_err( "Failed to allocate output buffer!\n");
mpp_frame_set_width(inputFrame, width); outbufMem = NULL;
mpp_frame_set_height(inputFrame, height); return 1;
mpp_frame_set_hor_stride(inputFrame, horStride);
mpp_frame_set_ver_stride(inputFrame, verStride);
if (!use_fd_flag) {
RK_U32 outputBufferSize = horStride * verStride;
ret = mpp_buffer_get(memGroup, &pictureMem, aEncInStrm->size);
if (ret != MPP_OK) {
mpp_err( "Failed to allocate pictureMem buffer!\n");
pictureMem = NULL;
return ret;
}
memcpy((RK_U8*) mpp_buffer_get_ptr(pictureMem), aEncInStrm->buf, aEncInStrm->size);
ret = mpp_buffer_get(memGroup, &outbufMem, outputBufferSize);
if (ret != MPP_OK) {
mpp_err( "Failed to allocate output buffer!\n");
outbufMem = NULL;
return 1;
}
} else {
MppBufferInfo inputCommit;
MppBufferInfo outputCommit;
memset(&inputCommit, 0, sizeof(inputCommit));
memset(&outputCommit, 0, sizeof(outputCommit));
inputCommit.type = MPP_BUFFER_TYPE_ION;
inputCommit.size = aEncInStrm->size;
inputCommit.fd = aEncInStrm->bufPhyAddr;
outputCommit.type = MPP_BUFFER_TYPE_ION;
outputCommit.size = horStride * verStride; // TODO
outputCommit.fd = aEncOut->keyFrame/*bufferFd*/;
outputCommit.ptr = (void*)aEncOut->data;
mpp_log_f(" new ffmpeg provide fd input fd %d output fd %d", aEncInStrm->bufPhyAddr, aEncOut->keyFrame/*bufferFd*/);
ret = mpp_buffer_import(&pictureMem, &inputCommit);
if (MPP_OK != ret) {
mpp_err("mpp_buffer_test mpp_buffer_commit failed\n");
//goto ??; // TODO
}
ret = mpp_buffer_import(&outbufMem, &outputCommit);
if (MPP_OK != ret) {
mpp_err("mpp_buffer_test mpp_buffer_commit failed\n");
}
mpp_log_f("mpp import input fd %d output fd %d",
mpp_buffer_get_fd(pictureMem), mpp_buffer_get_fd(outbufMem)/*(((MppBufferImpl*)pictureMem)->info.fd), (((MppBufferImpl*)outbufMem)->info.fd)*/);
}
//mpp_packet_init(&outputPakcet, outbufMem, aEncOut->size);
mpp_frame_set_buffer(inputFrame, pictureMem);
mpp_packet_init_with_buffer(&outputPakcet, outbufMem);
do {
ret = mpi->dequeue(mpp_ctx, MPP_PORT_INPUT, &task);
if (ret) {
mpp_err("mpp task input dequeue failed\n");
goto ENCODE_FAIL;
}
if (task == NULL) {
mpp_log("mpi dequeue from MPP_PORT_INPUT fail, task equal with NULL!");
usleep(3000);
} else
break;
} while (1);
mpp_task_meta_set_frame (task, MPP_META_KEY_INPUT_FRM, inputFrame);
mpp_task_meta_set_packet(task, MPP_META_KEY_OUTPUT_PKT, outputPakcet);
if (mpi != NULL) {
ret = mpi->enqueue(mpp_ctx, MPP_PORT_INPUT, task);
if (ret) {
mpp_err("mpp task input enqueue failed\n");
goto ENCODE_FAIL;
}
task = NULL;
do {
ret = mpi->dequeue(mpp_ctx, MPP_PORT_OUTPUT, &task);
if (ret) {
mpp_err("ret %d mpp task output dequeue failed\n", ret);
goto ENCODE_FAIL;
}
if (task) {
MppFrame frame_out = NULL;
MppFrame packet_out = NULL;
mpp_task_meta_get_frame (task, MPP_META_KEY_INPUT_FRM, &frame_out);
mpp_task_meta_get_packet(task, MPP_META_KEY_OUTPUT_PKT, &packet_out);
mpp_assert(packet_out == outputPakcet);
mpp_assert(frame_out == inputFrame);
mpp_log_f("encoded frame %d\n", frame_count);
frame_count++;
ret = mpi->enqueue(mpp_ctx, MPP_PORT_OUTPUT, task);
if (ret) {
mpp_err("mpp task output enqueue failed\n");
goto ENCODE_FAIL;
}
task = NULL;
break;
}
usleep(3000);
} while (1);
} else {
mpp_err("mpi pointer is NULL, failed!");
}
// copy encoded stream into output buffer, and set outpub stream size
if (outputPakcet != NULL) {
aEncOut->size = mpp_packet_get_length(outputPakcet);
if (!use_fd_flag)
memcpy(aEncOut->data, (RK_U8*) mpp_buffer_get_ptr(outbufMem), aEncOut->size);
mpp_buffer_put(outbufMem);
mpp_packet_deinit(&outputPakcet);
} else {
mpp_log("outputPacket is NULL!");
}
if (pictureMem)
mpp_buffer_put(pictureMem);
if (inputFrame) {
mpp_frame_deinit(&inputFrame);
inputFrame = NULL;
} }
} else { } else {
aEncOut->data[0] = 0x00; inputCommit.type = MPP_BUFFER_TYPE_ION;
aEncOut->data[1] = 0x00; inputCommit.size = aEncInStrm->size;
aEncOut->data[2] = 0x00; inputCommit.fd = aEncInStrm->bufPhyAddr;
aEncOut->data[3] = 0x01;
memset(aEncOut->data + 4, 0xFF, 500 - 4); outputCommit.type = MPP_BUFFER_TYPE_ION;
aEncOut->size = 500; outputCommit.size = hor_stride * ver_stride; // TODO
outputCommit.fd = aEncOut->keyFrame/*bufferFd*/;
outputCommit.ptr = (void*)aEncOut->data;
ret = mpp_buffer_import(&pictureMem, &inputCommit);
if (MPP_OK != ret) {
mpp_err("mpp_buffer_test mpp_buffer_commit failed\n");
}
ret = mpp_buffer_import(&outbufMem, &outputCommit);
if (MPP_OK != ret) {
mpp_err("mpp_buffer_test mpp_buffer_commit failed\n");
}
mpp_log_f("mpp import input fd %d output fd %d",
mpp_buffer_get_fd(pictureMem), mpp_buffer_get_fd(outbufMem)/*(((MppBufferImpl*)pictureMem)->info.fd), (((MppBufferImpl*)outbufMem)->info.fd)*/);
} }
mpp_log_f("ok\n");
//mpp_packet_init(&packet, outbufMem, aEncOut->size);
mpp_frame_set_buffer(frame, pictureMem);
mpp_packet_init_with_buffer(&packet, outbufMem);
do {
ret = mpi->dequeue(mpp_ctx, MPP_PORT_INPUT, &task);
if (ret) {
mpp_err("mpp task input dequeue failed\n");
goto ENCODE_FAIL;
}
if (task == NULL) {
mpp_log("mpi dequeue from MPP_PORT_INPUT fail, task equal with NULL!");
usleep(3000);
} else
break;
} while (1);
mpp_task_meta_set_frame (task, MPP_META_KEY_INPUT_FRM, frame);
mpp_task_meta_set_packet(task, MPP_META_KEY_OUTPUT_PKT, packet);
if (mpi != NULL) {
ret = mpi->enqueue(mpp_ctx, MPP_PORT_INPUT, task);
if (ret) {
mpp_err("mpp task input enqueue failed\n");
goto ENCODE_FAIL;
}
task = NULL;
do {
ret = mpi->dequeue(mpp_ctx, MPP_PORT_OUTPUT, &task);
if (ret) {
mpp_err("ret %d mpp task output dequeue failed\n", ret);
goto ENCODE_FAIL;
}
if (task) {
MppFrame frame_out = NULL;
MppFrame packet_out = NULL;
mpp_task_meta_get_frame (task, MPP_META_KEY_INPUT_FRM, &frame_out);
mpp_task_meta_get_packet(task, MPP_META_KEY_OUTPUT_PKT, &packet_out);
mpp_assert(packet_out == packet);
mpp_assert(frame_out == frame);
mpp_log_f("encoded frame %d\n", frame_count);
frame_count++;
ret = mpi->enqueue(mpp_ctx, MPP_PORT_OUTPUT, task);
if (ret) {
mpp_err("mpp task output enqueue failed\n");
goto ENCODE_FAIL;
}
task = NULL;
break;
}
usleep(3000);
} while (1);
} else {
mpp_err("mpi pointer is NULL, failed!");
}
// copy encoded stream into output buffer, and set outpub stream size
if (packet != NULL) {
aEncOut->size = mpp_packet_get_length(packet);
if (!use_fd_flag)
memcpy(aEncOut->data, (RK_U8*) mpp_buffer_get_ptr(outbufMem), aEncOut->size);
mpp_buffer_put(outbufMem);
mpp_packet_deinit(&packet);
} else {
mpp_log("outputPacket is NULL!");
}
if (pictureMem)
mpp_buffer_put(pictureMem);
if (frame) {
mpp_frame_deinit(&frame);
frame = NULL;
}
vpu_api_dbg_func("leave ret %d\n", ret);
return ret; return ret;
ENCODE_FAIL: ENCODE_FAIL:
if (inputFrame != NULL) if (frame != NULL)
mpp_frame_deinit(&inputFrame); mpp_frame_deinit(&frame);
if (outputPakcet != NULL) if (packet != NULL)
mpp_packet_deinit(&outputPakcet); mpp_packet_deinit(&packet);
return ret; return ret;
} }
RK_S32 VpuApiLegacy::encoder_sendframe(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm) RK_S32 VpuApiLegacy::encoder_sendframe(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm)
{ {
mpp_log_f("in\n"); RK_S32 ret = 0;
(void)ctx; vpu_api_dbg_func("enter\n");
(void)aEncInStrm;
mpp_log_f("ok\n"); RK_U32 width = ctx->width;
return 0; RK_U32 height = ctx->height;
RK_U32 hor_stride = MPP_ALIGN(width, 16);
RK_U32 ver_stride = MPP_ALIGN(height, 16);
RK_S32 pts = aEncInStrm->timeUs;
/* try import input buffer and output buffer */
MppFrame frame = NULL;
MppBuffer buffer = NULL;
MppBufferInfo info;
memset(&info, 0, sizeof(info));
info.type = MPP_BUFFER_TYPE_ION;
info.size = aEncInStrm->size;
info.fd = aEncInStrm->bufPhyAddr;
mpp_log_f("aEncInStrm->nFlags %d size %d pts %lld\n",
aEncInStrm->nFlags, aEncInStrm->size, aEncInStrm->timeUs);
vpu_api_dbg_input("input info fd %d size %d\n", info.fd, info.size);
ret = mpp_frame_init(&frame);
if (MPP_OK != ret) {
mpp_err_f("mpp_frame_init failed\n");
goto FUNC_RET;
}
mpp_frame_set_width(frame, width);
mpp_frame_set_height(frame, height);
mpp_frame_set_hor_stride(frame, hor_stride);
mpp_frame_set_ver_stride(frame, ver_stride);
mpp_frame_set_pts(frame, pts);
if (aEncInStrm->size) {
ret = mpp_buffer_import(&buffer, &info);
if (MPP_OK != ret) {
mpp_err_f("mpp_buffer_commit fd %d size %d failed\n",
aEncInStrm->bufPhyAddr, aEncInStrm->size);
goto FUNC_RET;
}
}
mpp_frame_set_buffer(frame, buffer);
if (aEncInStrm->nFlags || aEncInStrm->size == 0) {
mpp_log_f("found eos true");
mpp_frame_set_eos(frame, 1);
}
vpu_api_dbg_input("w %d h %d fd %d size %d\n", width, height,
mpp_buffer_get_fd(buffer), mpp_buffer_get_size(buffer));
ret = mpi->encode_put_frame(mpp_ctx, frame);
if (ret)
mpp_err_f("encode_put_frame ret %d\n", ret);
aEncInStrm->size = 0;
FUNC_RET:
if (buffer) {
mpp_buffer_put(buffer);
buffer = NULL;
}
vpu_api_dbg_func("leave ret %d\n", ret);
return ret;
} }
RK_S32 VpuApiLegacy::encoder_getstream(VpuCodecContext *ctx, EncoderOut_t *aEncOut) RK_S32 VpuApiLegacy::encoder_getstream(VpuCodecContext *ctx, EncoderOut_t *aEncOut)
{ {
mpp_log_f("in\n"); RK_S32 ret = 0;
(void)ctx; MppPacket packet = NULL;
(void)aEncOut; vpu_api_dbg_func("enter\n");
mpp_log_f("ok\n"); (void) ctx;
return 0;
ret = mpi->encode_get_packet(mpp_ctx, &packet);
if (ret) {
mpp_err_f("encode_get_packet failed ret %d\n", ret);
goto FUNC_RET;
}
if (packet) {
RK_U8 *src = (RK_U8 *)mpp_packet_get_data(packet);
RK_U8 *dst = (RK_U8 *)malloc(SZ_1M);
RK_U32 eos = mpp_packet_get_eos(packet);
RK_S64 pts = mpp_packet_get_pts(packet);
RK_U32 flag = mpp_packet_get_flag(packet);
size_t length = mpp_packet_get_length(packet);
mpp_assert(length);
mpp_assert(dst);
// remove first 00 00 00 01
length -= 4;
aEncOut->data = dst;
aEncOut->size = (RK_S32)length;
aEncOut->timeUs = pts;
aEncOut->keyFrame = (flag & MPP_PACKET_FLAG_INTRA) ? (1) : (0);
memcpy(dst, src + 4, length);
vpu_api_dbg_output("get packet %p size %d pts %lld keyframe %d eos %d\n",
packet, length, pts, aEncOut->keyFrame, eos);
mEosSet = eos;
mpp_packet_deinit(&packet);
} else {
aEncOut->size = 0;
vpu_api_dbg_output("encode_get_packet get NULL packet\n");
if (mEosSet)
ret = -1;
}
FUNC_RET:
vpu_api_dbg_func("leave ret %d\n", ret);
return ret;
} }
RK_S32 VpuApiLegacy::perform(RK_U32 cmd, RK_U32 *data) RK_S32 VpuApiLegacy::perform(RK_U32 cmd, RK_U32 *data)
{ {
mpp_log_f("in\n"); vpu_api_dbg_func("enter\n");
(void)cmd; (void)cmd;
(void)data; (void)data;
mpp_log_f("ok\n"); vpu_api_dbg_func("leave\n");
return 0; return 0;
} }
@@ -583,7 +696,7 @@ static RK_U32 default_align_16(RK_U32 val)
} }
RK_S32 VpuApiLegacy::control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param) RK_S32 VpuApiLegacy::control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param)
{ {
mpp_log_f("in\n"); vpu_api_dbg_func("enter\n");
(void)ctx; (void)ctx;
if (mpi == NULL && !init_ok) { if (mpi == NULL && !init_ok) {
@@ -652,7 +765,7 @@ RK_S32 VpuApiLegacy::control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param)
if (mpicmd < MPI_CMD_BUTT) if (mpicmd < MPI_CMD_BUTT)
ret = mpi->control(mpp_ctx, (MpiCmd)mpicmd, (MppParam)param); ret = mpi->control(mpp_ctx, (MpiCmd)mpicmd, (MppParam)param);
mpp_log_f("ok\n"); vpu_api_dbg_func("leave\n");
return ret; return ret;
} }

View File

@@ -20,8 +20,24 @@
#include "vpu_api.h" #include "vpu_api.h"
#include "rk_mpi.h" #include "rk_mpi.h"
#include <stdio.h> #include <stdio.h>
#define OMX_BUFFERFLAG_EOS 0x00000001 #define OMX_BUFFERFLAG_EOS 0x00000001
#define VPU_API_DBG_FUNCTION (0x00000001)
#define VPU_API_DBG_DUMP_YUV (0x00000002)
#define VPU_API_DBG_DUMP_LOG (0x00000004)
#define VPU_API_DBG_INPUT (0x00000010)
#define VPU_API_DBG_OUTPUT (0x00000020)
#define vpu_api_dbg(flag, fmt, ...) _mpp_dbg(vpu_api_debug, flag, fmt, ## __VA_ARGS__)
#define vpu_api_dbg_f(flag, fmt, ...) _mpp_dbg_f(vpu_api_debug, flag, fmt, ## __VA_ARGS__)
#define vpu_api_dbg_func(fmt, ...) vpu_api_dbg_f(VPU_API_DBG_FUNCTION, fmt, ## __VA_ARGS__)
#define vpu_api_dbg_input(fmt, ...) vpu_api_dbg_f(VPU_API_DBG_INPUT, fmt, ## __VA_ARGS__)
#define vpu_api_dbg_output(fmt, ...) vpu_api_dbg_f(VPU_API_DBG_OUTPUT, fmt, ## __VA_ARGS__)
extern RK_U32 vpu_api_debug;
class VpuApiLegacy class VpuApiLegacy
{ {
public: public:
@@ -49,17 +65,15 @@ private:
RK_U32 init_ok; RK_U32 init_ok;
RK_U32 frame_count; RK_U32 frame_count;
RK_U32 set_eos; RK_U32 set_eos;
RK_U32 vpu_api_debug;
FILE *fp; FILE *fp;
RK_U8 *fp_buf; RK_U8 *fp_buf;
MppBufferGroup memGroup; MppBufferGroup memGroup;
MppBuffer pictureMem; MppBuffer pictureMem;
MppBuffer outbufMem; MppBuffer outbufMem;
MppFrame inputFrame;
MppPacket outputPakcet;
RK_U8* outData; RK_U8* outData;
RK_U32 use_fd_flag; RK_U32 use_fd_flag;
MppTask task;
RK_U32 mEosSet;
}; };
#endif /*_VPU_API_H_*/ #endif /*_VPU_API_H_*/

View File

@@ -57,6 +57,7 @@ Mpp::Mpp()
mCoding(MPP_VIDEO_CodingUnused), mCoding(MPP_VIDEO_CodingUnused),
mInitDone(0), mInitDone(0),
mPacketBlock(0), mPacketBlock(0),
mInputBlock(0),
mOutputBlock(0), mOutputBlock(0),
mMultiFrame(0), mMultiFrame(0),
mStatus(0), mStatus(0),
@@ -95,6 +96,11 @@ MPP_RET Mpp::init(MppCtxType type, MppCodingType coding)
mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_ION); mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_ION);
mpp_buffer_group_limit_config(mPacketGroup, 0, 3); mpp_buffer_group_limit_config(mPacketGroup, 0, 3);
mpp_task_queue_init(&mInputTaskQueue);
mpp_task_queue_init(&mOutputTaskQueue);
mpp_task_queue_setup(mInputTaskQueue, 4);
mpp_task_queue_setup(mOutputTaskQueue, 4);
} break; } break;
case MPP_CTX_ENC : { case MPP_CTX_ENC : {
mFrames = new mpp_list((node_destructor)NULL); mFrames = new mpp_list((node_destructor)NULL);
@@ -105,19 +111,19 @@ MPP_RET Mpp::init(MppCtxType type, MppCodingType coding)
mThreadCodec = new MppThread(mpp_enc_control_thread, this, "mpp_enc_ctrl"); mThreadCodec = new MppThread(mpp_enc_control_thread, this, "mpp_enc_ctrl");
//mThreadHal = new MppThread(mpp_enc_hal_thread, this, "mpp_enc_hal"); //mThreadHal = new MppThread(mpp_enc_hal_thread, this, "mpp_enc_hal");
mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_NORMAL); mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_ION);
mpp_buffer_group_get_external(&mFrameGroup, MPP_BUFFER_TYPE_ION); mpp_buffer_group_get_external(&mFrameGroup, MPP_BUFFER_TYPE_ION);
mpp_task_queue_init(&mInputTaskQueue);
mpp_task_queue_init(&mOutputTaskQueue);
mpp_task_queue_setup(mInputTaskQueue, 1);
mpp_task_queue_setup(mOutputTaskQueue, 1);
} break; } break;
default : { default : {
mpp_err("Mpp error type %d\n", mType); mpp_err("Mpp error type %d\n", mType);
} break; } break;
} }
mpp_task_queue_init(&mInputTaskQueue);
mpp_task_queue_init(&mOutputTaskQueue);
mpp_task_queue_setup(mInputTaskQueue, 4);
mpp_task_queue_setup(mOutputTaskQueue, 4);
mInputPort = mpp_task_queue_get_port(mInputTaskQueue, MPP_PORT_INPUT); mInputPort = mpp_task_queue_get_port(mInputTaskQueue, MPP_PORT_INPUT);
mOutputPort = mpp_task_queue_get_port(mOutputTaskQueue, MPP_PORT_OUTPUT); mOutputPort = mpp_task_queue_get_port(mOutputTaskQueue, MPP_PORT_OUTPUT);
@@ -275,14 +281,48 @@ MPP_RET Mpp::put_frame(MppFrame frame)
if (!mInitDone) if (!mInitDone)
return MPP_NOK; return MPP_NOK;
AutoMutex autoLock(mFrames->mutex()); MPP_RET ret = MPP_NOK;
if (mFrames->list_size() < 4) { MppTask task = NULL;
mFrames->add_at_tail(frame, sizeof(MppFrameImpl));
mThreadCodec->signal(); do {
mFramePutCount++; if (NULL == task) {
return MPP_OK; ret = dequeue(MPP_PORT_INPUT, &task);
} if (ret) {
return MPP_NOK; mpp_log_f("failed to dequeue from input port ret %d\n", ret);
break;
}
}
/* FIXME: use wait to do block wait */
if (mInputBlock && NULL == task) {
msleep(2);
continue;
}
mpp_assert(task);
ret = mpp_task_meta_set_frame(task, MPP_META_KEY_INPUT_FRM, frame);
if (ret) {
mpp_log_f("failed to set input frame to task ret %d\n", ret);
break;
}
ret = enqueue(MPP_PORT_INPUT, task);
if (ret) {
mpp_log_f("failed to enqueue task to input port ret %d\n", ret);
break;
}
if (mInputBlock) {
while (MPP_NOK == mpp_port_can_dequeue(mInputPort)) {
msleep(2);
}
}
break;
} while (1);
return ret;
} }
MPP_RET Mpp::get_packet(MppPacket *packet) MPP_RET Mpp::get_packet(MppPacket *packet)
@@ -290,18 +330,47 @@ MPP_RET Mpp::get_packet(MppPacket *packet)
if (!mInitDone) if (!mInitDone)
return MPP_NOK; return MPP_NOK;
AutoMutex autoLock(mPackets->mutex()); MPP_RET ret = MPP_OK;
if (0 == mPackets->list_size()) { MppTask task = NULL;
mThreadCodec->signal();
if (mOutputBlock)
mPackets->wait();
}
if (mPackets->list_size()) { do {
mPackets->del_at_head(packet, sizeof(packet)); if (NULL == task) {
mPacketGetCount++; ret = dequeue(MPP_PORT_OUTPUT, &task);
} if (ret) {
return MPP_OK; mpp_log_f("failed to dequeue from output port ret %d\n", ret);
break;
}
}
/* FIXME: use wait to do block wait */
if (NULL == task) {
if (mOutputBlock) {
msleep(2);
continue;
} else {
break;
}
}
mpp_assert(task);
ret = mpp_task_meta_get_packet(task, MPP_META_KEY_OUTPUT_PKT, packet);
if (ret) {
mpp_log_f("failed to get output packet from task ret %d\n", ret);
break;
}
mpp_assert(*packet);
ret = enqueue(MPP_PORT_OUTPUT, task);
if (ret) {
mpp_log_f("failed to enqueue task to output port ret %d\n", ret);
}
break;
} while (1);
return ret;
} }
MPP_RET Mpp::dequeue(MppPortType type, MppTask *task) MPP_RET Mpp::dequeue(MppPortType type, MppTask *task)
@@ -370,6 +439,9 @@ MPP_RET Mpp::control(MpiCmd cmd, MppParam param)
ret = control_osal(cmd, param); ret = control_osal(cmd, param);
} break; } break;
case CMD_MODULE_MPP : { case CMD_MODULE_MPP : {
mpp_assert(cmd > MPP_CMD_BASE);
mpp_assert(cmd < MPP_CMD_END);
ret = control_mpp(cmd, param); ret = control_mpp(cmd, param);
} break; } break;
case CMD_MODULE_CODEC : { case CMD_MODULE_CODEC : {
@@ -393,6 +465,9 @@ MPP_RET Mpp::control(MpiCmd cmd, MppParam param)
ret = control_isp(cmd, param); ret = control_isp(cmd, param);
} break; } break;
default : { default : {
mpp_assert(cmd > MPP_CODEC_CMD_BASE);
mpp_assert(cmd < MPP_CODEC_CMD_END);
ret = control_codec(cmd, param); ret = control_codec(cmd, param);
} break; } break;
} }
@@ -482,17 +557,19 @@ MPP_RET Mpp::reset()
MPP_RET Mpp::control_mpp(MpiCmd cmd, MppParam param) MPP_RET Mpp::control_mpp(MpiCmd cmd, MppParam param)
{ {
MPP_RET ret = MPP_NOK; MPP_RET ret = MPP_OK;
mpp_assert(cmd > MPP_CMD_BASE);
mpp_assert(cmd < MPP_CMD_END);
switch (cmd) { switch (cmd) {
case MPP_SET_INPUT_BLOCK: {
RK_U32 block = *((RK_U32 *)param);
mInputBlock = block;
} break;
case MPP_SET_OUTPUT_BLOCK: { case MPP_SET_OUTPUT_BLOCK: {
RK_U32 block = *((RK_U32 *)param); RK_U32 block = *((RK_U32 *)param);
mOutputBlock = block; mOutputBlock = block;
} break; } break;
default : { default : {
ret = MPP_NOK;
} break; } break;
} }
return ret; return ret;
@@ -514,9 +591,6 @@ MPP_RET Mpp::control_codec(MpiCmd cmd, MppParam param)
{ {
MPP_RET ret = MPP_NOK; MPP_RET ret = MPP_NOK;
mpp_assert(cmd > MPP_CODEC_CMD_BASE);
mpp_assert(cmd < MPP_CODEC_CMD_END);
(void)cmd; (void)cmd;
(void)param; (void)param;
return ret; return ret;

View File

@@ -132,6 +132,7 @@ private:
RK_U32 mInitDone; RK_U32 mInitDone;
RK_U32 mPacketBlock; RK_U32 mPacketBlock;
RK_U32 mInputBlock;
RK_U32 mOutputBlock; RK_U32 mOutputBlock;
RK_U32 mMultiFrame; RK_U32 mMultiFrame;