使用FFMPEG3.4.2版本进行视频的解码为YUV格式
最近关注的流媒体方向技术,FFMPEG学习是绕不过去的,不过网上关于FFMPEG的应用基本是基于2015年左右的版本,最新的FFMPEG视频解码部分变动还是挺大的,特此记录一下解码过程:
首先当然是FFMPEG的解码器等的初始化:
// 一定要先调用该注册FFMPEG,否则下面的都无法使用
av_register_all();
// 调用该初始化函数才能读取RTSP/RTMP等网络流的协议数据,否则干瞪眼,只解码本地文件的可以无视
avformat_network_init();
初始化完后需要申请一个AVFormatContext对象 *pFormatCtx = avformat_alloc_context();用于解码的上下文,有点FFMPEG基础的都明白这是老套路了。
然后呢还是老套路,调用以下两个函数:
// decodeUrl即为你要进行解码的链接,可以是本地文件路径,也可以是RTSP/RTMP等网络视频流的URL路径
avformat_open_input(&pFormatCtx, decodeUrl, NULL, NULL);
avformat_find_stream_info(pFormatCtx, NULL);
然后就在pFormatCtx->nb_streams找对应的解码类型为视频格式的解码器,这里跟老版本是有点不一样的,codecpar是新推荐的成员变量:
videoindex = -1;
for (uint32_t i = 0; i < pFormatCtx->nb_streams; i++)
{
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoindex = i;
break;
}
}
接下来还是有点区别的,不过一般人还是可以靠自己解决的
AVCodec *pCodec = avcodec_find_decoder(pFormatCtx->streams[videoindex]->codecpar->codec_id);
if (pCodec == NULL)
{
return -1;
}
AVCodecContext *pCodecCtx = avcodec_alloc_context3(pCodec);
获取视频解码器并创建解码器上下文,很好理解,套路一样就是细节改了改;
下面就开始打开解码器了,这个没变:
avcodec_open2(pCodecCtx, pCodec, NULL);
然后创建视频帧及YUV帧对象跟数据包对象
AVFrame *pFrame = av_frame_alloc();
AVFrame *pFrameYUV = av_frame_alloc();
AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket));
接下来就是循环读取数据并解码了
while (av_read_frame(pFormatCtx, packet) >= 0)
{if (packet->stream_index == videoindex)
{
// 视频帧进行解码,注意这里很不一样了,之前一个函数调用即可,现在需要自己再次写一个解码函数,具体看下面函数实现ret = Decode(pCodecCtx, pFrame, packet);if (ret < 0){printf("Decode Error.\n");av_packet_unref(packet);continue;}// 这里即为解码出来的数据进行YUV转换存储y_size = pCodecCtx->width*pCodecCtx->height;fwrite(pFrame->data[0], 1, y_size, fp_yuv); //Y fwrite(pFrame->data[1], 1, y_size / 4, fp_yuv); //Ufwrite(pFrame->data[2], 1, y_size / 4, fp_yuv); //Vprintf("Write one frame...\n");}
// 用完了别忘了释放packetav_packet_unref(packet);
}
上面的没啥好说的,主要是Decode函数的实现不一样了,改动挺大的,下面贴出实现代码
int Decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt)
{int ret;// 先发送包数据到解码上下文中ret = avcodec_send_packet(dec_ctx, pkt);if (ret < 0){printf("Error sending a packet for decoding\n");return ret;}// 然后从解码上下文中读取帧数据到frame对象中return avcodec_receive_frame(dec_ctx, frame);
}
不知道官方基于何种意愿做此修改的,个人觉着麻烦多了,因为我要多写不少代码。。。
至此解码工作基本完成,当然用完了资源别忘了还给人家:
av_frame_free(&pFrameYUV);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
然后测试了下本地视频文件的解码,测试OK,做完后觉着很不错嘛,然而,然而真的那么如你所愿么?显然不是的。。。
在我一时兴起测试RTSP流的时候发现FFMPEG会报错,无法获取,提示什么FFMPEG编译没有添加-lpthread之类的选项,这是什么鬼?懵逼了,因为我是从官方下载的动态链接库,这是你会发现还是GG好使的。。。话不多说,贴解决办法:
在avformat_open_input函数调用中最后一个options参数进行设置RTSP传输基于TCP即可。。。
AVDictionary* options = NULL;
av_dict_set(&options, "rtsp_transport", "tcp", 0);
avformat_open_input(&pFormatCtx, c_TestFile, NULL, &options);
是的,这么设置过后就可以解码RTSP流数据了,知道了后是不是很简单,当然用完了资源记得一定要还:
av_dict_free(&options);
好的,想到的就这么多了。。。
使用FFMPEG3.4.2版本进行视频的解码为YUV格式相关推荐
- FFmpeg4入门07:解码视频并保存为YUV格式文件
上一篇我们解码并保存了其中的几帧确保解码过程和结果是对的.本篇我们将解码整个视频并保存为标准的YUV格式(YUV格式具体信息详见YUV格式介绍),我们就选YUV420P(I420)作为输出格式. 保存 ...
- 视频与图像RGB/YUV格式详解
计算机彩色显示器显示色彩的原理与彩色电视机一样,都是采用R(Red).G(Green).B(Blue)相加混色的原理:通过发射出三种不同强度的电子束,使屏幕内侧覆盖的红.绿.蓝磷光材料发光而产生色彩. ...
- H.264/AVC视频编解码技术详解 第一章 视频信息与压缩编码
H.264/AVC视频编解码技术详解系列笔记 是对 H.264/AVC视频编解码技术详解 课程的学习 文章目录 人与世界的交互 视频信号的表示方法 视频压缩编码 视频信息为什么可以被压缩? 视频压缩编 ...
- 深入浅出理解视频编解码技术
导读:随着移动互联网技术的蓬勃发展,视频已无处不在.视频直播.视频点播.短视频.视频聊天,已经完全融入了每个人的生活.Cisco 发布的最新报告中写道,到 2022 年,在移动互联网流量中,视频数据占 ...
- 音视频-视频编/解码 实战
先来简单看下 音视频的采集 . 一.音视频的采集 音视频采集的核心流程: 音/视频采集 用到的视频输出的类是AVCaptureVideoDataOutput,音频输出的类是AVCaptureAudio ...
- ffmpeg音视频编解码的封装
//导入头文件 //核心库 #include "libavcodec/avcodec.h" //封装格式处理库 #include "libavformat/avforma ...
- FFMPEG总结 -- 音视频编解码和转码(全)
在经过一周的学习后,现将其稍加总结下:附代码及详细注释. 简单分为如下六个部分 一.播放一个视频文件的流程 二.ffmpeg 视频编码 (YUV编码为H.264) 三.ffmpeg 视频解码 (解码为 ...
- 使用FFMPEG——4.2.2版本实现提取视频编码解码文件,ffmpeg基础学习。
FFMPEG基础学习 视频解码,并且输出到文件. 我通过雷霄骅的博客学习FFMPEG,在学习过程中发现"雷神"的代码由于版本的问题,很多代码已经无法在FFMPEG--4.2.2版本 ...
- 音视频从入门到精通——ffmpeg3之打印多媒体文件音视频信息
ffmpeg3之打印多媒体文件音视频信息 av_dump_format函数 /*** Print detailed information about the input or output form ...
- MediaCodec在Android视频硬解码组件的应用
https://yq.aliyun.com/articles/632892 云栖社区> 博客列表> 正文 MediaCodec在Android视频硬解码组件的应用 cheenc 2018- ...
最新文章
- 有漏洞无作为才可怕、可耻!
- 动态代理之: com.sun.proxy.$Proxy0 cannot be cast to 问题
- CISCO 路由器(1)
- SCCM 2012系列13 操作系统播发②
- react学习笔记10:显示隐藏效果和tab切换效果
- 解决idea使用maven打自定义jar缺失
- 在linux内核中修改TCP MSS值
- Taro使用wxParse富文本组件
- UnionID与OpenID的区别【转自微信官方文档】
- 模拟退火算法求解超市布局问题
- 【数字IC】深入浅出理解UART协议
- iOS学习爬坑记录4:ios8中的搜索栏,使用UISearchController
- Squid缓存代理服务器
- unity中导入的角色没有Avatar
- C/C++ 机房预约系统
- 计算机用户域怎么删除,如何删除域内非活动计算机账号?
- 【Unity3D-Mirror多人坦克大战】坦克生成、移动和摄像机跟随(二)
- 大学生PHP简单网站制作方法 学生PHP网站作业 动态PHP毕业设计 PHP MYSQL在线留言板网站源码
- 设计模式之原型模式(C语言)
- 大唐天下平台模式开发
热门文章
- 大学计算机基础及应用课后题答案第二版,《大学计算机基础》课后题答案完整版...
- Swift之Attempting to badge the application icon but haven't received permission from the user to badg
- uniapp引入腾讯防水墙
- 卷积神经网络与机器视觉,卷积神经网络图像分类
- 卡内基梅隆大学计算机专业有哪些,卡内基梅隆大学计算机系统类大学排名最新资讯总结篇...
- Mybatis报错 :Error evaluating expression ‘condition.xxxx!= null ‘
- VISTA、Win7激活administrator用户
- DNA甲基化经CTCF和黏连蛋白复合体调节RNA可变剪切
- Matlab 网络通信(TCP IP)
- Microsoft buildup new website for open-source project