[codec_h265d]: merge csy's h265d module

[hal_task]: add input_packet to parser_prepare output, change stmbuf to input_index

git-svn-id: https://10.10.10.66:8443/svn/MediaProcessPlatform/trunk/mpp@352 6e48237b-75ef-9749-8fc9-41990f28c85a
This commit is contained in:
ChenHengming
2015-10-12 15:56:08 +00:00
parent c318361d13
commit 511e6bbbb0
22 changed files with 904 additions and 317 deletions

View File

@@ -311,19 +311,21 @@ RK_S32 vpu_close_context(struct VpuCodecContext **ctx);
/* /*
* vpu_mem api * 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; typedef struct vpu_display_mem_pool vpu_display_mem_pool;
struct vpu_display_mem_pool { struct vpu_display_mem_pool {
int (*commit_hdl)(vpu_display_mem_pool *p, int hdl, int size); vpu_display_mem_pool_FIELDS
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];
}; };
#ifdef __cplusplus #ifdef __cplusplus
@@ -334,6 +336,7 @@ extern "C"
/* /*
* vpu memory handle interface * vpu memory handle interface
*/ */
RK_S32 VPUMemJudgeIommu();
RK_S32 VPUMallocLinear(VPUMemLinear_t *p, RK_U32 size); RK_S32 VPUMallocLinear(VPUMemLinear_t *p, RK_U32 size);
RK_S32 VPUFreeLinear(VPUMemLinear_t *p); RK_S32 VPUFreeLinear(VPUMemLinear_t *p);
RK_S32 VPUMemDuplicate(VPUMemLinear_t *dst, VPUMemLinear_t *src); 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 VPUMemFlush(VPUMemLinear_t *p);
RK_S32 VPUMemClean(VPUMemLinear_t *p); RK_S32 VPUMemClean(VPUMemLinear_t *p);
RK_S32 VPUMemInvalidate(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 * vpu memory allocator and manager interface

View File

@@ -34,7 +34,7 @@ set_target_properties(mpp PROPERTIES FOLDER "mpp")
add_subdirectory(legacy) 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) add_subdirectory(test)

View File

