ffmpeg解码提取帧RGB格式信息

简介: 使用ffmpeg和qt实现播放视频功能

一.ffmpeg主要结构体

1.结构体

1.AVFormatContext

封装格式上下文结构体,也是统领全局的结构体,保存了视频文件封装格式相关信息

通过avformat_alloc_context()函数分配空间,并初始化默认参数


参数:

nb_streams代表封装格式里流有几个

streams[]代表第几个流,其中codec参数代表编解码器对应的上下文对象结构体,codec中codec_type代表类型:AVMEDIA_TYPE_VIDEO为视频类型,AVMEDIA_TYPE_AUDIO为音频类型


2.AVInputFormat/AVOutpufFormat

封装格式,保存了视频文件封装格式相关信息

3.AVStream

视频文件中流

4.AVCodecContext

编码器上下文,保存了编解码相关信息

5.AVCodec

每种编解码器

6.AVPacket

存储一帧压缩编码数据

7.AVFrame

存储一帧解码后像素数据

2.函数

二.ffmpeg解码提取帧RGB格式信息

1.打开视频文件  avformat_open_input()

AVFormatContext*封装格式上下文结构体;//用来保存视频相关信息的结构体,指针别忘记封装格式上下文结构体=avformat_alloc_context();//分配空间intres=avformat_open_input(&forContent,
文件路径+文件名称,nullptr,nullptr);
if(res!=0)//判断是否打开视频文件return;    

2.获取视频信息 如视频码流、音频码流等

//打开视频文件成功,获取文件信息res=avformat_find_stream_info(封装格式上下文结构体,nullptr);
//查看有没有相关视频流信息if(res<0)
return;

3.查找流信息  avformat_find_stream_info()

//一个视频流有多股码流,存在封装格式上下文结构体中streams数组中int第几路流(为视频流的那路流)=-1;
//nb_streams代表封装格式里面的结构体信息有几个,正常两个:音频信息、视频信息for(inti=0;i<封装格式上下文结构体->nb_streams;i++) //i小于流的个数{
if(封装格式上下文结构体->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)//视频流    {
第几路流(为视频流的那路流)=i;//标识类型break;
     }
}
//判断是否有视频流信息if(第几路流(为视频流的那路流)==-1)
return;

4.找到解码器  avcodec_find_decoder()

//编解码器对应的上下文对象结构体:保存解码器信息以及图形的宽高、像素信息AVCodecContext*编解码器对应的上下文对象=封装格式上下文结构体->streams[videoType]->codec;
//查找对应的视频流解码器AVCodec*具体编解码器=avcodec_find_decoder(编解码器对应的上下文对象->codec_id);
if(decoder==nullptr)//判断是否找到解码器return;

5.打开解码器 avcodec_open2()

//找到了解码器,打开解码器res=avcodec_open2(编解码器对应的上下文对象,具体编解码器,nullptr);
if(res!=0)
return;

6.读取码流中的一帧码流数据  av_read_frame()

//AVPacket 用来存储一帧一帧的压缩数据AVPacket*pkt=nullptr;
//设置缓冲区,开空间pkt=(AVPacket*) malloc(sizeof(AVPacket));
intsize=codec->width*codec->height;//计算一张图片数据大小av_new_packet(pkt,size);
/* pictureRGB 保存解码后的RGB像素数据* picture    保存未处理的像素数据*/AVFrame*RGB,*picture=nullptr;
//内存分配RGB=av_frame_alloc();
picture=av_frame_alloc();
//大小以及格式设置RGBRGB->width=codec->width;//宽度RGB->height=codec->height;//高度RGB->format=codec->pix_fmt;//格式设置//一帧码流数据解码后得到RGB像素数据有多大intnumByte_RGB=avpicture_get_size(AV_PIX_FMT_RGB32,编解码器对应的上下文对象->width,编解码器对应的上下文对象->height);
//开的空间用来保存RGB像素数据大小uint8_t*buffer_RGB=(uint8_t*)av_malloc(numByte_RGB*sizeof(uint8_t));
//像素数据的填充avpicture_fill((AVPicture*)RGB,buffer_RGB,AV_PIX_FMT_RGB32,编解码器对应的上下文对象->width,
编解码器对应的上下文对象->height);
//转换规则SwsContext*sws_RGB=nullptr;//保存转换规则的结构体//转换规则的设置AV_PIX_FMT_RGB32sws_RGB=sws_getContext(编解码器对应的上下文对象->width,编解码器对应的上下文对象->height,编解码器对应的上下文对象->pix_fmt,
编解码器对应的上下文对象->width,编解码器对应的上下文对象->height,AV_PIX_FMT_RGB32,  //目标格式SWS_BICUBIC,nullptr,nullptr,nullptr);         //转换规则

