基于rkmedia的视频解码

将ts流flv流mp4流视频数据解码

        这里main文件主要是执行了rkmedia_decoder_init 与decode_threads_init两个工作,其中第一个工作是初始化vdec模块(video decode)

//这是rv1126对视频数据进行解码的文件
#include <stdio.h>
// #include "video_queue.h"
using namespace std;
#include "rkmedia_module_config.h"
#include "video_queue.h"
video_queue *video_queue1 = new video_queue(); 
extern int rkmedia_decoder_init();
extern void decode_threads_init();
int main(int argc, char *argv[])
{rkmedia_decoder_init();decode_threads_init();while (1){/* code */}// while(1)// {// }return 0;
}

视频解码模块初始化如下:

RK_MPI_SYS_Init是初始化rkmdia模块之前必须要使用的

配置了解码模块H264、软件解码、帧格式的过程(通常来说我们选用帧解码而非流解码)

(在这一步时候我调试发现一直出现解码模块初始化失败的报错,后来发现是文件中其他的库可能放的不够或者放错了,编译是没问题的执行时一直报错VDEC Create失败)

int rkmedia_decoder_init()
{int ret;RK_MPI_SYS_Init();VDEC_CHN_ATTR_S vdec_attrs;vdec_attrs.enCodecType    = RK_CODEC_TYPE_H264;       //解码数据格式 H264vdec_attrs.enDecodecMode  = VIDEO_DECODEC_SOFTWARE;   //解码模式:软件解码 硬件解码vdec_attrs.enMode         = VIDEO_MODE_FRAME;         //数据格式 帧格式 流格式ret = RK_MPI_VDEC_CreateChn(0,&vdec_attrs);if(ret){printf("creat chnnel err!\r\n");printf("Create Vdec[0] failed! ret=%d\n", ret);return -1;}printf("vdec creat chnnel success!\r\n");return 0;
}

创建线程模块主要是创建了三个线程:

1.读取本地被编码的数据read_video_thread并存入队列

2.将队列内的数据转化为rkmedia能读懂的形式并输出到VDEC

3.从VDEC取出解码数据显示

#include<stdio.h>
#include<pthread.h>
pthread_t read_video_pid;
pthread_t send_video_decode_pid;
pthread_t display_video_pid;extern void *read_video_thread(void *arg); 
extern void *send_video_decode_thread(void *arg); 
extern void *display_video_thread(void *arg); void decode_threads_init()
{//读取本地编码后的视频文件到队列pthread_create(&read_video_pid,NULL,read_video_thread,NULL);// //取出队列中的编码后的视频文件送往解码器pthread_create(&send_video_decode_pid,NULL,send_video_decode_thread,NULL);// //显示解码后的数据pthread_create(&display_video_pid,NULL,display_video_thread,NULL);printf("decode threads creat success!\r\n");
}

read_video_thread:这个主要是调用了ffmpeg库来读取编码的数据

这里我总结了6步,打开文件、获取文件信息、获取流、获取编码器、获取编码器上下文并绑定、开始读取,这里其实与编码部分类似


#include <stdio.h>
//确保ffmpeg_include.h正确使用的预处理宏
#define __STDC_CONSTANT_MACROS
#define TS_FILE "video.ts"
// #include "include/ffmpeg_include.h"
#include "video_queue.h"
#include <stdlib.h>
#include<pthread.h>#define __STDC_CONSTANT_MACROS
extern "C"
{
#include <libavutil/avassert.h>
#include <libavutil/channel_layout.h>
#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libswresample/swresample.h>
#include "libavutil/time.h"
}
extern video_queue* video_queue1;/*1.打开文件2.获取文件信息3.获取对应流4.获取对应编码器5.分配编码器上下文并绑定编码器6.开始读取
*/
void *read_video_thread(void *arg) {pthread_detach(pthread_self());printf("----------------read_video_thread-------------\r\n");AVFormatContext *avfmt_context = NULL;//打开媒体文件并绑定信息到媒体上下文int ret = avformat_open_input(&avfmt_context, TS_FILE, NULL, NULL);if (ret < 0) {printf("avformat_open_input error\r\n");return NULL;}//寻找对应流文件avformat_find_stream_info(avfmt_context,nullptr); int numret = av_find_best_stream(avfmt_context,AVMEDIA_TYPE_VIDEO,-1,-1,nullptr,0);if(numret <0){printf("find best stream err!\r\n");avformat_free_context(avfmt_context);return NULL;}  AVCodec *avcode = avcodec_find_decoder(avfmt_context->streams[numret]->codecpar->codec_id);AVCodecContext *avcodecontext = avcodec_alloc_context3(avcode);ret = avcodec_parameters_to_context(avcodecontext,avfmt_context->streams[numret]->codecpar);if(ret < 0){avcodec_free_context(&avcodecontext);printf("get code context err!\r\n");return NULL;} AVPacket *packet = av_packet_alloc();while(av_read_frame(avfmt_context,packet) >= 0){if(packet->stream_index == numret){video_data_packet_t *video_packet = (video_data_packet_t *)malloc(sizeof(video_data_packet_t));memcpy(video_packet->videobuff,packet->data,packet->size);video_packet->size = packet->size;video_queue1 ->putVideoPacketQueue(video_packet);}}// 释放资源if (avfmt_context) {avformat_close_input(&avfmt_context);}return NULL;
}

