diff --git a/inc/vpu_api.h b/inc/vpu_api.h index fa0d4669..033fd385 100644 --- a/inc/vpu_api.h +++ b/inc/vpu_api.h @@ -311,19 +311,21 @@ RK_S32 vpu_close_context(struct VpuCodecContext **ctx); /* * vpu_mem api */ +#define vpu_display_mem_pool_FIELDS \ + RK_S32 (*commit_hdl)(vpu_display_mem_pool *p, RK_S32 hdl, RK_S32 size); \ + void* (*get_free)(vpu_display_mem_pool *p); \ + RK_S32 (*inc_used)(vpu_display_mem_pool *p, void *hdl); \ + RK_S32 (*put_used)(vpu_display_mem_pool *p, void *hdl); \ + RK_S32 (*reset)(vpu_display_mem_pool *p); \ + RK_S32 (*get_unused_num)(vpu_display_mem_pool *p); \ + RK_S32 buff_size;\ + float version; \ + RK_S32 res[18]; typedef struct vpu_display_mem_pool vpu_display_mem_pool; struct vpu_display_mem_pool { - int (*commit_hdl)(vpu_display_mem_pool *p, int hdl, int size); - void* (*get_free)(vpu_display_mem_pool *p); - int (*inc_used)(vpu_display_mem_pool *p, int hdl); - int (*put_used)(vpu_display_mem_pool *p, int hdl); - int (*reset)(vpu_display_mem_pool *p); - int (*get_unused_num)(vpu_display_mem_pool *p); - int buff_size; - float version; - int res[18]; + vpu_display_mem_pool_FIELDS }; #ifdef __cplusplus @@ -334,6 +336,7 @@ extern "C" /* * vpu memory handle interface */ +RK_S32 VPUMemJudgeIommu(); RK_S32 VPUMallocLinear(VPUMemLinear_t *p, RK_U32 size); RK_S32 VPUFreeLinear(VPUMemLinear_t *p); RK_S32 VPUMemDuplicate(VPUMemLinear_t *dst, VPUMemLinear_t *src); @@ -341,6 +344,9 @@ RK_S32 VPUMemLink(VPUMemLinear_t *p); RK_S32 VPUMemFlush(VPUMemLinear_t *p); RK_S32 VPUMemClean(VPUMemLinear_t *p); RK_S32 VPUMemInvalidate(VPUMemLinear_t *p); +RK_S32 VPUMemGetFD(VPUMemLinear_t *p); +RK_S32 vpu_mem_judge_used_heaps_type(); + /* * vpu memory allocator and manager interface diff --git a/mpp/CMakeLists.txt b/mpp/CMakeLists.txt index ee3a583a..095640ca 100644 --- a/mpp/CMakeLists.txt +++ b/mpp/CMakeLists.txt @@ -34,7 +34,7 @@ set_target_properties(mpp PROPERTIES FOLDER "mpp") add_subdirectory(legacy) -target_link_libraries(mpp mpp_codec mpp_hal mpp_legacy osal) +target_link_libraries(mpp mpp_codec mpp_hal osal) add_subdirectory(test) diff --git a/mpp/codec/dec/dummy/dummy_dec_api.c b/mpp/codec/dec/dummy/dummy_dec_api.c index bc0ac569..0a5eed37 100644 --- a/mpp/codec/dec/dummy/dummy_dec_api.c +++ b/mpp/codec/dec/dummy/dummy_dec_api.c @@ -19,6 +19,8 @@ #include #include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_packet.h" #include "dummy_dec_api.h" @@ -30,6 +32,9 @@ typedef struct DummyDec_t { MppBufSlots frame_slots; MppBufSlots packet_slots; RK_U32 task_count; + void *stream; + size_t stream_size; + MppPacket task_pkt; RK_U32 slots_inited; RK_U32 frame_count; @@ -41,17 +46,34 @@ MPP_RET dummy_dec_init(void *dec, ParserCfg *cfg) { DummyDec *p; RK_S32 i; + void *stream; + size_t stream_size = SZ_512K; + MppPacket task_pkt; + if (NULL == dec) { mpp_err_f("found NULL intput dec %p cfg %p\n", dec, cfg); return MPP_ERR_NULL_PTR; } + stream = mpp_malloc_size(void, stream_size); + if (NULL == stream) { + mpp_err_f("failed to malloc stream buffer size %d\n", stream_size); + return MPP_ERR_MALLOC; + } + + mpp_packet_init(&task_pkt, stream, stream_size); + if (NULL == task_pkt) { + mpp_err_f("failed to create mpp_packet for task\n"); + return MPP_ERR_UNKNOW; + } + p = (DummyDec *)dec; p->frame_slots = cfg->frame_slots; p->packet_slots = cfg->packet_slots; p->task_count = cfg->task_count = 2; - p->slots_inited = 0; - p->frame_count = 0; + p->stream = stream; + p->stream_size = stream_size; + p->task_pkt = task_pkt; for (i = 0; i < DUMMY_DEC_REF_COUNT; i++) { p->slot_index[i] = -1; } @@ -60,10 +82,17 @@ MPP_RET dummy_dec_init(void *dec, ParserCfg *cfg) MPP_RET dummy_dec_deinit(void *dec) { + DummyDec *p; if (NULL == dec) { mpp_err_f("found NULL intput\n"); return MPP_ERR_NULL_PTR; } + + p = (DummyDec *)dec; + if (p->task_pkt) + mpp_packet_deinit(&p->task_pkt); + if (p->stream) + mpp_free(p->stream); return MPP_OK; } @@ -106,7 +135,8 @@ MPP_RET dummy_dec_prepare(void *dec, MppPacket pkt, HalDecTask *task) RK_U32 frame_count; MppBufSlots slots; RK_S32 i; - char *data; + RK_U8 *data; + size_t length; if (NULL == dec) { mpp_err_f("found NULL intput\n"); @@ -120,8 +150,19 @@ MPP_RET dummy_dec_prepare(void *dec, MppPacket pkt, HalDecTask *task) frame_count = p->frame_count; // set pos to indicate that buffer is done - data = mpp_packet_get_data(pkt); - mpp_packet_set_pos(pkt, data + mpp_packet_get_size(pkt)); + data = mpp_packet_get_data(pkt); + length = mpp_packet_get_length(pkt); + if (length > p->stream_size) { + mpp_realloc(p->stream, RK_U8, length); + } + if (p->stream) { + memcpy(p->stream, data, length); + task->input_packet = p->task_pkt; + } else { + mpp_err("failed to found task buffer for hardware\n"); + return MPP_ERR_UNKNOW; + } + mpp_packet_set_pos(pkt, data + length); /* * set slots information diff --git a/mpp/codec/dec/h265/h265d_codec.h b/mpp/codec/dec/h265/h265d_codec.h index 5a982c7e..dd36fb4e 100644 --- a/mpp/codec/dec/h265/h265d_codec.h +++ b/mpp/codec/dec/h265/h265d_codec.h @@ -66,6 +66,7 @@ enum MppPictureStructure { }; #define END_NOT_FOUND (-100) +#define MPP_PARSER_PTS_NB 4 typedef struct SplitContext { RK_U8 *buffer; @@ -77,6 +78,31 @@ typedef struct SplitContext { RK_S32 overread; ///< the number of bytes which where irreversibly read from the next frame RK_S32 overread_index; ///< the index into ParseContext.buffer of the overread bytes RK_U64 state64; ///< contains the last 8 bytes in MSB order + RK_S64 pts; /* pts of the current frame */ + RK_S64 dts; /* dts of the current frame */ + RK_S64 frame_offset; /* offset of the current frame */ + RK_S64 cur_offset; /* current offset + (incremented by each av_parser_parse()) */ + RK_S64 next_frame_offset; /* offset of the next frame */ + /* private data */ + RK_S64 last_pts; + RK_S64 last_dts; + RK_S32 fetch_timestamp; + + RK_S32 cur_frame_start_index; + RK_S64 cur_frame_offset[MPP_PARSER_PTS_NB]; + RK_S64 cur_frame_pts[MPP_PARSER_PTS_NB]; + RK_S64 cur_frame_dts[MPP_PARSER_PTS_NB]; + + RK_S64 offset; ///< byte offset from starting packet start + RK_S64 cur_frame_end[MPP_PARSER_PTS_NB]; + /** + * Set by parser to 1 for key frames and 0 for non-key frames. + * It is initialized to -1, so if the parser doesn't set this flag, + * old-style fallback using AV_PICTURE_TYPE_I picture type as key frames + * will be used. + */ + RK_S32 key_frame; RK_S32 eos; } SplitContext_t; @@ -144,7 +170,7 @@ extern "C" { RK_S32 h265d_parser2_syntax(void *ctx); -RK_S32 h265d_syntax_fill_slice(void *ctx, MppBuffer *streambuf); +RK_S32 h265d_syntax_fill_slice(void *ctx, RK_S32 input_index); #ifdef __cplusplus diff --git a/mpp/codec/dec/h265/h265d_parser.c b/mpp/codec/dec/h265/h265d_parser.c index 904f69ed..0fead366 100644 --- a/mpp/codec/dec/h265/h265d_parser.c +++ b/mpp/codec/dec/h265/h265d_parser.c @@ -32,6 +32,7 @@ #include "mpp_mem.h" #include "mpp_env.h" #include "h265d_syntax.h" +#include "mpp_packet_impl.h" #define START_CODE 0x000001 ///< start_code_prefix_one_3bytes @@ -179,33 +180,91 @@ RK_S32 h265d_split_init(void **sc) return MPP_ERR_NOMEM; } } + s->fetch_timestamp = 1; return MPP_OK; } +void mpp_fetch_timestamp(SplitContext_t *s, RK_S32 off, RK_S32 remove) +{ + RK_S32 i; + + s->dts = s->pts = -1; + s->offset = 0; + for (i = 0; i < MPP_PARSER_PTS_NB; i++) { + if ( s->cur_offset + off >= s->cur_frame_offset[i] + && (s->frame_offset < s->cur_frame_offset[i] || + (!s->frame_offset && !s->next_frame_offset)) // first field/frame + // check disabled since MPEG-TS does not send complete PES packets + && /*s->next_frame_offset + off <*/ s->cur_frame_end[i]) { + s->dts = s->cur_frame_dts[i]; + s->pts = s->cur_frame_pts[i]; + s->offset = s->next_frame_offset - s->cur_frame_offset[i]; + /* if (remove) + s->cur_frame_offset[i] = INT64_MAX;*/ + if (s->cur_offset + off < s->cur_frame_end[i]) + break; + } + } +} RK_S32 h265d_split_frame(void *sc, const RK_U8 **poutbuf, RK_S32 *poutbuf_size, - const RK_U8 *buf, RK_S32 buf_size) + const RK_U8 *buf, RK_S32 buf_size, RK_S64 pts, RK_S64 dts) { - RK_S32 next; + RK_S32 next, i; SplitContext_t *s = (SplitContext_t*)sc; + + if (s->cur_offset + buf_size != + s->cur_frame_end[s->cur_frame_start_index]) { /* skip remainder packets */ + /* add a new packet descriptor */ + i = (s->cur_frame_start_index + 1) & (MPP_PARSER_PTS_NB - 1); + s->cur_frame_start_index = i; + s->cur_frame_offset[i] = s->cur_offset; + s->cur_frame_end[i] = s->cur_offset + buf_size; + s->cur_frame_pts[i] = pts; + s->cur_frame_dts[i] = dts; + h265d_dbg(H265D_DBG_TIME, "s->cur_frame_start_index = %d,cur_frame_offset = %lld,s->cur_frame_end = %lld pts = %lld", + s->cur_frame_start_index, s->cur_frame_offset[i], s->cur_frame_end[i], pts); + } + + if (s->fetch_timestamp) { + s->fetch_timestamp = 0; + s->last_pts = s->pts; + s->last_dts = s->dts; + mpp_fetch_timestamp(s, 0, 0); + } + if (s->eos) { *poutbuf = s->buffer; *poutbuf_size = s->index; return 0; } + next = hevc_find_frame_end(s, buf, buf_size); if (mpp_combine_frame(s, next, &buf, &buf_size) < 0) { *poutbuf = NULL; *poutbuf_size = 0; + s->cur_offset += buf_size; return buf_size; } *poutbuf = buf; *poutbuf_size = buf_size; + if (next < 0) next = 0; + + if (*poutbuf_size) { + /* fill the data for the current frame */ + s->frame_offset = s->next_frame_offset; + + /* offset of the next frame */ + s->next_frame_offset = s->cur_offset + next; + s->fetch_timestamp = 1; + } + + s->cur_offset += next; return next; } @@ -415,6 +474,7 @@ static RK_S32 set_sps(HEVCContext *s, const HEVCSPS *sps) s->h265dctx->height = sps->output_height; s->h265dctx->pix_fmt = sps->pix_fmt; s->h265dctx->sample_aspect_ratio = sps->vui.sar; + mpp_buf_slot_setup(s->slots, 22, s->h265dctx->coded_width * s->h265dctx->coded_height * 7 / 4 , 0); if (sps->vui.video_signal_type_present_flag) s->h265dctx->color_range = sps->vui.video_full_range_flag ? MPPCOL_RANGE_JPEG @@ -1279,7 +1339,7 @@ RK_S32 mpp_hevc_extract_rbsp(HEVCContext *s, const RK_U8 *src, int length, si = di = i; while (si + 2 < length) { // remove escapes (very rare 1:2^22) - if (src[si + 2] >= 3) { + if (src[si + 2] > 3) { dst[di++] = src[si++]; dst[di++] = src[si++]; } else if (src[si] == 0 && src[si + 1] == 0) { @@ -1459,47 +1519,6 @@ fail: return ret; } - -MPP_RET h265d_prepare(void *ctx, MppPacket pkt, HalDecTask *task) -{ - - MPP_RET ret = MPP_OK; - H265dContext_t *h265dctx = (H265dContext_t *)ctx; - HEVCContext *s = (HEVCContext *)h265dctx->priv_data; - RK_U8 *buf = NULL; - void *pos = NULL; - RK_S32 length = 0; - s->eos = mpp_packet_get_eos(pkt); - buf = (RK_U8 *)mpp_packet_get_pos(pkt); - length = (RK_S32)mpp_packet_get_size(pkt); - s->pts = mpp_packet_get_pts(pkt); - - if (h265dctx->need_split) { - RK_S32 consume = 0; - RK_U8 *split_out_buf = NULL; - RK_S32 split_size = 0; - consume = h265d_split_frame(h265dctx->split_cxt, (const RK_U8**)&split_out_buf, &split_size, - (const RK_U8*)buf, length); - pos = buf + consume; - mpp_packet_set_pos(pkt, pos); - if (split_size) { - buf = split_out_buf; - length = split_size; - } else { - return MPP_FAIL_SPLIT_FRAME; - } - } - ret = split_nal_units(s, buf, length); - - if (MPP_OK == ret) { - if (MPP_OK == h265d_syntax_fill_slice(s->h265dctx, task->stmbuf)) { - task->valid = 1; - } - } - return ret; - -} - static RK_S32 parser_nal_units(HEVCContext *s) { /* parse the NAL units */ @@ -1515,6 +1534,104 @@ static RK_S32 parser_nal_units(HEVCContext *s) fail: return ret; } +static RK_S32 hevc_parser_extradata(HEVCContext *s) +{ + H265dContext_t *h265dctx = s->h265dctx; + RK_S32 ret = MPP_SUCCESS; + if (h265dctx->extradata_size > 3 && + (h265dctx->extradata[0] || h265dctx->extradata[1] || + h265dctx->extradata[2] > 1)) { + /* It seems the extradata is encoded as hvcC format. + * Temporarily, we support configurationVersion==0 until 14496-15 3rd + * is finalized. When finalized, configurationVersion will be 1 and we + * can recognize hvcC by checking if h265dctx->extradata[0]==1 or not. */ + mpp_err("extradata is encoded as hvcC format"); + s->is_nalff = 1; + } else { + s->is_nalff = 0; + ret = split_nal_units(s, h265dctx->extradata, h265dctx->extradata_size); + if (ret < 0) + return ret; + ret = parser_nal_units(s); + if (ret < 0) + return ret; + } + return ret; +} + +MPP_RET h265d_prepare(void *ctx, MppPacket pkt, HalDecTask *task) +{ + + MPP_RET ret = MPP_OK; + H265dContext_t *h265dctx = (H265dContext_t *)ctx; + HEVCContext *s = h265dctx->priv_data; + SplitContext_t *sc = (SplitContext_t*)h265dctx->split_cxt; + RK_S64 pts = -1, dts = -1; + RK_U8 *buf = NULL; + void *pos = NULL; + RK_S32 length = 0; + s->eos = sc->eos = mpp_packet_get_eos(pkt); + buf = mpp_packet_get_pos(pkt); + pts = mpp_packet_get_pts(pkt); + dts = mpp_packet_get_dts(pkt); + h265d_dbg(H265D_DBG_TIME, "prepare get pts %lld", pts); + length = mpp_packet_get_length(pkt); + + if (mpp_packet_get_flag(pkt)& MPP_PACKET_FLAG_EXTRA_DATA) { + h265dctx->extradata_size = length; + h265dctx->extradata = buf; + hevc_parser_extradata(s); + pos = buf + length; + mpp_packet_set_pos(pkt, pos); + return MPP_OK; + } + if (h265dctx->need_split) { + RK_S32 consume = 0; + RK_U8 *split_out_buf = NULL; + RK_S32 split_size = 0; + + consume = h265d_split_frame(h265dctx->split_cxt, (const RK_U8**)&split_out_buf, &split_size, + (const RK_U8*)buf, length, pts, dts); + pos = buf + consume; + mpp_packet_set_pos(pkt, pos); + if (split_size) { + buf = split_out_buf; + length = split_size; + s->checksum_buf = buf; //check with openhevc + s->checksum_buf_size = split_size; + h265d_dbg(H265D_DBG_TIME, "split frame get pts %lld", sc->pts); + s->pts = sc->pts; + } else { + return MPP_FAIL_SPLIT_FRAME; + } + } + ret = split_nal_units(s, buf, length); + + if (MPP_OK == ret) { + if (MPP_OK == h265d_syntax_fill_slice(s->h265dctx, task->input)) { + task->valid = 1; + } + } + return ret; + +} + +MPP_RET h265d_get_stream(void *ctx, RK_U8 **buf, RK_S32 *size){ + MPP_RET ret = MPP_OK; + H265dContext_t *h265dctx = (H265dContext_t *)ctx; + HEVCContext *s = h265dctx->priv_data; + *buf = s->checksum_buf; + *size = s->checksum_buf_size; + return ret; +} + +MPP_RET h265d_set_compare_info(void *ctx, void *info){ + MPP_RET ret = MPP_OK; + H265dContext_t *h265dctx = (H265dContext_t *)ctx; + h265dctx->compare_info = info; + return ret; +} + MPP_RET h265d_parse(void *ctx, HalDecTask *task) { @@ -1540,6 +1657,9 @@ MPP_RET h265d_parse(void *ctx, HalDecTask *task) s->task->syntax.data = s->hal_pic_private; s->task->syntax.number = 1; s->task->valid = 1; + if (s->eos) { + s->task->eos = 1; + } } #if 0 for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) { @@ -1637,30 +1757,6 @@ fail: return MPP_ERR_NOMEM; } -static RK_S32 hevc_parser_extradata(HEVCContext *s) -{ - H265dContext_t *h265dctx = s->h265dctx; - RK_S32 ret = MPP_SUCCESS; - if (h265dctx->extradata_size > 3 && - (h265dctx->extradata[0] || h265dctx->extradata[1] || - h265dctx->extradata[2] > 1)) { - /* It seems the extradata is encoded as hvcC format. - * Temporarily, we support configurationVersion==0 until 14496-15 3rd - * is finalized. When finalized, configurationVersion will be 1 and we - * can recognize hvcC by checking if h265dctx->extradata[0]==1 or not. */ - mpp_err("extradata is encoded as hvcC format"); - s->is_nalff = 1; - } else { - s->is_nalff = 0; - ret = split_nal_units(s, h265dctx->extradata, h265dctx->extradata_size); - if (ret < 0) - return ret; - ret = parser_nal_units(s); - if (ret < 0) - return ret; - } - return ret; -} MPP_RET h265d_init(void *ctx, ParserCfg *parser_cfg) { @@ -1703,6 +1799,7 @@ MPP_RET h265d_init(void *ctx, ParserCfg *parser_cfg) s->slots = parser_cfg->frame_slots; + s->packet_slots = parser_cfg->packet_slots; if (h265dctx->extradata_size > 0 && h265dctx->extradata) { ret = hevc_parser_extradata(s); @@ -1718,9 +1815,17 @@ MPP_RET h265d_init(void *ctx, ParserCfg *parser_cfg) MPP_RET h265d_flush(void *ctx) { RK_S32 ret = 0; + RK_S32 eos = 1; + H265dContext_t *h265dctx = (H265dContext_t *)ctx; + HEVCContext *s = (HEVCContext *)h265dctx->priv_data; + HEVCFrame *frame = NULL; + MppBuffer framebuf = NULL; do { ret = mpp_hevc_output_frame(ctx, 1); } while (ret); + frame = &s->DPB[s->output_frame_idx]; + + mpp_buf_slot_set_prop(s->slots, frame->slot_index, SLOT_EOS, &eos); return MPP_OK; } diff --git a/mpp/codec/dec/h265/h265d_parser.h b/mpp/codec/dec/h265/h265d_parser.h index 8c5cb532..d1152bae 100644 --- a/mpp/codec/dec/h265/h265d_parser.h +++ b/mpp/codec/dec/h265/h265d_parser.h @@ -47,6 +47,7 @@ extern RK_U32 h265d_debug; #define H265D_DBG_SEI (0x00000020) #define H265D_DBG_GLOBAL (0x00000040) #define H265D_DBG_REF (0x00000080) +#define H265D_DBG_TIME (0x00000100) #define h265d_dbg(flag, fmt, ...) _mpp_dbg(h265d_debug, flag, fmt, ## __VA_ARGS__) @@ -687,13 +688,13 @@ typedef struct HEVCContext { MppBufSlots slots; + MppBufSlots packet_slots; HalDecTask *task; void *hal_pic_private; RK_S64 pts; - } HEVCContext; RK_S32 mpp_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps, diff --git a/mpp/codec/dec/h265/h265d_parser2_syntax.c b/mpp/codec/dec/h265/h265d_parser2_syntax.c index dd668d04..d67c695a 100644 --- a/mpp/codec/dec/h265/h265d_parser2_syntax.c +++ b/mpp/codec/dec/h265/h265d_parser2_syntax.c @@ -262,13 +262,16 @@ RK_S32 h265d_parser2_syntax(void *ctx) return 0; } -RK_S32 h265d_syntax_fill_slice(void *ctx, MppBuffer *streambuf) +RK_S32 h265d_syntax_fill_slice(void *ctx, RK_S32 input_index) { H265dContext_t *h265dctx = (H265dContext_t *)ctx; const HEVCContext *h = h265dctx->priv_data; h265d_dxva2_picture_context_t *ctx_pic = h->hal_pic_private; + MppBuffer streambuf = NULL; RK_S32 i, count = 0; RK_U32 position = 0; + mpp_err("input_index = %d",input_index); + mpp_buf_slot_get_prop(h->packet_slots, input_index, SLOT_BUFFER, &streambuf); RK_U8 *ptr = (RK_U8 *)mpp_buffer_get_ptr(streambuf); RK_U8 *current = ptr; if (current == NULL) { @@ -300,8 +303,8 @@ RK_S32 h265d_syntax_fill_slice(void *ctx, MppBuffer *streambuf) current += start_code_size; position += start_code_size; memcpy(current, h->nals[i].data, h->nals[i].size); - mpp_err("h->nals[%d].size = %d", i, h->nals[i].size); - fill_slice_short(&ctx_pic->slice_short[i], position, h->nals[i].size); + mpp_log("h->nals[%d].size = %d", i, h->nals[i].size); + fill_slice_short(&ctx_pic->slice_short[count], position, h->nals[i].size); current += h->nals[i].size; position += h->nals[i].size; count++; @@ -309,6 +312,9 @@ RK_S32 h265d_syntax_fill_slice(void *ctx, MppBuffer *streambuf) ctx_pic->slice_count = count; ctx_pic->bitstream_size = position; ctx_pic->bitstream = (RK_U8*)ptr; + + mpp_buf_slot_set_flag(h->packet_slots, input_index, SLOT_CODEC_READY); + mpp_buf_slot_set_flag(h->packet_slots, input_index, SLOT_HAL_INPUT); return MPP_OK; __BITREAD_ERR: return MPP_ERR_STREAM; diff --git a/mpp/codec/dec/h265/h265d_ps.c b/mpp/codec/dec/h265/h265d_ps.c index 5d7b41d3..b7ad489d 100644 --- a/mpp/codec/dec/h265/h265d_ps.c +++ b/mpp/codec/dec/h265/h265d_ps.c @@ -1596,10 +1596,6 @@ RK_S32 mpp_hevc_decode_nal_sps(HEVCContext *s) READ_ONEBIT(gb, &sps->sao_enabled); READ_ONEBIT(gb, &sps->pcm_enabled_flag); - mpp_err("sps->amp_enabled_flag = %d", sps->amp_enabled_flag); - mpp_err("sps->sao_enabled = %d", sps->sao_enabled); - mpp_err("sps->pcm_enabled_flag = %d", sps->pcm_enabled_flag); - if (sps->pcm_enabled_flag) { READ_BITS(gb, 4, &sps->pcm.bit_depth); sps->pcm.bit_depth += 1; @@ -1706,8 +1702,7 @@ RK_S32 mpp_hevc_decode_nal_sps(HEVCContext *s) s->h265dctx->width = sps->width; s->h265dctx->height = sps->height; // Inferred parameters - sps->log2_ctb_size = sps->log2_min_cb_size + - sps->log2_diff_max_min_coding_block_size; + sps->log2_ctb_size = sps->log2_min_cb_size + sps->log2_diff_max_min_coding_block_size; sps->log2_min_pu_size = sps->log2_min_cb_size - 1; sps->ctb_width = (sps->width + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size; @@ -1749,6 +1744,17 @@ RK_S32 mpp_hevc_decode_nal_sps(HEVCContext *s) sps->log2_max_trafo_size); goto err; } + if (s->h265dctx->compare_info != NULL) { + CurrentFameInf_t *info = (CurrentFameInf_t *)s->h265dctx->compare_info; + HEVCSPS *openhevc_sps = (HEVCSPS *)&info->sps[sps_id]; + + if (compare_sps(openhevc_sps, (HEVCSPS *)sps_buf) < 0) { + mpp_err("compare sps with openhevc error found"); + mpp_assert(0); + return -1; + } + + } #if 0 if (s->h265dctx->debug & FF_DEBUG_BITSTREAM) { h265d_dbg(H265D_DBG_SPS, @@ -1762,17 +1768,7 @@ RK_S32 mpp_hevc_decode_nal_sps(HEVCContext *s) /* check if this is a repeat of an already parsed SPS, then keep the * original one. * otherwise drop all PPSes that depend on it */ - if (s->h265dctx->compare_info != NULL) { - CurrentFameInf_t *info = (CurrentFameInf_t *)s->h265dctx->compare_info; - HEVCSPS *openhevc_sps = (HEVCSPS *)&info->sps[sps_id]; - mpp_log("compare sps in"); - if (compare_sps(openhevc_sps, (HEVCSPS *)sps_buf) < 0) { - mpp_err("compare sps with openhevc error found"); - mpp_assert(0); - return -1; - } - mpp_log("compare sps ok"); - } + if (s->sps_list[sps_id] && !memcmp(s->sps_list[sps_id], sps_buf, sizeof(HEVCSPS))) { mpp_free(sps_buf); diff --git a/mpp/codec/dec/h265/test/CMakeLists.txt b/mpp/codec/dec/h265/test/CMakeLists.txt index dfdce861..2befb6ad 100644 --- a/mpp/codec/dec/h265/test/CMakeLists.txt +++ b/mpp/codec/dec/h265/test/CMakeLists.txt @@ -8,13 +8,13 @@ if(H265D_TEST) add_executable(h265d_parser_test h265d_parser_test.c) include_directories(.) link_directories(.) - if(LINUX) + if(UNIX) set(OPENHEVCSO "${CMAKE_SOURCE_DIR}/mpp/codec/dec/h265/test") add_library(openhevcwrapper SHARED IMPORTED) set_target_properties(openhevcwrapper PROPERTIES IMPORTED_LOCATION "${OPENHEVCSO}/libLibOpenHevcWrapper.so") - target_link_libraries(h265d_parser_test openhevcwrapper m h265d_parse osal h265d_hal mpp_codec mpp utils) + target_link_libraries(h265d_parser_test openhevcwrapper m mpp utils) else() target_link_libraries(h265d_parser_test mpp utils) endif() diff --git a/mpp/codec/dec/h265/test/h265d_parser_test.c b/mpp/codec/dec/h265/test/h265d_parser_test.c index d1421f18..072a3195 100644 --- a/mpp/codec/dec/h265/test/h265d_parser_test.c +++ b/mpp/codec/dec/h265/test/h265d_parser_test.c @@ -250,7 +250,7 @@ static RK_S32 poll_task(void *hal, MppBufSlots slots, HalDecTask *dec) RK_S32 id; id = dec->refer[i]; if (id >= 0) - mpp_buf_slot_clr_flag(slots, id, SLOT_HAL_OUTPUT); + mpp_buf_slot_clr_flag(slots, id, SLOT_HAL_INPUT); } return MPP_OK; @@ -264,19 +264,15 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd) RK_S32 nal_len = 0; void *mpp_codex_ctx = NULL; void *hal = NULL; -// void *openHevcHandle = NULL; MppBufSlots slots; + MppBufSlots packet_slots; ParserCfg parser_cfg; MppHalCfg hal_cfg; MppBufferGroup mFrameGroup = NULL; MppBufferGroup mStreamGroup = NULL; MppPacket rkpkt = NULL; MppFrame frame = NULL; - - MppBuffer prestrem = NULL; - MppBuffer currentstrem = NULL; - - HalDecTask *cutask = NULL; + HalDecTask *curtask = NULL; HalDecTask *pretask = NULL; FILE * fp = NULL; @@ -291,7 +287,7 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd) cmd->height = 2160; } - cutask = mpp_calloc(HalDecTask, 1); + curtask = mpp_calloc(HalDecTask, 1); pretask = mpp_calloc(HalDecTask, 1); mpp_codex_ctx = mpp_calloc_size(void, api_h265d_parser.ctx_size); @@ -317,7 +313,9 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd) mpp_log("mallc in void * value %d \n", sizeof(void *)); buf = mpp_malloc(RK_U8, 2048000); mpp_buf_slot_init(&slots); - mpp_buf_slot_setup(slots, 20, cmd->width * cmd->height * 2, 0); + + mpp_buf_slot_init(&packet_slots); + mpp_buf_slot_setup(packet_slots, 2, 1024*1024, 0); if (NULL == slots) { mpp_err("could not init buffer slot\n"); return MPP_ERR_UNKNOW; @@ -338,12 +336,27 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd) return ret; } } - - mpp_buffer_get(mStreamGroup, ¤tstrem, 1024 * 1024); - mpp_buffer_get(mStreamGroup, &prestrem, 2 * 1024 * 1024); - +#ifndef ANDROID +#ifdef COMPARE + { + void *openHevcHandle = NULL; + openHevcHandle = libOpenHevcInit(1, 1); + libOpenHevcSetCheckMD5(openHevcHandle, 0); + libOpenHevcSetTemporalLayer_id(openHevcHandle, 7); + libOpenHevcSetActiveDecoders(openHevcHandle, 0); + libOpenHevcSetDebugMode(openHevcHandle, 0); + libOpenHevcStartDecoder(openHevcHandle); + if (!openHevcHandle) { + fprintf(stderr, "could not open OpenHevc\n"); + exit(1); + } + } +#endif +#endif parser_cfg.frame_slots = slots; + parser_cfg.packet_slots = packet_slots; hal_cfg.frame_slots = slots; + hal_cfg.packet_slots = packet_slots; h265d_init(mpp_codex_ctx, &parser_cfg); hal_h265d_init(hal, &hal_cfg); mpp_log("mallc out \n"); @@ -351,6 +364,9 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd) mpp_log("malloc fail for input buf"); } //buf[0] = 0; + memset(curtask, 0, sizeof(HalDecTask)); + memset(&curtask->refer, -1, sizeof(curtask->refer)); + curtask->input = -1; while (!feof(pInFile)) { RK_U32 index; RK_U8 *tmpbuf = buf; @@ -360,10 +376,24 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd) mpp_err("get nal len from file %d", nal_len); do { mpp_packet_init(&rkpkt, tmpbuf, nal_len); - memset(cutask, 0, sizeof(HalDecTask)); - memset(&cutask->refer, -1, sizeof(cutask->refer)); - cutask->stmbuf = currentstrem; - h265d_prepare(mpp_codex_ctx, rkpkt, cutask); + if(-1 == curtask->input){ + if (MPP_OK == mpp_buf_slot_get_unused(packet_slots, &index) ) { + MppBuffer buffer = NULL; + curtask->input = index; + + mpp_err("mpp_buf_slot_get_prop"); + mpp_buf_slot_get_prop(packet_slots, index, SLOT_BUFFER, &buffer); + if (NULL == buffer) { + RK_U32 size = mpp_buf_slot_get_size(packet_slots); + mpp_err("mpp_buffer_get"); + mpp_buffer_get(mStreamGroup, &buffer, size); + if (buffer != NULL) + mpp_err("mpp_buf_slot_set_prop %p",buffer); + mpp_buf_slot_set_prop(packet_slots, index, SLOT_BUFFER, buffer); + } + } + } + h265d_prepare(mpp_codex_ctx, rkpkt, curtask); pos = (RK_U8 *)mpp_packet_get_pos(rkpkt); if (pos < (tmpbuf + nal_len)) { tmpbuf = pos; @@ -372,20 +402,34 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd) } else { nal_len = 0; } - if (cutask->valid) { + if (curtask->valid) { if (wait_task) { poll_task(hal, slots, pretask); wait_task = 0; } - cutask->valid = 0; - h265d_parse(mpp_codex_ctx, cutask); + curtask->valid = 0; +#ifndef ANDROID +#ifdef COMPARE + mpp_err("hevc_decode_frame in \n"); + void *sliceInfo = NULL; + RK_U8 *split_out_buf = NULL; + RK_S32 split_size = 0; + h265d_get_stream(mpp_codex_ctx,&split_out_buf,&split_size); + libOpenHevcDecode(openHevcHandle, split_out_buf, split_size, 0); + sliceInfo = libOpenHevcGetSliceInfo(openHevcHandle); + mpp_err("open hevc out \n"); + h265d_set_compare_info(mpp_codex_ctx,sliceInfo); +#endif +#endif + h265d_parse(mpp_codex_ctx, curtask); } - if (cutask->valid) { + if (curtask->valid) { HalTaskInfo syn; - MppBuffer buffer = NULL; + syn.dec = *curtask; + index = curtask->output; - syn.dec = *cutask; - index = cutask->output; + MppBuffer buffer = NULL; + mpp_err("frame get unused"); mpp_buf_slot_get_prop(slots, index, SLOT_BUFFER, &buffer); if (NULL == buffer) { RK_U32 size = mpp_buf_slot_get_size(slots); @@ -399,16 +443,13 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd) hal_h265d_start(hal, &syn); { - MppBuffer tmp = NULL; HalDecTask *task = NULL; - - tmp = currentstrem; - currentstrem = prestrem; - prestrem = tmp; - - task = cutask; - cutask = pretask; + task = curtask; + curtask = pretask; pretask = task; + memset(curtask, 0, sizeof(HalDecTask)); + memset(&curtask->refer, -1, sizeof(curtask->refer)); + curtask->input = -1; } wait_task = 1; } @@ -418,24 +459,27 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd) ret = mpp_buf_slot_dequeue(slots, &index, QUEUE_DISPLAY); if (ret == MPP_OK) { mpp_log("get_display for "); + mpp_buf_slot_get_prop(slots, index, SLOT_FRAME, &frame); + if (frame) { + #if 1//def DUMP + RK_U32 stride_w, stride_h; + void *ptr = NULL; + MppBuffer framebuf; + stride_w = mpp_frame_get_hor_stride(frame); + stride_h = mpp_frame_get_ver_stride(frame); + framebuf = mpp_frame_get_buffer(frame); + ptr = mpp_buffer_get_ptr(framebuf); + if(fp){ + fwrite(ptr, 1, stride_w * stride_h * 3 / 2, fp); + fflush(fp); + } + #endif + mpp_frame_deinit(&frame); + frame = NULL; + } + mpp_buf_slot_clr_flag(slots, index, SLOT_QUEUE_USE); } - mpp_buf_slot_get_prop(slots, index, SLOT_FRAME, &frame); - if (frame) { -#if 1//def DUMP - RK_U32 stride_w, stride_h; - void *ptr = NULL; - MppBuffer framebuf; - stride_w = mpp_frame_get_hor_stride(frame); - stride_h = mpp_frame_get_ver_stride(frame); - framebuf = mpp_frame_get_buffer(frame); - ptr = mpp_buffer_get_ptr(framebuf); - fwrite(ptr, 1, stride_w * stride_h * 3 / 2, fp); - fflush(fp); -#endif - mpp_frame_deinit(&frame); - frame = NULL; - } - mpp_buf_slot_clr_flag(slots, index, SLOT_QUEUE_USE); + } while (ret == MPP_OK); mpp_packet_deinit(&rkpkt); } while ( nal_len ); @@ -445,6 +489,14 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd) poll_task(hal, slots, pretask); wait_task = 0; } + + if (-1 != curtask->input) { + MppBuffer buffer = NULL; + mpp_buf_slot_get_prop(packet_slots, curtask->input, SLOT_BUFFER, &buffer); + mpp_err("mpp_buf_slot free for last packet %p",buffer); + mpp_buffer_put(buffer); + } + h265d_flush((void*)mpp_codex_ctx); do { RK_U32 index; @@ -468,20 +520,35 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd) mpp_err("hal_h265d_deinit in"); hal_h265d_deinit(hal); } - if (slots != NULL) + if (slots != NULL){ + mpp_err("frame slots deInit"); mpp_buf_slot_deinit(slots); + } + if (packet_slots != NULL){ + mpp_err("packet slots deInit"); + mpp_buf_slot_deinit(packet_slots); + } if (mFrameGroup != NULL) { + mpp_err("mFrameGroup deInit"); mpp_buffer_group_put(mFrameGroup); } - if (currentstrem) - mpp_buffer_put(currentstrem); - if (prestrem) - mpp_buffer_put(prestrem); if (mStreamGroup != NULL) { + mpp_err("mStreamGroup deInit"); mpp_buffer_group_put(mStreamGroup); } +#ifndef ANDROID +#ifdef COMPARE + if (openHevcHandle != NULL) { + libOpenHevcClose(openHevcHandle); + openHevcHandle = NULL; + } +#endif +#endif + if(fp){ + fclose(fp); + } mpp_free(buf); mpp_free(mpp_codex_ctx); diff --git a/mpp/codec/inc/h265d_api.h b/mpp/codec/inc/h265d_api.h index 734d25b0..f22c6e49 100644 --- a/mpp/codec/inc/h265d_api.h +++ b/mpp/codec/inc/h265d_api.h @@ -35,6 +35,10 @@ RK_S32 mpp_hevc_split_frame(void *sc, const RK_U8 **poutbuf, RK_S32 *poutbuf_size, const RK_U8 *buf, RK_S32 buf_size); +MPP_RET h265d_get_stream(void *ctx, RK_U8 **buf, RK_S32 *size); // used for compare openhevc +MPP_RET h265d_set_compare_info(void *ctx, void *info); + + #ifdef __cplusplus } #endif diff --git a/mpp/codec/inc/mpp_buf_slot.h b/mpp/codec/inc/mpp_buf_slot.h index e2473632..d8fd0cd0 100644 --- a/mpp/codec/inc/mpp_buf_slot.h +++ b/mpp/codec/inc/mpp_buf_slot.h @@ -169,7 +169,7 @@ RK_U32 mpp_buf_slot_get_size(MppBufSlots slots); * mpp_buf_slot_dec_hw_ref * - when hal finished on hardware decoding it MUST be called once for each used slot */ -MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_U32 *index); +MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_S32 *index); /* * mpp_buf_slot_set_buffer @@ -199,8 +199,8 @@ typedef enum SlotUsageType_e { SLOT_USAGE_BUTT, } SlotUsageType; -MPP_RET mpp_buf_slot_set_flag(MppBufSlots slots, RK_U32 index, SlotUsageType type); -MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_U32 index, SlotUsageType type); +MPP_RET mpp_buf_slot_set_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type); +MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type); // TODO: can be extended here typedef enum SlotQueueType_e { @@ -211,8 +211,8 @@ typedef enum SlotQueueType_e { QUEUE_BUTT, } SlotQueueType; -MPP_RET mpp_buf_slot_enqueue(MppBufSlots slots, RK_U32 index, SlotQueueType type); -MPP_RET mpp_buf_slot_dequeue(MppBufSlots slots, RK_U32 *index, SlotQueueType type); +MPP_RET mpp_buf_slot_enqueue(MppBufSlots slots, RK_S32 index, SlotQueueType type); +MPP_RET mpp_buf_slot_dequeue(MppBufSlots slots, RK_S32 *index, SlotQueueType type); typedef enum SlotPropType_e { SLOT_EOS, @@ -221,8 +221,8 @@ typedef enum SlotPropType_e { SLOT_PROP_BUTT, } SlotPropType; -MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_U32 index, SlotPropType type, void *val); -MPP_RET mpp_buf_slot_get_prop(MppBufSlots slots, RK_U32 index, SlotPropType type, void *val); +MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val); +MPP_RET mpp_buf_slot_get_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val); #ifdef __cplusplus } diff --git a/mpp/codec/mpp_buf_slot.cpp b/mpp/codec/mpp_buf_slot.cpp index f19b24ee..2299a844 100644 --- a/mpp/codec/mpp_buf_slot.cpp +++ b/mpp/codec/mpp_buf_slot.cpp @@ -159,7 +159,7 @@ typedef union SlotStatus_u { } SlotStatus; typedef struct MppBufSlotLog_t { - RK_U32 index; + RK_S32 index; MppBufSlotOps ops; SlotStatus status_in; SlotStatus status_out; @@ -169,7 +169,7 @@ struct MppBufSlotEntry_t { MppBufSlotsImpl *slots; struct list_head list; SlotStatus status; - RK_U32 index; + RK_S32 index; RK_U32 eos; MppFrame frame; @@ -178,7 +178,7 @@ struct MppBufSlotEntry_t { struct MppBufSlotsImpl_t { Mutex *lock; - RK_U32 count; + RK_S32 count; RK_U32 size; // status tracing @@ -199,7 +199,39 @@ struct MppBufSlotsImpl_t { MppBufSlotEntry *slots; }; -static void add_slot_log(mpp_list *logs, RK_U32 index, MppBufSlotOps op, SlotStatus before, SlotStatus after) +static void dump_slots(MppBufSlotsImpl *impl) +{ + RK_S32 i; + MppBufSlotEntry *slot = impl->slots; + + mpp_log("\ndumping slots %p count %d size %d\n", impl, impl->count, impl->size); + mpp_log("decode count %d\n", impl->decode_count); + mpp_log("display count %d\n", impl->display_count); + + for (i = 0; i < impl->count; i++, slot++) { + SlotStatus status = slot->status; + mpp_log("slot %2d used %d refer %d decoding %d display %d\n", + i, status.on_used, status.codec_use, status.hal_use, status.queue_use); + } + + mpp_log("\nslot operation history:\n\n"); + + mpp_list *logs = impl->logs; + if (logs) { + while (logs->list_size()) { + MppBufSlotLog log; + logs->del_at_head(&log, sizeof(log)); + mpp_log("index %2d op: %s status in %08x out %08x", + log.index, op_string[log.ops], log.status_in.val, log.status_out.val); + } + } + + mpp_assert(0); + + return; +} + +static void add_slot_log(mpp_list *logs, RK_S32 index, MppBufSlotOps op, SlotStatus before, SlotStatus after) { if (logs) { MppBufSlotLog log = { @@ -214,9 +246,10 @@ static void add_slot_log(mpp_list *logs, RK_U32 index, MppBufSlotOps op, SlotSta } } -static void slot_ops_with_log(mpp_list *logs, MppBufSlotEntry *slot, MppBufSlotOps op) +static void slot_ops_with_log(MppBufSlotsImpl *impl, MppBufSlotEntry *slot, MppBufSlotOps op) { - RK_U32 index = slot->index; + RK_U32 error = 0; + RK_S32 index = slot->index; SlotStatus status = slot->status; SlotStatus before = status; switch (op) { @@ -253,8 +286,10 @@ static void slot_ops_with_log(mpp_list *logs, MppBufSlotEntry *slot, MppBufSlotO case SLOT_CLR_HAL_INPUT : { if (status.hal_use) status.hal_use--; - else + else { mpp_err("can not clr hal_input on slot %d\n", slot->index); + error = 1; + } } break; case SLOT_SET_HAL_OUTPUT : { status.hal_output = 1; @@ -273,8 +308,10 @@ static void slot_ops_with_log(mpp_list *logs, MppBufSlotEntry *slot, MppBufSlotO case SLOT_DEQUEUE : { if (status.queue_use) status.queue_use--; - else + else { mpp_err("can not clr queue_use on slot %d\n", slot->index); + error = 1; + } } break; case SLOT_SET_EOS : { status.eos = 1; @@ -299,53 +336,26 @@ static void slot_ops_with_log(mpp_list *logs, MppBufSlotEntry *slot, MppBufSlotO } break; default : { mpp_err("found invalid operation code %d\n", op); + error = 1; } break; } slot->status = status; buf_slot_dbg(BUF_SLOT_DBG_OPS_RUNTIME, "index %2d op: %s status in %08x out %08x", index, op_string[op], before.val, status.val); - add_slot_log(logs, index, op, before, status); -} - -static void dump_slots(MppBufSlotsImpl *impl) -{ - RK_U32 i; - MppBufSlotEntry *slot = impl->slots; - - mpp_log("\ndumping slots %p count %d size %d\n", impl, impl->count, impl->size); - mpp_log("decode count %d\n", impl->decode_count); - mpp_log("display count %d\n", impl->display_count); - - for (i = 0; i < impl->count; i++, slot++) { - SlotStatus status = slot->status; - mpp_log("slot %2d used %d refer %d decoding %d display %d\n", - i, status.on_used, status.codec_use, status.hal_use, status.queue_use); - } - - mpp_log("\nslot operation history:\n\n"); - - mpp_list *logs = impl->logs; - if (logs) { - while (logs->list_size()) { - MppBufSlotLog log; - logs->del_at_head(&log, sizeof(log)); - mpp_log("index %2d op: %s status in %08x out %08x", - log.index, op_string[log.ops], log.status_in.val, log.status_out.val); - } - } - + add_slot_log(impl->logs, index, op, before, status); + if (error) + dump_slots(impl); } static void init_slot_entry(MppBufSlotsImpl *impl, RK_S32 pos, RK_S32 count) { - mpp_list *logs = impl->logs; MppBufSlotEntry *slot = impl->slots; for (RK_S32 i = 0; i < count; i++, slot++) { slot->slots = impl; INIT_LIST_HEAD(&slot->list); slot->index = pos + i; slot->frame = NULL; - slot_ops_with_log(logs, slot, SLOT_INIT); + slot_ops_with_log(impl, slot, SLOT_INIT); } } @@ -367,12 +377,12 @@ static void check_entry_unused(MppBufSlotsImpl *impl, MppBufSlotEntry *entry) !status.queue_use) { if (entry->frame) { mpp_frame_deinit(&entry->frame); - slot_ops_with_log(impl->logs, entry, SLOT_CLR_FRAME); + slot_ops_with_log(impl, entry, SLOT_CLR_FRAME); } else mpp_buffer_put(entry->buffer); - slot_ops_with_log(impl->logs, entry, SLOT_CLR_BUFFER); - slot_ops_with_log(impl->logs, entry, SLOT_CLR_ON_USE); + slot_ops_with_log(impl, entry, SLOT_CLR_BUFFER); + slot_ops_with_log(impl, entry, SLOT_CLR_ON_USE); } } @@ -414,7 +424,7 @@ MPP_RET mpp_buf_slot_deinit(MppBufSlots slots) mpp_assert(list_empty(&impl->queue[i])); } MppBufSlotEntry *slot = (MppBufSlotEntry *)impl->slots; - RK_U32 i; + RK_S32 i; for (i = 0; i < impl->count; i++, slot++) mpp_assert(!slot->status.on_used); @@ -516,7 +526,7 @@ RK_U32 mpp_buf_slot_get_size(MppBufSlots slots) return impl->size; } -MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_U32 *index) +MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_S32 *index) { if (NULL == slots || NULL == index) { mpp_err_f("found NULL input\n"); @@ -525,13 +535,13 @@ MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_U32 *index) MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; Mutex::Autolock auto_lock(impl->lock); - RK_U32 i; + RK_S32 i; MppBufSlotEntry *slot = impl->slots; for (i = 0; i < impl->count; i++, slot++) { if (!slot->status.on_used) { *index = i; - slot_ops_with_log(impl->logs, slot, SLOT_SET_ON_USE); - slot_ops_with_log(impl->logs, slot, SLOT_SET_NOT_READY); + slot_ops_with_log(impl, slot, SLOT_SET_ON_USE); + slot_ops_with_log(impl, slot, SLOT_SET_NOT_READY); return MPP_OK; } } @@ -543,7 +553,7 @@ MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_U32 *index) return MPP_NOK; } -MPP_RET mpp_buf_slot_set_flag(MppBufSlots slots, RK_U32 index, SlotUsageType type) +MPP_RET mpp_buf_slot_set_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type) { if (NULL == slots) { mpp_err_f("found NULL input\n"); @@ -553,11 +563,11 @@ MPP_RET mpp_buf_slot_set_flag(MppBufSlots slots, RK_U32 index, SlotUsageType typ MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; Mutex::Autolock auto_lock(impl->lock); slot_assert(impl, index < impl->count); - slot_ops_with_log(impl->logs, &impl->slots[index], set_flag_op[type]); + slot_ops_with_log(impl, &impl->slots[index], set_flag_op[type]); return MPP_OK; } -MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_U32 index, SlotUsageType type) +MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type) { if (NULL == slots) { mpp_err_f("found NULL input\n"); @@ -568,7 +578,7 @@ MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_U32 index, SlotUsageType typ Mutex::Autolock auto_lock(impl->lock); slot_assert(impl, index < impl->count); MppBufSlotEntry *slot = &impl->slots[index]; - slot_ops_with_log(impl->logs, slot, clr_flag_op[type]); + slot_ops_with_log(impl, slot, clr_flag_op[type]); if (type == SLOT_HAL_OUTPUT) impl->decode_count++; @@ -577,7 +587,7 @@ MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_U32 index, SlotUsageType typ return MPP_OK; } -MPP_RET mpp_buf_slot_enqueue(MppBufSlots slots, RK_U32 index, SlotQueueType type) +MPP_RET mpp_buf_slot_enqueue(MppBufSlots slots, RK_S32 index, SlotQueueType type) { if (NULL == slots) { mpp_err_f("found NULL input\n"); @@ -588,7 +598,7 @@ MPP_RET mpp_buf_slot_enqueue(MppBufSlots slots, RK_U32 index, SlotQueueType type Mutex::Autolock auto_lock(impl->lock); slot_assert(impl, index < impl->count); MppBufSlotEntry *slot = &impl->slots[index]; - slot_ops_with_log(impl->logs, slot, SLOT_ENQUEUE); + slot_ops_with_log(impl, slot, SLOT_ENQUEUE); // add slot to display list list_del_init(&slot->list); @@ -596,7 +606,7 @@ MPP_RET mpp_buf_slot_enqueue(MppBufSlots slots, RK_U32 index, SlotQueueType type return MPP_OK; } -MPP_RET mpp_buf_slot_dequeue(MppBufSlots slots, RK_U32 *index, SlotQueueType type) +MPP_RET mpp_buf_slot_dequeue(MppBufSlots slots, RK_S32 *index, SlotQueueType type) { if (NULL == slots || NULL == index) { mpp_err_f("found NULL input\n"); @@ -615,14 +625,14 @@ MPP_RET mpp_buf_slot_dequeue(MppBufSlots slots, RK_U32 *index, SlotQueueType typ // make sure that this slot is just the next display slot list_del_init(&slot->list); slot_assert(impl, (RK_U32)slot->index < impl->count); - slot_ops_with_log(impl->logs, slot, SLOT_DEQUEUE); + slot_ops_with_log(impl, slot, SLOT_DEQUEUE); impl->display_count++; *index = slot->index; return MPP_OK; } -MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_U32 index, SlotPropType type, void *val) +MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val) { if (NULL == slots || NULL == val || type >= SLOT_PROP_BUTT) { mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val); @@ -633,7 +643,7 @@ MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_U32 index, SlotPropType type Mutex::Autolock auto_lock(impl->lock); slot_assert(impl, index < impl->count); MppBufSlotEntry *slot = &impl->slots[index]; - slot_ops_with_log(impl->logs, slot, set_val_op[type]); + slot_ops_with_log(impl, slot, set_val_op[type]); switch (type) { case SLOT_EOS: { @@ -668,7 +678,7 @@ MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_U32 index, SlotPropType type return MPP_OK; } -MPP_RET mpp_buf_slot_get_prop(MppBufSlots slots, RK_U32 index, SlotPropType type, void *val) +MPP_RET mpp_buf_slot_get_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val) { if (NULL == slots || NULL == val || type >= SLOT_PROP_BUTT) { mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val); diff --git a/mpp/codec/mpp_dec.cpp b/mpp/codec/mpp_dec.cpp index 96580093..69bd1700 100644 --- a/mpp/codec/mpp_dec.cpp +++ b/mpp/codec/mpp_dec.cpp @@ -24,6 +24,7 @@ #include "mpp.h" #include "mpp_dec.h" +#include "mpp_buffer_impl.h" #include "mpp_packet_impl.h" #include "mpp_frame_impl.h" @@ -36,6 +37,8 @@ void *mpp_dec_parser_thread(void *data) MppPacket packet = NULL; MppBufSlots frame_slots = dec->frame_slots; MppBufSlots packet_slots = dec->packet_slots; + RK_S32 stream_index = -1; + size_t stream_size = 0; /* * parser thread need to wait at cases below: @@ -46,11 +49,13 @@ void *mpp_dec_parser_thread(void *data) */ RK_U32 wait_on_task_hnd = 0; RK_U32 wait_on_packet = 0; + RK_U32 wait_on_input_index = 0; + RK_U32 wait_on_input_buffer = 0; RK_U32 wait_on_prev = 0; RK_U32 wait_on_change = 0; - RK_U32 wait_on_buffer = 0; + RK_U32 wait_on_frame_buffer = 0; - RK_U32 pkt_buf_ready = 0; + RK_U32 pkt_buf_copyied = 0; RK_U32 prev_task_done = 1; RK_U32 curr_task_ready = 0; RK_U32 curr_task_parsed = 0; @@ -58,6 +63,9 @@ void *mpp_dec_parser_thread(void *data) HalTaskHnd task = NULL; HalTaskInfo task_local; HalDecTask *task_dec = &task_local.dec; + MppBuffer buffer = NULL; + + hal_task_info_init(&task_local, MPP_CTX_DEC); while (MPP_THREAD_RUNNING == parser->get_status()) { /* @@ -65,7 +73,7 @@ void *mpp_dec_parser_thread(void *data) */ parser->lock(); if (wait_on_task_hnd || wait_on_packet || - wait_on_prev || wait_on_change || wait_on_buffer) + wait_on_prev || wait_on_change || wait_on_frame_buffer) parser->wait(); parser->unlock(); @@ -85,7 +93,7 @@ void *mpp_dec_parser_thread(void *data) /* * 2. get packet to parse */ - if (!packet) { + if (!packet && !curr_task_ready) { mpp_list *packets = mpp->mPackets; Mutex::Autolock autoLock(packets->mutex()); if (packets->list_size()) { @@ -128,6 +136,44 @@ void *mpp_dec_parser_thread(void *data) if (!curr_task_ready) continue; + // NOTE: packet in task should be ready now + mpp_assert(task_dec->input_packet); + + // copy prepared stream to hardware buffer + if (task_dec->input < 0) { + mpp_buf_slot_get_unused(packet_slots, &task_dec->input); + } + + wait_on_input_index = (task_dec->input < 0); + if (wait_on_input_index) + continue; + + stream_index = task_dec->input; + stream_size = mpp_packet_get_size(task_dec->input_packet); + mpp_buf_slot_get_prop(packet_slots, stream_index, SLOT_BUFFER, &buffer); + if (NULL == buffer) { + mpp_buffer_get(mpp->mPacketGroup, &buffer, stream_size); + if (buffer) + mpp_buf_slot_set_prop(packet_slots, stream_index, SLOT_BUFFER, buffer); + } else { + MppBufferImpl *buf = (MppBufferImpl *)buffer; + mpp_assert(buf->info.size >= stream_size); + } + + wait_on_input_buffer = (NULL == buffer); + if (wait_on_input_buffer) + continue; + + if (!pkt_buf_copyied) { + MppBufferImpl *buf = (MppBufferImpl *)buffer; + void *src = mpp_packet_get_data(task_dec->input_packet); + size_t size = mpp_packet_get_size(task_dec->input_packet); + memcpy(buf->info.ptr, src, size); + 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); + pkt_buf_copyied = 1; + } + // wait previous task done if (!prev_task_done) { HalTaskHnd task_prev = NULL; @@ -156,6 +202,14 @@ void *mpp_dec_parser_thread(void *data) if (wait_on_change) continue; + /* + * 5. chekc frame buffer group is internal or external + */ + if (NULL == mpp->mFrameGroup) { + mpp_log("mpp_dec use internal frame buffer group\n"); + mpp_buffer_group_get_internal(&mpp->mFrameGroup, MPP_BUFFER_TYPE_ION); + } + /* * 5. do buffer operation according to usage information * @@ -169,7 +223,7 @@ void *mpp_dec_parser_thread(void *data) * frame to hal loop. */ RK_S32 output = task_dec->output; - MppBuffer buffer = NULL; + buffer = NULL; mpp_buf_slot_get_prop(frame_slots, output, SLOT_BUFFER, &buffer); if (NULL == buffer) { RK_U32 size = mpp_buf_slot_get_size(frame_slots); @@ -178,8 +232,8 @@ void *mpp_dec_parser_thread(void *data) mpp_buf_slot_set_prop(frame_slots, output, SLOT_BUFFER, buffer); } - wait_on_buffer = (NULL == buffer); - if (wait_on_buffer) + wait_on_frame_buffer = (NULL == buffer); + if (wait_on_frame_buffer) continue; // register genertation @@ -207,12 +261,18 @@ void *mpp_dec_parser_thread(void *data) mpp->mTaskPutCount++; task = NULL; + pkt_buf_copyied = 0; curr_task_ready = 0; curr_task_parsed = 0; prev_task_done = 0; hal_task_info_init(&task_local, MPP_CTX_DEC); } - + if (NULL != task) { + mpp_buf_slot_get_prop(packet_slots, task_dec->input, SLOT_BUFFER, &buffer); + if (buffer) + mpp_buffer_put(buffer); + } + mpp_buffer_group_clear(mpp->mPacketGroup); return NULL; } @@ -224,6 +284,7 @@ void *mpp_dec_hal_thread(void *data) HalTaskGroup tasks = dec->tasks; mpp_list *frames = mpp->mFrames; MppBufSlots frame_slots = dec->frame_slots; + MppBufSlots packet_slots = dec->packet_slots; /* * hal thread need to wait at cases below: @@ -260,6 +321,7 @@ void *mpp_dec_hal_thread(void *data) * 3. add frame to output list * repeat 2 and 3 until not frame can be output */ + 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); for (RK_U32 i = 0; i < MPP_ARRAY_ELEMS(task_dec->refer); i++) { RK_S32 index = task_dec->refer[i]; @@ -267,7 +329,11 @@ void *mpp_dec_hal_thread(void *data) mpp_buf_slot_clr_flag(frame_slots, index, SLOT_HAL_INPUT); } - RK_U32 index; + if (task_dec->eos) { + mpp_dec_flush(dec); + } + + RK_S32 index; while (MPP_OK == mpp_buf_slot_dequeue(frame_slots, &index, QUEUE_DISPLAY)) { MppFrame frame; mpp_buf_slot_get_prop(frame_slots, index, SLOT_FRAME, &frame); @@ -311,6 +377,8 @@ MPP_RET mpp_dec_init(MppDec **dec, MppCodingType coding) break; } + mpp_buf_slot_setup(packet_slots,2, SZ_512K, 0); + ParserCfg parser_cfg = { coding, frame_slots, diff --git a/mpp/hal/hal_task.cpp b/mpp/hal/hal_task.cpp index 517dbefa..d6691717 100644 --- a/mpp/hal/hal_task.cpp +++ b/mpp/hal/hal_task.cpp @@ -194,8 +194,13 @@ MPP_RET hal_task_info_init(HalTaskInfo *task, MppCtxType type) return MPP_ERR_UNKNOW; } if (MPP_CTX_DEC == type) { - task->dec.valid = 0; - task->dec.output = -1; + HalDecTask *p = &task->dec; + p->valid = 0; + p->eos = 0; + p->info_change = 0; + p->input_packet = NULL; + p->output = -1; + p->input = -1; memset(&task->dec.syntax, 0, sizeof(task->dec.syntax)); memset(task->dec.refer, -1, sizeof(task->dec.refer)); } else { diff --git a/mpp/hal/inc/hal_task.h b/mpp/hal/inc/hal_task.h index d98d63bd..6384850a 100644 --- a/mpp/hal/inc/hal_task.h +++ b/mpp/hal/inc/hal_task.h @@ -76,11 +76,18 @@ typedef struct MppSyntax_t { typedef struct HalDecTask_t { // set by parser to signal that it is valid RK_U32 valid; + RK_U32 eos; + RK_U32 info_change; // current tesk protocol syntax information MppSyntax syntax; - MppBuffer stmbuf; + // packet need to be copied to hardware buffer + // parser will create this packet and mpp_dec will copy it to hardware bufffer + MppPacket input_packet; + + // current task input slot index + RK_S32 input; // for test purpose // current tesk output slot index diff --git a/mpp/hal/rkdec/h265d/hal_h265d_reg.c b/mpp/hal/rkdec/h265d/hal_h265d_reg.c index ad94839b..9308e648 100644 --- a/mpp/hal/rkdec/h265d/hal_h265d_reg.c +++ b/mpp/hal/rkdec/h265d/hal_h265d_reg.c @@ -50,6 +50,7 @@ RK_U32 h265h_debug = 0; typedef struct h265d_reg_context { RK_S32 vpu_socket; MppBufSlots slots; + MppBufSlots packet_slots; MppBufferGroup group; MppBuffer cabac_table_data; MppBuffer scaling_list_data; @@ -257,6 +258,7 @@ MPP_RET hal_h265d_init(void *hal, MppHalCfg *cfg) reg_cxt->slots = cfg->frame_slots; + reg_cxt->packet_slots = cfg->packet_slots; ///<- VPUClientInit #ifdef ANDROID if (reg_cxt->vpu_socket <= 0) { @@ -1252,7 +1254,11 @@ RK_S32 hal_h265d_output_pps_packet(void *hal, void *dxva) fwrite(pps_ptr, 1, 80 * 64, fp); fflush(fp); #endif - mpp_free(pps_packet); +#ifndef ANDROID + if (pps_packet != NULL) { + mpp_free(pps_packet); + } +#endif return 0; } @@ -1268,6 +1274,7 @@ MPP_RET hal_h265d_gen_regs(void *hal, HalTaskInfo *syn) RK_S32 ret = MPP_SUCCESS; #ifdef ANDROID MppBuffer framebuf = NULL; + MppBuffer streambuf = NULL; #endif h265d_dxva2_picture_context_t *dxva_cxt = (h265d_dxva2_picture_context_t *)syn->dec.syntax.data; @@ -1289,12 +1296,7 @@ MPP_RET hal_h265d_gen_regs(void *hal, HalTaskInfo *syn) /* output pps */ hal_h265d_output_pps_packet(hal, syn->dec.syntax.data); -#ifdef dump - if (fp != NULL) { - fwrite(dxva_cxt->bitstream, 1, dxva_cxt->bitstream_size, fp); - fflush(fp); - } -#endif + hal_h265d_slice_output_rps(syn->dec.syntax.data, rps_ptr); if (NULL == reg_cxt->hw_regs) { @@ -1350,7 +1352,8 @@ MPP_RET hal_h265d_gen_regs(void *hal, HalTaskInfo *syn) hw_regs->sw_cabactbl_base = mpp_buffer_get_fd(reg_cxt->cabac_table_data); hw_regs->sw_pps_base = mpp_buffer_get_fd(reg_cxt->pps_data); hw_regs->sw_rps_base = mpp_buffer_get_fd(reg_cxt->rps_data); - hw_regs->sw_strm_rlc_base = mpp_buffer_get_fd(syn->dec.stmbuf); + mpp_buf_slot_get_prop(reg_cxt->packet_slots, syn->dec.input, SLOT_BUFFER, &streambuf); + hw_regs->sw_strm_rlc_base = mpp_buffer_get_fd(streambuf); #endif hw_regs->sw_stream_len = ((dxva_cxt->bitstream_size + 15) & (~15)) + 64; @@ -1419,10 +1422,9 @@ MPP_RET hal_h265d_start(void *hal, HalTaskInfo *task) MPP_RET hal_h265d_wait(void *hal, HalTaskInfo *task) { MPP_RET ret = MPP_OK; - (void) task; - (void) hal; -#ifdef ANDROID h265d_reg_context_t *reg_cxt = (h265d_reg_context_t *)hal; + MppBuffer streambuf = NULL; +#ifdef ANDROID RK_U8* p = (RK_U8*)reg_cxt->hw_regs; RK_S32 i; VPU_CMD_TYPE cmd; @@ -1439,6 +1441,10 @@ MPP_RET hal_h265d_wait(void *hal, HalTaskInfo *task) p += 4; } #endif + mpp_buf_slot_get_prop(reg_cxt->packet_slots, task->dec.input, SLOT_BUFFER, &streambuf); + mpp_buf_slot_clr_flag(reg_cxt->packet_slots, task->dec.input, SLOT_HAL_INPUT); + mpp_buffer_put(streambuf); + return ret; } diff --git a/mpp/legacy/CMakeLists.txt b/mpp/legacy/CMakeLists.txt index 406105f3..7dff8008 100644 --- a/mpp/legacy/CMakeLists.txt +++ b/mpp/legacy/CMakeLists.txt @@ -4,9 +4,9 @@ include_directories(.) # ---------------------------------------------------------------------------- # add mpp implement # ---------------------------------------------------------------------------- -add_library(mpp_legacy STATIC +add_library(mpp_legacy SHARED vpu_api.cpp vpu_api_legacy.cpp ) set_target_properties(mpp_legacy PROPERTIES FOLDER "mpp/legacy") -target_link_libraries(mpp_legacy osal) +target_link_libraries(mpp_legacy mpp osal) diff --git a/mpp/legacy/vpu_api.cpp b/mpp/legacy/vpu_api.cpp index 512fe2c8..dd552f9f 100644 --- a/mpp/legacy/vpu_api.cpp +++ b/mpp/legacy/vpu_api.cpp @@ -17,12 +17,22 @@ #define MODULE_TAG "vpu_api" #include - #include "mpp_log.h" #include "mpp_mem.h" - +#include "mpp_buffer.h" #include "vpu_api_legacy.h" #include "vpu_api.h" +#include "vpu.h" + +#ifdef ANDROID +#include +#endif + +typedef struct vpu_display_mem_pool_impl { + vpu_display_mem_pool_FIELDS + MppBufferGroup group; + RK_S32 size; +} vpu_display_mem_pool_impl; static RK_S32 vpu_api_init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size) { @@ -32,7 +42,6 @@ static RK_S32 vpu_api_init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_ mpp_log("vpu_api_init fail, input invalid"); return VPU_API_ERR_UNKNOW; } - VpuApi* api = (VpuApi*)(ctx->vpuApiObj); if (api == NULL) { mpp_log("vpu_api_init fail, vpu api invalid"); @@ -70,7 +79,7 @@ static RK_S32 vpu_api_sendstream(VpuCodecContext *ctx, VideoPacket_t *pkt) return VPU_API_ERR_UNKNOW; } - return api->decode_sendstream(ctx, pkt); + return api->decode_sendstream(pkt); } static RK_S32 vpu_api_getframe(VpuCodecContext *ctx, DecoderOut_t *aDecOut) @@ -86,7 +95,7 @@ static RK_S32 vpu_api_getframe(VpuCodecContext *ctx, DecoderOut_t *aDecOut) return VPU_API_ERR_UNKNOW; } - return api->decode_getoutframe(ctx, aDecOut); + return api->decode_getoutframe(aDecOut); } static RK_S32 vpu_api_sendframe(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm) @@ -168,6 +177,22 @@ static RK_S32 vpu_api_control(VpuCodecContext *ctx, VPU_API_CMD cmdType, void *p return VPU_API_ERR_UNKNOW; } + mpp_log("vpu_api_control in"); + switch (cmdType) { + case VPU_API_SET_VPUMEM_CONTEXT: { + + mpp_log("vpu_api_control in vpu mem contxt"); + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)param; + + param = (void*)p_mempool->group; + break; + } + default: { + break; + } + } + + mpp_log("vpu_api_control to mpi"); return api->control(ctx, cmdType, param); } @@ -186,6 +211,7 @@ RK_S32 vpu_open_context(VpuCodecContext **ctx) s->enableparsing = 1; VpuApi* api = new VpuApi(); + if (api == NULL) { mpp_err("Vpu api object has not been properly allocated"); return -1; @@ -234,6 +260,139 @@ RK_S32 vpu_close_context(VpuCodecContext **ctx) return 0; } +static RK_S32 commit_memory_handle(vpu_display_mem_pool *p, RK_S32 mem_hdl, RK_S32 size) +{ + MppBufferInfo info; + MPP_RET ret = MPP_OK; + + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + memset(&info, 0, sizeof(MppBufferInfo)); + info.type = MPP_BUFFER_TYPE_ION; + info.fd = mem_hdl; + info.size = size; + p_mempool->size = size; + ret = mpp_buffer_commit(p_mempool->group, &info); + return mem_hdl; +} + +static void* get_free_memory_vpumem(vpu_display_mem_pool *p) +{ + MPP_RET ret = MPP_OK; + MppBuffer buffer = NULL; + VPUMemLinear_t *dmabuf = mpp_calloc(VPUMemLinear_t, 1); + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + if (dmabuf == NULL) { + return NULL; + } + ret = mpp_buffer_get(p_mempool->group, &buffer, p_mempool->size); + if (MPP_OK != ret) { + mpp_free(dmabuf); + return NULL; + } + dmabuf->phy_addr = (RK_U32)mpp_buffer_get_fd(buffer); + dmabuf->vir_addr = (RK_U32*)mpp_buffer_get_ptr(buffer); + dmabuf->size = p_mempool->size; + dmabuf->offset = (RK_U32*)buffer; + return NULL; + +} + +static RK_S32 inc_used_memory_handle_ref(vpu_display_mem_pool *p, void * hdl) +{ + (void)p; + VPUMemLinear_t *dmabuf = (VPUMemLinear_t *)hdl; + MppBuffer buffer = (MppBuffer)dmabuf->offset; + if (buffer != NULL) { + mpp_buffer_inc_ref(buffer); + } + return MPP_OK; + +} + +static RK_S32 put_used_memory_handle(vpu_display_mem_pool *p, void *hdl) +{ + (void)p; + VPUMemLinear_t *dmabuf = (VPUMemLinear_t *)hdl; + MppBuffer buf = (MppBuffer)dmabuf->offset; + if (buf != NULL) { + mpp_buffer_put(buf); + } + return MPP_OK; +} + +static RK_S32 get_free_memory_num(vpu_display_mem_pool *p) +{ + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + if (p_mempool->group != NULL) { + return mpp_buffer_group_unused(p_mempool->group); + } + return 0; +} + +static RK_S32 reset_vpu_mem_pool(vpu_display_mem_pool *p) +{ + (void)p; + // vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + return 0; + +} + + +vpu_display_mem_pool* open_vpu_memory_pool() +{ + mpp_err("open_vpu_memory_pool in\n"); + vpu_display_mem_pool_impl *p_mempool = mpp_calloc(vpu_display_mem_pool_impl, 1); + + if (NULL == p_mempool) { + return NULL; + } + mpp_buffer_group_get_external(&p_mempool->group, MPP_BUFFER_TYPE_ION); + if (NULL == p_mempool->group) { + return NULL; + } + p_mempool->commit_hdl = commit_memory_handle; + p_mempool->get_free = get_free_memory_vpumem; + p_mempool->put_used = put_used_memory_handle; + p_mempool->inc_used = inc_used_memory_handle_ref; + p_mempool->reset = reset_vpu_mem_pool; + p_mempool->get_unused_num = get_free_memory_num; + p_mempool->version = 1; + p_mempool->buff_size = -1; + return (vpu_display_mem_pool*)p_mempool; +} + +void close_vpu_memory_pool(vpu_display_mem_pool *p) +{ + + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + mpp_buffer_group_put(p_mempool->group); + return; +} + +int create_vpu_memory_pool_allocator(vpu_display_mem_pool **ipool, int num, int size) +{ + (void)ipool; + (void)num; + (void)size; + return 0; +} + +void release_vpu_memory_pool_allocator(vpu_display_mem_pool *ipool) +{ + (void)ipool; +} + +RK_S32 VPUMemJudgeIommu() +{ + int ret = 0; +#ifdef ANDROID + if (VPUClientGetIOMMUStatus() > 0) { + //mpp_err("media.used.iommu"); + ret = 1; + } +#endif + return ret; +} RK_S32 VPUMallocLinear(VPUMemLinear_t *p, RK_U32 size) @@ -245,10 +404,11 @@ RK_S32 VPUMallocLinear(VPUMemLinear_t *p, RK_U32 size) RK_S32 VPUFreeLinear(VPUMemLinear_t *p) { - (void)p; + put_used_memory_handle(NULL, p); return 0; } + RK_S32 VPUMemDuplicate(VPUMemLinear_t *dst, VPUMemLinear_t *src) { (void)dst; @@ -281,26 +441,30 @@ RK_S32 VPUMemInvalidate(VPUMemLinear_t *p) return 0; } -vpu_display_mem_pool* open_vpu_memory_pool() +RK_S32 VPUMemGetFD(VPUMemLinear_t *p) { - return NULL; + RK_S32 fd = 0; + MppBuffer buffer = (MppBuffer)p->offset; + fd = mpp_buffer_get_fd(buffer); + //mpp_err("fd = 0x%x",fd); + return fd; + } -void close_vpu_memory_pool(vpu_display_mem_pool *p) +RK_S32 vpu_mem_judge_used_heaps_type() { - (void)p; -} + // TODO, use property_get +#if 0 //def ANDROID + if (!VPUClientGetIOMMUStatus() > 0) { + return ION_HEAP(ION_CMA_HEAP_ID); + } else { + ALOGV("USE ION_SYSTEM_HEAP"); + return ION_HEAP(ION_VMALLOC_HEAP_ID); + } +#endif -int create_vpu_memory_pool_allocator(vpu_display_mem_pool **ipool, int num, int size) -{ - (void)ipool; - (void)num; - (void)size; return 0; } -void release_vpu_memory_pool_allocator(vpu_display_mem_pool *ipool) -{ - (void)ipool; -} + diff --git a/mpp/legacy/vpu_api_legacy.cpp b/mpp/legacy/vpu_api_legacy.cpp index 9f33fb85..68191716 100644 --- a/mpp/legacy/vpu_api_legacy.cpp +++ b/mpp/legacy/vpu_api_legacy.cpp @@ -17,48 +17,57 @@ #define MODULE_TAG "vpu_api_legacy" #include "mpp_log.h" - +#include "mpp_frame.h" #include "vpu_api_legacy.h" +#include "mpp_mem.h" + VpuApi::VpuApi() { mpp_log_f("in\n"); + mpp_ctx = NULL; + mpi = NULL; +#ifdef DUMP_YUV + fp = fopen("data/hevcdump.yuv", "wb"); +#endif + frame_count = 0; mpp_log_f("ok\n"); + } VpuApi::~VpuApi() { mpp_log_f("in\n"); + mpp_deinit(mpp_ctx); mpp_log_f("ok\n"); } RK_S32 VpuApi::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size) { mpp_log_f("in\n"); - (void)ctx; - (void)extraData; - (void)extra_size; - mpp_log_f("ok\n"); - return 0; -} + MPP_RET ret = MPP_OK; + MppCtxType type; + MppPacket pkt = NULL; -RK_S32 VpuApi::send_stream(RK_U8* buf, RK_U32 size, RK_S64 timestamp, RK_S32 usePts) -{ - mpp_log_f("in\n"); - (void)buf; - (void)size; - (void)timestamp; - (void)usePts; - mpp_log_f("ok\n"); - return 0; -} + if (CODEC_DECODER == ctx->codecType) { + type = MPP_CTX_DEC; + } else if (CODEC_ENCODER == ctx->codecType) { + type = MPP_CTX_ENC; + } else { + return MPP_ERR_VPU_CODEC_INIT; + } + + ret = mpp_init(&mpp_ctx, &mpi, type, (MppCodingType)ctx->videoCoding); + mpp_err("mpp_ctx = %p", mpp_ctx); + if (extraData != NULL) { + mpp_packet_init(&pkt, extraData, extra_size); + mpp_packet_set_extra_data(pkt); + mpi->decode_put_packet(mpp_ctx, pkt); + mpp_packet_deinit(&pkt); + } -RK_S32 VpuApi::get_frame(DecoderOut_t *aDecOut) -{ - mpp_log_f("in\n"); - (void)aDecOut; mpp_log_f("ok\n"); - return 0; + return ret; } RK_S32 VpuApi::flush(VpuCodecContext *ctx) @@ -79,21 +88,73 @@ RK_S32 VpuApi::decode(VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aD return 0; } -RK_S32 VpuApi::decode_sendstream(VpuCodecContext *ctx, VideoPacket_t *pkt) +RK_S32 VpuApi::decode_sendstream(VideoPacket_t *pkt) { - mpp_log_f("in\n"); - (void)ctx; - (void)pkt; - mpp_log_f("ok\n"); + //mpp_log_f("in\n"); + MppPacket mpkt = NULL; + mpp_packet_init(&mpkt, pkt->data, pkt->size); + mpp_packet_set_pts(mpkt, pkt->pts); + if (pkt->nFlags & OMX_BUFFERFLAG_EOS) { + mpp_err("decode_sendstream set eos"); + mpp_packet_set_eos(mpkt); + } + if (mpi->decode_put_packet(mpp_ctx, mpkt) == MPP_OK) { + pkt->size = 0; + } + mpp_packet_deinit(&mpkt); + // mpp_log_f("ok\n"); return 0; } -RK_S32 VpuApi:: decode_getoutframe(VpuCodecContext *ctx, DecoderOut_t *aDecOut) +RK_S32 VpuApi:: decode_getoutframe(DecoderOut_t *aDecOut) { - mpp_log_f("in\n"); - (void)ctx; - (void)aDecOut; - mpp_log_f("ok\n"); + // mpp_log_f("in\n"); + VPU_FRAME *vframe = (VPU_FRAME *)aDecOut->data; + MppFrame mframe = NULL; + if (NULL == mpi) { + aDecOut->size = 0; + return 0; + } + if (MPP_OK == mpi->decode_get_frame(mpp_ctx, &mframe)) { + MppBuffer buf; + RK_U64 pts; + RK_U32 fd; + void* ptr; + aDecOut->size = sizeof(VPU_FRAME); + vframe->DisplayWidth = mpp_frame_get_width(mframe); + vframe->DisplayHeight = mpp_frame_get_height(mframe); + vframe->FrameWidth = mpp_frame_get_hor_stride(mframe); + vframe->FrameHeight = mpp_frame_get_ver_stride(mframe); + pts = mpp_frame_get_pts(mframe); + aDecOut->timeUs = pts; + // mpp_err("get one frame timeUs %lld",aDecOut->timeUs); + vframe->ShowTime.TimeHigh = (RK_U32)(pts >> 32); + vframe->ShowTime.TimeLow = (RK_U32)pts; + buf = mpp_frame_get_buffer(mframe); + ptr = mpp_buffer_get_ptr(buf); + fd = mpp_buffer_get_fd(buf); + vframe->FrameBusAddr[0] = fd; + vframe->FrameBusAddr[1] = fd; + vframe->vpumem.vir_addr = (RK_U32*)ptr; + frame_count++; +#ifdef DUMP_YUV + if (frame_count > 350) { + fwrite(ptr, 1, vframe->FrameWidth * vframe->FrameHeight * 3 / 2, fp); + fflush(fp); + } +#endif + vframe->vpumem.phy_addr = fd; + vframe->vpumem.size = vframe->FrameWidth * vframe->FrameHeight * 3 / 2; + vframe->vpumem.offset = (RK_U32*)buf; + if (mpp_frame_get_eos(mframe)) { + aDecOut->nFlags = VPU_API_EOS_STREAM_REACHED; + } + mpp_free(mframe); + } else { + aDecOut->size = 0; + } + + // mpp_log_f("ok\n"); return 0; } @@ -137,9 +198,18 @@ RK_S32 VpuApi::perform(RK_U32 cmd, RK_U32 *data) RK_S32 VpuApi::control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param) { mpp_log_f("in\n"); + MpiCmd mpicmd; (void)ctx; - (void)cmd; - (void)param; + switch (cmd) { + case VPU_API_SET_VPUMEM_CONTEXT: { + mpicmd = MPP_DEC_SET_EXT_BUF_GROUP; + break; + } + default: { + break; + } + } + return mpi->control(mpp_ctx, (MpiCmd)mpicmd, (MppParam)param); mpp_log_f("ok\n"); return 0; } diff --git a/mpp/legacy/vpu_api_legacy.h b/mpp/legacy/vpu_api_legacy.h index af228ae4..e21b10a9 100644 --- a/mpp/legacy/vpu_api_legacy.h +++ b/mpp/legacy/vpu_api_legacy.h @@ -18,7 +18,10 @@ #define _VPU_API_H_ #include "vpu_api.h" +#include "rk_mpi.h" +#include +#define OMX_BUFFERFLAG_EOS 0x00000001 class VpuApi { public: @@ -29,20 +32,24 @@ public: RK_S32 flush(VpuCodecContext *ctx); RK_S32 decode(VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut); - RK_S32 decode_sendstream(VpuCodecContext *ctx, VideoPacket_t *pkt); - RK_S32 decode_getoutframe(VpuCodecContext *ctx, DecoderOut_t *aDecOut); + RK_S32 decode_sendstream(VideoPacket_t *pkt); + RK_S32 decode_getoutframe(DecoderOut_t *aDecOut); RK_S32 preProcessPacket(VpuCodecContext *ctx, VideoPacket_t *pkt); RK_S32 encode(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm, EncoderOut_t *aEncOut); RK_S32 encoder_sendframe(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm); RK_S32 encoder_getstream(VpuCodecContext *ctx, EncoderOut_t *aEncOut); - RK_S32 send_stream(RK_U8* buf, RK_U32 size, RK_S64 timestamp, RK_S32 usePts); - RK_S32 get_frame(DecoderOut_t *aDecOut); - RK_S32 perform(RK_U32 cmd, RK_U32 *data); RK_S32 control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param); +private: + MppCtx mpp_ctx; + MppApi *mpi; + RK_U32 frame_count; +#ifdef DUMP_YUV + FILE *fp; +#endif }; #endif /*_VPU_API_H_*/ diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index c4bde1d7..ba0bcb1d 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -66,12 +66,9 @@ Mpp::Mpp(MppCtxType type, MppCodingType coding) mThreadHal = new MppThread(mpp_dec_hal_thread, this); mpp_buffer_group_get_internal(&mInternalGroup, MPP_BUFFER_TYPE_ION); - mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_ION); - mpp_buffer_group_limit_config(mPacketGroup, MPP_TEST_PACKET_SIZE, 4); + mpp_buffer_group_limit_config(mPacketGroup, 0, 4); - mpp_buffer_group_get_internal(&mFrameGroup, MPP_BUFFER_TYPE_ION); - mpp_buffer_group_limit_config(mFrameGroup, MPP_TEST_FRAME_SIZE, 4); } break; case MPP_CTX_ENC : { mFrames = new mpp_list((node_destructor)NULL); @@ -94,7 +91,7 @@ Mpp::Mpp(MppCtxType type, MppCodingType coding) if (mFrames && mPackets && (mDec || mEnc) && mThreadCodec && mThreadHal && - mPacketGroup && mFrameGroup) { + mPacketGroup) { mThreadCodec->start(); mThreadHal->start(); } else { @@ -161,7 +158,8 @@ void Mpp::clear() MPP_RET Mpp::put_packet(MppPacket packet) { Mutex::Autolock autoLock(mPackets->mutex()); - if (mPackets->list_size() < 4) { + RK_U32 eos = mpp_packet_get_eos(packet); + if (mPackets->list_size() < 4 || eos) { MppPacket pkt; mpp_packet_copy_init(&pkt, packet); mPackets->add_at_tail(&pkt, sizeof(pkt));