From af111d36a196395952ae38e4d3a38e48d2d2562e Mon Sep 17 00:00:00 2001 From: DingWei Date: Mon, 28 Mar 2016 00:49:35 +0000 Subject: [PATCH] [h264d] update h264d_test, resolve probleam which single-version demo slot buffer leak, add muti-thread version. [h264d] Astyle [h264d] add free buffer for debug git-svn-id: https://10.10.10.66:8443/svn/MediaProcessPlatform/trunk/mpp@596 6e48237b-75ef-9749-8fc9-41990f28c85a --- mpp/codec/dec/h264/h264d_api.c | 12 +- mpp/codec/dec/h264/h264d_dpb.c | 19 +- mpp/codec/dec/h264/h264d_init.c | 5 +- mpp/codec/dec/h264/h264d_init.h | 2 +- mpp/codec/dec/h264/h264d_parse.c | 9 +- mpp/codec/dec/h264/h264d_sei.c | 4 +- mpp/codec/dec/h264/h264d_slice.c | 17 +- mpp/codec/dec/h264/h264d_sps.c | 2 +- mpp/common/h264d_log.h | 2 +- mpp/test/h264d_rwfile.c | 14 +- mpp/test/h264d_rwfile.h | 17 +- mpp/test/h264d_test.c | 597 +++++++++++++++++++++++-------- 12 files changed, 497 insertions(+), 203 deletions(-) diff --git a/mpp/codec/dec/h264/h264d_api.c b/mpp/codec/dec/h264/h264d_api.c index 023144a9..1f938ddd 100644 --- a/mpp/codec/dec/h264/h264d_api.c +++ b/mpp/codec/dec/h264/h264d_api.c @@ -364,7 +364,7 @@ static MPP_RET init_dec_ctx(H264_DecCtx_t *p_Dec) p_Dec->dxva_ctx = &p_Dec->mem->dxva_ctx; //!< init Dpb_memory Mark for (i = 0; i < MAX_MARK_SIZE; i++) { - reset_dpb_mark(&p_Dec->dpb_mark[i], i); + reset_dpb_mark(&p_Dec->dpb_mark[i]); } mpp_buf_slot_setup(p_Dec->frame_slots, MAX_MARK_SIZE); //!< malloc mpp packet @@ -404,7 +404,7 @@ static void flush_dpb_buf_slot(H264_DecCtx_t *p_Dec) mpp_buf_slot_clr_flag(p_Dec->frame_slots, p_mark->slot_idx, SLOT_CODEC_USE); } } - reset_dpb_mark(p_mark, i); + reset_dpb_mark(p_mark); } } @@ -599,7 +599,7 @@ MPP_RET h264d_flush(void *decoder) p_Dec->p_Inp->task_eos = 1; mpp_buf_slot_set_prop(p_Dec->frame_slots, p_Dec->last_frame_slot_idx, SLOT_EOS, &p_Dec->p_Inp->task_eos); __RETURN: - H264D_DBG(H264D_DBG_DPB_DISPLAY, "[DPB display] flush end, task_eos=%d, last_slot_idx=%d", p_Dec->p_Inp->task_eos, p_Dec->last_frame_slot_idx); + H264D_DBG(H264D_DBG_DPB_DISPLAY, "[DPB_display] flush end, task_eos=%d, last_slot_idx=%d", p_Dec->p_Inp->task_eos, p_Dec->last_frame_slot_idx); FunctionOut(p_Dec->logctx.parr[RUN_PARSE]); return ret = MPP_OK; __FAILED: @@ -671,7 +671,7 @@ MPP_RET h264d_prepare(void *decoder, MppPacket pkt, HalDecTask *task) goto __RETURN; } } - H264D_DBG(H264D_DBG_INPUT, "[pkt_in timeUs] is_avcC=%d, in_pts=%lld, pkt_eos=%d, len=%d, g_framecnt=%d \n", + H264D_DBG(H264D_DBG_INPUT, "[pkt_in_timeUs] is_avcC=%d, in_pts=%lld, pkt_eos=%d, len=%d, g_framecnt=%d \n", p_Inp->is_nalff, p_Inp->in_pts, p_Inp->pkt_eos, p_Inp->in_length, p_Dec->p_Vid->g_framecnt); if (p_Inp->is_nalff) { @@ -679,7 +679,7 @@ MPP_RET h264d_prepare(void *decoder, MppPacket pkt, HalDecTask *task) task->valid = p_Inp->task_valid; //!< prepare valid flag } else { do { - (ret = parse_prepare_fast(p_Inp, p_Dec->p_Cur)); + (ret = parse_prepare(p_Inp, p_Dec->p_Cur)); task->valid = p_Inp->task_valid; //!< prepare valid flag } while (mpp_packet_get_length(pkt) && !task->valid); } @@ -753,7 +753,7 @@ __FAILED: { mpp_buf_slot_set_flag(p_Dec->frame_slots, dec_pic->mem_mark->slot_idx, SLOT_QUEUE_USE); mpp_buf_slot_enqueue (p_Dec->frame_slots, dec_pic->mem_mark->slot_idx, QUEUE_DISPLAY); mpp_buf_slot_clr_flag(p_Dec->frame_slots, dec_pic->mem_mark->slot_idx, SLOT_CODEC_USE); - dec_pic->mem_mark->out_flag = 0; + reset_dpb_mark(dec_pic->mem_mark); p_Dec->p_Vid->dec_pic = NULL; mpp_frame_set_discard(mframe, 1); } diff --git a/mpp/codec/dec/h264/h264d_dpb.c b/mpp/codec/dec/h264/h264d_dpb.c index fa5e7b43..d44de387 100644 --- a/mpp/codec/dec/h264/h264d_dpb.c +++ b/mpp/codec/dec/h264/h264d_dpb.c @@ -635,7 +635,7 @@ static void free_dpb_mark(H264_DecCtx_t *p_Dec, H264_DpbMark_t *p, RK_S32 struct } else if (structure == BOTTOM_FIELD) { p->bot_used = (p->bot_used > 0) ? (p->bot_used - 1) : 0; } - H264D_DBG(H264D_DBG_DPB_FREE, "[DPB free] top_used=%d, bot_used=%d, out_flag=%d, slot_idx=%d \n", + H264D_DBG(H264D_DBG_DPB_FREE, "[DPB_free] top_used=%d, bot_used=%d, out_flag=%d, slot_idx=%d \n", p->top_used, p->bot_used, p->out_flag, p->slot_idx); if (p->top_used == 0 && p->bot_used == 0 && p->out_flag == 0 && (p->slot_idx >= 0)) { @@ -648,7 +648,7 @@ static void free_dpb_mark(H264_DecCtx_t *p_Dec, H264_DpbMark_t *p, RK_S32 struct RK_U64 pts = frame ? mpp_frame_get_pts(frame) : 0; RK_U32 poc = frame ? mpp_frame_get_poc(frame) : 0; mpp_buf_slot_get_prop(p_Dec->frame_slots, p->slot_idx, SLOT_BUFFER, &mbuffer); - H264D_DBG(H264D_DBG_DPB_FREE, "[DPB free] g_frame_no=%d, structure=%d, mark_idx=%d, slot_idx=%d(%p), poc=%d, pts=%lld, %p \n", + H264D_DBG(H264D_DBG_DPB_FREE, "[DPB_free] g_frame_no=%d, structure=%d, mark_idx=%d, slot_idx=%d(%p), poc=%d, pts=%lld, %p \n", p_Dec->p_Vid->g_framecnt, structure, p->mark_idx, p->slot_idx, mbuffer, poc, pts, frame); } } @@ -665,7 +665,7 @@ static MPP_RET remove_frame_from_dpb(H264_DpbBuf_t *p_Dpb, RK_S32 pos) H264_DecCtx_t *p_Dec = p_Dpb->p_Vid->p_Dec; LogCtx_t *runlog = p_Dec->logctx.parr[RUN_PARSE]; - H264D_DBG(H264D_DBG_DPB_FREE, "[FREE MALLOC] is_used=%d, used_size=%d,frame(%p), top(%p), bot(%p)", + H264D_DBG(H264D_DBG_DPB_FREE, "[FREE_MALLOC] is_used=%d, used_size=%d,frame(%p), top(%p), bot(%p)", fs->is_used, p_Dpb->used_size, fs->frame, fs->top_field, fs->bottom_field); switch (fs->is_used) { @@ -792,6 +792,8 @@ static MPP_RET dpb_combine_field_yuv(H264dVideoCtx_t *p_Vid, H264_FrameStore_t * fs->frame->mem_mark = fs->bottom_field->mem_mark; } else { ASSERT(fs->is_used == 0x03); + fs->frame->mem_malloc_type = fs->top_field->mem_malloc_type; + fs->frame->mem_mark = fs->top_field->mem_mark; } } fs->poc = fs->frame->poc = fs->frame->frame_poc = MPP_MIN(fs->top_field->poc, fs->bottom_field->poc); @@ -916,6 +918,8 @@ static void write_picture(H264_StorePic_t *p, H264dVideoCtx_t *p_Vid) H264_DpbMark_t *p_mark = NULL; p_mark = p->mem_mark; + H264D_DBG(H264D_DBG_DPB_FREE, "[DPB_free] write_picture, type=%d, structure=%d, poc=%d, out_flag=%d", + p->mem_malloc_type, p->structure, p->poc, p_mark->out_flag); if ((p->mem_malloc_type == Mem_Malloc || p->mem_malloc_type == Mem_TopOnly || p->mem_malloc_type == Mem_BotOnly) @@ -962,9 +966,11 @@ static void write_picture(H264_StorePic_t *p, H264dVideoCtx_t *p_Vid) { MppBuffer mbuffer = NULL; mpp_buf_slot_get_prop(p_Vid->p_Dec->frame_slots, p_mark->slot_idx, SLOT_BUFFER, &mbuffer); - H264D_DBG(H264D_DBG_DPB_DISPLAY, "[DPB dispaly] layer_id=%d, pic_num=%d, poc=%d, last_poc=%d, slice_type=%d(idr=%d), slot_idx=%d(%p), pts=%lld, g_framecnt=%d \n", + H264D_DBG(H264D_DBG_DPB_DISPLAY, "[DPB_dispaly] layer_id=%d, pic_num=%d, poc=%d, last_poc=%d, slice_type=%d(idr=%d), slot_idx=%d(%p), pts=%lld, g_framecnt=%d \n", p->layer_id, p->pic_num, p->poc, p_Vid->last_outputpoc[p->layer_id], p->slice_type, p->idr_flag, p_mark->slot_idx, mbuffer, mpp_frame_get_pts(mframe), p_Vid->g_framecnt); } + H264D_DBG(H264D_DBG_DPB_FREE, "[DPB_free] after, out_flag=%d", p_mark->out_flag); + } } @@ -1371,11 +1377,10 @@ MPP_RET store_picture_in_dpb(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p) p_Dpb->last_picture = NULL; } p_Dpb->used_size++; - H264D_DBG(H264D_DBG_DPB_INFO, "[DPB size] p_Dpb->used_size=%d", p_Dpb->used_size); + H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_size] p_Dpb->used_size=%d", p_Dpb->used_size); update_ref_list(p_Dpb); update_ltref_list(p_Dpb); mpp_buf_slot_set_flag(p_Vid->p_Dec->frame_slots, p->mem_mark->slot_idx, SLOT_CODEC_USE); - __RETURN: return ret = MPP_OK; __FAILED: @@ -1670,7 +1675,7 @@ __FAILED: void free_storable_picture(H264_DecCtx_t *p_Dec, H264_StorePic_t *p) { if (p) { - H264D_DBG(H264D_DBG_DPB_FREE, "[FREE MALLOC] type=%d", p->mem_malloc_type); + H264D_DBG(H264D_DBG_DPB_FREE, "[DPB_free] type=%d", p->mem_malloc_type); if (p->mem_malloc_type == Mem_Malloc || p->mem_malloc_type == Mem_Clone) { free_dpb_mark(p_Dec, p->mem_mark, p->structure); diff --git a/mpp/codec/dec/h264/h264d_init.c b/mpp/codec/dec/h264/h264d_init.c index 621b2ae0..0ed650f3 100644 --- a/mpp/codec/dec/h264/h264d_init.c +++ b/mpp/codec/dec/h264/h264d_init.c @@ -421,7 +421,7 @@ static void dpb_mark_malloc(H264dVideoCtx_t *p_Vid, H264_StorePic_t *dec_pic) { MppBuffer mbuffer = NULL; mpp_buf_slot_get_prop(p_Dec->frame_slots, cur_mark->slot_idx, SLOT_BUFFER, &mbuffer); - H264D_DBG(H264D_DBG_DPB_MALLIC, "[DPB malloc] g_framecnt=%d, mark_idx=%d, slot_idx=%d, slice_type=%d, lay_id=%d, pts=%lld \n", + H264D_DBG(H264D_DBG_DPB_MALLIC, "[DPB_malloc] g_framecnt=%d, mark_idx=%d, slot_idx=%d, slice_type=%d, lay_id=%d, pts=%lld \n", p_Vid->g_framecnt, cur_mark->mark_idx, cur_mark->slot_idx, dec_pic->slice_type, layer_id, p_Vid->p_Inp->in_pts); } @@ -1890,12 +1890,11 @@ static MPP_RET check_refer_dpb_buf_slots(H264_SLICE_t *currSlice) *********************************************************************** */ //extern "C" -MPP_RET reset_dpb_mark(H264_DpbMark_t *p_mark, RK_U32 idx) +MPP_RET reset_dpb_mark(H264_DpbMark_t *p_mark) { p_mark->top_used = 0; p_mark->bot_used = 0; p_mark->out_flag = 0; - p_mark->mark_idx = idx; p_mark->slot_idx = -1; p_mark->pic = NULL; p_mark->mframe = NULL; diff --git a/mpp/codec/dec/h264/h264d_init.h b/mpp/codec/dec/h264/h264d_init.h index 8c10a381..519e0445 100644 --- a/mpp/codec/dec/h264/h264d_init.h +++ b/mpp/codec/dec/h264/h264d_init.h @@ -30,7 +30,7 @@ extern "C" { MPP_RET update_dpb (H264_DecCtx_t *p_Dec); MPP_RET init_picture (H264_SLICE_t *currSlice); -MPP_RET reset_dpb_mark(H264_DpbMark_t *p_mark, RK_U32 idx); +MPP_RET reset_dpb_mark(H264_DpbMark_t *p_mark); #ifdef __cplusplus } #endif diff --git a/mpp/codec/dec/h264/h264d_parse.c b/mpp/codec/dec/h264/h264d_parse.c index 4334c375..79327523 100644 --- a/mpp/codec/dec/h264/h264d_parse.c +++ b/mpp/codec/dec/h264/h264d_parse.c @@ -226,6 +226,7 @@ static MPP_RET parser_one_nalu(H264_SLICE_t *currSlice) switch (currSlice->p_Cur->nalu.nalu_type) { case NALU_TYPE_SLICE: case NALU_TYPE_IDR: + H264D_DBG(H264D_DBG_PARSE_NALU, "nalu_type=SLICE."); FUN_CHECK(ret = process_slice(currSlice)); if (currSlice->is_new_picture) { currSlice->p_Dec->nalu_ret = StartOfPicture; @@ -235,22 +236,21 @@ static MPP_RET parser_one_nalu(H264_SLICE_t *currSlice) if (currSlice->layer_id && currSlice->p_Inp->mvc_disable) { currSlice->p_Dec->nalu_ret = MvcDisAble; } - H264D_DBG(H264D_DBG_PARSE_NALU, "nalu_type=SLICE."); break; case NALU_TYPE_SPS: + H264D_DBG(H264D_DBG_PARSE_NALU, "nalu_type=SPS"); FUN_CHECK(ret = process_sps(currSlice)); currSlice->p_Dec->nalu_ret = NALU_SPS; - H264D_DBG(H264D_DBG_PARSE_NALU, "nalu_type=SPS"); break; case NALU_TYPE_PPS: + H264D_DBG(H264D_DBG_PARSE_NALU, "nalu_type=PPS"); FUN_CHECK(ret = process_pps(currSlice)); currSlice->p_Dec->nalu_ret = NALU_PPS; - H264D_DBG(H264D_DBG_PARSE_NALU, "nalu_type=PPS"); break; case NALU_TYPE_SUB_SPS: + H264D_DBG(H264D_DBG_PARSE_NALU, "nalu_type=SUB_SPS"); FUN_CHECK(ret = process_subsps(currSlice)); currSlice->p_Dec->nalu_ret = NALU_SubSPS; - H264D_DBG(H264D_DBG_PARSE_NALU, "nalu_type=SUB_SPS"); break; case NALU_TYPE_SEI: //FUN_CHECK(ret = process_sei(currSlice)); @@ -299,6 +299,7 @@ static MPP_RET parser_one_nalu(H264_SLICE_t *currSlice) return ret = MPP_OK; __FAILED: + H264D_DBG(H264D_DBG_PARSE_NALU, "parser_one_nalu error."); currSlice->p_Dec->nalu_ret = ReadNaluError; return ret; } diff --git a/mpp/codec/dec/h264/h264d_sei.c b/mpp/codec/dec/h264/h264d_sei.c index df88ba93..b142b53c 100644 --- a/mpp/codec/dec/h264/h264d_sei.c +++ b/mpp/codec/dec/h264/h264d_sei.c @@ -68,7 +68,7 @@ static MPP_RET interpret_user_data_unregistered_info(RK_U8 *payload, RK_S32 size { MPP_RET ret = MPP_ERR_UNKNOW; - H264D_DBG(H264D_DBG_SEI, "[SEI info] user data info, size=%d", size); + H264D_DBG(H264D_DBG_SEI, "[SEI_info] user data info, size=%d", size); ASSERT(size >= 16); sei_msg->user_data_DivX_flag = strstr(_strupr((char *)&payload[16]), "DIVX") ? 1 : 0; @@ -247,7 +247,7 @@ static MPP_RET parserSEI(H264_SLICE_t *cur_slice, BitReadCtx_t *p_bitctx, H264_S MPP_RET ret = MPP_ERR_UNKNOW; H264dVideoCtx_t *p_Vid = cur_slice->p_Vid; - H264D_DBG(H264D_DBG_SEI, "[SEI info] type=%d \n", sei_msg->type); + H264D_DBG(H264D_DBG_SEI, "[SEI_info] type=%d \n", sei_msg->type); switch (sei_msg->type) { case SEI_BUFFERING_PERIOD: FUN_CHECK(ret = interpret_buffering_period_info(msg, sei_msg->payload_size, p_bitctx, sei_msg)); diff --git a/mpp/codec/dec/h264/h264d_slice.c b/mpp/codec/dec/h264/h264d_slice.c index 91ca0ac8..3a8a07f1 100644 --- a/mpp/codec/dec/h264/h264d_slice.c +++ b/mpp/codec/dec/h264/h264d_slice.c @@ -342,8 +342,8 @@ static MPP_RET set_slice_user_parmeters(H264_SLICE_t *currSlice) } VAL_CHECK(ret, check_sps_pps(cur_sps, cur_subsps, cur_pps) != MPP_NOK); - H264D_DBG(H264D_DBG_PPS_SPS, "[SLICE_HEAD] layer_id=%d,sps_id=%d, pps_id=%d", currSlice->layer_id, - cur_sps->seq_parameter_set_id, cur_pps->pic_parameter_set_id); + H264D_DBG(H264D_DBG_PPS_SPS, "[SLICE_HEAD] layer_id=%d,sps_id=%d, pps_id=%d, structure=%d", currSlice->layer_id, + cur_sps->seq_parameter_set_id, cur_pps->pic_parameter_set_id, currSlice->structure); FUN_CHECK(ret = activate_sps(p_Vid, cur_sps, cur_subsps)); FUN_CHECK(ret = activate_pps(p_Vid, cur_pps)); @@ -443,14 +443,13 @@ MPP_RET process_slice(H264_SLICE_t *currSlice) LogInfo(p_bitctx->ctx, "----------------------------- SLICE begin --------------------------------"); //!< read slice head syntax READ_UE(p_bitctx, &currSlice->start_mb_nr, "first_mb_in_slice"); - //FPRINT(g_debug_file1, "first_mb_in_slice = %d \n", currSlice->start_mb_nr); + READ_UE(p_bitctx, &temp, "slice_type"); + p_Vid->slice_type = currSlice->slice_type = temp % 5; + READ_UE(p_bitctx, &currSlice->pic_parameter_set_id, "slice_pic_parameter_set_id"); + init_slice_parmeters(currSlice); + FUN_CHECK(ret = set_slice_user_parmeters(currSlice)); + //!< read rest slice header syntax if (currSlice->start_mb_nr == 0/*is_new_picture(currSlice)*/) { - READ_UE(p_bitctx, &temp, "slice_type"); - p_Vid->slice_type = currSlice->slice_type = temp % 5; - READ_UE(p_bitctx, &currSlice->pic_parameter_set_id, "slice_pic_parameter_set_id"); - init_slice_parmeters(currSlice); - FUN_CHECK(ret = set_slice_user_parmeters(currSlice)); - //!< read rest slice header syntax READ_BITS(p_bitctx, currSlice->active_sps->log2_max_frame_num_minus4 + 4, &currSlice->frame_num, "frame_num"); if (currSlice->active_sps->frame_mbs_only_flag) { //!< user in_slice info p_Vid->structure = FRAME; diff --git a/mpp/codec/dec/h264/h264d_sps.c b/mpp/codec/dec/h264/h264d_sps.c index bf88ac36..05776bb6 100644 --- a/mpp/codec/dec/h264/h264d_sps.c +++ b/mpp/codec/dec/h264/h264d_sps.c @@ -568,7 +568,7 @@ MPP_RET activate_sps(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps, H264_subSPS_t *sub } VAL_CHECK(ret, p_Vid->dpb_size[0] > 0); } - H264D_DBG(H264D_DBG_DPB_INFO, "[DPB size] dpb_size[0]=%d, mvc_flag=%d, dpb_size[1]=%d", + H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_size] dpb_size[0]=%d, mvc_flag=%d, dpb_size[1]=%d", p_Vid->dpb_size[0], p_Vid->active_mvc_sps_flag, p_Vid->dpb_size[1]); update_video_pars(p_Vid, p_Vid->active_sps); __RETURN: diff --git a/mpp/common/h264d_log.h b/mpp/common/h264d_log.h index 689d60d8..0e8dd22b 100644 --- a/mpp/common/h264d_log.h +++ b/mpp/common/h264d_log.h @@ -67,7 +67,7 @@ do {\ #define H264D_ERR(fmt, ...)\ do {\ if (H264D_DBG_ERROR & rkv_h264d_parse_debug)\ - { mpp_err(fmt, ## __VA_ARGS__); }\ + { mpp_log(fmt, ## __VA_ARGS__); }\ } while (0) #define ASSERT(val)\ diff --git a/mpp/test/h264d_rwfile.c b/mpp/test/h264d_rwfile.c index 95c181aa..3bfa0cdf 100644 --- a/mpp/test/h264d_rwfile.c +++ b/mpp/test/h264d_rwfile.c @@ -48,7 +48,7 @@ static const RK_U32 IOBUFSIZE = 16 * 1024 * 1024; //524288 static const RK_U32 STMBUFSIZE = 16 * 1024 * 1024; //524288 - +RK_U32 rkv_h264d_test_debug = 0; //!< values for nalu_type typedef enum { NALU_TYPE_NULL = 0, @@ -507,14 +507,6 @@ static MPP_RET read_next_nalu(InputParams *p_in) ASSERT(forbidden_bit == 0); read_bits( pStrmData, 2, &nal_reference_idc); read_bits( pStrmData, 5, &nalu_type); - if (g_nalu_cnt2 == 344) { - g_nalu_cnt2 = g_nalu_cnt2; - } - //if (g_debug_file0 == NULL) - //{ - // g_debug_file0 = fopen("rk_debugfile_view0.txt", "wb"); - //} - //FPRINT(g_debug_file0, "[Read_NALU] g_nalu_cnt = %d, nalu_type = %d, nalu_size = %d\n", g_nalu_cnt2++, nalu_type, p_in->IO.nalubytes); nalu_header_bytes = 1; if ((nalu_type == NALU_TYPE_PREFIX) || (nalu_type == NALU_TYPE_SLC_EXT)) { @@ -528,10 +520,6 @@ static MPP_RET read_next_nalu(InputParams *p_in) if ( nalu_type == NALU_TYPE_SLICE || nalu_type == NALU_TYPE_IDR) { set_streamdata(pStrmData, (p_in->IO.pNALU + nalu_header_bytes), 4); // reset read_ue(pStrmData, &first_mb_in_slice); - //FPRINT(g_debug_file0, "first_mb_in_slice = %d \n", first_mb_in_slice); - //if (first_mb_in_slice == 0) { - // FPRINT(g_debug_file0, "--- new frame ---- \n"); - //} if (!p_in->is_fist_frame && (first_mb_in_slice == 0)) { p_in->is_new_frame = 1; } diff --git a/mpp/test/h264d_rwfile.h b/mpp/test/h264d_rwfile.h index 1b187544..933ef39d 100644 --- a/mpp/test/h264d_rwfile.h +++ b/mpp/test/h264d_rwfile.h @@ -18,7 +18,7 @@ #include #include "rk_type.h" #include "mpp_err.h" - +#include "mpp_log.h" #ifndef __H264D_RWFILE_H__ #define __H264D_RWFILE_H__ @@ -61,6 +61,21 @@ typedef struct inp_par_t { void *bitctx; } InputParams; +extern RK_U32 rkv_h264d_test_debug; + + +#define H264D_TEST_TRACE (0x00000001) +#define H264D_TEST_TIME (0x00000002) +#define H264D_TEST_MUTI_THREAD (0x00000004) +#define H264D_TEST_DUMPYUV (0x00000008) +#define H264D_TEST_FPGA (0x00000010) + + +#define H264D_TEST_LOG(level, fmt, ...)\ +do {\ + if (level & rkv_h264d_test_debug)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ +} while (0) #ifdef __cplusplus diff --git a/mpp/test/h264d_test.c b/mpp/test/h264d_test.c index c9b88f21..a6ca60e7 100644 --- a/mpp/test/h264d_test.c +++ b/mpp/test/h264d_test.c @@ -21,7 +21,10 @@ #include "vld.h" #endif #include -#include "mpp_log.h" + +#include "vpu_api.h" + +#include "h264d_log.h" #include "mpp_env.h" #include "mpp_dec.h" #include "mpp_hal.h" @@ -37,28 +40,58 @@ #include "h264d_api.h" #include "hal_task.h" #include "hal_h264d_api.h" +#include "mpp_thread.h" +typedef enum { + HAL_THREAD_UNINITED, + HAL_THREAD_RUNNING, + HAL_THREAD_WAITING, + HAL_THREAD_STOPPING, +} HalStatus; + +typedef struct hal_thread_param_t { + HalStatus hal_status; + pthread_t halThread; + pthread_mutex_t parLock; + pthread_cond_t parCond; + pthread_mutex_t halLock; + pthread_cond_t halCond; +} HalThreadPar_t; + +typedef struct h264d_test_ctx_t { + MppDec m_api; + InputParams m_in; + HalTaskInfo m_task; + HalThreadPar_t m_hal; + MppBuffer m_dec_pkt_buf; + MppBuffer m_dec_pic_buf; + MppBufferGroup mFrameGroup; + MppBufferGroup mStreamGroup; +} H264dTestCtx_t; static MPP_RET manual_set_env(void) { #if defined(_MSC_VER) - mpp_env_set_u32("h264d_log_help", 1 ); - mpp_env_set_u32("h264d_log_show", 1 ); - mpp_env_set_u32("h264d_log_ctrl", 0x800B ); - mpp_env_set_u32("h264d_log_level", 5 ); - mpp_env_set_u32("h264d_log_decframe", 0 ); - mpp_env_set_u32("h264d_log_begframe", 0 ); - mpp_env_set_u32("h264d_log_endframe", 0 ); - mpp_env_set_u32("h264d_log_yuv", 0 ); - mpp_env_set_u32("h264d_chg_org", 0 ); //!< 0:VDPU 1: RKVDEC - mpp_env_set_str("h264d_log_outpath", "F:/h264_log/allegro_dat" ); - mpp_env_set_str("h264d_log_cmppath", "F:/h264_log_driver/trunk_dat" ); + mpp_env_set_u32("h264d_log_help", 1); + mpp_env_set_u32("h264d_log_show", 1); + mpp_env_set_u32("h264d_log_ctrl", 0x800B); + mpp_env_set_u32("h264d_log_level", 5); + mpp_env_set_u32("h264d_log_decframe", 0); + mpp_env_set_u32("h264d_log_begframe", 0); + mpp_env_set_u32("h264d_log_endframe", 0); + mpp_env_set_u32("h264d_log_yuv", 0); + mpp_env_set_u32("h264d_chg_org", 0); //!< 0:VDPU 1: RKVDEC + mpp_env_set_str("h264d_log_outpath", "F:/h264_log/allegro_dat"); + mpp_env_set_str("h264d_log_cmppath", "F:/h264_log_driver/trunk_dat"); #endif return MPP_OK; } -static MPP_RET decoder_deinit(MppDec *pApi) + +static MPP_RET decoder_deinit(H264dTestCtx_t *pctx) { + MppDec *pApi = &pctx->m_api; + if (pApi->parser) { parser_deinit(pApi->parser); pApi->parser = NULL; @@ -75,17 +108,50 @@ static MPP_RET decoder_deinit(MppDec *pApi) mpp_buf_slot_deinit(pApi->packet_slots); pApi->packet_slots = NULL; } - + if (pctx->m_dec_pkt_buf) { + mpp_buffer_put(pctx->m_dec_pkt_buf); + } + if (pctx->m_dec_pic_buf) { + mpp_buffer_put(pctx->m_dec_pic_buf); + } + if (pctx->mFrameGroup != NULL) { + mpp_err("mFrameGroup deInit"); + mpp_buffer_group_put(pctx->mFrameGroup); + } + if (pctx->mStreamGroup != NULL) { + mpp_err("mStreamGroup deInit"); + mpp_buffer_group_put(pctx->mStreamGroup); + } return MPP_OK; } -static MPP_RET decoder_init(MppDec *pApi) +static MPP_RET decoder_init(H264dTestCtx_t *pctx) { - RK_U32 hal_device_id = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - ParserCfg parser_cfg; - MppHalCfg hal_cfg; + MPP_RET ret = MPP_ERR_UNKNOW; + ParserCfg parser_cfg; + MppHalCfg hal_cfg; + MppDec *pApi = &pctx->m_api; + + manual_set_env(); // set env, in windows + + mpp_env_get_u32("rkv_h264d_test_debug", &rkv_h264d_test_debug, 0); + + if (pctx->mFrameGroup == NULL) { + ret = mpp_buffer_group_get_internal(&pctx->mFrameGroup, MPP_BUFFER_TYPE_ION); + if (MPP_OK != ret) { + mpp_err("h264d mpp_buffer_group_get failed\n"); + goto __FAILED; + } + } + if (pctx->mStreamGroup == NULL) { + ret = mpp_buffer_group_get_internal(&pctx->mStreamGroup, MPP_BUFFER_TYPE_ION); + if (MPP_OK != ret) { + mpp_err("h264d mpp_buffer_group_get failed\n"); + goto __FAILED; + } + } + // codec pApi->coding = MPP_VIDEO_CodingAVC; // malloc slot FUN_CHECK(ret = mpp_buf_slot_init(&pApi->frame_slots)); @@ -96,21 +162,24 @@ static MPP_RET decoder_init(MppDec *pApi) // init parser part memset(&parser_cfg, 0, sizeof(parser_cfg)); parser_cfg.coding = pApi->coding; - parser_cfg.frame_slots = pApi->frame_slots; + parser_cfg.frame_slots = pApi->frame_slots; parser_cfg.packet_slots = pApi->packet_slots; - parser_cfg.task_count = 2; + parser_cfg.task_count = 2; FUN_CHECK(ret = parser_init(&pApi->parser, &parser_cfg)); // init hal part memset(&hal_cfg, 0, sizeof(hal_cfg)); hal_cfg.type = MPP_CTX_DEC; hal_cfg.coding = pApi->coding; hal_cfg.work_mode = HAL_MODE_LIBVPU; - mpp_env_get_u32("h264d_chg_org", &hal_device_id, 0); - //if (hal_device_id == 1) { - hal_cfg.device_id = HAL_RKVDEC; - //} else { - // hal_cfg.device_id = HAL_VDPU; - //} + { + RK_U32 hal_device_id = 0; + mpp_env_get_u32("h264d_chg_org", &hal_device_id, 1); + if (hal_device_id == 1) { + hal_cfg.device_id = HAL_RKVDEC; + } else { + hal_cfg.device_id = HAL_VDPU; + } + } hal_cfg.frame_slots = pApi->frame_slots; hal_cfg.packet_slots = pApi->packet_slots; hal_cfg.task_count = parser_cfg.task_count; @@ -118,73 +187,54 @@ static MPP_RET decoder_init(MppDec *pApi) pApi->tasks = hal_cfg.tasks; return MPP_OK; + __FAILED: - decoder_deinit(pApi); + decoder_deinit(pctx); return ret; } - - -int main(int argc, char **argv) +static MPP_RET flush_decoded_frames(MppDec *pApi, FILE *fp) { - RK_U32 i = 0; - RK_U32 end_of_flag = 0; - RK_S32 frame_slot_idx = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - MppPacket pkt = NULL; + RK_S32 slot_idx = 0; MppFrame out_frame = NULL; - RK_U32 out_yuv_flag = 0; - MppBuffer dec_pkt_buf = NULL; - MppBuffer dec_pic_buf = NULL; - MppBufferGroup mFrameGroup = NULL; - MppBufferGroup mStreamGroup = NULL; - InputParams *pIn = mpp_calloc(InputParams, 1); - MppDec *pApi = mpp_calloc(MppDec, 1); - HalTaskInfo *task = mpp_calloc_size(HalTaskInfo, sizeof(HalTaskInfo)); - - if (mFrameGroup == NULL) { - ret = mpp_buffer_group_get_internal(&mFrameGroup, MPP_BUFFER_TYPE_ION); - if (MPP_OK != ret) { - mpp_err("h264d mpp_buffer_group_get failed\n"); - return ret; + while (MPP_OK == mpp_buf_slot_dequeue(pApi->frame_slots, &slot_idx, QUEUE_DISPLAY)) { + mpp_buf_slot_get_prop(pApi->frame_slots, slot_idx, SLOT_FRAME, &out_frame); + if (out_frame) { + RK_U32 stride_w, stride_h; + void *ptr = NULL; + MppBuffer framebuf; + stride_w = mpp_frame_get_hor_stride(out_frame); + stride_h = mpp_frame_get_ver_stride(out_frame); + framebuf = mpp_frame_get_buffer(out_frame); + ptr = mpp_buffer_get_ptr(framebuf); + if ((rkv_h264d_test_debug & H264D_TEST_DUMPYUV) && fp) { + fwrite(ptr, 1, stride_w * stride_h * 3 / 2, fp); + fflush(fp); + } + mpp_frame_deinit(&out_frame); + out_frame = NULL; } + mpp_buf_slot_clr_flag(pApi->frame_slots, slot_idx, SLOT_QUEUE_USE); } - if (mStreamGroup == NULL) { - ret = mpp_buffer_group_get_internal(&mStreamGroup, MPP_BUFFER_TYPE_ION); - if (MPP_OK != ret) { - mpp_err("h264d mpp_buffer_group_get failed\n"); - return ret; - } - } + return MPP_OK; +} - //if (g_debug_file0 == NULL) { - // g_debug_file0 = fopen("rk_debugfile_view0.txt", "wb"); - //} - //if (g_debug_file1 == NULL) { - // g_debug_file1 = fopen("rk_debugfile_view1.txt", "wb"); - //} - - MEM_CHECK(ret, pIn && pApi && task); - mpp_log("== test start == \n"); - // set debug mode - FUN_CHECK(ret = manual_set_env()); - // input paramters configure - FUN_CHECK(ret = h264d_configure(pIn, argc, argv)); - // open files - FUN_CHECK(ret = h264d_open_files(pIn)); - FUN_CHECK(ret = h264d_alloc_frame_buffer(pIn)); - - //!< init decoder - FUN_CHECK(ret = decoder_init(pApi)); +static MPP_RET decoder_single_test(H264dTestCtx_t *pctx) +{ + MppPacket pkt = NULL; + RK_U32 end_of_flag = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + MppDec *pApi = &pctx->m_api; + InputParams *pIn = &pctx->m_in; + HalTaskInfo *task = &pctx->m_task; //!< initial task memset(task, 0, sizeof(HalTaskInfo)); memset(task->dec.refer, -1, sizeof(task->dec.refer)); task->dec.input = -1; - do { //!< get one packet if (pkt == NULL) { @@ -192,17 +242,16 @@ int main(int argc, char **argv) (pIn->iDecFrmNum && (pIn->iFrmdecoded >= pIn->iDecFrmNum))) { mpp_packet_init(&pkt, NULL, 0); mpp_packet_set_eos(pkt); - //FPRINT(g_debug_file0, "[READ_PKT]pIn->iFrmdecoded=%d, strm_pkt_len=%d, is_eof=%d \n", pIn->iFrmdecoded, 0, 1); } else { FUN_CHECK(ret = h264d_read_one_frame(pIn)); mpp_packet_init(&pkt, pIn->strm.pbuf, pIn->strm.strmbytes); - //FPRINT(g_debug_file0, "[READ_PKT]pIn->iFrmdecoded=%d, strm_pkt_len=%d, is_eof=%d \n", - //pIn->iFrmdecoded, pIn->strm.strmbytes, 0); } - mpp_log("---- decoder, read_one_frame Frame_no = %d \n", pIn->iFrmdecoded++); + H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] ---- decoder, read_one_frame Frame_no = %d", pIn->iFrmdecoded); + pIn->iFrmdecoded++; } //!< prepare FUN_CHECK(ret = parser_prepare(pApi->parser, pkt, &task->dec)); + //!< parse if (task->dec.valid) { MppBufferImpl *buf = NULL; @@ -211,15 +260,14 @@ int main(int argc, char **argv) if (task->dec.input < 0) { mpp_buf_slot_get_unused(pApi->packet_slots, &task->dec.input); } - - mpp_buf_slot_get_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, &dec_pkt_buf); - if (NULL == dec_pkt_buf) { + mpp_buf_slot_get_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, &pctx->m_dec_pkt_buf); + if (NULL == pctx->m_dec_pkt_buf) { size_t stream_size = mpp_packet_get_size(task->dec.input_packet); - mpp_buffer_get(mStreamGroup, &dec_pkt_buf, stream_size); - if (dec_pkt_buf) - mpp_buf_slot_set_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, dec_pkt_buf); + mpp_buffer_get(pctx->mStreamGroup, &pctx->m_dec_pkt_buf, stream_size); + if (pctx->m_dec_pkt_buf) + mpp_buf_slot_set_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, pctx->m_dec_pkt_buf); } - buf = (MppBufferImpl *)dec_pkt_buf; + buf = (MppBufferImpl *)pctx->m_dec_pkt_buf; memcpy(buf->info.ptr, mpp_packet_get_data(task->dec.input_packet), mpp_packet_get_length(task->dec.input_packet)); mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_CODEC_READY); @@ -230,56 +278,113 @@ int main(int argc, char **argv) if (mpp_packet_get_length(pkt) == 0) { if (mpp_packet_get_eos(pkt)) { end_of_flag = 1; //!< end of stream + task->dec.valid = 0; + mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); + mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); } mpp_packet_deinit(&pkt); pkt = NULL; } //!< run hal module if (task->dec.valid) { - mpp_buf_slot_get_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, &dec_pic_buf); - if (NULL == dec_pic_buf) { + if (mpp_buf_slot_is_changed(pApi->frame_slots)) { + mpp_buf_slot_ready(pApi->frame_slots); + } + mpp_buf_slot_get_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, &pctx->m_dec_pic_buf); + if (NULL == pctx->m_dec_pic_buf) { RK_U32 size = (RK_U32)mpp_buf_slot_get_size(pApi->frame_slots); - // mpp_err("run hal module, size = %d", size); - mpp_buffer_get(mFrameGroup, &dec_pic_buf, size); - if (dec_pic_buf) - mpp_buf_slot_set_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, dec_pic_buf); + mpp_buffer_get(pctx->mFrameGroup, &pctx->m_dec_pic_buf, size); + if (pctx->m_dec_pic_buf) + mpp_buf_slot_set_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, pctx->m_dec_pic_buf); } FUN_CHECK(ret = mpp_hal_reg_gen(pApi->hal, task)); + FUN_CHECK(ret = mpp_hal_hw_start(pApi->hal, task)); FUN_CHECK(ret = mpp_hal_hw_wait(pApi->hal, task)); - if (dec_pkt_buf) { - mpp_buffer_put(dec_pkt_buf); + if (pctx->m_dec_pkt_buf) { + mpp_buffer_put(pctx->m_dec_pkt_buf); } mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); - //!< write frame out - mpp_env_get_u32("h264d_log_yuv", &out_yuv_flag, 0); - //mpp_log("h264d_log_yuv=%d", out_yuv_flag); - while (MPP_OK == mpp_buf_slot_dequeue(pApi->frame_slots, &frame_slot_idx, QUEUE_DISPLAY)) { - mpp_buf_slot_get_prop(pApi->frame_slots, frame_slot_idx, SLOT_FRAME, &out_frame); - //mpp_log("write picture out, slot_idx=%d, yuv_fp_is_null=%d", frame_slot_idx, (pIn->fp_yuv_data == NULL)); - if (out_frame) { - RK_U32 stride_w, stride_h; - void *ptr = NULL; - MppBuffer framebuf; - stride_w = mpp_frame_get_hor_stride(out_frame); - stride_h = mpp_frame_get_ver_stride(out_frame); - framebuf = mpp_frame_get_buffer(out_frame); - ptr = mpp_buffer_get_ptr(framebuf); - if (out_yuv_flag && pIn->fp_yuv_data) { - fwrite(ptr, 1, stride_w * stride_h * 3 / 2, pIn->fp_yuv_data); - fflush(pIn->fp_yuv_data); - } - mpp_frame_deinit(&out_frame); - out_frame = NULL; - } - mpp_buf_slot_clr_flag(pApi->frame_slots, frame_slot_idx, SLOT_QUEUE_USE); - } + flush_decoded_frames(pApi, pIn->fp_yuv_data); //!< clear refrece flag - for (i = 0; i < MPP_ARRAY_ELEMS(task->dec.refer); i++) { - if (task->dec.refer[i] >= 0) { - mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.refer[i], SLOT_HAL_INPUT); + { + RK_U32 i = 0; + for (i = 0; i < MPP_ARRAY_ELEMS(task->dec.refer); i++) { + if (task->dec.refer[i] >= 0) { + mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.refer[i], SLOT_HAL_INPUT); + } + } + } + //!< reset task + memset(task, 0, sizeof(HalTaskInfo)); + memset(task->dec.refer, -1, sizeof(task->dec.refer)); + task->dec.input = -1; + + } + } while (!end_of_flag); + //!< flush dpb and send to display + FUN_CHECK(ret = mpp_dec_flush(pApi)); + flush_decoded_frames(pApi, pIn->fp_yuv_data); + + ret = MPP_OK; +__FAILED: + return ret; +} + +static void *hal_thread_run(void *in_ctx) +{ + H264dTestCtx_t *pctx = (H264dTestCtx_t *)in_ctx; + + MppDec *pApi = &pctx->m_api; + InputParams *pIn = &pctx->m_in; + HalTaskInfo *task = &pctx->m_task; + HalThreadPar_t *p_hal = &pctx->m_hal; + HalStatus hal_status = p_hal->hal_status; + + do { + //!< wait + { + pthread_mutex_lock(&p_hal->halLock); + H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] pthread_cond_wait(par_Cond)."); + pthread_cond_wait(&p_hal->parCond, &p_hal->halLock); + pthread_mutex_unlock(&p_hal->halLock); + } + //!< break + { + pthread_mutex_lock(&p_hal->halLock); + hal_status = p_hal->hal_status; + pthread_mutex_unlock(&p_hal->halLock); + } + H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] hal_status=%d.", hal_status); + if (hal_status == HAL_THREAD_STOPPING) { + H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] 2222222222."); + break; + } + //!< signal + { + pthread_mutex_lock(&p_hal->halLock); + mpp_hal_hw_wait(pctx->m_api.hal, &pctx->m_task); + //pthread_cond_signal(&p_hal->halCond); + H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] pthread_cond_signal(hal_Cond)."); + pthread_mutex_unlock(&p_hal->halLock); + } + { + if (pctx->m_dec_pkt_buf) { + mpp_buffer_put(pctx->m_dec_pkt_buf); + } + mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); + mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); + //!< write frame out + flush_decoded_frames(pApi, pIn->fp_yuv_data); + //!< clear refrece flag + { + RK_U32 i = 0; + for (i = 0; i < MPP_ARRAY_ELEMS(task->dec.refer); i++) { + if (task->dec.refer[i] >= 0) { + mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.refer[i], SLOT_HAL_INPUT); + } } } //!< reset task @@ -287,45 +392,227 @@ int main(int argc, char **argv) memset(task->dec.refer, -1, sizeof(task->dec.refer)); task->dec.input = -1; } - } while (!end_of_flag); + pthread_cond_signal(&p_hal->halCond); - //FPRINT(g_debug_file1, "[FLUSH] flush begin \n"); + } while (hal_status != HAL_THREAD_STOPPING); + H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] 4444444444444444"); + + return NULL; +} + +static MPP_RET decoder_muti_deinit(H264dTestCtx_t *pctx) +{ + void *ptr = NULL; + HalThreadPar_t *p_hal = &pctx->m_hal; + + H264D_TEST_LOG(H264D_TEST_TRACE, "decoder_deinit In."); + pthread_join(p_hal->halThread, &ptr); + H264D_TEST_LOG(H264D_TEST_TRACE, "halThread(%p)destroy success", &p_hal->halThread); + + pthread_cond_destroy(&p_hal->parCond); + pthread_cond_destroy(&p_hal->halCond); + pthread_mutex_destroy(&p_hal->parLock); + pthread_mutex_destroy(&p_hal->halLock); + H264D_TEST_LOG(H264D_TEST_TRACE, "3333333333333"); + H264D_TEST_LOG(H264D_TEST_TRACE, "decoder_deinit Ok."); + + return MPP_OK; +} + +static MPP_RET decoder_muti_init(H264dTestCtx_t *pctx) +{ + HalThreadPar_t *p_hal = &pctx->m_hal; + + p_hal->hal_status = HAL_THREAD_RUNNING; + //!< create lock and condition + { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&p_hal->parLock, &attr); + pthread_mutex_init(&p_hal->halLock, &attr); + pthread_mutexattr_destroy(&attr); + + pthread_cond_init(&p_hal->parCond, NULL); + pthread_cond_init(&p_hal->halCond, NULL); + H264D_TEST_LOG(H264D_TEST_TRACE, "mutex and condition create success."); + pthread_mutex_lock(&p_hal->halLock); + pthread_cond_signal(&p_hal->halCond); + H264D_TEST_LOG(H264D_TEST_TRACE, "pthread_cond_signal(hal_Cond)."); + pthread_mutex_unlock(&p_hal->halLock); + + } + //!< create hal thread + { + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + if (0 == pthread_create(&p_hal->halThread, &attr, hal_thread_run, pctx)) { + H264D_TEST_LOG(H264D_TEST_TRACE, "hal_thread(%p) create success.", &p_hal->halThread); + } + pthread_attr_destroy(&attr); + } + return MPP_OK; +} + +static MPP_RET decoder_muti_test(H264dTestCtx_t *pctx) +{ + MppPacket pkt = NULL; + RK_U32 end_of_flag = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + + MppDec *pApi = &pctx->m_api; + InputParams *pIn = &pctx->m_in; + HalTaskInfo *task = &pctx->m_task; + //!< init decoder + FUN_CHECK(ret = decoder_muti_init(pctx)); + //!< initial task + memset(task, 0, sizeof(HalTaskInfo)); + memset(task->dec.refer, -1, sizeof(task->dec.refer)); + task->dec.input = -1; + do { + //!< get one packet + if (pkt == NULL) { + if (pIn->is_eof || + (pIn->iDecFrmNum && (pIn->iFrmdecoded >= pIn->iDecFrmNum))) { + mpp_packet_init(&pkt, NULL, 0); + mpp_packet_set_eos(pkt); + } else { + FUN_CHECK(ret = h264d_read_one_frame(pIn)); + mpp_packet_init(&pkt, pIn->strm.pbuf, pIn->strm.strmbytes); + } + H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] ---- decoder, read_one_frame Frame_no = %d", pIn->iFrmdecoded); + pIn->iFrmdecoded++; + } + //!< prepare + FUN_CHECK(ret = parser_prepare(pApi->parser, pkt, &task->dec)); + { + HalThreadPar_t *p_hal = &pctx->m_hal; + pthread_mutex_lock(&p_hal->parLock); + H264D_TEST_LOG(H264D_TEST_TRACE, "pthread_cond_wait(hal Cond)."); + pthread_cond_wait(&p_hal->halCond, &p_hal->parLock); + pthread_mutex_unlock(&p_hal->parLock); + } + //!< parse + if (task->dec.valid) { + MppBufferImpl *buf = NULL; + + task->dec.valid = 0; + if (task->dec.input < 0) { + mpp_buf_slot_get_unused(pApi->packet_slots, &task->dec.input); + } + + mpp_buf_slot_get_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, &pctx->m_dec_pkt_buf); + if (NULL == pctx->m_dec_pkt_buf) { + size_t stream_size = mpp_packet_get_size(task->dec.input_packet); + mpp_buffer_get(pctx->mStreamGroup, &pctx->m_dec_pkt_buf, stream_size); + if (pctx->m_dec_pkt_buf) + mpp_buf_slot_set_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, pctx->m_dec_pkt_buf); + } + buf = (MppBufferImpl *)pctx->m_dec_pkt_buf; + memcpy(buf->info.ptr, mpp_packet_get_data(task->dec.input_packet), mpp_packet_get_length(task->dec.input_packet)); + + mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_CODEC_READY); + mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); + FUN_CHECK(ret = parser_parse(pApi->parser, &task->dec)); + } + //!< deinit packet + if (mpp_packet_get_length(pkt) == 0) { + if (mpp_packet_get_eos(pkt)) { + end_of_flag = 1; //!< end of stream + task->dec.valid = 0; + { + HalThreadPar_t *p_hal = &pctx->m_hal; + pthread_mutex_lock(&p_hal->parLock); + p_hal->hal_status = HAL_THREAD_STOPPING; + pthread_cond_signal(&p_hal->parCond); + H264D_TEST_LOG(H264D_TEST_TRACE, "1111111111111111"); + pthread_mutex_unlock(&p_hal->parLock); + } + + mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); + mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); + } + mpp_packet_deinit(&pkt); + pkt = NULL; + } + //!< run hal module + if (task->dec.valid) { + if (mpp_buf_slot_is_changed(pApi->frame_slots)) { + mpp_buf_slot_ready(pApi->frame_slots); + } + mpp_buf_slot_get_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, &pctx->m_dec_pic_buf); + if (NULL == pctx->m_dec_pic_buf) { + RK_U32 size = (RK_U32)mpp_buf_slot_get_size(pApi->frame_slots); + mpp_buffer_get(pctx->mFrameGroup, &pctx->m_dec_pic_buf, size); + if (pctx->m_dec_pic_buf) + mpp_buf_slot_set_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, pctx->m_dec_pic_buf); + } + FUN_CHECK(ret = mpp_hal_reg_gen(pApi->hal, task)); + + FUN_CHECK(ret = mpp_hal_hw_start(pApi->hal, task)); + { + HalThreadPar_t *p_hal = &pctx->m_hal; + + pthread_mutex_lock(&p_hal->parLock); + pthread_cond_signal(&p_hal->parCond); + H264D_TEST_LOG(H264D_TEST_TRACE, "pthread_cond_single(par Cond)."); + pthread_mutex_unlock(&p_hal->parLock); + } + } + } while (!end_of_flag); //!< flush dpb and send to display FUN_CHECK(ret = mpp_dec_flush(pApi)); - while (MPP_OK == mpp_buf_slot_dequeue(pApi->frame_slots, &frame_slot_idx, QUEUE_DISPLAY)) { - //mpp_log("get_display for index = %d", frame_slot_idx); - mpp_buf_slot_get_prop(pApi->frame_slots, frame_slot_idx, SLOT_FRAME, &out_frame); - if (out_frame) { - mpp_frame_deinit(&out_frame); - } - mpp_buf_slot_clr_flag(pApi->frame_slots, frame_slot_idx, SLOT_QUEUE_USE); - } + flush_decoded_frames(pApi, pIn->fp_yuv_data); - //FPRINT(g_debug_file1, "+++++++ all test return +++++++ \n"); ret = MPP_OK; __FAILED: - decoder_deinit(pApi); - h264d_free_frame_buffer(pIn); - //h264d_write_fpga_data(pIn); //!< for fpga debug - h264d_close_files(pIn); - MPP_FREE(pIn); - MPP_FREE(pApi); - MPP_FREE(task); - - if (dec_pkt_buf) { - mpp_buffer_put(dec_pkt_buf); - } - if (dec_pic_buf) { - mpp_buffer_put(dec_pic_buf); - } - if (mFrameGroup != NULL) { - mpp_err("mFrameGroup deInit"); - mpp_buffer_group_put(mFrameGroup); - } - if (mStreamGroup != NULL) { - mpp_err("mStreamGroup deInit"); - mpp_buffer_group_put(mStreamGroup); - } + decoder_muti_deinit(pctx); + + return ret; +} + + +int main(int argc, char **argv) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + InputParams *pInput = NULL; + H264dTestCtx_t *pctx = NULL; + + MEM_CHECK(ret, pctx = mpp_calloc(H264dTestCtx_t, 1)); + // prepare + pInput = &pctx->m_in; + FUN_CHECK(ret = h264d_configure(pInput, argc, argv)); + FUN_CHECK(ret = h264d_open_files(pInput)); + FUN_CHECK(ret = h264d_alloc_frame_buffer(pInput)); + // init + decoder_init(pctx); + // decode + if (rkv_h264d_test_debug & H264D_TEST_MUTI_THREAD) { + ret = decoder_muti_test(pctx); + if (ret != MPP_OK) { + H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] Muti-thread test error."); + goto __FAILED; + } + } else { + ret = decoder_single_test(pctx); + if (ret != MPP_OK) { + H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] Single-thread test error."); + goto __FAILED; + } + } + ret = MPP_OK; + +__FAILED: + decoder_deinit(pctx); + h264d_free_frame_buffer(pInput); + if ((ret == MPP_OK) + && (H264D_TEST_FPGA & rkv_h264d_test_debug)) { + h264d_write_fpga_data(pInput); //!< for fpga debug + } + h264d_close_files(pInput); + MPP_FREE(pctx); + H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] decoder_deinit over."); return ret; }