将队列内packet转化为rkmedia能识别的数据:

rkmedia会读取MEDIA_BUFFER类型的数据实质也就是void *,因此我们先分配了这样的MEDIA_BUFFER数据(这里可以理解MEDIA_BUFFER是一个画布,需要指定其框架大小后往里面填充数据),然后把我们的数据拷进去,大小也考进去,发送到VDEC最后释放

#include <stdio.h>
#include <cstdlib>
#include<pthread.h>
#include <stdlib.h>
#include "video_queue.h"
#include "rkmedia_buffer.h"
#include <string.h>
#include <rkmedia_api.h>extern video_queue* video_queue1;
//为什么要把mp4的packet放入队列再取出送到decoder?
//因为mp4的packet是普通的数据,而rv1126解码器需要读取特定类型的数据
/*1.取出数据2.创建画布3.复制信息4.发送数据5.释放信息*/
void *send_video_decode_thread(void *arg)
{free(arg);pthread_detach(pthread_self());MB_IMAGE_INFO_S image_info = {1920,1080,1920,1080,IMAGE_TYPE_NV12};MEDIA_BUFFER mb = NULL;// avformat_open_input();while(1){video_data_packet_t *video_packet = video_queue1->getVideoPacketQueue();//MEDIA_BUFFER就是视频模板 属性 是否硬件buffer 硬件buffer是否有缓冲区mb = RK_MPI_MB_CreateImageBuffer(&image_info,RK_TRUE,MB_FLAG_NOCACHED);memcpy(RK_MPI_MB_GetPtr(mb),video_packet->videobuff,video_packet->size);printf("size if %d\r\n",video_packet->size);RK_MPI_MB_SetSize(mb,video_packet->size);RK_MPI_SYS_SendMediaBuffer(RK_ID_VDEC,0,mb);RK_MPI_MB_ReleaseBuffer(mb);}return NULL;
}

