From 04b6a23ce20af9fb7547763318de5c99f0305f84 Mon Sep 17 00:00:00 2001 From: Herman Chen Date: Sun, 9 Oct 2016 16:34:09 +0800 Subject: [PATCH] [test]: modify mpi_dec_test for mjpeg decoding 1. clear input packet length when packet is copied 2. modify mjpeg advanced decoding path in mpi_dec_test 3. add numerator and denominator set prop function 4. remove extra log on first info change 5. fix eos process and buffer size check in advanced decoding flow 6. fix jpegd stream length config error Change-Id: Id6c26ebda090eb4076f27deaad4d61b4221f2653 Signed-off-by: Herman Chen --- mpp/base/inc/mpp_buf_slot.h | 2 + mpp/base/mpp_buf_slot.cpp | 14 ++++-- mpp/codec/dec/jpeg/jpegd_parser.c | 41 +++++++++------- mpp/codec/mpp_dec.cpp | 22 +++++++++ mpp/mpp.cpp | 3 ++ test/mpi_dec_test.c | 78 +++++++++++++++++++------------ 6 files changed, 110 insertions(+), 50 deletions(-) diff --git a/mpp/base/inc/mpp_buf_slot.h b/mpp/base/inc/mpp_buf_slot.h index 7f81eec6..b925bb35 100644 --- a/mpp/base/inc/mpp_buf_slot.h +++ b/mpp/base/inc/mpp_buf_slot.h @@ -231,6 +231,8 @@ MPP_RET mpp_buf_slot_get_prop(MppBufSlots slots, RK_S32 index, SlotPropType type typedef enum SlotsPropType_e { SLOTS_EOS, + SLOTS_NUMERATOR, // numerator of buffer size scale ratio + SLOTS_DENOMINATOR, // denominator of buffer size scale ratio SLOTS_HOR_ALIGN, // input must be buf_align function pointer SLOTS_VER_ALIGN, // input must be buf_align function pointer SLOTS_LEN_ALIGN, diff --git a/mpp/base/mpp_buf_slot.cpp b/mpp/base/mpp_buf_slot.cpp index 477d0fb2..26c124c3 100644 --- a/mpp/base/mpp_buf_slot.cpp +++ b/mpp/base/mpp_buf_slot.cpp @@ -815,9 +815,11 @@ MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_S32 index, SlotPropType type impl->info_changed = 1; #ifdef RKPLATFORM MppFrameImpl *old = (MppFrameImpl *)impl->info; - mpp_log("info change found\n"); - mpp_log("old width %4d height %4d stride hor %4d ver %4d fmt %4d\n", - old->width, old->height, old->hor_stride, old->ver_stride, old->fmt); + if (old->width || old->height) { + mpp_log("info change found\n"); + mpp_log("old width %4d height %4d stride hor %4d ver %4d fmt %4d\n", + old->width, old->height, old->hor_stride, old->ver_stride, old->fmt); + } mpp_log("new width %4d height %4d stride hor %4d ver %4d fmt %4d\n", dst->width, dst->height, dst->hor_stride, dst->ver_stride, dst->fmt); #endif @@ -901,6 +903,12 @@ MPP_RET mpp_slots_set_prop(MppBufSlots slots, SlotsPropType type, void *val) case SLOTS_EOS: { impl->eos = value; } break; + case SLOTS_NUMERATOR : { + impl->numerator = value; + } break; + case SLOTS_DENOMINATOR : { + impl->denominator = value; + } break; case SLOTS_HOR_ALIGN: { impl->hal_hor_align = (AlignFunc)val; } break; diff --git a/mpp/codec/dec/jpeg/jpegd_parser.c b/mpp/codec/dec/jpeg/jpegd_parser.c index 4cbaef38..cfdd054a 100644 --- a/mpp/codec/dec/jpeg/jpegd_parser.c +++ b/mpp/codec/dec/jpeg/jpegd_parser.c @@ -1125,22 +1125,22 @@ MPP_RET jpegd_prepare(void *ctx, MppPacket pkt, HalDecTask *task) MPP_RET ret = MPP_OK; JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; MppPacket input_packet = JpegParserCtx->input_packet; - RK_U32 pkt_length = 0; RK_U32 copy_length = 0; - void *pPacket = NULL; - RK_U8 *pPos = NULL; - - task->valid = 0; + void *base = mpp_packet_get_pos(pkt); + RK_U8 *pos = base; + RK_U32 pkt_length = (RK_U32)mpp_packet_get_length(pkt); + RK_U32 eos = (pkt_length) ? (mpp_packet_get_eos(pkt)) : (1); JpegParserCtx->pts = mpp_packet_get_pts(pkt); - JpegParserCtx->eos = mpp_packet_get_eos(pkt); - pkt_length = (RK_U32)mpp_packet_get_length(pkt); - pPacket = pPos = mpp_packet_get_pos(pkt); - if (JpegParserCtx->eos) { + task->valid = 0; + task->flags.eos = eos; + JpegParserCtx->eos = eos; + JPEGD_INFO_LOG("pkt_length %d eos %d\n", pkt_length, eos); + + if (!pkt_length) { JPEGD_INFO_LOG("it is end of stream."); - task->flags.eos = 1; return ret; } @@ -1158,10 +1158,10 @@ MPP_RET jpegd_prepare(void *ctx, MppPacket pkt, HalDecTask *task) JpegParserCtx->bufferSize = pkt_length + 1024; } - jpegd_parser_split_frame(pPacket, pkt_length, JpegParserCtx->recv_buffer, ©_length); + jpegd_parser_split_frame(base, pkt_length, JpegParserCtx->recv_buffer, ©_length); - pPos += pkt_length; - mpp_packet_set_pos(pkt, pPos); + pos += pkt_length; + mpp_packet_set_pos(pkt, pos); if (copy_length != pkt_length) { JPEGD_INFO_LOG("there seems to be something wrong with split_frame. pkt_length:%d, copy_length:%d", pkt_length, copy_length); } @@ -1175,7 +1175,7 @@ MPP_RET jpegd_prepare(void *ctx, MppPacket pkt, HalDecTask *task) jpg_file = fopen(name, "wb+"); if (jpg_file) { JPEGD_INFO_LOG("input jpeg(%d Bytes) saving to %s\n", pkt_length, name); - fwrite(pPacket, pkt_length, 1, jpg_file); + fwrite(base, pkt_length, 1, jpg_file); fclose(jpg_file); JpegParserCtx->input_jpeg_count++; } @@ -2379,15 +2379,24 @@ MPP_RET jpegd_allocate_frame(JpegParserContext *ctx) } if (pCtx->frame_slot_index == -1) { + RK_U32 value; + mpp_frame_set_width(pCtx->output_frame, pCtx->pSyntax->frame.X); mpp_frame_set_height(pCtx->output_frame, pCtx->pSyntax->frame.Y); mpp_frame_set_hor_stride(pCtx->output_frame, pCtx->pSyntax->frame.X); mpp_frame_set_ver_stride(pCtx->output_frame, pCtx->pSyntax->frame.Y); mpp_frame_set_pts(pCtx->output_frame, pCtx->pts); + if (pCtx->eos) + mpp_frame_set_eos(pCtx->output_frame, 1); + mpp_buf_slot_get_unused(pCtx->frame_slots, &pCtx->frame_slot_index); JPEGD_INFO_LOG("frame_slot_index:%d, X:%d, Y:%d", pCtx->frame_slot_index, pCtx->pSyntax->frame.X, pCtx->pSyntax->frame.Y); + value = 3; + mpp_slots_set_prop(pCtx->frame_slots, SLOTS_NUMERATOR, &value); + value = 2; + mpp_slots_set_prop(pCtx->frame_slots, SLOTS_DENOMINATOR, &value); mpp_buf_slot_set_prop(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_FRAME, pCtx->output_frame); mpp_buf_slot_set_flag(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_CODEC_USE); mpp_buf_slot_set_flag(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_HAL_OUTPUT); @@ -2453,7 +2462,7 @@ MPP_RET jpegd_decode_frame(JpegParserContext *ctx) if (!pSyntax->info.SliceReadyForPause && !pSyntax->info.inputBufferEmpty && pCtx->bufferSize) { pSyntax->info.inputStreaming = 1; - pSyntax->info.inputBufferLen = pCtx->bufferSize; + pSyntax->info.inputBufferLen = pCtx->streamLength; pSyntax->info.decodedStreamLen += pSyntax->info.inputBufferLen; } @@ -2616,7 +2625,7 @@ MPP_RET jpegd_init(void *ctx, ParserCfg *parser_cfg) JpegParserCtx->frame_slots = parser_cfg->frame_slots; JpegParserCtx->packet_slots = parser_cfg->packet_slots; JpegParserCtx->frame_slot_index = -1; - mpp_buf_slot_setup(JpegParserCtx->frame_slots, 16); + mpp_buf_slot_setup(JpegParserCtx->frame_slots, 1); JpegParserCtx->recv_buffer = mpp_calloc(RK_U8, JPEGD_STREAM_BUFF_SIZE); if (NULL == JpegParserCtx->recv_buffer) { diff --git a/mpp/codec/mpp_dec.cpp b/mpp/codec/mpp_dec.cpp index 39d6fc8c..c58ee576 100644 --- a/mpp/codec/mpp_dec.cpp +++ b/mpp/codec/mpp_dec.cpp @@ -868,6 +868,17 @@ void *mpp_dec_advanced_thread(void *data) parser_prepare(dec->parser, packet, task_dec); + /* + * We may find eos in prepare step and there will be no anymore vaild task generated. + * So here we try push eos task to hal, hal will push all frame to display then + * push a eos frame to tell all frame decoded + */ + if (task_dec->flags.eos && !task_dec->valid) { + mpp_frame_init(&frame); + mpp_frame_set_eos(frame, 1); + goto DEC_OUT; + } + /* * look for a unused packet slot index */ @@ -886,6 +897,17 @@ void *mpp_dec_advanced_thread(void *data) goto DEC_OUT; } + if (mpp_buf_slot_is_changed(frame_slots)) { + size_t slot_size = mpp_buf_slot_get_size(frame_slots); + size_t buffer_size = mpp_buffer_get_size(output_buffer); + + if (slot_size == buffer_size) { + mpp_buf_slot_ready(frame_slots); + } + + mpp_assert(slot_size == buffer_size); + } + mpp_buf_slot_set_prop(frame_slots, task_dec->output, SLOT_BUFFER, output_buffer); // register genertation diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index c1278f29..c7b88b4b 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -252,6 +252,9 @@ MPP_RET Mpp::put_packet(MppPacket packet) mPackets->add_at_tail(&pkt, sizeof(pkt)); mPacketPutCount++; mThreadCodec->signal(); + + // when packet has been send clear the length + mpp_packet_set_length(pkt, 0); return MPP_OK; } diff --git a/test/mpi_dec_test.c b/test/mpi_dec_test.c index ed2caad3..a1f4f16f 100644 --- a/test/mpi_dec_test.c +++ b/test/mpi_dec_test.c @@ -153,6 +153,7 @@ int mpi_dec_test_decode_simple(MpiDecTestCmd *cmd) mpp_packet_write(packet, 0, buf, read_size); // reset pos mpp_packet_set_pos(packet, buf); + mpp_packet_set_length(packet, read_size); // setup eos flag if (pkt_eos) mpp_packet_set_eos(packet); @@ -239,11 +240,6 @@ MPP_TEST_OUT: fp_input = NULL; } - if (MPP_OK == ret) - mpp_log("mpi_dec_test success\n"); - else - mpp_err("mpi_dec_test failed ret %d\n", ret); - return ret; } @@ -276,9 +272,9 @@ int mpi_dec_test_decode_advanced(MpiDecTestCmd *cmd) MppBuffer frm_buf = NULL; size_t packet_size = MPI_DEC_STREAM_SIZE; size_t read_size = 0; + size_t file_size = 0; RK_U32 frame_count = 0; void *buf = NULL; - (void)read_size; MppBufferGroup frm_grp = NULL; MppBufferGroup pkt_grp = NULL; @@ -291,6 +287,12 @@ int mpi_dec_test_decode_advanced(MpiDecTestCmd *cmd) mpp_err("failed to open input file %s\n", cmd->file_input); goto MPP_TEST_OUT; } + + // get file size for MJPEG + fseek(fp_input, 0L, SEEK_END); + file_size = ftell(fp_input); + rewind(fp_input); + mpp_log("input file size %ld\n", file_size); } if (cmd->have_output) { @@ -313,10 +315,6 @@ int mpi_dec_test_decode_advanced(MpiDecTestCmd *cmd) 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) { @@ -330,6 +328,11 @@ int mpi_dec_test_decode_advanced(MpiDecTestCmd *cmd) goto MPP_TEST_OUT; } + // NOTE: for mjpeg decoding send the whole file + if (type == MPP_VIDEO_CodingMJPEG) { + packet_size = file_size; + } + 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); @@ -366,11 +369,17 @@ int mpi_dec_test_decode_advanced(MpiDecTestCmd *cmd) while (!pkt_eos) { MppTask task = NULL; read_size = fread(buf, 1, packet_size, fp_input); - /* if (read_size != packet_size || feof(fp_input)) { + if (read_size != packet_size || feof(fp_input)) { mpp_log("found last packet\n"); pkt_eos = 1; - }*/ - pkt_eos = 1; + } + + // reset pos + mpp_packet_set_pos(packet, buf); + mpp_packet_set_length(packet, read_size); + // setup eos flag + if (pkt_eos) + mpp_packet_set_eos(packet); do { ret = mpi->dequeue(ctx, MPP_PORT_INPUT, &task); /* input queue */ @@ -410,15 +419,22 @@ int mpi_dec_test_decode_advanced(MpiDecTestCmd *cmd) 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 (frame) { + /* write frame to file here */ + MppBuffer buf_out = mpp_frame_get_buffer(frame_out); - if (fp_output) - fwrite(ptr, 1, len, fp_output); + if (buf_out) { + void *ptr = mpp_buffer_get_ptr(buf_out); + size_t len = mpp_buffer_get_size(buf_out); - mpp_log_f("decoded frame %d size %d\n", frame_count, len); + if (fp_output) + fwrite(ptr, 1, len, fp_output); + + mpp_log("decoded frame %d size %d\n", frame_count, len); + } + + if (mpp_frame_get_eos(frame_out)) + mpp_log("found eos frame\n"); } ret = mpi->enqueue(ctx, MPP_PORT_OUTPUT, task); /* output queue */ @@ -453,13 +469,13 @@ MPP_TEST_OUT: ctx = NULL; } - if (buf) { - mpp_free(buf); - buf = NULL; + if (pkt_buf) { + mpp_buffer_put(pkt_buf); + pkt_buf = NULL; } if (frm_buf) { - mpp_free(frm_buf); + mpp_buffer_put(frm_buf); frm_buf = NULL; } @@ -473,11 +489,6 @@ MPP_TEST_OUT: fp_input = NULL; } - if (MPP_OK == ret) - mpp_log_f("success\n"); - else - mpp_err_f("failed ret %d\n", ret); - return ret; } @@ -628,11 +639,16 @@ int main(int argc, char **argv) mpp_env_set_u32("mpi_debug", cmd->debug); if (cmd->type != MPP_VIDEO_CodingMJPEG) { - mpi_dec_test_decode_simple(cmd); + ret = mpi_dec_test_decode_simple(cmd); } else { - mpi_dec_test_decode_advanced(cmd); + ret = mpi_dec_test_decode_advanced(cmd); } + if (MPP_OK == ret) + mpp_log("test success\n"); + else + mpp_err("test failed ret %d\n", ret); + mpp_env_set_u32("mpi_debug", 0x0); return 0; }