mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-07 18:11:02 +08:00
[mpi_dec_test]:add advanced decoding path
(1) when decoding mjpeg, switch to mpi_dec_test_decode_advanced (2) add advanced decoding interface for mjpeg in vpu_api_legacy.cpp Change-Id: Ib1848d1686c76826385f76405dda81dd0405cb62 Signed-off-by: timkingh.huang <timkingh.huang@rock-chips.com>
This commit is contained in:

committed by
Herman Chen

parent
deb649610c
commit
44852d9696
@@ -2406,8 +2406,6 @@ MPP_RET jpegd_update_frame(JpegParserContext *ctx)
|
|||||||
return MPP_ERR_NULL_PTR;
|
return MPP_ERR_NULL_PTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpp_buf_slot_set_flag(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_QUEUE_USE);
|
|
||||||
mpp_buf_slot_enqueue(pCtx->frame_slots, pCtx->frame_slot_index, QUEUE_DISPLAY);
|
|
||||||
mpp_buf_slot_clr_flag(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_CODEC_USE);
|
mpp_buf_slot_clr_flag(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_CODEC_USE);
|
||||||
pCtx->frame_slot_index = -1;
|
pCtx->frame_slot_index = -1;
|
||||||
|
|
||||||
|
@@ -63,6 +63,7 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
void *mpp_dec_parser_thread(void *data);
|
void *mpp_dec_parser_thread(void *data);
|
||||||
void *mpp_dec_hal_thread(void *data);
|
void *mpp_dec_hal_thread(void *data);
|
||||||
|
void *mpp_dec_advanced_thread(void *data);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@@ -791,6 +791,149 @@ void *mpp_dec_hal_thread(void *data)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MPP_RET dec_release_task_in_port(MppPort port)
|
||||||
|
{
|
||||||
|
MPP_RET ret = MPP_OK;
|
||||||
|
MppPacket packet = NULL;
|
||||||
|
MppFrame frame = NULL;
|
||||||
|
MppTask mpp_task;
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = mpp_port_dequeue(port, &mpp_task);
|
||||||
|
if (ret || mpp_task == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
packet = NULL;
|
||||||
|
frame = NULL;
|
||||||
|
ret = mpp_task_meta_get_frame(mpp_task, KEY_OUTPUT_FRAME, &frame);
|
||||||
|
if (frame) {
|
||||||
|
mpp_frame_deinit(&frame);
|
||||||
|
frame = NULL;
|
||||||
|
}
|
||||||
|
ret = mpp_task_meta_get_packet(mpp_task, KEY_INPUT_PACKET, &packet);
|
||||||
|
if (packet) {
|
||||||
|
mpp_packet_deinit(&packet);
|
||||||
|
packet = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mpp_port_enqueue(port, mpp_task);
|
||||||
|
mpp_task = NULL;
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *mpp_dec_advanced_thread(void *data)
|
||||||
|
{
|
||||||
|
Mpp *mpp = (Mpp*)data;
|
||||||
|
MppDec *dec = mpp->mDec;
|
||||||
|
MppBufSlots frame_slots = dec->frame_slots;
|
||||||
|
MppBufSlots packet_slots = dec->packet_slots;
|
||||||
|
MppThread *thd_dec = mpp->mThreadCodec;
|
||||||
|
DecTask task; /* decoder task */
|
||||||
|
DecTask *pTask = &task;
|
||||||
|
dec_task_init(pTask);
|
||||||
|
HalDecTask *task_dec = &pTask->info.dec;
|
||||||
|
|
||||||
|
MppPort input = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_OUTPUT);
|
||||||
|
MppPort output = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_INPUT);
|
||||||
|
MppTask mpp_task = NULL;
|
||||||
|
MPP_RET ret = MPP_OK;
|
||||||
|
MppFrame frame = NULL;
|
||||||
|
MppPacket packet = NULL;
|
||||||
|
|
||||||
|
while (MPP_THREAD_RUNNING == thd_dec->get_status()) {
|
||||||
|
thd_dec->lock();
|
||||||
|
ret = mpp_port_dequeue(input, &mpp_task);
|
||||||
|
if (ret || NULL == mpp_task) {
|
||||||
|
thd_dec->wait();
|
||||||
|
}
|
||||||
|
thd_dec->unlock();
|
||||||
|
|
||||||
|
if (mpp_task != NULL) {
|
||||||
|
mpp_task_meta_get_packet(mpp_task, KEY_INPUT_PACKET, &packet);
|
||||||
|
mpp_task_meta_get_frame (mpp_task, KEY_OUTPUT_FRAME, &frame);
|
||||||
|
|
||||||
|
if (NULL == packet) {
|
||||||
|
mpp_port_enqueue(input, mpp_task);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mpp_packet_get_buffer(packet)) {
|
||||||
|
/*
|
||||||
|
* if there is available buffer in the input packet do decoding
|
||||||
|
*/
|
||||||
|
MppBuffer input_buffer = mpp_packet_get_buffer(packet);
|
||||||
|
MppBuffer output_buffer = mpp_frame_get_buffer(frame);
|
||||||
|
|
||||||
|
parser_prepare(dec->parser, packet, task_dec);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* look for a unused packet slot index
|
||||||
|
*/
|
||||||
|
if (task_dec->input < 0) {
|
||||||
|
mpp_buf_slot_get_unused(packet_slots, &task_dec->input);
|
||||||
|
}
|
||||||
|
mpp_buf_slot_set_prop(packet_slots, task_dec->input, SLOT_BUFFER, input_buffer);
|
||||||
|
mpp_buf_slot_set_flag(packet_slots, task_dec->input, SLOT_CODEC_READY);
|
||||||
|
mpp_buf_slot_set_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT);
|
||||||
|
|
||||||
|
ret = parser_parse(dec->parser, task_dec);
|
||||||
|
if (ret != MPP_OK) {
|
||||||
|
mpp_err_f("something wrong with parser_parse!\n");
|
||||||
|
mpp_buf_slot_clr_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT);
|
||||||
|
mpp_frame_init(&frame);
|
||||||
|
goto DEC_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
mpp_buf_slot_set_prop(frame_slots, task_dec->output, SLOT_BUFFER, output_buffer);
|
||||||
|
|
||||||
|
// register genertation
|
||||||
|
mpp_hal_reg_gen(dec->hal, &pTask->info);
|
||||||
|
mpp_hal_hw_start(dec->hal, &pTask->info);
|
||||||
|
mpp_hal_hw_wait(dec->hal, &pTask->info);
|
||||||
|
|
||||||
|
mpp_buf_slot_clr_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT);
|
||||||
|
mpp_buf_slot_clr_flag(frame_slots, task_dec->output, SLOT_HAL_OUTPUT);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* else init a empty frame for output
|
||||||
|
*/
|
||||||
|
mpp_log_f("line(%d): Error! Get no buffer from input packet\n", __LINE__);
|
||||||
|
mpp_frame_init(&frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* first clear output packet
|
||||||
|
* then enqueue task back to input port
|
||||||
|
* final user will release the mpp_frame they had input
|
||||||
|
*/
|
||||||
|
DEC_OUT:
|
||||||
|
mpp_task_meta_set_packet(mpp_task, KEY_INPUT_PACKET, packet);
|
||||||
|
mpp_port_enqueue(input, mpp_task);
|
||||||
|
mpp_task = NULL;
|
||||||
|
|
||||||
|
// send finished task to output port
|
||||||
|
mpp_port_dequeue(output, &mpp_task);
|
||||||
|
mpp_task_meta_set_frame(mpp_task, KEY_OUTPUT_FRAME, frame);
|
||||||
|
|
||||||
|
// setup output task here
|
||||||
|
mpp_port_enqueue(output, mpp_task);
|
||||||
|
mpp_task = NULL;
|
||||||
|
packet = NULL;
|
||||||
|
frame = NULL;
|
||||||
|
|
||||||
|
hal_task_info_init(&pTask->info, MPP_CTX_DEC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear remain task in output port
|
||||||
|
dec_release_task_in_port(input);
|
||||||
|
dec_release_task_in_port(mpp->mOutputPort);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
MPP_RET mpp_dec_init(MppDec **dec, MppDecCfg *cfg)
|
MPP_RET mpp_dec_init(MppDec **dec, MppDecCfg *cfg)
|
||||||
{
|
{
|
||||||
MPP_RET ret;
|
MPP_RET ret;
|
||||||
|
@@ -130,6 +130,7 @@ typedef struct HalDecTask_t {
|
|||||||
// for test purpose
|
// for test purpose
|
||||||
// current tesk output slot index
|
// current tesk output slot index
|
||||||
RK_S32 output;
|
RK_S32 output;
|
||||||
|
|
||||||
// current task reference slot index, -1 for unused
|
// current task reference slot index, -1 for unused
|
||||||
RK_S32 refer[MAX_DEC_REF_NUM];
|
RK_S32 refer[MAX_DEC_REF_NUM];
|
||||||
} HalDecTask;
|
} HalDecTask;
|
||||||
|
@@ -361,12 +361,205 @@ RK_S32 VpuApiLegacy::flush(VpuCodecContext *ctx)
|
|||||||
|
|
||||||
RK_S32 VpuApiLegacy::decode(VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut)
|
RK_S32 VpuApiLegacy::decode(VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut)
|
||||||
{
|
{
|
||||||
RK_S32 ret = 0;
|
MPP_RET ret = MPP_OK;
|
||||||
vpu_api_dbg_func("enter\n");
|
vpu_api_dbg_func("enter\n");
|
||||||
|
|
||||||
(void)ctx;
|
if (ctx->videoCoding == OMX_RK_VIDEO_CodingMJPEG) {
|
||||||
(void)pkt;
|
MppTask task = NULL;
|
||||||
(void)aDecOut;
|
|
||||||
|
if (!init_ok) {
|
||||||
|
mpp_err("init failed!\n");
|
||||||
|
return VPU_API_ERR_VPU_CODEC_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check input param */
|
||||||
|
if (!pkt || !aDecOut) {
|
||||||
|
mpp_err("invalid input %p and output %p\n", pkt, aDecOut);
|
||||||
|
return VPU_API_ERR_UNKNOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkt->size <= 0) {
|
||||||
|
mpp_err("invalid input size %d\n", pkt->size);
|
||||||
|
return VPU_API_ERR_UNKNOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* try import input buffer and output buffer */
|
||||||
|
RK_S32 fd = -1;
|
||||||
|
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 = NULL;
|
||||||
|
MppPacket packet = NULL;
|
||||||
|
MppBuffer str_buf = NULL; /* input */
|
||||||
|
MppBuffer pic_buf = NULL; /* output */
|
||||||
|
|
||||||
|
ret = mpp_frame_init(&frame);
|
||||||
|
if (MPP_OK != ret) {
|
||||||
|
mpp_err_f("mpp_frame_init failed\n");
|
||||||
|
goto DECODE_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = (RK_S32)(pkt->pts & 0xffffffff);
|
||||||
|
if (fd_input < 0) {
|
||||||
|
fd_input = is_valid_dma_fd(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd_input) {
|
||||||
|
MppBufferInfo inputCommit;
|
||||||
|
|
||||||
|
memset(&inputCommit, 0, sizeof(inputCommit));
|
||||||
|
inputCommit.type = MPP_BUFFER_TYPE_ION;
|
||||||
|
inputCommit.size = pkt->size;
|
||||||
|
inputCommit.fd = fd;
|
||||||
|
|
||||||
|
ret = mpp_buffer_import(&str_buf, &inputCommit);
|
||||||
|
if (ret) {
|
||||||
|
mpp_err_f("import input picture buffer failed\n");
|
||||||
|
goto DECODE_OUT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (NULL == pkt->data) {
|
||||||
|
ret = MPP_ERR_NULL_PTR;
|
||||||
|
goto DECODE_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mpp_buffer_get(memGroup, &str_buf, pkt->size);
|
||||||
|
if (ret) {
|
||||||
|
mpp_err_f("allocate input picture buffer failed\n");
|
||||||
|
goto DECODE_OUT;
|
||||||
|
}
|
||||||
|
memcpy((RK_U8*) mpp_buffer_get_ptr(str_buf), pkt->data, pkt->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = (RK_S32)(aDecOut->timeUs & 0xffffffff);
|
||||||
|
if (fd_output < 0) {
|
||||||
|
fd_output = is_valid_dma_fd(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd_output) {
|
||||||
|
MppBufferInfo outputCommit;
|
||||||
|
|
||||||
|
memset(&outputCommit, 0, sizeof(outputCommit));
|
||||||
|
/* in order to avoid interface change use space in output to transmit information */
|
||||||
|
outputCommit.type = MPP_BUFFER_TYPE_ION;
|
||||||
|
outputCommit.fd = fd;
|
||||||
|
outputCommit.size = width * height * 3 / 2;
|
||||||
|
outputCommit.ptr = (void*)aDecOut->data;
|
||||||
|
|
||||||
|
ret = mpp_buffer_import(&pic_buf, &outputCommit);
|
||||||
|
if (ret) {
|
||||||
|
mpp_err_f("import output stream buffer failed\n");
|
||||||
|
goto DECODE_OUT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = mpp_buffer_get(memGroup, &pic_buf, hor_stride * ver_stride * 3 / 2);
|
||||||
|
if (ret) {
|
||||||
|
mpp_err_f("allocate output stream buffer failed\n");
|
||||||
|
goto DECODE_OUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mpp_packet_init_with_buffer(&packet, str_buf); /* input */
|
||||||
|
mpp_frame_set_buffer(frame, pic_buf); /* output */
|
||||||
|
|
||||||
|
vpu_api_dbg_func("mpp import input fd %d output fd %d",
|
||||||
|
mpp_buffer_get_fd(str_buf), mpp_buffer_get_fd(pic_buf));
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = mpi->dequeue(mpp_ctx, MPP_PORT_INPUT, &task);
|
||||||
|
if (ret) {
|
||||||
|
mpp_err("mpp task input dequeue failed\n");
|
||||||
|
goto DECODE_OUT;
|
||||||
|
}
|
||||||
|
if (task == NULL) {
|
||||||
|
vpu_api_dbg_func("mpi dequeue from MPP_PORT_INPUT fail, task equal with NULL!");
|
||||||
|
msleep(3);
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
mpp_task_meta_set_packet(task, KEY_INPUT_PACKET, packet);
|
||||||
|
mpp_task_meta_set_frame (task, KEY_OUTPUT_FRAME, frame);
|
||||||
|
|
||||||
|
if (mpi != NULL) {
|
||||||
|
ret = mpi->enqueue(mpp_ctx, MPP_PORT_INPUT, task);
|
||||||
|
if (ret) {
|
||||||
|
mpp_err("mpp task input enqueue failed\n");
|
||||||
|
goto DECODE_OUT;
|
||||||
|
}
|
||||||
|
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 DECODE_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (task) {
|
||||||
|
MppFrame frame_out = NULL;
|
||||||
|
|
||||||
|
mpp_task_meta_get_frame(task, KEY_OUTPUT_FRAME, &frame_out);
|
||||||
|
mpp_assert(frame_out == frame);
|
||||||
|
vpu_api_dbg_func("decoded 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 DECODE_OUT;
|
||||||
|
}
|
||||||
|
task = NULL;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
msleep(3);
|
||||||
|
} while (1);
|
||||||
|
} else {
|
||||||
|
mpp_err("mpi pointer is NULL, failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy encoded stream into output buffer, and set outpub stream size
|
||||||
|
if (frame != NULL) {
|
||||||
|
MppBuffer buf_out = mpp_frame_get_buffer(frame);
|
||||||
|
size_t len = mpp_buffer_get_size(buf_out);
|
||||||
|
aDecOut->size = len;
|
||||||
|
|
||||||
|
if (!is_valid_dma_fd(fd)) {
|
||||||
|
mpp_log_f("fd for output is invalid!\n");
|
||||||
|
if (NULL == aDecOut->data) {
|
||||||
|
if (NULL == outData)
|
||||||
|
outData = mpp_malloc(RK_U8, (width * height));
|
||||||
|
aDecOut->data = outData;
|
||||||
|
}
|
||||||
|
memcpy(aDecOut->data, (RK_U8*) mpp_buffer_get_ptr(pic_buf), aDecOut->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
vpu_api_dbg_func("get frame %p size %d\n", frame, len);
|
||||||
|
|
||||||
|
mpp_frame_deinit(&frame);
|
||||||
|
} else {
|
||||||
|
mpp_log("outputPacket is NULL!");
|
||||||
|
}
|
||||||
|
|
||||||
|
DECODE_OUT:
|
||||||
|
if (str_buf) {
|
||||||
|
mpp_buffer_put(str_buf);
|
||||||
|
str_buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pic_buf) {
|
||||||
|
mpp_buffer_put(pic_buf);
|
||||||
|
pic_buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame)
|
||||||
|
mpp_frame_deinit(&frame);
|
||||||
|
|
||||||
|
if (packet)
|
||||||
|
mpp_packet_deinit(&packet);
|
||||||
|
}
|
||||||
|
|
||||||
vpu_api_dbg_func("leave ret %d\n", ret);
|
vpu_api_dbg_func("leave ret %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
21
mpp/mpp.cpp
21
mpp/mpp.cpp
@@ -93,6 +93,7 @@ MPP_RET Mpp::init(MppCtxType type, MppCodingType coding)
|
|||||||
};
|
};
|
||||||
mpp_dec_init(&mDec, &cfg);
|
mpp_dec_init(&mDec, &cfg);
|
||||||
|
|
||||||
|
if (mCoding != MPP_VIDEO_CodingMJPEG) {
|
||||||
mThreadCodec = new MppThread(mpp_dec_parser_thread, this, "mpp_dec_parser");
|
mThreadCodec = new MppThread(mpp_dec_parser_thread, this, "mpp_dec_parser");
|
||||||
mThreadHal = new MppThread(mpp_dec_hal_thread, this, "mpp_dec_hal");
|
mThreadHal = new MppThread(mpp_dec_hal_thread, this, "mpp_dec_hal");
|
||||||
|
|
||||||
@@ -103,6 +104,14 @@ MPP_RET Mpp::init(MppCtxType type, MppCodingType coding)
|
|||||||
mpp_task_queue_init(&mOutputTaskQueue);
|
mpp_task_queue_init(&mOutputTaskQueue);
|
||||||
mpp_task_queue_setup(mInputTaskQueue, 4);
|
mpp_task_queue_setup(mInputTaskQueue, 4);
|
||||||
mpp_task_queue_setup(mOutputTaskQueue, 4);
|
mpp_task_queue_setup(mOutputTaskQueue, 4);
|
||||||
|
} else {
|
||||||
|
mThreadCodec = new MppThread(mpp_dec_advanced_thread, this, "mpp_dec_parser");
|
||||||
|
|
||||||
|
mpp_task_queue_init(&mInputTaskQueue);
|
||||||
|
mpp_task_queue_init(&mOutputTaskQueue);
|
||||||
|
mpp_task_queue_setup(mInputTaskQueue, 1);
|
||||||
|
mpp_task_queue_setup(mOutputTaskQueue, 1);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case MPP_CTX_ENC : {
|
case MPP_CTX_ENC : {
|
||||||
mFrames = new mpp_list((node_destructor)NULL);
|
mFrames = new mpp_list((node_destructor)NULL);
|
||||||
@@ -129,7 +138,14 @@ MPP_RET Mpp::init(MppCtxType type, MppCodingType coding)
|
|||||||
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);
|
||||||
|
|
||||||
if (mFrames && mPackets &&
|
if (mCoding == MPP_VIDEO_CodingMJPEG &&
|
||||||
|
mFrames && mPackets &&
|
||||||
|
(mDec) &&
|
||||||
|
mThreadCodec/* &&
|
||||||
|
mPacketGroup*/) {
|
||||||
|
mThreadCodec->start();
|
||||||
|
mInitDone = 1;
|
||||||
|
} else if (mFrames && mPackets &&
|
||||||
(mDec) &&
|
(mDec) &&
|
||||||
mThreadCodec && mThreadHal &&
|
mThreadCodec && mThreadHal &&
|
||||||
mPacketGroup) {
|
mPacketGroup) {
|
||||||
@@ -531,10 +547,13 @@ MPP_RET Mpp::reset()
|
|||||||
|
|
||||||
if (mType == MPP_CTX_DEC) {
|
if (mType == MPP_CTX_DEC) {
|
||||||
mpp_dec_reset(mDec);
|
mpp_dec_reset(mDec);
|
||||||
|
|
||||||
|
if (mDec->coding != MPP_VIDEO_CodingMJPEG) {
|
||||||
mThreadCodec->lock();
|
mThreadCodec->lock();
|
||||||
mThreadCodec->signal();
|
mThreadCodec->signal();
|
||||||
mThreadCodec->unlock();
|
mThreadCodec->unlock();
|
||||||
mThreadCodec->wait(THREAD_RESET);
|
mThreadCodec->wait(THREAD_RESET);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mpp_enc_reset(mEnc);
|
mpp_enc_reset(mEnc);
|
||||||
}
|
}
|
||||||
|
@@ -55,7 +55,7 @@ static OptionInfo mpi_dec_cmd[] = {
|
|||||||
{"d", "debug", "debug flag"},
|
{"d", "debug", "debug flag"},
|
||||||
};
|
};
|
||||||
|
|
||||||
int mpi_dec_test(MpiDecTestCmd *cmd)
|
int mpi_dec_test_decode_simple(MpiDecTestCmd *cmd)
|
||||||
{
|
{
|
||||||
MPP_RET ret = MPP_OK;
|
MPP_RET ret = MPP_OK;
|
||||||
RK_U32 pkt_eos = 0;
|
RK_U32 pkt_eos = 0;
|
||||||
@@ -247,6 +247,239 @@ MPP_TEST_OUT:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mpi_dec_test_decode_advanced(MpiDecTestCmd *cmd)
|
||||||
|
{
|
||||||
|
MPP_RET ret = MPP_OK;
|
||||||
|
RK_U32 pkt_eos = 0;
|
||||||
|
FILE *fp_input = NULL;
|
||||||
|
FILE *fp_output = NULL;
|
||||||
|
|
||||||
|
// base flow context
|
||||||
|
MppCtx ctx = NULL;
|
||||||
|
MppApi *mpi = NULL;
|
||||||
|
|
||||||
|
// input / output
|
||||||
|
MppPacket packet = NULL;
|
||||||
|
MppFrame frame = NULL;
|
||||||
|
|
||||||
|
MpiCmd mpi_cmd = MPP_CMD_BASE;
|
||||||
|
MppParam param = NULL;
|
||||||
|
RK_U32 need_split = 1;
|
||||||
|
|
||||||
|
// paramter for resource malloc
|
||||||
|
RK_U32 width = cmd->width;
|
||||||
|
RK_U32 height = cmd->height;
|
||||||
|
MppCodingType type = cmd->type;
|
||||||
|
|
||||||
|
// resources
|
||||||
|
MppBuffer pkt_buf = NULL;
|
||||||
|
MppBuffer frm_buf = NULL;
|
||||||
|
size_t packet_size = MPI_DEC_STREAM_SIZE;
|
||||||
|
size_t read_size = 0;
|
||||||
|
RK_U32 frame_count = 0;
|
||||||
|
void *buf = NULL;
|
||||||
|
(void)read_size;
|
||||||
|
|
||||||
|
MppBufferGroup frm_grp = NULL;
|
||||||
|
MppBufferGroup pkt_grp = NULL;
|
||||||
|
|
||||||
|
mpp_log("mpi_dec_test start\n");
|
||||||
|
|
||||||
|
if (cmd->have_input) {
|
||||||
|
fp_input = fopen(cmd->file_input, "rb");
|
||||||
|
if (NULL == fp_input) {
|
||||||
|
mpp_err("failed to open input file %s\n", cmd->file_input);
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd->have_output) {
|
||||||
|
fp_output = fopen(cmd->file_output, "w+b");
|
||||||
|
if (NULL == fp_output) {
|
||||||
|
mpp_err("failed to open output file %s\n", cmd->file_output);
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mpp_buffer_group_get_internal(&frm_grp, MPP_BUFFER_TYPE_ION);
|
||||||
|
if (ret) {
|
||||||
|
mpp_err("failed to get buffer group for input frame ret %d\n", ret);
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mpp_buffer_group_get_internal(&pkt_grp, MPP_BUFFER_TYPE_ION);
|
||||||
|
if (ret) {
|
||||||
|
mpp_err("failed to get buffer group for output packet ret %d\n", ret);
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(fp_input, 0L, SEEK_END);
|
||||||
|
packet_size = ftell(fp_input);
|
||||||
|
fseek(fp_input, 0L, SEEK_SET);
|
||||||
|
|
||||||
|
RK_U32 frm_size = width * height * 3 / 2;
|
||||||
|
ret = mpp_frame_init(&frame); /* output frame */
|
||||||
|
if (MPP_OK != ret) {
|
||||||
|
mpp_err("mpp_frame_init failed\n");
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mpp_buffer_get(frm_grp, &frm_buf, frm_size);
|
||||||
|
if (ret) {
|
||||||
|
mpp_err("failed to get buffer for input frame ret %d\n", ret);
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mpp_buffer_get(pkt_grp, &pkt_buf, packet_size);
|
||||||
|
if (ret) {
|
||||||
|
mpp_err("failed to get buffer for input frame ret %d\n", ret);
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
mpp_packet_init_with_buffer(&packet, pkt_buf);
|
||||||
|
buf = mpp_buffer_get_ptr(pkt_buf);
|
||||||
|
|
||||||
|
mpp_frame_set_buffer(frame, frm_buf);
|
||||||
|
mpp_log("mpi_dec_test decoder test start w %d h %d type %d\n", width, height, type);
|
||||||
|
|
||||||
|
// decoder demo
|
||||||
|
ret = mpp_create(&ctx, &mpi);
|
||||||
|
if (MPP_OK != ret) {
|
||||||
|
mpp_err("mpp_create failed\n");
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: decoder split mode need to be set before init
|
||||||
|
mpi_cmd = MPP_DEC_SET_PARSER_SPLIT_MODE;
|
||||||
|
param = &need_split;
|
||||||
|
ret = mpi->control(ctx, mpi_cmd, param);
|
||||||
|
if (MPP_OK != ret) {
|
||||||
|
mpp_err("mpi->control failed\n");
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mpp_init(ctx, MPP_CTX_DEC, type);
|
||||||
|
if (MPP_OK != ret) {
|
||||||
|
mpp_err("mpp_init failed\n");
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!pkt_eos) {
|
||||||
|
MppTask task = NULL;
|
||||||
|
read_size = fread(buf, 1, packet_size, fp_input);
|
||||||
|
/* if (read_size != packet_size || feof(fp_input)) {
|
||||||
|
mpp_log("found last packet\n");
|
||||||
|
pkt_eos = 1;
|
||||||
|
}*/
|
||||||
|
pkt_eos = 1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = mpi->dequeue(ctx, MPP_PORT_INPUT, &task); /* input queue */
|
||||||
|
if (ret) {
|
||||||
|
mpp_err("mpp task input dequeue failed\n");
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (task == NULL) {
|
||||||
|
mpp_log("mpi dequeue from MPP_PORT_INPUT fail, task equal with NULL!");
|
||||||
|
msleep(3);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
mpp_task_meta_set_packet(task, KEY_INPUT_PACKET, packet);
|
||||||
|
mpp_task_meta_set_frame (task, KEY_OUTPUT_FRAME, frame);
|
||||||
|
|
||||||
|
ret = mpi->enqueue(ctx, MPP_PORT_INPUT, task); /* input queue */
|
||||||
|
if (ret) {
|
||||||
|
mpp_err("mpp task input enqueue failed\n");
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
msleep(20);
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = mpi->dequeue(ctx, MPP_PORT_OUTPUT, &task); /* output queue */
|
||||||
|
if (ret) {
|
||||||
|
mpp_err("mpp task output dequeue failed\n");
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (task) {
|
||||||
|
MppFrame frame_out = NULL;
|
||||||
|
mpp_task_meta_get_frame(task, KEY_OUTPUT_FRAME, &frame_out);
|
||||||
|
//mpp_assert(packet_out == packet);
|
||||||
|
|
||||||
|
if (frame) { /* write frame to file here */
|
||||||
|
MppBuffer buf_out = mpp_frame_get_buffer(frame_out);
|
||||||
|
void *ptr = mpp_buffer_get_ptr(buf_out);
|
||||||
|
size_t len = mpp_buffer_get_size(buf_out);
|
||||||
|
|
||||||
|
if (fp_output)
|
||||||
|
fwrite(ptr, 1, len, fp_output);
|
||||||
|
|
||||||
|
mpp_log_f("decoded frame %d size %d\n", frame_count, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mpi->enqueue(ctx, MPP_PORT_OUTPUT, task); /* output queue */
|
||||||
|
if (ret) {
|
||||||
|
mpp_err("mpp task output enqueue failed\n");
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mpi->reset(ctx);
|
||||||
|
if (MPP_OK != ret) {
|
||||||
|
mpp_err("mpi->reset failed\n");
|
||||||
|
goto MPP_TEST_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
MPP_TEST_OUT:
|
||||||
|
if (packet) {
|
||||||
|
mpp_packet_deinit(&packet);
|
||||||
|
packet = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame) {
|
||||||
|
mpp_frame_deinit(&frame);
|
||||||
|
frame = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx) {
|
||||||
|
mpp_destroy(ctx);
|
||||||
|
ctx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf) {
|
||||||
|
mpp_free(buf);
|
||||||
|
buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frm_buf) {
|
||||||
|
mpp_free(frm_buf);
|
||||||
|
frm_buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fp_output) {
|
||||||
|
fclose(fp_output);
|
||||||
|
fp_output = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fp_input) {
|
||||||
|
fclose(fp_input);
|
||||||
|
fp_input = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MPP_OK == ret)
|
||||||
|
mpp_log_f("success\n");
|
||||||
|
else
|
||||||
|
mpp_err_f("failed ret %d\n", ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void mpi_dec_test_help()
|
static void mpi_dec_test_help()
|
||||||
{
|
{
|
||||||
@@ -394,7 +627,11 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
mpp_env_set_u32("mpi_debug", cmd->debug);
|
mpp_env_set_u32("mpi_debug", cmd->debug);
|
||||||
|
|
||||||
mpi_dec_test(cmd);
|
if (cmd->type != MPP_VIDEO_CodingMJPEG) {
|
||||||
|
mpi_dec_test_decode_simple(cmd);
|
||||||
|
} else {
|
||||||
|
mpi_dec_test_decode_advanced(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
mpp_env_set_u32("mpi_debug", 0x0);
|
mpp_env_set_u32("mpi_debug", 0x0);
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user