显示模块,我没屏幕,没做,但是你可以建立一个线程然后RK_MPI_SYS_GetMediaBuffer得到数据然后RK_MPI_MB_GetImageInfo获取信息,打印出来看这个信息判断是否正常运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/475863.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据新视界 -- Impala 性能优化:量子计算启发下的数据加密与性能平衡(下)(30 / 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

RPC框架负载均衡

什么是负载均衡&#xff1f; 当一个服务节点无法支撑现有的访问量时&#xff0c;会部署多个节点&#xff0c;组成一个集群&#xff0c;然后通过负载均衡&#xff0c;将请求分发给这个集群下的每个服务节点&#xff0c;从而达到多个服务节点共同分担请求压力的目的。 负载均衡主…

JMeter监听器与压测监控之 InfluxDB

1. 简介 在本文中&#xff0c;我们将介绍如何在 Kali Linux 上通过 Docker 安装 InfluxDB&#xff0c;并使用 JMeter 对其进行性能监控。InfluxDB 是一个高性能的时序数据库&#xff0c;而 JMeter 是一个开源的性能测试工具&#xff0c;可以用于对各种服务进行负载测试和性能监…

Banana Pi BPI-CanMV-K230D-Zero 采用嘉楠科技 K230D RISC-V芯片设计

概述 Banana Pi BPI-CanMV-K230D-Zero 采用嘉楠科技 K230D RISC-V芯片设计,探索 RISC-V Vector1.0 的前沿技术&#xff0c;选择嘉楠科技的 Canmv K230D Zero 开发板。这款创新的开发板是由嘉楠科技与香蕉派开源社区联合设计研发&#xff0c;搭载了先进的勘智 K230D 芯片。 K230…

如何判断注入点传参类型--理论

注入点传参类型 在我们找到注入点后&#xff0c;首先要判断传参的类型&#xff0c;才能以正确的形式向数据库查询数据。 注入点传参一般分为数字型和字符型。 数字型&#xff1a;当传入的参数为整形时&#xff0c;存在SQL注入漏洞&#xff0c;就可以认为是数字型注入。 字符…

HarmonyOS(57) UI性能优化

性能优化是APP开发绕不过的话题&#xff0c;那么在HarmonyOS开发过程中怎么进行性能优化呢&#xff1f;今天就来总结下相关知识点。 UI性能优化 1、避免在组件的生命周期内执行高耗时操作2、合理使用ResourceManager3、优先使用Builder方法代替自定义组件4、参考资料 1、避免在…

AI Prompt Engineering

AI Prompt Engineering 简介 Prompt Engineering, 提示工程&#xff0c;是人工智能领域的一项技术&#xff0c;它旨在通过设计高效的提示词&#xff08;prompts&#xff09;来优化生成式 AI&#xff08;如 GPT、DALLE 等&#xff09;的输出。提示词是用户与生成式 AI 交互的核…

NVR接入录像回放平台EasyCVR视频融合平台加油站监控应用场景与实际功能

在现代社会中&#xff0c;加油站作为重要的能源供应点&#xff0c;面临着安全监管与风险管理的双重挑战。为应对这些问题&#xff0c;安防监控平台EasyCVR推出了一套全面的加油站监控方案。该方案结合了智能分析网关V4的先进识别技术和EasyCVR视频监控平台的强大监控功能&#…

大语言模型中ReLU函数的计算过程及其函数介绍

文章目录 概要ReLU定义 概要 **ReLU 作用&#xff1a;**主要用于为神经网络引入非线性能力&#xff0c;作用是将输入中的整数保留原值&#xff0c;负数置为 0。 从而在层与层之间引入非线性&#xff0c;使神经网络能够拟合复杂的非线性关系。 **ReLU使用场景&#xff1a;**Lla…

【图像检测】深度学习与传统算法的区别(识别逻辑、学习能力、泛化能力)

识别逻辑 深度学习 使用了端到端的学习策略&#xff0c;直接学习从图像到检测结果的映射关系&#xff0c;自动提取特征&#xff0c;并且根据特征与特征之间的关系&#xff0c;计算出检测结果。 传统算法 则是人工提取特征&#xff0c;比如边缘特征&#xff0c;直线特征&#x…

C++-第25课-哈希表性能的分析

目录 一、哈希表概述 1. 什么是哈希表​编辑 2. 哈希表的优点 3. 哈希表的缺点 二、哈希函数 常见哈希函数 三. 哈希冲突的原因和解决方法 一.哈希冲突的原因 二、哈希冲突的解决方法 1. 链表法&#xff08;Separate Chaining&#xff09; 2. 开放寻址法&#xff08;…

HDMI数据传输三种使用场景

视频和音频的传输 在HDMI传输音频中有3种方式进行传输&#xff0c;第一种将音频和视频信号被嵌入到同一数据流中&#xff0c;通过一个TMDS&#xff08;Transition Minimized Differential Signaling&#xff09;通道传输。第二种ARC。第三张种eARC。这三种音频的传输在HDMI线中…

LCR 184.设计自助结算系统

1.题目要求: 2.题目代码: class Checkout { public:deque<int> array;Checkout() {array.clear();}//求最大值int get_max() {if(array.size() 0){return -1;}else{vector<int> temp(array.begin(),array.end());vector<int> :: iterator it max_element…

Vue3-小兔鲜项目出现问题及其解决方法(未写完)

基础操作 &#xff08;1&#xff09;使用create-vue搭建Vue3项目 要保证node -v 版本在16以上 &#xff08;2&#xff09;添加pinia到vue项目 npm init vuelatest npm i pinia //导入creatPiniaimport {createPinia} from pinia//执行方法得到实例const pinia createPinia()…

VUE:基于MVVN的前端js框架

文章目录 vue框架v-show vue框架 注意是 先写函数名&#xff0c;再写function。 handle:function (){}下面是错误的 function:handle(){}3 v-show 本质上等于号后面还是判断条件&#xff0c;所以不能写赋值语句&#xff0c;下面是正确的 下面是错误的 v-show " ge…

金融数据中心容灾“大咖说” | Veritas的“高举高打”之道

中国人民银行发布的《金融数据中心容灾建设指引》&#xff08;JR/T 0264—2024&#xff09;已于2024年7月29日正式实施。这一金融行业标准对金融数据中心容灾建设中的“组织保障、需求分析、体系规划、建设要求、运维管理”进行了规范和指导。面对不断增加的各类网络、业务、应…

VUE字符串转日期加天数

文章为本新手菜鸡的问题记录&#xff0c;如有错误和不足还行大佬指正 文章目录 问题描述解决方法 问题描述 得到一串字符串的日期&#xff0c;因为不是规范的日期格式&#xff0c;无法使用moment().add()方法&#xff0c;那么如何实现增加天数的操作&#xff1f; 解决方法 1…

高校企业数据挖掘平台推荐

TipDM数据挖掘建模平台是由广东泰迪智能科技股份有限公司自主研发打造的可视化、一站式、高性能的数据挖掘与人工智能建模服务平台&#xff0c;致力于为使用者打通从数据接入、数据预处理、模型开发训练、模型评估比较、模型应用部署到模型任务调度的全链路。平台内置丰富的机器…

《TCP/IP网络编程》学习笔记 | Chapter 14:多播与广播

《TCP/IP网络编程》学习笔记 | Chapter 14&#xff1a;多播与广播 《TCP/IP网络编程》学习笔记 | Chapter 14&#xff1a;多播与广播多播多播的数据传输方式和特点路由&#xff08;Routing&#xff09;和 TTL&#xff08;Time to Live&#xff0c;生存时间&#xff09;&#xf…

利用 TensorFlow Profiler:在 AMD GPU 上优化 TensorFlow 模型

TensorFlow Profiler in practice: Optimizing TensorFlow models on AMD GPUs — ROCm Blogs 简介 TensorFlow Profiler 是一组旨在衡量 TensorFlow 模型执行期间资源利用率和性能的工具。它提供了关于模型如何与硬件资源交互的深入见解&#xff0c;包括执行时间和内存使用情…