RK3399中的ffmpeg与rkmpp

RK3399 中的ffmpeg对于rkmpp硬件解码的转换

{
	AVCodecContext *codecCtx;
	
	size_t unused;
	RKMPPDecodeContext *rk_context = codecCtx->priv_data;
	RKMPPDecoder *decoder = (RKMPPDecoder *) rk_context->decoder_ref->data;
	ret = mpp_buffer_group_limit_config(decoder->frame_group, 0, 30); //重新group为30长度
	unused = mpp_buffer_group_unused(decoder->frame_group); //获取未使用个数
	log("CH:%d, unused:%d\n", mediaService->chNo, unused);
}
...
while(1) ..... 循环读取视频流并解码
//解码成AVFrame
ret=avcodec_send_packet(codecCtx,pkt);
if(ret!=0){
	avcodec_flush_buffers(codecCtx); //刷新后可以重新解码
	continue;
}
avcodec_receive_frame(codecCtx, avframe);

{  //移动avframe到其他第放使用 format 为 AV_PIX_FMT_DRM_PRIME,即rkmpp的DRM数据
	AVFrame *dst_avframe = av_frame_alloc();
	av_frame_move_ref(dst_avframe, avframe);
	av_frame_unref(avframe); //必须加
	
	//将AVFrmae转换为rkmpp的数据格式
	AVBufferRef* framecontextref = (AVBufferRef*) av_buffer_get_opaque(
				avframe->buf[0]);
	RKMPPFrameContext *framecontext =
				(RKMPPFrameContext *) framecontextref->data;
	MppFrame mppframe=framecontext->frame;
	MppBuffer mppbuffer = mpp_frame_get_buffer(mppframe);
	MppFrameFormat format = mpp_frame_get_fmt(mppframe); //应该为MPP_FMT_YUV420SP(NV12)
	int width = mpp_frame_get_width(mppframe);
	int height = mpp_frame_get_height(mppframe);
	int hor_stride = mpp_frame_get_hor_stride(mppframe);
	int ver_stride = mpp_frame_get_ver_stride(mppframe);
	uint8_t *yuvDataPtr=mpp_buffer_get_ptr(buffer); //YUV数据(NV12)
	//这样可以处理MPP的硬件数据,缩放,截图可以使用RGA
}

...

avcodec_flush_buffers(codecCtx);
{
		RKMPPDecodeContext *rk_context = ffContext->pCodecCtx->priv_data;
		RKMPPDecoder *decoder = (RKMPPDecoder *) rk_context->decoder_ref->data;
		//等待未使用个数为原始的30个
		while (30 != (unused = mpp_buffer_group_unused(decoder->frame_group)))
		{
			logInfo("Media", "CH:%d, mpp_buffer_group_unused:%d\n", mediaService->chNo, unused);
			sleep(1);
		}
}

RK3399 rga转换

/格式转化
MppFrame srcframe = AVFrame2MppFrame(avframe);
int hor_stride = mpp_frame_get_hor_stride(srcframe);
int ver_stride = mpp_frame_get_ver_stride(srcframe);
int src_width = mpp_frame_get_width(srcframe);
int src_height = mpp_frame_get_height(srcframe);
MppBuffer buffer = mpp_frame_get_buffer(srcframe);
uint8_t *src_yuv_ptr = (uint8_t*) mpp_buffer_get_ptr(buffer);


rga_info_t src_info; //原图像
memset(&src_info, 0, sizeof(rga_info_t));
src_info.fd = mpp_buffer_get_fd(buffer); 
src_info.mmuFlag = 1;
rga_set_rect(&src_info.rect, 0, 0, src_width, src_height,hor_stride, ver_stride, RK_FORMAT_YCbCr_420_SP);  //NV12

//目标图像存储空间分配
int dst_width = src_width;
int dst_height = src_height;
int dst_hor = MPP_ALIGN(dst_width, 1); //默认16字节对其,才能编码成JPG,这里使用1字节对齐
int dst_ver = MPP_ALIGN(dst_height, 1); //默认16字节对其
int framesize = dst_ver * dst_hor * 3 / 2;
MppBuffer dst_buffer;
mpp_buffer_get(NULL, &dst_buffer, framesize); //申请内存

rga_info_t dst_info; //目标图像
memset(&dst_info, 0, sizeof(rga_info_t));
dst_info.fd = mpp_buffer_get_fd(dst_buffer);
dst_info.mmuFlag = 1;
rga_set_rect(&dst_info.rect, 0, 0, dst_width, dst_height,dst_hor, dst_ver, RK_FORMAT_YCrCb_420_P);
ret = c_RkRgaBlit(&src_info, &dst_info, NULL);
void *yuv_ptr = mpp_buffer_get_ptr(dst_buffer);
//对yuv_ptr做运算,人脸,车辆,车牌等 因为RK3399没有NPU,故而在CPU中处理GPU数据

mpp_buffer_put(dst_buffer); //释放内存

后记

使用MppBufferGroup时的limit数量太多时,最好调用mpp_buffer_group_clear做清理,否则会导致内存增长不退

  • 1
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
RKMPP是一个用于视频编解码和处理的多媒体处理框架,而FFmpeg是一个开源的跨平台多媒体处理库。这两个框架在功能上有一些相似之处。RKMPP的API思路与绝大多数编解码库是一致的,通过队列操作方式实现编解码控制。与FFmpeg相比,学习RKMPP会比较容易,因为它们的API非常相似。RKMPP支持基于FFmpeg实现的硬件解码,可以利用CUDA、DXVA2、QSV、D3D11VA和OpenCL等不同类型的GPU设备进行加速。RKMPP提供了丰富的功能,包括视频解码和编码,视频处理(如拷贝、缩放、色彩空间转换和场视频解交织等)。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [RKMPP库快速上手--(一)RKMPP功能及使用详解](https://blog.csdn.net/fanyun_01/article/details/126089171)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [基于ffmpeg实现硬件解码功能](https://download.csdn.net/download/xym352860763/84995063)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值