@@ -19,6 +19,8 @@
#include <string.h> #include <string.h>
#include "mpp_log.h" #include "mpp_log.h"
#include "mpp_mem.h"
#include "mpp_packet.h"
#include "dummy_dec_api.h" #include "dummy_dec_api.h"
@@ -30,6 +32,9 @@ typedef struct DummyDec_t {
MppBufSlots frame_slots; MppBufSlots frame_slots;
MppBufSlots packet_slots; MppBufSlots packet_slots;
RK_U32 task_count; RK_U32 task_count;
void *stream;
size_t stream_size;
MppPacket task_pkt;
RK_U32 slots_inited; RK_U32 slots_inited;
RK_U32 frame_count; RK_U32 frame_count;
@@ -41,17 +46,34 @@ MPP_RET dummy_dec_init(void *dec, ParserCfg *cfg)
{ {
DummyDec *p; DummyDec *p;
RK_S32 i; RK_S32 i;
void *stream;
size_t stream_size = SZ_512K;
MppPacket task_pkt;
if (NULL == dec) { if (NULL == dec) {
mpp_err_f("found NULL intput dec %p cfg %p\n", dec, cfg); mpp_err_f("found NULL intput dec %p cfg %p\n", dec, cfg);
return MPP_ERR_NULL_PTR; 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 = (DummyDec *)dec;
p->frame_slots = cfg->frame_slots; p->frame_slots = cfg->frame_slots;
p->packet_slots = cfg->packet_slots; p->packet_slots = cfg->packet_slots;
p->task_count = cfg->task_count = 2; p->task_count = cfg->task_count = 2;
p->slots_inited = 0; p->stream = stream;
p->frame_count = 0; p->stream_size = stream_size;
p->task_pkt = task_pkt;
for (i = 0; i < DUMMY_DEC_REF_COUNT; i++) { for (i = 0; i < DUMMY_DEC_REF_COUNT; i++) {
p->slot_index[i] = -1; 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) MPP_RET dummy_dec_deinit(void *dec)
{ {
DummyDec *p;
if (NULL == dec) { if (NULL == dec) {
mpp_err_f("found NULL intput\n"); mpp_err_f("found NULL intput\n");
return MPP_ERR_NULL_PTR; 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; return MPP_OK;
} }
@@ -106,7 +135,8 @@ MPP_RET dummy_dec_prepare(void *dec, MppPacket pkt, HalDecTask *task)
RK_U32 frame_count; RK_U32 frame_count;
MppBufSlots slots; MppBufSlots slots;
RK_S32 i; RK_S32 i;
char *data; RK_U8 *data;
size_t length;
if (NULL == dec) { if (NULL == dec) {
mpp_err_f("found NULL intput\n"); mpp_err_f("found NULL intput\n");
@@ -121,7 +151,18 @@ MPP_RET dummy_dec_prepare(void *dec, MppPacket pkt, HalDecTask *task)
// set pos to indicate that buffer is done // set pos to indicate that buffer is done
data = mpp_packet_get_data(pkt); data = mpp_packet_get_data(pkt);
mpp_packet_set_pos(pkt, data + mpp_packet_get_size(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 * set slots information

View File

@@ -66,6 +66,7 @@ enum MppPictureStructure {
}; };
#define END_NOT_FOUND (-100) #define END_NOT_FOUND (-100)
#define MPP_PARSER_PTS_NB 4
typedef struct SplitContext { typedef struct SplitContext {
RK_U8 *buffer; 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; ///< 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_S32 overread_index; ///< the index into ParseContext.buffer of the overread bytes
RK_U64 state64; ///< contains the last 8 bytes in MSB order 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; RK_S32 eos;
} SplitContext_t; } SplitContext_t;
@@ -144,7 +170,7 @@ extern "C" {
RK_S32 h265d_parser2_syntax(void *ctx); 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 #ifdef __cplusplus

View File

@@ -32,6 +32,7 @@
#include "mpp_mem.h" #include "mpp_mem.h"
#include "mpp_env.h" #include "mpp_env.h"
#include "h265d_syntax.h" #include "h265d_syntax.h"
#include "mpp_packet_impl.h"
#define START_CODE 0x000001 ///< start_code_prefix_one_3bytes #define START_CODE 0x000001 ///< start_code_prefix_one_3bytes
@@ -179,33 +180,91 @@ RK_S32 h265d_split_init(void **sc)
return MPP_ERR_NOMEM; return MPP_ERR_NOMEM;
} }
} }
s->fetch_timestamp = 1;
return MPP_OK; 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, RK_S32 h265d_split_frame(void *sc,
const RK_U8 **poutbuf, RK_S32 *poutbuf_size, 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; 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) { if (s->eos) {
*poutbuf = s->buffer; *poutbuf = s->buffer;
*poutbuf_size = s->index; *poutbuf_size = s->index;
return 0; return 0;
} }
next = hevc_find_frame_end(s, buf, buf_size); next = hevc_find_frame_end(s, buf, buf_size);
if (mpp_combine_frame(s, next, &buf, &buf_size) < 0) { if (mpp_combine_frame(s, next, &buf, &buf_size) < 0) {
*poutbuf = NULL; *poutbuf = NULL;
*poutbuf_size = 0; *poutbuf_size = 0;
s->cur_offset += buf_size;
return buf_size; return buf_size;
} }
*poutbuf = buf; *poutbuf = buf;
*poutbuf_size = buf_size; *poutbuf_size = buf_size;
if (next < 0) if (next < 0)
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; return next;
} }
@@ -415,6 +474,7 @@ static RK_S32 set_sps(HEVCContext *s, const HEVCSPS *sps)
s->h265dctx->height = sps->output_height; s->h265dctx->height = sps->output_height;
s->h265dctx->pix_fmt = sps->pix_fmt; s->h265dctx->pix_fmt = sps->pix_fmt;
s->h265dctx->sample_aspect_ratio = sps->vui.sar; 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) if (sps->vui.video_signal_type_present_flag)
s->h265dctx->color_range = sps->vui.video_full_range_flag ? MPPCOL_RANGE_JPEG 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; si = di = i;
while (si + 2 < length) { while (si + 2 < length) {
// remove escapes (very rare 1:2^22) // 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++];
dst[di++] = src[si++]; dst[di++] = src[si++];
} else if (src[si] == 0 && src[si + 1] == 0) { } else if (src[si] == 0 && src[si + 1] == 0) {
@@ -1459,47 +1519,6 @@ fail:
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 = (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) static RK_S32 parser_nal_units(HEVCContext *s)
{ {
/* parse the NAL units */ /* parse the NAL units */
@@ -1515,6 +1534,104 @@ static RK_S32 parser_nal_units(HEVCContext *s)
fail: fail:
return ret; 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) 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.data = s->hal_pic_private;
s->task->syntax.number = 1; s->task->syntax.number = 1;
s->task->valid = 1; s->task->valid = 1;
if (s->eos) {
s->task->eos = 1;
}
} }
#if 0 #if 0
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) { for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
@@ -1637,30 +1757,6 @@ fail:
return MPP_ERR_NOMEM; 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) 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->slots = parser_cfg->frame_slots;
s->packet_slots = parser_cfg->packet_slots;
if (h265dctx->extradata_size > 0 && h265dctx->extradata) { if (h265dctx->extradata_size > 0 && h265dctx->extradata) {
ret = hevc_parser_extradata(s); ret = hevc_parser_extradata(s);
@@ -1718,9 +1815,17 @@ MPP_RET h265d_init(void *ctx, ParserCfg *parser_cfg)
MPP_RET h265d_flush(void *ctx) MPP_RET h265d_flush(void *ctx)
{ {
RK_S32 ret = 0; 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 { do {
ret = mpp_hevc_output_frame(ctx, 1); ret = mpp_hevc_output_frame(ctx, 1);
} while (ret); } 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; return MPP_OK;
} }

View File

@@ -47,6 +47,7 @@ extern RK_U32 h265d_debug;
#define H265D_DBG_SEI (0x00000020) #define H265D_DBG_SEI (0x00000020)
#define H265D_DBG_GLOBAL (0x00000040) #define H265D_DBG_GLOBAL (0x00000040)
#define H265D_DBG_REF (0x00000080) #define H265D_DBG_REF (0x00000080)
#define H265D_DBG_TIME (0x00000100)
#define h265d_dbg(flag, fmt, ...) _mpp_dbg(h265d_debug, flag, fmt, ## __VA_ARGS__) #define h265d_dbg(flag, fmt, ...) _mpp_dbg(h265d_debug, flag, fmt, ## __VA_ARGS__)
@@ -687,13 +688,13 @@ typedef struct HEVCContext {
MppBufSlots slots; MppBufSlots slots;
MppBufSlots packet_slots;
HalDecTask *task; HalDecTask *task;
void *hal_pic_private; void *hal_pic_private;
RK_S64 pts; RK_S64 pts;
} HEVCContext; } HEVCContext;
RK_S32 mpp_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps, RK_S32 mpp_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps,

View File

@@ -262,13 +262,16 @@ RK_S32 h265d_parser2_syntax(void *ctx)
return 0; 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; H265dContext_t *h265dctx = (H265dContext_t *)ctx;
const HEVCContext *h = h265dctx->priv_data; const HEVCContext *h = h265dctx->priv_data;
h265d_dxva2_picture_context_t *ctx_pic = h->hal_pic_private; h265d_dxva2_picture_context_t *ctx_pic = h->hal_pic_private;
MppBuffer streambuf = NULL;
RK_S32 i, count = 0; RK_S32 i, count = 0;
RK_U32 position = 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 *ptr = (RK_U8 *)mpp_buffer_get_ptr(streambuf);
RK_U8 *current = ptr; RK_U8 *current = ptr;
if (current == NULL) { if (current == NULL) {
@@ -300,8 +303,8 @@ RK_S32 h265d_syntax_fill_slice(void *ctx, MppBuffer *streambuf)
current += start_code_size; current += start_code_size;
position += start_code_size; position += start_code_size;
memcpy(current, h->nals[i].data, h->nals[i].size); memcpy(current, h->nals[i].data, h->nals[i].size);
mpp_err("h->nals[%d].size = %d", i, h->nals[i].size); mpp_log("h->nals[%d].size = %d", i, h->nals[i].size);
fill_slice_short(&ctx_pic->slice_short[i], position, h->nals[i].size); fill_slice_short(&ctx_pic->slice_short[count], position, h->nals[i].size);
current += h->nals[i].size; current += h->nals[i].size;
position += h->nals[i].size; position += h->nals[i].size;
count++; count++;
@@ -309,6 +312,9 @@ RK_S32 h265d_syntax_fill_slice(void *ctx, MppBuffer *streambuf)
ctx_pic->slice_count = count; ctx_pic->slice_count = count;
ctx_pic->bitstream_size = position; ctx_pic->bitstream_size = position;
ctx_pic->bitstream = (RK_U8*)ptr; 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; return MPP_OK;
__BITREAD_ERR: __BITREAD_ERR:
return MPP_ERR_STREAM; return MPP_ERR_STREAM;

View File

@@ -1596,10 +1596,6 @@ RK_S32 mpp_hevc_decode_nal_sps(HEVCContext *s)
READ_ONEBIT(gb, &sps->sao_enabled); READ_ONEBIT(gb, &sps->sao_enabled);
READ_ONEBIT(gb, &sps->pcm_enabled_flag); 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) { if (sps->pcm_enabled_flag) {
READ_BITS(gb, 4, &sps->pcm.bit_depth); READ_BITS(gb, 4, &sps->pcm.bit_depth);
sps->pcm.bit_depth += 1; 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->width = sps->width;
s->h265dctx->height = sps->height; s->h265dctx->height = sps->height;
// Inferred parameters // Inferred parameters
sps->log2_ctb_size = sps->log2_min_cb_size + sps->log2_ctb_size = sps->log2_min_cb_size + sps->log2_diff_max_min_coding_block_size;
sps->log2_diff_max_min_coding_block_size;
sps->log2_min_pu_size = sps->log2_min_cb_size - 1; 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; 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); sps->log2_max_trafo_size);
goto err; 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 0
if (s->h265dctx->debug & FF_DEBUG_BITSTREAM) { if (s->h265dctx->debug & FF_DEBUG_BITSTREAM) {
h265d_dbg(H265D_DBG_SPS, 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 /* check if this is a repeat of an already parsed SPS, then keep the
* original one. * original one.
* otherwise drop all PPSes that depend on it */ * 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] && if (s->sps_list[sps_id] &&
!memcmp(s->sps_list[sps_id], sps_buf, sizeof(HEVCSPS))) { !memcmp(s->sps_list[sps_id], sps_buf, sizeof(HEVCSPS))) {
mpp_free(sps_buf); mpp_free(sps_buf);

View File

@@ -8,13 +8,13 @@ if(H265D_TEST)
add_executable(h265d_parser_test h265d_parser_test.c) add_executable(h265d_parser_test h265d_parser_test.c)
include_directories(.) include_directories(.)
link_directories(.) link_directories(.)
if(LINUX) if(UNIX)
set(OPENHEVCSO "${CMAKE_SOURCE_DIR}/mpp/codec/dec/h265/test") set(OPENHEVCSO "${CMAKE_SOURCE_DIR}/mpp/codec/dec/h265/test")
add_library(openhevcwrapper SHARED IMPORTED) add_library(openhevcwrapper SHARED IMPORTED)
set_target_properties(openhevcwrapper PROPERTIES set_target_properties(openhevcwrapper PROPERTIES
IMPORTED_LOCATION IMPORTED_LOCATION
"${OPENHEVCSO}/libLibOpenHevcWrapper.so") "${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() else()
target_link_libraries(h265d_parser_test mpp utils) target_link_libraries(h265d_parser_test mpp utils)
endif() endif()

View File

@@ -250,7 +250,7 @@ static RK_S32 poll_task(void *hal, MppBufSlots slots, HalDecTask *dec)
RK_S32 id; RK_S32 id;
id = dec->refer[i]; id = dec->refer[i];
if (id >= 0) 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; return MPP_OK;
@@ -264,19 +264,15 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd)
RK_S32 nal_len = 0; RK_S32 nal_len = 0;
void *mpp_codex_ctx = NULL; void *mpp_codex_ctx = NULL;
void *hal = NULL; void *hal = NULL;
// void *openHevcHandle = NULL;
MppBufSlots slots; MppBufSlots slots;
MppBufSlots packet_slots;
ParserCfg parser_cfg; ParserCfg parser_cfg;
MppHalCfg hal_cfg; MppHalCfg hal_cfg;
MppBufferGroup mFrameGroup = NULL; MppBufferGroup mFrameGroup = NULL;
MppBufferGroup mStreamGroup = NULL; MppBufferGroup mStreamGroup = NULL;
MppPacket rkpkt = NULL; MppPacket rkpkt = NULL;
MppFrame frame = NULL; MppFrame frame = NULL;
HalDecTask *curtask = NULL;
MppBuffer prestrem = NULL;
MppBuffer currentstrem = NULL;
HalDecTask *cutask = NULL;
HalDecTask *pretask = NULL; HalDecTask *pretask = NULL;
FILE * fp = NULL; FILE * fp = NULL;
@@ -291,7 +287,7 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd)
cmd->height = 2160; cmd->height = 2160;
} }
cutask = mpp_calloc(HalDecTask, 1); curtask = mpp_calloc(HalDecTask, 1);
pretask = mpp_calloc(HalDecTask, 1); pretask = mpp_calloc(HalDecTask, 1);
mpp_codex_ctx = mpp_calloc_size(void, api_h265d_parser.ctx_size); 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 *)); mpp_log("mallc in void * value %d \n", sizeof(void *));
buf = mpp_malloc(RK_U8, 2048000); buf = mpp_malloc(RK_U8, 2048000);
mpp_buf_slot_init(&slots); 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) { if (NULL == slots) {
mpp_err("could not init buffer slot\n"); mpp_err("could not init buffer slot\n");
return MPP_ERR_UNKNOW; return MPP_ERR_UNKNOW;
@@ -338,12 +336,27 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd)
return ret; return ret;
} }
} }
#ifndef ANDROID
mpp_buffer_get(mStreamGroup, &currentstrem, 1024 * 1024); #ifdef COMPARE
mpp_buffer_get(mStreamGroup, &prestrem, 2 * 1024 * 1024); {
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.frame_slots = slots;
parser_cfg.packet_slots = packet_slots;
hal_cfg.frame_slots = slots; hal_cfg.frame_slots = slots;
hal_cfg.packet_slots = packet_slots;
h265d_init(mpp_codex_ctx, &parser_cfg); h265d_init(mpp_codex_ctx, &parser_cfg);
hal_h265d_init(hal, &hal_cfg); hal_h265d_init(hal, &hal_cfg);
mpp_log("mallc out \n"); mpp_log("mallc out \n");
@@ -351,6 +364,9 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd)
mpp_log("malloc fail for input buf"); mpp_log("malloc fail for input buf");
} }
//buf[0] = 0; //buf[0] = 0;
memset(curtask, 0, sizeof(HalDecTask));
memset(&curtask->refer, -1, sizeof(curtask->refer));
curtask->input = -1;
while (!feof(pInFile)) { while (!feof(pInFile)) {
RK_U32 index; RK_U32 index;
RK_U8 *tmpbuf = buf; 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); mpp_err("get nal len from file %d", nal_len);
do { do {
mpp_packet_init(&rkpkt, tmpbuf, nal_len); mpp_packet_init(&rkpkt, tmpbuf, nal_len);
memset(cutask, 0, sizeof(HalDecTask)); if(-1 == curtask->input){
memset(&cutask->refer, -1, sizeof(cutask->refer)); if (MPP_OK == mpp_buf_slot_get_unused(packet_slots, &index) ) {
cutask->stmbuf = currentstrem; MppBuffer buffer = NULL;
h265d_prepare(mpp_codex_ctx, rkpkt, cutask); 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); pos = (RK_U8 *)mpp_packet_get_pos(rkpkt);
if (pos < (tmpbuf + nal_len)) { if (pos < (tmpbuf + nal_len)) {
tmpbuf = pos; tmpbuf = pos;
@@ -372,20 +402,34 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd)
} else { } else {
nal_len = 0; nal_len = 0;
} }
if (cutask->valid) { if (curtask->valid) {
if (wait_task) { if (wait_task) {
poll_task(hal, slots, pretask); poll_task(hal, slots, pretask);
wait_task = 0; wait_task = 0;
} }
cutask->valid = 0; curtask->valid = 0;
h265d_parse(mpp_codex_ctx, cutask); #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; HalTaskInfo syn;
MppBuffer buffer = NULL; syn.dec = *curtask;
index = curtask->output;
syn.dec = *cutask; MppBuffer buffer = NULL;
index = cutask->output; mpp_err("frame get unused");
mpp_buf_slot_get_prop(slots, index, SLOT_BUFFER, &buffer); mpp_buf_slot_get_prop(slots, index, SLOT_BUFFER, &buffer);
if (NULL == buffer) { if (NULL == buffer) {
RK_U32 size = mpp_buf_slot_get_size(slots); 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); hal_h265d_start(hal, &syn);
{ {
MppBuffer tmp = NULL;
HalDecTask *task = NULL; HalDecTask *task = NULL;
task = curtask;
tmp = currentstrem; curtask = pretask;
currentstrem = prestrem;
prestrem = tmp;
task = cutask;
cutask = pretask;
pretask = task; pretask = task;
memset(curtask, 0, sizeof(HalDecTask));
memset(&curtask->refer, -1, sizeof(curtask->refer));
curtask->input = -1;
} }
wait_task = 1; wait_task = 1;
} }
@@ -418,7 +459,6 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd)
ret = mpp_buf_slot_dequeue(slots, &index, QUEUE_DISPLAY); ret = mpp_buf_slot_dequeue(slots, &index, QUEUE_DISPLAY);
if (ret == MPP_OK) { if (ret == MPP_OK) {
mpp_log("get_display for "); mpp_log("get_display for ");
}
mpp_buf_slot_get_prop(slots, index, SLOT_FRAME, &frame); mpp_buf_slot_get_prop(slots, index, SLOT_FRAME, &frame);
if (frame) { if (frame) {
#if 1//def DUMP #if 1//def DUMP
@@ -429,13 +469,17 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd)
stride_h = mpp_frame_get_ver_stride(frame); stride_h = mpp_frame_get_ver_stride(frame);
framebuf = mpp_frame_get_buffer(frame); framebuf = mpp_frame_get_buffer(frame);
ptr = mpp_buffer_get_ptr(framebuf); ptr = mpp_buffer_get_ptr(framebuf);
if(fp){
fwrite(ptr, 1, stride_w * stride_h * 3 / 2, fp); fwrite(ptr, 1, stride_w * stride_h * 3 / 2, fp);
fflush(fp); fflush(fp);
}
#endif #endif
mpp_frame_deinit(&frame); mpp_frame_deinit(&frame);
frame = NULL; frame = NULL;
} }
mpp_buf_slot_clr_flag(slots, index, SLOT_QUEUE_USE); mpp_buf_slot_clr_flag(slots, index, SLOT_QUEUE_USE);
}
} while (ret == MPP_OK); } while (ret == MPP_OK);
mpp_packet_deinit(&rkpkt); mpp_packet_deinit(&rkpkt);
} while ( nal_len ); } while ( nal_len );
@@ -445,6 +489,14 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd)
poll_task(hal, slots, pretask); poll_task(hal, slots, pretask);
wait_task = 0; 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); h265d_flush((void*)mpp_codex_ctx);
do { do {
RK_U32 index; RK_U32 index;
@@ -468,20 +520,35 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd)
mpp_err("hal_h265d_deinit in"); mpp_err("hal_h265d_deinit in");
hal_h265d_deinit(hal); hal_h265d_deinit(hal);
} }
if (slots != NULL) if (slots != NULL){
mpp_err("frame slots deInit");
mpp_buf_slot_deinit(slots); mpp_buf_slot_deinit(slots);
}
if (packet_slots != NULL){
mpp_err("packet slots deInit");
mpp_buf_slot_deinit(packet_slots);
}
if (mFrameGroup != NULL) { if (mFrameGroup != NULL) {
mpp_err("mFrameGroup deInit");
mpp_buffer_group_put(mFrameGroup); mpp_buffer_group_put(mFrameGroup);
} }
if (currentstrem)
mpp_buffer_put(currentstrem);
if (prestrem)
mpp_buffer_put(prestrem);
if (mStreamGroup != NULL) { if (mStreamGroup != NULL) {
mpp_err("mStreamGroup deInit");
mpp_buffer_group_put(mStreamGroup); 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(buf);
mpp_free(mpp_codex_ctx); mpp_free(mpp_codex_ctx);

View File

@@ -35,6 +35,10 @@ RK_S32 mpp_hevc_split_frame(void *sc,
const RK_U8 **poutbuf, RK_S32 *poutbuf_size, const RK_U8 **poutbuf, RK_S32 *poutbuf_size,
const RK_U8 *buf, RK_S32 buf_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 #ifdef __cplusplus
} }
#endif #endif

View File

@@ -169,7 +169,7 @@ RK_U32 mpp_buf_slot_get_size(MppBufSlots slots);
* mpp_buf_slot_dec_hw_ref * mpp_buf_slot_dec_hw_ref
* - when hal finished on hardware decoding it MUST be called once for each used slot * - 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 * mpp_buf_slot_set_buffer
@@ -199,8 +199,8 @@ typedef enum SlotUsageType_e {
SLOT_USAGE_BUTT, SLOT_USAGE_BUTT,
} SlotUsageType; } SlotUsageType;
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);
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);
// TODO: can be extended here // TODO: can be extended here
typedef enum SlotQueueType_e { typedef enum SlotQueueType_e {
@@ -211,8 +211,8 @@ typedef enum SlotQueueType_e {
QUEUE_BUTT, QUEUE_BUTT,
} SlotQueueType; } SlotQueueType;
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);
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);
typedef enum SlotPropType_e { typedef enum SlotPropType_e {
SLOT_EOS, SLOT_EOS,
@@ -221,8 +221,8 @@ typedef enum SlotPropType_e {
SLOT_PROP_BUTT, SLOT_PROP_BUTT,
} SlotPropType; } SlotPropType;
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);
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);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -159,7 +159,7 @@ typedef union SlotStatus_u {
} SlotStatus; } SlotStatus;
typedef struct MppBufSlotLog_t { typedef struct MppBufSlotLog_t {
RK_U32 index; RK_S32 index;
MppBufSlotOps ops; MppBufSlotOps ops;
SlotStatus status_in; SlotStatus status_in;
SlotStatus status_out; SlotStatus status_out;
@@ -169,7 +169,7 @@ struct MppBufSlotEntry_t {
MppBufSlotsImpl *slots; MppBufSlotsImpl *slots;
struct list_head list; struct list_head list;
SlotStatus status; SlotStatus status;
RK_U32 index; RK_S32 index;
RK_U32 eos; RK_U32 eos;
MppFrame frame; MppFrame frame;
@@ -178,7 +178,7 @@ struct MppBufSlotEntry_t {
struct MppBufSlotsImpl_t { struct MppBufSlotsImpl_t {
Mutex *lock; Mutex *lock;
RK_U32 count; RK_S32 count;
RK_U32 size; RK_U32 size;
// status tracing // status tracing
@@ -199,7 +199,39 @@ struct MppBufSlotsImpl_t {
MppBufSlotEntry *slots; 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) { if (logs) {
MppBufSlotLog log = { 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 status = slot->status;
SlotStatus before = status; SlotStatus before = status;
switch (op) { switch (op) {
@@ -253,8 +286,10 @@ static void slot_ops_with_log(mpp_list *logs, MppBufSlotEntry *slot, MppBufSlotO
case SLOT_CLR_HAL_INPUT : { case SLOT_CLR_HAL_INPUT : {
if (status.hal_use) if (status.hal_use)
status.hal_use--; status.hal_use--;
else else {
mpp_err("can not clr hal_input on slot %d\n", slot->index); mpp_err("can not clr hal_input on slot %d\n", slot->index);
error = 1;
}
} break; } break;
case SLOT_SET_HAL_OUTPUT : { case SLOT_SET_HAL_OUTPUT : {
status.hal_output = 1; status.hal_output = 1;
@@ -273,8 +308,10 @@ static void slot_ops_with_log(mpp_list *logs, MppBufSlotEntry *slot, MppBufSlotO
case SLOT_DEQUEUE : { case SLOT_DEQUEUE : {
if (status.queue_use) if (status.queue_use)
status.queue_use--; status.queue_use--;
else else {
mpp_err("can not clr queue_use on slot %d\n", slot->index); mpp_err("can not clr queue_use on slot %d\n", slot->index);
error = 1;
}
} break; } break;
case SLOT_SET_EOS : { case SLOT_SET_EOS : {
status.eos = 1; status.eos = 1;
@@ -299,53 +336,26 @@ static void slot_ops_with_log(mpp_list *logs, MppBufSlotEntry *slot, MppBufSlotO
} break; } break;
default : { default : {
mpp_err("found invalid operation code %d\n", op); mpp_err("found invalid operation code %d\n", op);
error = 1;
} break; } break;
} }
slot->status = status; slot->status = status;
buf_slot_dbg(BUF_SLOT_DBG_OPS_RUNTIME, "index %2d op: %s status in %08x out %08x", 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); index, op_string[op], before.val, status.val);
add_slot_log(logs, index, op, before, status); add_slot_log(impl->logs, index, op, before, status);
} if (error)
dump_slots(impl);
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);
}
}
} }
static void init_slot_entry(MppBufSlotsImpl *impl, RK_S32 pos, RK_S32 count) static void init_slot_entry(MppBufSlotsImpl *impl, RK_S32 pos, RK_S32 count)
{ {
mpp_list *logs = impl->logs;
MppBufSlotEntry *slot = impl->slots; MppBufSlotEntry *slot = impl->slots;
for (RK_S32 i = 0; i < count; i++, slot++) { for (RK_S32 i = 0; i < count; i++, slot++) {
slot->slots = impl; slot->slots = impl;
INIT_LIST_HEAD(&slot->list); INIT_LIST_HEAD(&slot->list);
slot->index = pos + i; slot->index = pos + i;
slot->frame = NULL; 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) { !status.queue_use) {
if (entry->frame) { if (entry->frame) {
mpp_frame_deinit(&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 } else
mpp_buffer_put(entry->buffer); mpp_buffer_put(entry->buffer);
slot_ops_with_log(impl->logs, entry, SLOT_CLR_BUFFER); slot_ops_with_log(impl, entry, SLOT_CLR_BUFFER);
slot_ops_with_log(impl->logs, entry, SLOT_CLR_ON_USE); 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])); mpp_assert(list_empty(&impl->queue[i]));
} }
MppBufSlotEntry *slot = (MppBufSlotEntry *)impl->slots; MppBufSlotEntry *slot = (MppBufSlotEntry *)impl->slots;
RK_U32 i; RK_S32 i;
for (i = 0; i < impl->count; i++, slot++) for (i = 0; i < impl->count; i++, slot++)
mpp_assert(!slot->status.on_used); mpp_assert(!slot->status.on_used);
@@ -516,7 +526,7 @@ RK_U32 mpp_buf_slot_get_size(MppBufSlots slots)
return impl->size; 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) { if (NULL == slots || NULL == index) {
mpp_err_f("found NULL input\n"); 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; MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
Mutex::Autolock auto_lock(impl->lock); Mutex::Autolock auto_lock(impl->lock);
RK_U32 i; RK_S32 i;
MppBufSlotEntry *slot = impl->slots; MppBufSlotEntry *slot = impl->slots;
for (i = 0; i < impl->count; i++, slot++) { for (i = 0; i < impl->count; i++, slot++) {
if (!slot->status.on_used) { if (!slot->status.on_used) {
*index = i; *index = i;
slot_ops_with_log(impl->logs, slot, SLOT_SET_ON_USE); slot_ops_with_log(impl, slot, SLOT_SET_ON_USE);
slot_ops_with_log(impl->logs, slot, SLOT_SET_NOT_READY); slot_ops_with_log(impl, slot, SLOT_SET_NOT_READY);
return MPP_OK; return MPP_OK;
} }
} }
@@ -543,7 +553,7 @@ MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_U32 *index)
return MPP_NOK; 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) { if (NULL == slots) {
mpp_err_f("found NULL input\n"); 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; MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
Mutex::Autolock auto_lock(impl->lock); Mutex::Autolock auto_lock(impl->lock);
slot_assert(impl, index < impl->count); 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; 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) { if (NULL == slots) {
mpp_err_f("found NULL input\n"); 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); Mutex::Autolock auto_lock(impl->lock);
slot_assert(impl, index < impl->count); slot_assert(impl, index < impl->count);
MppBufSlotEntry *slot = &impl->slots[index]; 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) if (type == SLOT_HAL_OUTPUT)
impl->decode_count++; impl->decode_count++;
@@ -577,7 +587,7 @@ MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_U32 index, SlotUsageType typ
return MPP_OK; 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) { if (NULL == slots) {
mpp_err_f("found NULL input\n"); 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); Mutex::Autolock auto_lock(impl->lock);
slot_assert(impl, index < impl->count); slot_assert(impl, index < impl->count);
MppBufSlotEntry *slot = &impl->slots[index]; 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 // add slot to display list
list_del_init(&slot->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; 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) { if (NULL == slots || NULL == index) {
mpp_err_f("found NULL input\n"); 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 // make sure that this slot is just the next display slot
list_del_init(&slot->list); list_del_init(&slot->list);
slot_assert(impl, (RK_U32)slot->index < impl->count); 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++; impl->display_count++;
*index = slot->index; *index = slot->index;
return MPP_OK; 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) { 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); 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); Mutex::Autolock auto_lock(impl->lock);
slot_assert(impl, index < impl->count); slot_assert(impl, index < impl->count);
MppBufSlotEntry *slot = &impl->slots[index]; 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) { switch (type) {
case SLOT_EOS: { case SLOT_EOS: {
@@ -668,7 +678,7 @@ MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_U32 index, SlotPropType type
return MPP_OK; 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) { 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); mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val);

View File

@@ -24,6 +24,7 @@
#include "mpp.h" #include "mpp.h"
#include "mpp_dec.h" #include "mpp_dec.h"
#include "mpp_buffer_impl.h"
#include "mpp_packet_impl.h" #include "mpp_packet_impl.h"
#include "mpp_frame_impl.h" #include "mpp_frame_impl.h"
@@ -36,6 +37,8 @@ void *mpp_dec_parser_thread(void *data)
MppPacket packet = NULL; MppPacket packet = NULL;
MppBufSlots frame_slots = dec->frame_slots; MppBufSlots frame_slots = dec->frame_slots;
MppBufSlots packet_slots = dec->packet_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: * 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_task_hnd = 0;
RK_U32 wait_on_packet = 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_prev = 0;
RK_U32 wait_on_change = 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 prev_task_done = 1;
RK_U32 curr_task_ready = 0; RK_U32 curr_task_ready = 0;
RK_U32 curr_task_parsed = 0; RK_U32 curr_task_parsed = 0;
@@ -58,6 +63,9 @@ void *mpp_dec_parser_thread(void *data)
HalTaskHnd task = NULL; HalTaskHnd task = NULL;
HalTaskInfo task_local; HalTaskInfo task_local;
HalDecTask *task_dec = &task_local.dec; 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()) { while (MPP_THREAD_RUNNING == parser->get_status()) {
/* /*
@@ -65,7 +73,7 @@ void *mpp_dec_parser_thread(void *data)
*/ */
parser->lock(); parser->lock();
if (wait_on_task_hnd || wait_on_packet || 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->wait();
parser->unlock(); parser->unlock();
@@ -85,7 +93,7 @@ void *mpp_dec_parser_thread(void *data)
/* /*
* 2. get packet to parse * 2. get packet to parse
*/ */
if (!packet) { if (!packet && !curr_task_ready) {
mpp_list *packets = mpp->mPackets; mpp_list *packets = mpp->mPackets;
Mutex::Autolock autoLock(packets->mutex()); Mutex::Autolock autoLock(packets->mutex());
if (packets->list_size()) { if (packets->list_size()) {
@@ -128,6 +136,44 @@ void *mpp_dec_parser_thread(void *data)
if (!curr_task_ready) if (!curr_task_ready)
continue; 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 // wait previous task done
if (!prev_task_done) { if (!prev_task_done) {
HalTaskHnd task_prev = NULL; HalTaskHnd task_prev = NULL;
@@ -156,6 +202,14 @@ void *mpp_dec_parser_thread(void *data)
if (wait_on_change) if (wait_on_change)
continue; 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 * 5. do buffer operation according to usage information
* *
@@ -169,7 +223,7 @@ void *mpp_dec_parser_thread(void *data)
* frame to hal loop. * frame to hal loop.
*/ */
RK_S32 output = task_dec->output; RK_S32 output = task_dec->output;
MppBuffer buffer = NULL; buffer = NULL;
mpp_buf_slot_get_prop(frame_slots, output, SLOT_BUFFER, &buffer); mpp_buf_slot_get_prop(frame_slots, output, SLOT_BUFFER, &buffer);
if (NULL == buffer) { if (NULL == buffer) {
RK_U32 size = mpp_buf_slot_get_size(frame_slots); 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); mpp_buf_slot_set_prop(frame_slots, output, SLOT_BUFFER, buffer);
} }
wait_on_buffer = (NULL == buffer); wait_on_frame_buffer = (NULL == buffer);
if (wait_on_buffer) if (wait_on_frame_buffer)
continue; continue;
// register genertation // register genertation
@@ -207,12 +261,18 @@ void *mpp_dec_parser_thread(void *data)
mpp->mTaskPutCount++; mpp->mTaskPutCount++;
task = NULL; task = NULL;
pkt_buf_copyied = 0;
curr_task_ready = 0; curr_task_ready = 0;
curr_task_parsed = 0; curr_task_parsed = 0;
prev_task_done = 0; prev_task_done = 0;
hal_task_info_init(&task_local, MPP_CTX_DEC); 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; return NULL;
} }
@@ -224,6 +284,7 @@ void *mpp_dec_hal_thread(void *data)
HalTaskGroup tasks = dec->tasks; HalTaskGroup tasks = dec->tasks;
mpp_list *frames = mpp->mFrames; mpp_list *frames = mpp->mFrames;
MppBufSlots frame_slots = dec->frame_slots; MppBufSlots frame_slots = dec->frame_slots;
MppBufSlots packet_slots = dec->packet_slots;
/* /*
* hal thread need to wait at cases below: * 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 * 3. add frame to output list
* repeat 2 and 3 until not frame can be output * 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); 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++) { for (RK_U32 i = 0; i < MPP_ARRAY_ELEMS(task_dec->refer); i++) {
RK_S32 index = 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); 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)) { while (MPP_OK == mpp_buf_slot_dequeue(frame_slots, &index, QUEUE_DISPLAY)) {
MppFrame frame; MppFrame frame;
mpp_buf_slot_get_prop(frame_slots, index, SLOT_FRAME, &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; break;
} }
mpp_buf_slot_setup(packet_slots,2, SZ_512K, 0);
ParserCfg parser_cfg = { ParserCfg parser_cfg = {
coding, coding,
frame_slots, frame_slots,

View File

@@ -194,8 +194,13 @@ MPP_RET hal_task_info_init(HalTaskInfo *task, MppCtxType type)
return MPP_ERR_UNKNOW; return MPP_ERR_UNKNOW;
} }
if (MPP_CTX_DEC == type) { if (MPP_CTX_DEC == type) {
task->dec.valid = 0; HalDecTask *p = &task->dec;
task->dec.output = -1; 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.syntax, 0, sizeof(task->dec.syntax));
memset(task->dec.refer, -1, sizeof(task->dec.refer)); memset(task->dec.refer, -1, sizeof(task->dec.refer));
} else { } else {

View File

@@ -76,11 +76,18 @@ typedef struct MppSyntax_t {
typedef struct HalDecTask_t { typedef struct HalDecTask_t {
// set by parser to signal that it is valid // set by parser to signal that it is valid
RK_U32 valid; RK_U32 valid;
RK_U32 eos;
RK_U32 info_change;
// current tesk protocol syntax information // current tesk protocol syntax information
MppSyntax syntax; 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 // for test purpose
// current tesk output slot index // current tesk output slot index

View File

@@ -50,6 +50,7 @@ RK_U32 h265h_debug = 0;
typedef struct h265d_reg_context { typedef struct h265d_reg_context {
RK_S32 vpu_socket; RK_S32 vpu_socket;
MppBufSlots slots; MppBufSlots slots;
MppBufSlots packet_slots;
MppBufferGroup group; MppBufferGroup group;
MppBuffer cabac_table_data; MppBuffer cabac_table_data;
MppBuffer scaling_list_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->slots = cfg->frame_slots;
reg_cxt->packet_slots = cfg->packet_slots;
///<- VPUClientInit ///<- VPUClientInit
#ifdef ANDROID #ifdef ANDROID
if (reg_cxt->vpu_socket <= 0) { 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); fwrite(pps_ptr, 1, 80 * 64, fp);
fflush(fp); fflush(fp);
#endif #endif
#ifndef ANDROID
if (pps_packet != NULL) {
mpp_free(pps_packet); mpp_free(pps_packet);
}
#endif
return 0; return 0;
} }
@@ -1268,6 +1274,7 @@ MPP_RET hal_h265d_gen_regs(void *hal, HalTaskInfo *syn)
RK_S32 ret = MPP_SUCCESS; RK_S32 ret = MPP_SUCCESS;
#ifdef ANDROID #ifdef ANDROID
MppBuffer framebuf = NULL; MppBuffer framebuf = NULL;
MppBuffer streambuf = NULL;
#endif #endif
h265d_dxva2_picture_context_t *dxva_cxt = (h265d_dxva2_picture_context_t *)syn->dec.syntax.data; 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 */ /* output pps */
hal_h265d_output_pps_packet(hal, syn->dec.syntax.data); 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); hal_h265d_slice_output_rps(syn->dec.syntax.data, rps_ptr);
if (NULL == reg_cxt->hw_regs) { 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_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_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_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 #endif
hw_regs->sw_stream_len = ((dxva_cxt->bitstream_size + 15) & (~15)) + 64; 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 hal_h265d_wait(void *hal, HalTaskInfo *task)
{ {
MPP_RET ret = MPP_OK; MPP_RET ret = MPP_OK;
(void) task;
(void) hal;
#ifdef ANDROID
h265d_reg_context_t *reg_cxt = (h265d_reg_context_t *)hal; 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_U8* p = (RK_U8*)reg_cxt->hw_regs;
RK_S32 i; RK_S32 i;
VPU_CMD_TYPE cmd; VPU_CMD_TYPE cmd;
@@ -1439,6 +1441,10 @@ MPP_RET hal_h265d_wait(void *hal, HalTaskInfo *task)
p += 4; p += 4;
} }
#endif #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; return ret;
} }

View File

@@ -4,9 +4,9 @@ include_directories(.)
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# add mpp implement # add mpp implement
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
add_library(mpp_legacy STATIC add_library(mpp_legacy SHARED
vpu_api.cpp vpu_api.cpp
vpu_api_legacy.cpp vpu_api_legacy.cpp
) )
set_target_properties(mpp_legacy PROPERTIES FOLDER "mpp/legacy") set_target_properties(mpp_legacy PROPERTIES FOLDER "mpp/legacy")
target_link_libraries(mpp_legacy osal) target_link_libraries(mpp_legacy mpp osal)

View File

@@ -17,12 +17,22 @@
#define MODULE_TAG "vpu_api" #define MODULE_TAG "vpu_api"
#include <string.h> #include <string.h>
#include "mpp_log.h" #include "mpp_log.h"
#include "mpp_mem.h" #include "mpp_mem.h"
#include "mpp_buffer.h"
#include "vpu_api_legacy.h" #include "vpu_api_legacy.h"
#include "vpu_api.h" #include "vpu_api.h"
#include "vpu.h"
#ifdef ANDROID
#include <linux/ion.h>
#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) 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"); mpp_log("vpu_api_init fail, input invalid");
return VPU_API_ERR_UNKNOW; return VPU_API_ERR_UNKNOW;
} }
VpuApi* api = (VpuApi*)(ctx->vpuApiObj); VpuApi* api = (VpuApi*)(ctx->vpuApiObj);
if (api == NULL) { if (api == NULL) {
mpp_log("vpu_api_init fail, vpu api invalid"); 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 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) 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 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) 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; 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); return api->control(ctx, cmdType, param);
} }
@@ -186,6 +211,7 @@ RK_S32 vpu_open_context(VpuCodecContext **ctx)
s->enableparsing = 1; s->enableparsing = 1;
VpuApi* api = new VpuApi(); VpuApi* api = new VpuApi();
if (api == NULL) { if (api == NULL) {
mpp_err("Vpu api object has not been properly allocated"); mpp_err("Vpu api object has not been properly allocated");
return -1; return -1;
@@ -234,6 +260,139 @@ RK_S32 vpu_close_context(VpuCodecContext **ctx)
return 0; 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) 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) RK_S32 VPUFreeLinear(VPUMemLinear_t *p)
{ {
(void)p; put_used_memory_handle(NULL, p);
return 0; return 0;
} }
RK_S32 VPUMemDuplicate(VPUMemLinear_t *dst, VPUMemLinear_t *src) RK_S32 VPUMemDuplicate(VPUMemLinear_t *dst, VPUMemLinear_t *src)
{ {
(void)dst; (void)dst;
@@ -281,26 +441,30 @@ RK_S32 VPUMemInvalidate(VPUMemLinear_t *p)
return 0; 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; return 0;
} }
void release_vpu_memory_pool_allocator(vpu_display_mem_pool *ipool)
{
(void)ipool;
}

View File

@@ -17,48 +17,57 @@
#define MODULE_TAG "vpu_api_legacy" #define MODULE_TAG "vpu_api_legacy"
#include "mpp_log.h" #include "mpp_log.h"
#include "mpp_frame.h"
#include "vpu_api_legacy.h" #include "vpu_api_legacy.h"
#include "mpp_mem.h"
VpuApi::VpuApi() VpuApi::VpuApi()
{ {
mpp_log_f("in\n"); 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"); mpp_log_f("ok\n");
} }
VpuApi::~VpuApi() VpuApi::~VpuApi()
{ {
mpp_log_f("in\n"); mpp_log_f("in\n");
mpp_deinit(mpp_ctx);
mpp_log_f("ok\n"); mpp_log_f("ok\n");
} }
RK_S32 VpuApi::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size) RK_S32 VpuApi::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size)
{ {
mpp_log_f("in\n"); mpp_log_f("in\n");
(void)ctx; MPP_RET ret = MPP_OK;
(void)extraData; MppCtxType type;
(void)extra_size; MppPacket pkt = NULL;
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;
} }
RK_S32 VpuApi::send_stream(RK_U8* buf, RK_U32 size, RK_S64 timestamp, RK_S32 usePts) ret = mpp_init(&mpp_ctx, &mpi, type, (MppCodingType)ctx->videoCoding);
{ mpp_err("mpp_ctx = %p", mpp_ctx);
mpp_log_f("in\n"); if (extraData != NULL) {
(void)buf; mpp_packet_init(&pkt, extraData, extra_size);
(void)size; mpp_packet_set_extra_data(pkt);
(void)timestamp; mpi->decode_put_packet(mpp_ctx, pkt);
(void)usePts; mpp_packet_deinit(&pkt);
mpp_log_f("ok\n");
return 0;
} }
RK_S32 VpuApi::get_frame(DecoderOut_t *aDecOut)
{
mpp_log_f("in\n");
(void)aDecOut;
mpp_log_f("ok\n"); mpp_log_f("ok\n");
return 0; return ret;
} }
RK_S32 VpuApi::flush(VpuCodecContext *ctx) RK_S32 VpuApi::flush(VpuCodecContext *ctx)
@@ -79,21 +88,73 @@ RK_S32 VpuApi::decode(VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aD
return 0; 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"); //mpp_log_f("in\n");
(void)ctx; MppPacket mpkt = NULL;
(void)pkt; mpp_packet_init(&mpkt, pkt->data, pkt->size);
mpp_log_f("ok\n"); 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; 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"); // mpp_log_f("in\n");
(void)ctx; VPU_FRAME *vframe = (VPU_FRAME *)aDecOut->data;
(void)aDecOut; MppFrame mframe = NULL;
mpp_log_f("ok\n"); 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; 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) RK_S32 VpuApi::control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param)
{ {
mpp_log_f("in\n"); mpp_log_f("in\n");
MpiCmd mpicmd;
(void)ctx; (void)ctx;
(void)cmd; switch (cmd) {
(void)param; 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"); mpp_log_f("ok\n");
return 0; return 0;
} }

View File

@@ -18,7 +18,10 @@
#define _VPU_API_H_ #define _VPU_API_H_
#include "vpu_api.h" #include "vpu_api.h"
#include "rk_mpi.h"
#include <stdio.h>
#define OMX_BUFFERFLAG_EOS 0x00000001
class VpuApi class VpuApi
{ {
public: public:
@@ -29,20 +32,24 @@ public:
RK_S32 flush(VpuCodecContext *ctx); RK_S32 flush(VpuCodecContext *ctx);
RK_S32 decode(VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut); RK_S32 decode(VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut);
RK_S32 decode_sendstream(VpuCodecContext *ctx, VideoPacket_t *pkt); RK_S32 decode_sendstream(VideoPacket_t *pkt);
RK_S32 decode_getoutframe(VpuCodecContext *ctx, DecoderOut_t *aDecOut); RK_S32 decode_getoutframe(DecoderOut_t *aDecOut);
RK_S32 preProcessPacket(VpuCodecContext *ctx, VideoPacket_t *pkt); RK_S32 preProcessPacket(VpuCodecContext *ctx, VideoPacket_t *pkt);
RK_S32 encode(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm, EncoderOut_t *aEncOut); RK_S32 encode(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm, EncoderOut_t *aEncOut);
RK_S32 encoder_sendframe(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm); RK_S32 encoder_sendframe(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm);
RK_S32 encoder_getstream(VpuCodecContext *ctx, EncoderOut_t *aEncOut); 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 perform(RK_U32 cmd, RK_U32 *data);
RK_S32 control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param); 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_*/ #endif /*_VPU_API_H_*/

View File

@@ -66,12 +66,9 @@ Mpp::Mpp(MppCtxType type, MppCodingType coding)
mThreadHal = new MppThread(mpp_dec_hal_thread, this); mThreadHal = new MppThread(mpp_dec_hal_thread, this);
mpp_buffer_group_get_internal(&mInternalGroup, MPP_BUFFER_TYPE_ION); mpp_buffer_group_get_internal(&mInternalGroup, MPP_BUFFER_TYPE_ION);
mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_ION); mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_ION);
mpp_buffer_group_limit_config(mPacketGroup, 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; } break;
case MPP_CTX_ENC : { case MPP_CTX_ENC : {
mFrames = new mpp_list((node_destructor)NULL); mFrames = new mpp_list((node_destructor)NULL);
@@ -94,7 +91,7 @@ Mpp::Mpp(MppCtxType type, MppCodingType coding)
if (mFrames && mPackets && if (mFrames && mPackets &&
(mDec || mEnc) && (mDec || mEnc) &&
mThreadCodec && mThreadHal && mThreadCodec && mThreadHal &&
mPacketGroup && mFrameGroup) { mPacketGroup) {
mThreadCodec->start(); mThreadCodec->start();
mThreadHal->start(); mThreadHal->start();
} else { } else {
@@ -161,7 +158,8 @@ void Mpp::clear()
MPP_RET Mpp::put_packet(MppPacket packet) MPP_RET Mpp::put_packet(MppPacket packet)
{ {
Mutex::Autolock autoLock(mPackets->mutex()); 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; MppPacket pkt;
mpp_packet_copy_init(&pkt, packet); mpp_packet_copy_init(&pkt, packet);
mPackets->add_at_tail(&pkt, sizeof(pkt)); mPackets->add_at_tail(&pkt, sizeof(pkt));