7.解码读到一帧码流数据 得到一帧的像素数据  

8.重复6,7两个步骤直到视频所有的帧都处理完

//一帧一帧的读取压缩数据while(av_read_frame(封装格式上下文结构体,pkt)==0)//读到数据{
if(pkt->stream_index==第几路流(为视频流的那路流))//判断一帧码流数据是不是需要得到的视频流    {
intptr=-1;
//解码res=avcodec_decode_video2(封装格式上下文结构体,picture,&ptr,pkt);
if(res<0)
return;
//压缩码流数据,解码后的像素数据,判断有没有数据可以解码,对谁进行解码if(ptr!=0)//解码操作         {
//把解码得到的坏数据剔除sws_scale(sws_RGB,picture->data,picture->linesize,0/*像素内存的偏移位*/,picture->height,
RGB->data,RGB->linesize);//RGBQImageimage((uchar*)RGB->data[0],RGB->width,RGB->height,QImage::Format_RGB32);//像素数据         }
        }
//释放包以及AVFrame资源av_packet_unref(pkt);
 }

9.关闭解码器

10.关闭视频文件


//释放AVFrameav_frame_free(&picture);
//关闭解码器avcodec_close(编解码器对应的上下文对象);
//释放视频信息结构体avformat_free_context(forContent)
sws_freeContext(sws_RGB); // 释放一个SwsContextav_frame_free(&RGB);
相关文章
|
2月前
|
缓存 监控 计算机视觉
视频监控笔记(三):opencv结合ffmpeg获取rtsp摄像头相关信息
本文介绍了如何使用OpenCV结合FFmpeg获取RTSP摄像头信息,包括网络架构、视频监控系统组成、以及如何读取和显示网络摄像头视频流。
73 1
|
2月前
FFmpeg学习笔记(二):多线程rtsp推流和ffplay拉流操作,并储存为多路avi格式的视频
这篇博客主要介绍了如何使用FFmpeg进行多线程RTSP推流和ffplay拉流操作,以及如何将视频流保存为多路AVI格式的视频文件。
347 0
|
5月前
|
数据采集 大数据 Python
FFmpeg 在爬虫中的应用案例:流数据解码详解
在大数据背景下,网络爬虫与FFmpeg结合,高效采集小红书短视频。需准备FFmpeg、Python及库如Requests和BeautifulSoup。通过设置User-Agent、Cookie及代理IP增强隐蔽性,解析HTML提取视频链接,利用FFmpeg下载并解码视频流。示例代码展示完整流程,强调代理IP对避免封禁的关键作用,助你掌握视频数据采集技巧。
FFmpeg 在爬虫中的应用案例:流数据解码详解
|
5月前
|
语音技术 C语言 Windows
语音识别------ffmpeg的使用01,ffmpeg的安装,会做PPT很好,ffmpeg不具备直接使用,只可以操作解码数据,ffmpeg用C语言写的,得学C语言,ffmpeg的安装
语音识别------ffmpeg的使用01,ffmpeg的安装,会做PPT很好,ffmpeg不具备直接使用,只可以操作解码数据,ffmpeg用C语言写的,得学C语言,ffmpeg的安装
|
6月前
|
Linux 编解码 Python
FFmpeg开发笔记(二十四)Linux环境给FFmpeg集成AV1的编解码器
AV1是一种高效免费的视频编码标准,由AOM联盟制定,相比H.265压缩率提升约27%。各大流媒体平台倾向使用AV1。本文介绍了如何在Linux环境下为FFmpeg集成AV1编解码库libaom、libdav1d和libsvtav1。涉及下载源码、配置、编译和安装步骤,包括设置环境变量以启用这三个库。
309 3
FFmpeg开发笔记(二十四)Linux环境给FFmpeg集成AV1的编解码器
|
6月前
|
编解码 Linux 计算机视觉
python 调用ffmpeg使用usb摄像头录制视频,输出h264格式,自动获取摄像头的最佳帧率和最大画面尺寸
使用 Python 调用 FFmpeg 进行 USB 摄像头视频录制,需先确保安装 FFmpeg 和 Python 的 `subprocess` 模块。代码示例展示了如何自动获取摄像头的最佳帧率和最大分辨率,然后录制视频。首先通过 FFmpeg 列出摄像头格式获取信息,解析出帧率和分辨率,选择最优值。之后调用 FFmpeg 命令录制视频,设置帧率、分辨率等参数。注意 `/dev/video0` 是 Linux 的摄像头设备路径,Windows 系统需相应调整。代码中未直接实现自动获取最佳参数,通常需要借助其他库如 OpenCV。
|
7月前
|
编解码 5G Linux
FFmpeg开发笔记(二十一)Windows环境给FFmpeg集成AVS3解码器
AVS3是中国首个8K及5G视频编码标准,相比AVS2和HEVC性能提升约30%。解码器libuavs3d支持8K/60P视频实时解码,兼容多种平台。《FFmpeg开发实战》书中介绍了在Windows环境下如何集成libuavs3d到FFmpeg。集成步骤包括下载源码、使用Visual Studio 2022编译、调整配置、安装库文件和头文件,以及重新配置和编译FFmpeg以启用libuavs3d。
123 0
FFmpeg开发笔记(二十一)Windows环境给FFmpeg集成AVS3解码器
|
7月前
|
编解码 Linux 5G
FFmpeg开发笔记(二十)Linux环境给FFmpeg集成AVS3解码器
AVS3,中国制定的第三代音视频标准,是首个针对8K和5G的视频编码标准,相比AVS2和HEVC性能提升约30%。uavs3d是AVS3的解码器,支持8K/60P实时解码,且在各平台有优秀表现。要为FFmpeg集成AVS3解码器libuavs3d,需从GitHub下载最新源码,解压后配置、编译和安装。之后,重新配置FFmpeg,启用libuavs3d并编译安装,通过`ffmpeg -version`确认成功集成。
141 0
FFmpeg开发笔记(二十)Linux环境给FFmpeg集成AVS3解码器
|
7月前
|
存储 缓存 调度
FFmpeg开发笔记(十九)FFmpeg开启两个线程分别解码音视频
《FFmpeg开发实战》第10章示例playsync.c在处理音频流和视频流交错的文件时能实现同步播放,但对于分开存储的格式,会出现先播放全部声音再快速播放视频的问题。为解决此问题,需改造程序,增加音频处理线程和队列,以及相关锁,先将音视频帧读入缓存,再按时间戳播放。改造包括声明新变量、初始化线程和锁、修改数据包处理方式等。代码修改后在playsync2.c中,编译运行成功,控制台显示日志,SDL窗口播放视频并同步音频,证明改造有效。
135 0
FFmpeg开发笔记(十九)FFmpeg开启两个线程分别解码音视频
|
2月前
|
Linux 开发工具 Android开发
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
ijkplayer是由Bilibili基于FFmpeg3.4研发并开源的播放器,适用于Android和iOS,支持本地视频及网络流媒体播放。本文详细介绍如何在新版Android Studio中导入并使用ijkplayer库,包括Gradle版本及配置更新、导入编译好的so文件以及添加直播链接播放代码等步骤,帮助开发者顺利进行App调试与开发。更多FFmpeg开发知识可参考《FFmpeg开发实战:从零基础到短视频上线》。
213 2
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频