#include "mppdecode.h"
MppDecode::MppDecode()
{
}
size_t MppDecode::mpp_buffer_group_usage(MppBufferGroup group)
{
if (nullptr == group)
{
mpp_err_f("input invalid group %p\n", group);
return MPP_BUFFER_MODE_BUTT;
}
MppBufferGroupImpl *p = (MppBufferGroupImpl *)group;
return p->usage;
}
int MppDecode::decode_simple(MppDecode::MpiDecLoopData *data, AVPacket *av_packet,QImage *tempimg)
{
RK_U32 pkt_done = 0;
RK_U32 pkt_eos = 0;
RK_U32 err_info = 0;
MPP_RET ret = MPP_OK;
MppCtx ctx = data->ctx;
MppApi *mpi = data->mpi;
MppPacket packet = nullptr;
MppFrame frame = nullptr;
ret = mpp_packet_init(&packet, av_packet->data, av_packet->size);
if(ret < 0)
{
return -1;
}
mpp_packet_set_pts(packet, av_packet->pts);
mpp_log("av_packet->data:%d",av_packet->data);
do {
RK_S32 times = 5;
// send the packet first if packet is not done
if (!pkt_done) {
ret = mpi->decode_put_packet(ctx, packet);
if (MPP_OK == ret)
pkt_done = 1;
}
// then get all available frame and release
do {
RK_S32 get_frm = 0;
RK_U32 frm_eos = 0;
try_again:
ret = mpi->decode_get_frame(ctx, &frame);
if (MPP_ERR_TIMEOUT == ret) {
if (times > 0) {
times--;
mmsleep(2);
goto try_again;
}
mpp_err("decode_get_frame failed too much time\n");
}
mpp_log("get MPP_OK:%d",MPP_OK);
mpp_log("get ret:%d",ret);
if (MPP_OK != ret) {
mpp_err("decode_get_frame failed ret %d\n", ret);
break;
}
mpp_log("get frame:%s",frame);
if (frame)
{
if (mpp_frame_get_info_change(frame)) {
RK_U32 width = mpp_frame_get_width(frame);
RK_U32 height = mpp_frame_get_height(frame);
RK_U32 hor_stride = mpp_frame_get_hor_stride(frame);
RK_U32 ver_stride = mpp_frame_get_ver_stride(frame);
RK_U32 buf_size = mpp_frame_get_buf_size(frame);
mpp_log("decode_get_frame get info changed found\n");
mpp_log("decoder require buffer w:h [%d:%d] stride [%d:%d] buf_size %d",
width, height, hor_stride, ver_stride, buf_size);
ret = mpp_buffer_group_get_internal(&data->frm_grp, MPP_BUFFER_TYPE_ION);
if (ret) {
mpp_err("get mpp buffer group failed ret %d\n", ret);
break;
}
mpi->control(ctx, MPP_DEC_SET_EXT_BUF_GROUP, data->frm_grp);
mpi->control(ctx, MPP_DEC_SET_INFO_CHANGE_READY, nullptr);
} else {
err_info = mpp_frame_get_errinfo(frame) | mpp_frame_get_discard(frame);
if (err_info) {
mpp_log("decoder_get_frame get err info:%d discard:%d.\n",
mpp_frame_get_errinfo(frame), mpp_frame_get_discard(frame));
}
data->frame_count++;
mpp_log("decode_get_frame get frame %d\n", data->frame_count);
if (!err_info){
mpp_log("no err_info");
mpp_log("frame:%p",frame);
MppBuffer buff = mpp_frame_get_buffer(frame);
if(dst_buf == nullptr)
{
dst_buf = (char*)malloc(DST_WIDTH*DST_HEIGHT*get_bpp_from_format(DST_FORMAT));
}
convertdata((char *)mpp_buffer_get_ptr(buff),dst_buf);
QImage qimg((uchar *)dst_buf,DST_WIDTH,DST_HEIGHT,QImage::Format_RGB888);
*tempimg = qimg.copy();
qDebug() << "yi zhen";
}
}
frm_eos = mpp_frame_get_eos(frame);
mpp_frame_deinit(&frame);
frame = nullptr;
get_frm = 1;
}
// try get runtime frame memory usage
if (data->frm_grp) {
size_t usage = mpp_buffer_group_usage(data->frm_grp);
if (usage > data->max_usage)
data->max_usage = usage;
}
// if last packet is send but last frame is not found continue
if (pkt_eos && pkt_done && !frm_eos) {
mmsleep(10);
continue;
}
if (frm_eos) {
mpp_log("found last frame\n");
break;
}
if (data->frame_num > 0 && data->frame_count >= data->frame_num) {
data->eos = 1;
break;
}
if (get_frm)
continue;
break;
} while (1);
if (data->frame_num > 0 && data->frame_count >= data->frame_num) {
data->eos = 1;
mpp_log("reach max frame number %d\n", data->frame_count);
break;
}
if (pkt_done)
break;
/*
* why sleep here:
* mpi->decode_put_packet will failed when packet in internal queue is
* full,waiting the package is consumed .Usually hardware decode one
* frame which resolution is 1080p needs 2 ms,so here we sleep 3ms
* * is enough.
*/
mmsleep(3);
} while (1);
mpp_packet_deinit(&packet);
return ret;
}
int MppDecode::convertdata(char *srcdata, char *dst_buf)
{
// rga
im_rect src_rect;
im_rect dst_rect;
rga_buffer_t src;
rga_buffer_t dst;
IM_STATUS STATUS;
int ret = 0;
memset(&src_rect, 0, sizeof(src_rect));
memset(&dst_rect, 0, sizeof(dst_rect));
memset(&src, 0, sizeof(src));
memset(&dst, 0, sizeof(dst));
memset(dst_buf,0x00,DST_WIDTH*DST_HEIGHT*get_bpp_from_format(DST_FORMAT));
src = wrapbuffer_virtualaddr(srcdata, SRC_WIDTH, SRC_HEIGHT, SRC_FORMAT);
dst = wrapbuffer_virtualaddr(dst_buf, DST_WIDTH, DST_HEIGHT, DST_FORMAT);
if(src.width == 0 || dst.width == 0) {
printf("%s, %s\n", __FUNCTION__, imStrError());
return -1;
}
src.format = SRC_FORMAT;
dst.format = DST_FORMAT;
ret = imcheck(src, dst, src_rect, dst_rect);
if (IM_STATUS_NOERROR != ret) {
printf("%d, check error! %s", __LINE__, imStrError((IM_STATUS)ret));
return -1;
}
STATUS = imcvtcolor(src, dst, src.format, dst.format);
printf("resizing .... %s\n", imStrError(STATUS));
}
评论1