没有合适的资源?快使用搜索试试~ 我知道了~
ffmpeg tutorial中文翻译
5星 · 超过95%的资源 需积分: 11 59 下载量 126 浏览量
2009-05-11
14:41:37
上传
评论 1
收藏 369KB PDF 举报
温馨提示
试读
78页
ffmpeg tutorial中文翻译 ,需要的可以看看,我是从网上找的自己做的pdf
资源推荐
资源详情
资源评论
指导 1:制作屏幕录像
概要
电影文件有很多基本的组成部分。首先,文件本身被称为容器 Container,容器
的类型决定了信息被存放在文件中的位置。AVI 和 Quicktime 就是容器的例子。
接着,你有一组流,例如,你经常有的是一个音频流和一个视频流。(一个流只
是一种想像出来的词语,用来表示一连串的通过时间来串连的数据元素)。在流
中的数据元素被称为帧 Frame。 每个流是由不同的编码器来编码生成的。编解
码器描述了实际的数据是如何被编码 Coded 和解码 DECoded 的,因此它的名字叫
做 CODEC。Divx 和 MP3 就是编解码器的例子。接着从流中被读出来的叫做包
Packets。包是一段数据,它包含了一段可以被解码成方便我们最后在应用程序
中操作的原始帧的 数据。根据我们的目的,每个包包含了完整的帧或者对于音
频来说是许多格式的完整帧。
基本上来说,处理视频和音频流是很容易的:
10 从 video.avi 文件中打开视频流 video_stream
20 从视频流中读取包到帧中
30 如果这个帧还不完整,跳到 20
40 对这个帧进行一些操作
50 跳回到 20
在这个程序中使用 ffmpeg 来处理多种媒体是相当容易的,虽然很多程序可能在
对帧进行操作的时候非常的复杂。因此在这篇指导中,我们将打开一个文件,读
取里面的视频流,而且我们对帧的操作将是把这个帧写到一个 PPM 文件中。
打开文件
首先,来看一下我们如何打开一个文件。通过 ffmpeg,你必需先初始化这个库。
(注意在某些系统中必需用<ffmpeg/avcodec.h>和<ffmpeg/avformat.h>来替
换)
#include <avcodec.h>
#include <avformat.h>
...
int main(int argc, charg *argv[]) {
av_register_all();
这里注册了所有的文件格式和编解码器的库,所以它们将被自动的使用在被打开
的合适格式的文件上。注意你只需要调用 av_register_all()一 次,因此我们
在主函数 main()中来调用它。如果你喜欢,也可以只注册特定的格式和编解码
器,但是通常你没有必要这样做。
现在我们可以真正的打开文件:
AVFormatContext *pFormatCtx;
// Open video file
if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0)
return -1; // Couldn't open file
我们通过第一个参数来获得文件名。这个函数读取文件的头部并且把信息保存到
我们给的 AVFormatContext 结构体中。最后三个参数用来指定特殊的文件格式,
缓冲大小和格式参数,但如果把它们设置为空 NULL 或者 0,libavformat 将自动
检测这些参数。
这个函数只是检测了文件的头部,所以接着我们需要检查在文件中的流的信息:
// Retrieve stream information
if(av_find_stream_info(pFormatCtx)<0)
return -1; // Couldn't find stream information
这个函数为 pFormatCtx->streams 填充上正确的信息。我们引进一个手工调试的
函数来看一下里面有什么:
// Dump information about file onto standard error
dump_format(pFormatCtx, 0, argv[1], 0);
现在 pFormatCtx->streams 仅仅是一组大小为 pFormatCtx->nb_streams 的指针,
所以让我们先跳过它直到我们找到一个视频流。
int i;
AVCodecContext *pCodecCtx;
// Find the first video stream
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {
videoStream=i;
break;
}
if(videoStream==-1)
return -1; // Didn't find a video stream
// Get a pointer to the codec context for the video stream
pCodecCtx=pFormatCtx->streams[videoStream]->codec;
流中关于编解码器的信息就是被我们叫做"codec context"(编解码器上下文)
的东西。这里面包含了流中所使用的关于编解码器的所有信息,现在我们有了一
个指向他的指针。但是我们必需要找到真正的编解码器并且打开它:
AVCodec *pCodec;
// Find the decoder for the video stream
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL) {
fprintf(stderr, "Unsupported codec!\n");
return -1; // Codec not found
}
// Open codec
if(avcodec_open(pCodecCtx, pCodec)<0)
return -1; // Could not open codec
有些人可能会从旧的指导中记得有两个关于这些代码其它部分:添加
CODEC_FLAG_TRUNCATED 到 pCodecCtx->flags 和添 加一个 hack 来粗糙的修正帧
率。这两个修正已经不在存在于 ffplay.c 中。因此,我必需假设它们不再必要。
我们移除了那些代码后还有一个需要指出的 不同点:pCodecCtx->time_base 现
在已经保存了帧率的信息。time_base 是一个结构体,它里面有一个分子和分母
(AVRational)。我们使用分数的方式来表示帧率是因为很多编解码器使用非整数
的帧率(例如 NTSC 使用 29.97fps)。
保存数据
现在我们需要找到一个地方来保存帧:
AVFrame *pFrame;
// Allocate video frame
pFrame=avcodec_alloc_frame();
因为我们准备输出保存 24 位 RGB 色的 PPM 文件,我们必需把帧的格式从原来的
转换为 RGB。FFMPEG 将为我们做这些转换。在大多数项目中(包括我们的这个)
我们都想把原始的帧转换成一个特定的格式。让我们先为转换来申请一帧的内
存。
// Allocate an AVFrame structure
pFrameRGB=avcodec_alloc_frame();
if(pFrameRGB==NULL)
return -1;
即使我们申请了一帧的内存,当转换的时候,我们仍然需要一个地方来放置原始
的数据。我们使用 avpicture_get_size 来获得我们需要的大小,然后手工申请
内存空间:
uint8_t *buffer;
int numBytes;
// Determine required buffer size and allocate buffer
numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
pCodecCtx->height);
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
av_malloc 是 ffmpeg 的 malloc,用来实现一个简单的 malloc 的包装,这样来保
证内存地址是对齐的(4 字节对齐或者 2 字节对齐)。它并不能保护你不被内存
泄漏,重复释放或者其它 malloc 的问题所困扰。
现在我们使用 avpicture_fill 来把帧和我们新申请的内存来结合。关于
AVPicture 的结成:AVPicture 结构体是 AVFrame 结构体的子集――AVFrame 结
构体的开始部分与 AVPicture 结构体是一样的。
// Assign appropriate parts of buffer to image planes in pFrameRGB
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
// of AVPicture
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
pCodecCtx->width, pCodecCtx->height);
最后,我们已经准备好来从流中读取数据了。
剩余77页未读,继续阅读
资源评论
- nataliu2013-01-22还是很不错的,帮了我很大忙
- heshimin2013-03-18感谢分享,有帮助
- 妙为2018-01-31值得学习,谢谢楼主分享,
wangyuv
- 粉丝: 0
- 资源: 10
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- AT32与Sxx32/Gx32替换对照表
- STM32VET6单片机+XC3S250E(FPGA)+AD9708 DDS信号发生器MCU+FPGA源码+PDF硬件设计原理图
- SCIPOptSuite-9.0.0-win64-VS15.exe
- GIS10.4补丁文件
- fdgsfdgfdsgsf
- 基于CodeMirror5实现的mybatis+sql提示扩展功能,主要是用于在线设计开发场景中的动态sql部分.zip
- 计算机毕业设计-aSP.NET某中学学生成绩管理系统的设计(源代码+)-毕设源码实例.zip
- springboot集成mybatis动态sql.zip
- mybatis中的动态sql, 涉及 where trim set if foreach等
- 简单- 快递运输(Java & JS & Python & C).html
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功