mpp 解码之后出现绿屏,花屏等现象,一般是由于h265数据对齐问题,

h264视频对齐方式为16位对齐方法。

h265视频对齐方式位256奇数对齐。

h265对齐之后的宽高可通过 MPP函数中的

reallyWidth = static_cast<int>( mpp_frame_get_hor_stride(frame));
reallyHight = static_cast<int>( mpp_frame_get_ver_stride(frame));

可将hor_stride 与 ver_stride 填入RGA 中的wrapbuffer_virtualaddr() 函数

src = wrapbuffer_virtualaddr(srcdata, reallyWidth, reallyHight, SRC_FORMAT);
dst = wrapbuffer_virtualaddr(dst_buf, srcWidth, srcHight, DST_FORMAT);

注意  上述代码中的srcWidth与srcHight是真实的宽高

此时解码出的图像有存在绿边现象。

作者用的qt,可通过Qimage 的copy函数进行拷贝,去除,也可通过rga裁剪进行去除

完整c文件如下:

mpp.c

#include "mppdecode.h"void MppDecode::slotGetSendMppSrcImg()
{srcImgSend = true;
}void MppDecode::setWidthHight(int width, int hight)
{
//    initSrcHight = hight;
//    initSrcWidth = width;
//    while(hight%16 != 0)
//    {
//        hight++;
//    }srcHight = hight;srcWidth = width;}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)
{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);//qDebug()<<"av_packet->data:"<<av_packet->data;do {RK_S32 times = 5;// send the packet first if packet is not doneif (!pkt_done) {ret = mpi->decode_put_packet(ctx, packet);if (MPP_OK == ret)pkt_done = 1;}// then get all available frame and releasedo {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");}//qDebug()<< "mpp_log" <<"get MPP_OK"<<MPP_OK;if (MPP_OK != ret) {mpp_err("decode_get_frame failed ret %d\n", ret);break;}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);qDebug()<<"mpp_log  :"<<"decode_get_frame get info changed found";qDebug("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) {qDebug("decoder_get_frame get err info:%d discard:%d.\n",mpp_frame_get_errinfo(frame), mpp_frame_get_discard(frame));}data->frame_count++;//qDebug("decode_get_frame get frame %d\n", data->frame_count);if (!err_info){//qDebug("no err_info");//qDebug("frame:%p",frame);MppBuffer buff = mpp_frame_get_buffer(frame);if(dst_buf == nullptr){reallyWidth = static_cast<int>( mpp_frame_get_hor_stride(frame));reallyHight = static_cast<int>( mpp_frame_get_ver_stride(frame));//                            //RK_U32 buf_size = mpp_frame_get_buf_size(frame);qDebug() << "srcHight"<<srcWidth<<"srcHight"<<srcHight;qDebug() << ".reallyWidth"<<reallyWidth<<".reallyHight"<<reallyHight;//dst_buf = (char*)malloc(srcWidth * srcHight * get_bpp_from_format(DST_FORMAT));dst_buf = (char*)malloc(reallyWidth * reallyHight * get_bpp_from_format(DST_FORMAT));//dstResize_buf = (char*)malloc(reallyWidth*reallyHight*get_bpp_from_format(DST_FORMAT));}convertdata((char *)mpp_buffer_get_ptr(buff),dst_buf);//convertdata((char *)mpp_buffer_get_ptr(buff),dst_buf,dstResize_buf);QImage qimg((uchar *)dst_buf,srcWidth,srcHight,QImage::Format_RGB888);if(qimg.isNull()){qDebug("空的");}
//                        QImage ResizeImg((uchar *)dstResize_buf,416,416,QImage::Format_RGB888);emit MySigSendMppImg(qimg.copy(0,0,2560-256,1440));//emit MySigSendMppImg(qimg.copy());//                        if(srcImgSend)
//                        {
//                            srcImgSend = false;
//                            QImage Img((uchar *)dst_buf,416,416,QImage::Format_RGB888);
//                            emit MySigSendMppImgSrc(Img.copy());
//                        }}}frm_eos = mpp_frame_get_eos(frame);mpp_frame_deinit(&frame);frame = nullptr;get_frm = 1;}// try get runtime frame memory usageif (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 continueif (pkt_eos && pkt_done && !frm_eos) {mmsleep(10);continue;}if (frm_eos) {qDebug("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;qDebug("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)
{// rgaim_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,srcWidth*srcHight*get_bpp_from_format(DST_FORMAT));src = wrapbuffer_virtualaddr(srcdata, reallyWidth, reallyHight, SRC_FORMAT);dst = wrapbuffer_virtualaddr(dst_buf, srcWidth, srcHight, 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);//qDebug("resizing .... %s\n", imStrError(STATUS));return 0;
}int MppDecode::convertdata(char *srcdata, char *dst_buf,char *dstResize_buf)
{im_rect        src_rect;im_rect        dst_rect;rga_buffer_t   src;rga_buffer_t    dst;rga_buffer_t    dstCrop;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(&dstCrop, 0, sizeof(dstCrop));//memset(dst_buf,0x00,srcWidth*srcHight*get_bpp_from_format(DST_FORMAT));src = wrapbuffer_virtualaddr(srcdata, reallyWidth, reallyHight, SRC_FORMAT);//qDebug() <<""dst = wrapbuffer_virtualaddr(dst_buf, srcWidth, srcHight, DST_FORMAT);//dstCrop = wrapbuffer_virtualaddr(dstResize_buf, srcWidth, srcHight, 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;//dstCrop.format = DST_FORMAT;src_rect.x      = 0;src_rect.y      = 0;src_rect.width  = srcWidth-256;src_rect.height = srcHight;//    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);//qDebug("resizing .... %s\n", imStrError(STATUS));//STATUS = imcrop(dst,dstCrop,src_rect);//qDebug("resizing .... %s\n", imStrError(STATUS));return 0;
}

头文件如下

#ifndef MPPDECODE_H
#define MPPDECODE_H
#define MODULE_TAG "mpi_dec_test"#include <string.h>#include "utils.h"
#include "rk_mpi.h"
#include "mpp_log.h"
#include "mpp_mem.h"
#include "mpp_env.h"
#include "mpp_time.h"
#include "mpp_common.h"
#include "mpp_frame.h"
#include "mpp_buffer_impl.h"
#include "mpp_frame_impl.h"
#include <im2d.hpp>
#include <rga.h>
#include <RgaUtils.h>
#include <QPixmap>
#include <QImage>
#include <QDebug>
extern "C"
{#include <libavformat/avformat.h>
}#define SRC_FORMAT RK_FORMAT_YCbCr_420_SP#define DST_FORMAT RK_FORMAT_RGB_888
//#define SRC_WIDTH  2592
//#define SRC_HEIGHT 1944
//#define DST_WIDTH  2592
//#define DST_HEIGHT 1944
#define MPI_DEC_STREAM_SIZE         (SZ_4K)
#define MPI_DEC_LOOP_COUNT          4
#define MAX_FILE_NAME_LENGTH        256
class MppDecode : public QObject
{Q_OBJECT
signals:void MySigSendMppImg(QImage img);void MySigSendMppImgSrc(QImage img);
public slots:void slotGetSendMppSrcImg();
public:void setWidthHight(int width,int hight);typedef struct{MppCtx          ctx;MppApi          *mpi;RK_U32          eos;char            *buf;RK_U32          quiet;MppBufferGroup  frm_grp;MppBufferGroup  pkt_grp;MppPacket       packet;size_t          packet_size;MppFrame        frame;FILE            *fp_input;RK_S32          frame_count;RK_S32          frame_num;size_t          max_usage;} MpiDecLoopData;typedef struct{char            file_input[MAX_FILE_NAME_LENGTH];char            file_output[MAX_FILE_NAME_LENGTH];MppCodingType   type;MppFrameFormat  format;RK_U32          width;RK_U32          height;RK_U32          debug;RK_U32          have_input;RK_U32          have_output;RK_U32          simple;RK_S32          timeout;RK_S32          frame_num;size_t          max_usage;} MpiDecTestCmd;size_t mpp_buffer_group_usage(MppBufferGroup group);int decode_simple(MpiDecLoopData *data, AVPacket* av_packet);int convertdata(char *srcdata,char * dst_buf);int convertdata(char *srcdata,char * dstsrc_buf,char *dst_buf);char* dst_buf = nullptr;//char* dstResize_buf = nullptr;//char* dstCrop = nullptr;int cout =0;int srcWidth;int srcHight;int initSrcHight;int initSrcWidth;bool srcImgSend;int reallyWidth;int reallyHight;};#endif // MPPDECODE_H

关于h265的在mpp解码的对齐问题,作者还有许多不明白之处,欢迎评论交流

RK平台 MPP 与RGA ,解码h265绿屏,花屏解决方法相关推荐

  1. VM平台添加设备时提示“无效的License组件”的解决方法

    VM平台添加设备时提示"无效的License组件"的解决方法 一般在添加设备时系统提示"无效的License组件"都是由于平台缺少对应的License组件导致的 ...

  2. ThinkBook15电脑开机出现绿屏错误代码无法使用解决方法

    ThinkBook15电脑开机出现绿屏错误代码无法使用解决方法.有用户使用ThinkBook15电脑的时候,去进行了系统的升级,但是升级了系统之后,发现自己的电脑屏幕变成了绿屏的了,而且出现了一些错误 ...

  3. uniapp视频播放绿屏/花屏的问题

    今天搞uniapp的时候发生了一个诡异的事情,有三个视频,前两个本地相册播放正常,uniapp中播放正常.第三个是本地相册播放正常,uniapp中播放有声音.进度条也正常就是绿屏,而且还花屏. 仔细检 ...

  4. 视频编解码 — 卡顿与花屏

    目录 卡顿问题 卡顿问题出现的可能性 1.帧率不够 2.编码出码率超过实际网络带宽 3.网络本身有一定的丢包率 视频花屏 1.帧不完整 2.参考帧不完整,导致花屏 3.YUV格式问题 4.stride ...

  5. 如何在12315网上投诉平台把内容复制粘贴到投诉内容那里的解决方法

    对于12315故意把投诉内容那里限制复制粘贴实在是很不方便.于是自己试了各种的方法,最后找到一个可行的办法,可以发出来给大家使用.免得输入半天后,登录过期或者别的问题导致提交不了,只能重新打的无耐. ...

  6. RK3399 Qt+RTSP+FFMPEG+MPP+RGA解码

    1.首先编译FFMpeg ,源码下载地址:Download FFmpeg tar -xvf ffmpeg-4.2.2.tar.bz2 cd ffmpeg-4.2.2 ./configure \--pr ...

  7. 直播问题分析总结 -- 花屏绿屏

    直播时有时会遇到花屏或绿屏的现象,都有那些原因会导致这种现象呢? 我梳理了部分原因: 视频直播花屏&绿屏 原因 花屏 花屏主要分为整个画面都花屏或局部花屏两种情况. 全屏花屏 正常花屏 有一种 ...

  8. 音视频直播开发问题分析总结 -- 花屏绿屏

    直播时有时会遇到花屏或绿屏的现象,都有那些原因会导致这种现象呢? 梳理了部分原因: 视频直播花屏&绿屏 原因 花屏 花屏主要分为整个画面都花屏或局部花屏两种情况. 全屏花屏 正常花屏 本文福利 ...

  9. 部分华为手机解h265绿屏问题。

    前言 华为荣耀某型号手机解h265绿屏,无法解码. 解 华为手机内置两个解码库,一个自己的,一个OMX.google.hevc.decoder 自己的解码绿屏 使用google的没问题,使用type方 ...

最新文章

  1. googleearthpro打开没有地球_人在月球上睡24小时, 相当于地球多少年? 科学家的回答出乎意料...
  2. mybatis调用存储过程
  3. 计算最小公倍数LCM
  4. 虚拟化平台服务器故障,Vsphere虚拟化平台故障切换
  5. C++基础语言知识大汇总(不断更新!!!)
  6. bzoj 2194: 快速傅立叶之二 FFT
  7. HTML&CSS:制作简易电商网站
  8. tftp: timeout
  9. 玩家浅谈MID平板电脑主流中端方案
  10. 1 10000以内的质数表C语言,求1万以内的质数表,有急用
  11. 基于龙芯CPU银河麒麟操作系统的国产半实物仿真系统ETestDEV
  12. linux怎么添加桌面图标,linux下添加桌面图标
  13. centos7系统开启ftp服务器,centos7 开启ftp服务器
  14. grpc原理及四种实现方式
  15. mysql密码认证插件_关于mysql:无法加载身份验证插件’caching_sha2_password’
  16. 身份证号码的严格校验(非正则)
  17. Android SwipeRefreshLayout GMail的下拉刷新效果
  18. Mac系统原生支持NTFS格式硬盘
  19. HR详谈求职简历筛选之道
  20. 文件无法上传到ftp服务器,无法上传文件到FTP服务器使用C++

热门文章

  1. Linux系统安全应用
  2. 获得网易云音乐歌曲播放的url
  3. 微信小程序实现简单定位功能
  4. MySQL数据库表的插入,修改,删除操作实验
  5. 怎么的测试用例是一个好的测试用例?
  6. Linux创建和删除目录
  7. SAAS云平台搭建札记: (一) 浅论SAAS多租户自助云服务平台的产品、服务和订单
  8. js中如何将字符串转化为时间,并计算时间差
  9. python中eps参数_Python minimize函数:向约束字典传递附加参数
  10. 腾讯QQ大数据:机器学习建模问题中的特征构造方法