FFMpeg笔记(二) 使用FFmpeg对视频进行编解码的一般流程
1. 编码:
1.对编码资源的初始化
AVCodec* m_pVideoEncoder;// 特定编码器的参数信息
AVCodecContext* m_pVideoEncoderContext;// 设置的编码参数信息
AVFrame* m_YUV_Frame;// RGB转换为YUV数据帧以减少传输数据量,减少网络带宽占用
AVFrame* m_RGB_Frame;// 获取到的数据帧
SwsContext* m_pSwsc;// 保存由YUV转换为RGB的转换参数的结构体
// 根据给定的编码器ID找到注册过的编码器
m_pVideoEncoder = avcodec_find_encoder(AV_CODEC_ID_H264);
if (!m_pVideoEncoder)
{
assert();
return false;
}
// 申请一个AVCodecContext结构体,注意使用avcodec_free_context()函数释放
m_pVideoEncoderContext = avcodec_alloc_context3(m_pVideoEncoder);
if(!m_pVideoEncoderContext)
{
assert();
return false;
} // 对m_pVideoEncoderContext设置一些参数
m_pVideoEncoderContext->width = frameWidth;
m_pVideoEncoderContext->height = frameHeight;
// ......
// 初始化AVCodecContext
int err = avcodec_open2(m_pVideoEncoderContext, m_pVideoEncoder,NULL);
if ( err < )
{
assert();
char errorStr[];
av_strerror(err,errorStr,); return false;
}
// 申请AVFrame
m_YUV_Frame = av_frame_alloc();
// 获取保留图像拉伸参数的结构体
m_pSwsc = sws_getContext(frameWidth,frameHeight,g_Format,frameWidth,frameHeight,AV_PIX_FMT_YUV420P,SWS_ALGORITHM,NULL,NULL,NULL);
if (!m_pSwsc)
{
assert();
return false;
}
m_RGB_Frame = av_frame_alloc();
2.编码
// 将原始数据(RGB格式的)填充到一个RGB的AVFrame中
avpicture_fill((AVPicture*)m_RGB_Frame, (uint8_t*)rawVideo, g_Format, m_nLastFrameWidth, m_nLastFrameHeight);
// 将RGB格式的AVFrame转换为YUV格式,以降低传输数据的总量
sws_scale(m_pSwsc,m_RGB_Frame->data,m_RGB_Frame->linesize,,m_pVideoEncoderContext->height,m_YUV_Frame->data,m_YUV_Frame->linesize); AVPacket packet;
av_init_packet(&packet);
int bOutPacketNonEmpty = 0;
int nRet = avcodec_encode_video2(m_pVideoEncoderContext, &packet, m_YUV_Frame, &bOutPacketNonEmpty);
if(nRet < )
{ return false; }
// 将AVPacket传输
// ......
2. 解码:
1.对解码资源的初始化
AVCodec* m_pVideoDecoder;
AVCodecContext* m_pVideoDecoderContext; AVPacket m_recvPacket;
AVFrame* m_pYUVFrame; SwsContext* m_pSwsc;// 保存由YUV转换为RGB的转换参数的结构体
AVFrame* m_pRGBFrame;// 用于显示
// 根据数据包的编码格式,找到对应的解码器
m_pVideoDecoder = avcodec_find_decoder((AVCodecID)codecid);
if (!m_pVideoDecoder)
{
fprintf(stderr, "Codec not found\n");
return false;
} m_pVideoDecoderContext = avcodec_alloc_context3(m_pVideoDecoder);
int ret = avcodec_open2( m_pVideoDecoderContext, m_pVideoDecoder, NULL);
if(ret < )
{
return false;
}
2.解码
av_init_packet(&m_recvPacket);
m_recvPacket.size = videoPacket.length;
m_recvPacket.data = videoPacket.pData; int got_frame = ;
while (m_recvPacket.size)
{
int len = avcodec_decode_video2(m_pVideoDecoderContext, m_pYUVFrame, &got_frame, &m_recvPacket);
if (len < )
{
return false;
}
if (m_recvPacket.data)
{
m_recvPacket.size -= len;
m_recvPacket.data += len;
}
} if(got_frame == )
{
return false;
}
// 将m_pYUVFrame转换为RGBFrame用于显示
// ......
FFMpeg笔记(二) 使用FFmpeg对视频进行编解码的一般流程的更多相关文章
- iOS8系统H264视频硬件编解码说明
公司项目原因,接触了一下视频流H264的编解码知识,之前项目使用的是FFMpeg多媒体库,利用CPU做视频的编码和解码,俗称为软编软解.该方法比较通用,但是占用CPU资源,编解码效率不高.一般系统都会 ...
- 转:关于视频H264编解码的应用实现
转:http://blog.csdn.net/scalerzhangjie/article/details/8273410 项目要用到视频编解码,最近半个月都在搞,说实话真是走了很多弯路,浪费了很多时 ...
- ffmpeg编解码视频导致噪声增大的一种解决方法
一.前言 ffmpeg在视音频编解码领域算是一个比较成熟的解决方案了.公司的一款视频编辑软件正是基于ffmpeg做了二次封装,并在此基础上进行音视频的编解码处理.然而,在观察编码后的视频质量时,发现图 ...
- 【视频编解码·学习笔记】8. 熵编码算法:基本算法列举 & 指数哥伦布编码
一.H.264中的熵编码基本方法: 熵编码具有消除数据之间统计冗余的功能,在编码端作为最后一道工序,将语法元素写入输出码流 熵解码作为解码过程的第一步,将码流解析出语法元素供后续步骤重建图像使用 在H ...
- 音视频编解码技术(一):MPEG-4/H.264 AVC 编解码标准
一.H264 概述 H.264,通常也被称之为H.264/AVC(或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC) 1. H.264视频编解码的意义 H.264的出现就是为了创 ...
- Android 音视频深入 二十一 FFmpeg视频剪切
视频剪切我意外的发现上一次的视频压缩的代码能够运行FFmpeg视频剪切的命令,但是不能做视频合并的命令,因为不能读取记录了几个视频的路径的txt文件. 这里我就说直说视频剪切的过程,不说代码,只说lo ...
- Android 音视频深入 二十 FFmpeg视频压缩(附源码下载)
项目源码https://github.com/979451341/FFmpegCompress 这个视频压缩是通过类似在mac终端上输入FFmpeg命令来完成,意思是我们需要在Android上达到能够 ...
- 视频专家之路【二】:ffmpeg工具的使用
本文是听了雷宵骅大神的课之后的总结,部分内容借用了其PPT的内容,如有侵权请告知删除. 雷宵骅大神的博客为:https://blog.csdn.net/leixiaohua1020 要学习汽修,那么首 ...
- 【FFMPEG】各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式
目录(?)[-] 编解码学习笔记二codec类型 编解码学习笔记三Mpeg系列Mpeg 1和Mpeg 2 编解码学习笔记四Mpeg系列Mpeg 4 编解码学习笔记五Mpeg系列AAC音频 编解码学习笔 ...
随机推荐
- redux、immutablejs和mobx性能对比(一)
一.前言 关于react的性能优化,有很多方面可以去做,而其中避免重复渲染又是比较重要的一点,那么为什么react会重复渲染,我们又该如何避免重复渲染呢,关于这方面官方其实早有说明:避免重复渲染,这里 ...
- HBuilder开发App Step1——环境搭建,HelloMUI 以及真机调试
No1. 必须搭建java环境 只需要最基础的java环境,也就是cmd下可以运行java和javac即可, 具体教程请自行百度,都会有很详细的教程,这里不重点介绍. No2. 下载安装HBuilde ...
- 利用GDAL从内存中直接解析图像数据
对于网络数据源,调度中可以把数据写入本地,然后读取本地数据格式进行影像的解析(地形有时候也用tif等格式). 此种方式会每次调度进行不必要的IO开销和时间花费. GDAL提供了相应的接口,直接从内存中 ...
- vip会员统计表 (vip等级是灵活配置的 非写死1是金卡用户 2是什么 等)
一个非常常见的报表,分析会员组成比例 以及最新增长情况 和上月同期会员增长情况. 比较特殊一点的是 报表中的 普通会员 和 金卡会员 临时会员 银卡会员 等列 都是根据会员等级配置表动态生成的(即 ...
- 【Java】得到当前股票信息
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; ...
- leetCode题解 寻找运动环
1.题目描述 Initially, there is a Robot at position (0, 0). Given a sequence of its moves, judge if this ...
- leveldb开篇
因为工作的需求,最近看了一些项目的源码,包括nginx.tair.leveldb,一直看了下来都没有写东西的习惯,虽然作了不少记录,但都是只有自己才能看懂的笔记. 好多次都说开始写blog,锻炼一下自 ...
- Semaphore-信号灯机制
我们创建一个可扩展大小的线程池,并且需要在线程池内同时让有限数目的线程并发运行时,就需要用到Semaphore(信号灯机制),Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目 ...
- Loadrunner11代理录制&各个常见功能介绍
1.代理录制: Lr代理工具:C:\Program Files (x86)\HP\LoadRunner\bin\wplus_init_wsock.exe 1) 设置代理 配置代理信息: 2)设置浏览器 ...
- PHP防SQL注入和XSS攻击
摘要: 就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.在用户名输入框中输入:' or 1=1#,密码随便输入,这时候的合成后的SQL ...