FFMpeg的output_example.c例子分析

 

该例子讲了如何输出一个libavformat库所支持格式的媒体文件。 (1)av_register_all(),初始化libavcodec库,并注册所有的编解码器和格式。 (2)guess_format(),根据文件名来获取输出文件格式,默认为mpeg。 (3)av_alloc_format_context()分配输出媒体内容。   ov->oformat = fmt;   snprintf( oc->filename, sizeof(oc->filename), “%s”, filename ); (4)add_video_stream()使用默认格式的编解码器来增加一个视频流,并初始化编解码器。   (4.1)av_new_stream()增加一个新的流到一个媒体文件。   (4.2)初始化编解码器:     c = st->codec;     c->codec_id = codec_id;     c->codec_type = CODEC_TYPE_VIDEO;     c->bit_rate = 400000;     c->width = 352;     c->height = 288;     c->time_base.den = STREAM_FRAME_RATE; //每秒25副图像     c->time_base.num = 1;     c->gop_size = 12;     c->pix_fmt = STREAM_PIX_FMT; //默认格式为PIX_FMT_YUV420P     …… …… (5)av_set_parameters()设置输出参数,即使没有参数,该函数也必须被调用。 (6)dump_format()输出格式信息,用于调试。 (7)open_video()打开视频编解码器并分配必要的编码缓存。   (7.1)avcodec_find_encoder()寻找c->codec_id指定的视频编码器。   (7.2)avcodec_open()打开编码器。   (7.3)分配视频输出缓存:     video_outbuf_size = 200000;     video_outbuf = av_malloc( video_outbuf_size );   (7.4)picture = alloc_picture()分配原始图像。     (7.4.1)avcodec_alloc_frame()分配一个AVFrame并设置默认值。     (7.4.2)size = avpicture_get_size()计算对于给定的图片格式以及宽和高,所需占用多少内存。     (7.4.3)picture_buf = av_malloc( size )分配所需内存。     (7.4.4)avpicture_fill()填充AVPicture的域。   (7.5)可选。如果输出格式不是YUV420P,那么临时的YUV420P格式的图像也是需要的,由此再转换为我们所需的格式,因此需要为临时的YUV420P图像分配缓存:   tmp_picture = alloc_picture() 说明:tmp_picture,picture,video_outbuf。如果输出格式为YUV420P,则直接通过avcodec_ encode_video()函数将picture缓存中的原始图像编码保存到video_outbuf缓存中;如果输出格式不是YUV420P,则需要先通过sws_scale()函数,将YUV420P格式转换为目标格式,此时tmp_picture缓存存放的是YUV420P格式的图像,而picture缓存为转换为目标格式后保存的图像,进而再将picture缓存中的图像编码保存到video_outbuf缓存中。 (8)url_fopen()打开输出文件,如果需要的话。 (9)av_write_header()写流动头部。 (10)LOOP循环{     计算当前视频时间video_pts     是否超时退出循环?     write_video_frame()视频编码   }   (10.1)write_video_frame()     如果图片不是YUV420P,则需要用sws_scale()函数先进行格式转换。     若需要原始图像:       av_init_packet()初始化一个包的选项域。       av_write_frame()向输出媒体文件写一个包,该包会包含一个视频帧。     若需要编码图像:       avcodec_encode_video()编码一视频帧。       av_init_packet()       av_write_frame() (11)close_video()关闭每个编解码器。 (12)av_write_trailer()写流的尾部。 (13)释放资源   av_freep()释放AVFormatContext下的AVStream->AVCodecContext和AVStream:     for( i = 0; i < oc->nb_streams; i++ ){       av_freep( &oc->streams[i]->codec );       av_freep( &oc->streams[i] );     }   url_fclose()关闭输出文件。   av_free()释放AVFormatContext。 apiexample.c例子教我们如何去利用ffmpeg库中的api函数来自己编写编解码程序。 (1)首先,main函数中一开始会去调用avcodec_init()函数,该函数的作用是初始化libavcodec,而我们在使用avcodec库时,该函数必须被调用。   (2)avcodec_register_all()函数,注册所有的编解码器(codecs),解析器(parsers)以及码流过滤器(bitstream filters)。当然我们也可以使用个别的注册函数来注册我们所要支持的格式。   (3)video_encode_example()函数用于视频编码,由图可知,所有的编码工作都在该函数内完成。   (4)avcodec_find_encoder()函数用于查找一个与codec ID相匹配的已注册的编码器。   (5)avcodec_alloc_context()函数用于分配一个AVCodecContext并设置默认值,如果失败返回NULL,并可用av_free()进行释放。   (6)avcodec_alloc_frame()函数用于分配一个AVFrame并设置默认值,如果失败返回NULL,并可用av_free()进行释放。   (7)设置参数:     设置采样参数,即比特率。     c->bit_rate = 400000;     设置分辨率,必须是2的倍数。     c->width = 352;     c->height = 288;     设置帧率。     c->time_base = (AVRational){1,25}; 该帧率为25,其实timebase = 1/framerate,花括号内分别为分子和分母。     设置GOP大小。     c->gop_size = 10; 该值表示每10帧会插入一个I帧(intra frame)。     设置B帧最大数。     c->max_b_frames = 1; 该值表示在两个非B帧之间,所允许插入的B帧的最大帧数。     设置像素格式。     c->pix_fmt = PIX_FMT_YUV420P; 该值将像素格式设置为YUV420P。   (8)avcodec_open()函数用给定的AVCodec来初始化AVCodecContext。   (9)接着是打开文件,f = fopen( filename, “wb” ); (10)分配图像和输出缓存。     申请100KB左右的内存作为输出缓存。 outbuf_size = 100000;     outbuf = malloc( outbuf_size );     根据帧的大小来确定YUV420所占内存大小,一个像素,RGB格式占用3个字节,而YUV420格式只占用两个字节。YUV420格式是指,每个像素都保留一个Y(亮度)分量,而在水平方向上,不是每行都取U和V分量,而是一行只取U分量,则其接着一行就只取V分量,以此重复,所以420不是指没有V,而是指一行采样只取U,另一行采样只取V。在取U和V时,每两个Y之间取一个U或V。但从4x4矩阵列来看,每4个矩阵点Y区域中,只有一个U和V,所以它们的比值是4:1。所以对于一个像素,RGB需要8 * 3 = 24位,即占3个字节;而YUV420P,8 + 8/4 + 8/4 = 12位,即占2个字节,其中8指Y分量,8/4指U和V分量。     size = c->width * c->height;     picture_buf = malloc( (size * 3) / 2 );     picture->data[0] = picture_buf;     picture->data[1] = picture->data[0] + size;     picture->data[2] = picture->data[1] + size / 4;     picture->linesize[0] = c->width;     picture->linesize[1] = c->width / 2;     picture->linesize[2] = c->width / 2;     其中,data[0]存放Y,data[1]存放U,data[2]存放V【FixMe】。linesize[0]表示Y分量的宽度,linesize[1]表示U分量的宽度,linesize[2]表示V分量的宽度。   (11)编码一秒钟的视频,帧率为25,所以需要循环25次,每次编码一帧。   (11.1)准备一幅伪图像,即自己自定义往里面塞数据。     for(y=0;yheight;y++){ for(x=0;xwidth;x++){ picture->data[0][y*picture->linesize[0]+x]=x+y+i*3; } } for(y=0;yheight/2;y++){ for(x=0;xwidth/2;x++){ picture->data[1][y*picture->linesize[1]+x]=128+y+i*2; picture->data[2][y*picture->linesize[2]+x]=64+x+i*5; } }   (11.2)avcodec_encode_video()从picture中编码一帧视频数据,并存入到outbuf中,而期间所使用的编码器为c。   (11.3)将编码完的数据写入到文件里。   (12)对延时的帧数据进行编码。因为像MPEG4中,I帧、P帧和B帧之间存在一定的延时【FixMe】。同样是avcodec_encode_video(),然后写入文件。   (13)添加结束代码,使其成为一个真正的mpeg文件。     outbuf[0] = 0x00;     outbuf[1] = 0x00;     outbuf[2] = 0x01;     outbuf[3] = 0xb7;     fwrite( outbuf, 1, 4, f );   这个结束代码表示什么???   (14)释放资源。     fclose(f);     free(picture_buf);     free(outbuf);     avcodec_close(c);     av_free(c);     av_free(picture);

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

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

相关文章

大量数据+同步+多线程_Vulkan 多线程渲染

1. Overview of Vulkan1.1 计算机图形软件图形软件有两个大类&#xff1a;专用软件包&#xff08;special-purpose packages&#xff09;和通用编程软件包&#xff08;general programming packages&#xff09;。专用软件包通常提供一种UI设计语言&#xff0c;让用户直接生成想…

(五)Maven中的聚合和继承

一、为什么要聚合&#xff1f; 定义&#xff1a;我们在开发过程中&#xff0c;创建了2个以上的模块&#xff0c;每个模块都是一个独立的maven project&#xff0c;在开始的时候我们可以独立的编译和测试运行每个模块&#xff0c;但是随着项目的不断变大和复杂化&#xff0c;我们…

Django/Flask/Tornado三大web框架性能分析

写在前面&#xff1a;本文的数据涉及到之前遇到过的问题&#xff0c;大概一次 http 请求到收到响应需要多少时间。这个问题在实际工作中与框架有比较大的关系&#xff0c;因此特别就框架的性能做了一次分析。这里使用之前的一个报告数据&#xff1a; Pythons Web Framework Ben…

python urllib模块学习笔记

这个模块是最基本最常用的&#xff0c;以前看过&#xff0c;总结一下 #coding : utf-8import urlliburl http://cnblogs.com#代理服务器proxies {http:http://127.0.0.1:8087}#使用代理服务器打开r urllib.urlopen(url,proxies proxies)print r.info()print r.getcode()pri…

漂亮特殊字体可复制_12个创意字体免费下载网站

今天为大家介绍12个创意字体的网站&#xff0c;这些网站都有提供免费下载的字体哦&#xff0c;希望对大家在创作上面有所帮助。FontSpace在Fontspace上有超过42000种免费字体。在这里字体被整齐的分门归类&#xff0c;帮助你找到想要的字体。除了典型的“serif” “script”等&…

DirectShow组件原理分析及应用

1 DirectX简介  DirectX是Microsoft公司为游戏和其他高性能多媒体应用所提供的一套底层应用程序编程接口。这些接口包括对二维和三维图形&#xff0c;声效和音乐&#xff0c;输入设备以及多玩家网络游戏等的支持。目前DirectX的最高版本是DirectX 9.0。  1.1 DirectX的组成…

栈溢出笔记1.3 准备Shellcode

经过1.1和1.2节的讲述&#xff0c;我们已经知道了怎样更改EIP的值。程序运行函数之后将跳转到我们设定的位置開始运行&#xff0c;因此&#xff0c;我们须要准备一个自己的程序&#xff0c;接手后面的工作。这是一个什么样的程序&#xff1f;是一个C语言编写的代码&#xff1f;…

DirectShow开发快速入门之慨述

文章来源&#xff1a;http://tech.163.com/school 2005-08-18 10:21:32 来源: 天极网摘要&#xff1a;本篇文档概括性的介绍了DirectShow的主要组成部分&#xff0c;以及一些Directshow的基本概念。熟悉这些基本的知识对于Directshow的应用开发或者过滤器的开发者都会有所帮助…

权限表使用联合主键吗_天天写 order by,你知道Mysql底层执行流程吗?

前言 在实际的开发中一定会碰到根据某个字段进行排序后来显示结果的需求&#xff0c;但是你真的理解order by在 Mysql 底层是如何执行的吗&#xff1f;假设你要查询城市是苏州的所有人名字&#xff0c;并且按照姓名进行排序返回前 1000 个人的姓名、年龄&#xff0c;这条 sql 语…

live555源代码简介

文章出自&#xff1a;http://blog.csdn.net/imliujie/archive/2008/01/30/2072657.aspx live555源代码简介liveMedia项目的源代码包括四个基本的库&#xff0c;各种测试代码以及IVE555 Media Server。四个基本的库分别是UsageEnvironment&TaskScheduler&#xff0c;groups…

并发无锁队列学习(单生产者单消费者模型)

1、引言 本文介绍单生产者单消费者模型的队列。依据写入队列的内容是定长还是变长&#xff0c;分为单生产者单消费者定长队列和单生产者单消费者变长队列两种。单生产者单消费者模型的队列操作过程是不须要进行加锁的。生产者通过写索引控制入队操作&#xff0c;消费者通过读索…

流媒体传输协议

1&#xff0e;流媒体( Streaming Media) 1.1流媒体概念 流媒体技术是网络技术和多媒体技术发展到一定阶段的产物。术语流媒体既可以指在网上传输连续时基媒体的流式技术,也可以指使用流式技术的连续时基媒体本身。在网上传输音频、视频等多媒体信息目前主要有两种方式:下载和流…

关闭浏览器网页触发事件_浅析浏览器渲染和 script 加载

前言前端代码离不开浏览器环境&#xff0c;理解 js、css 代码如何在浏览器中工作是非常重要的。如何优化渲染过程中的回流&#xff0c;重绘&#xff1f;script 脚本在页面中是怎么个加载顺序&#xff1f;了解这些对前端性能优化起着非常大的作用。借着这篇文章&#xff0c;让自…

Open vSwitch实验常用命令

1. 基本架构 ovs-vsctl: 管理ovsdb-server的配置&#xff0c;提供OVSDB的配置方法&#xff0c;包括创建和删除网桥、端口等&#xff1b; ovs-ofctl: 提供ovs-vswitchd的流表配置方法&#xff1b; ovs-dpctl: 配置OVS内核模块&#xff0c;提供缓存流表的操作方法&#xff1b…

Oracle 存储过程错误之PLS-00201: 必须声明标识符

转自&#xff1a;http://blog.csdn.net/u010678947/article/details/20702149 错误&#xff1a; ORA-06550: 第 1 行, 第 7 列: PLS-00201: 必须声明标识符ZUO.PROCE_TESTORA-06550: 第 1 行, 第 7 列: PL/SQL: Statement ignored 解决方法&#xff1a; &#xff08;1&#x…

mysql中如何把两个查询结果列数不同并成一张表_MySQL

引言本文整理了MySQL相关的知识&#xff0c;方便以后查阅。 基础架构下图是 MySQL 的一个简要架构图&#xff0c;从下图你可以很清晰的看到用户的 SQL 语句在 MySQL 内部是如何执行的。 先简单介绍一下下图涉及的一些组件的基本作用帮助大家理解这幅图。 - 连接器&#xff1a; …

scrapy框架_Python学习之Scrapy框架

爬虫界江湖地位No.1说起Python&#xff0c;不得不说到它的爬虫应用&#xff0c;由于Python的短小精悍&#xff0c;用它来开发爬虫应用是最合适不过了&#xff0c;基于Python抓取网页的库有很多&#xff0c;例如requests,beatifulsoup等等&#xff0c;但是要说到有哪一个框架&am…

cad移动时捕捉不到基点_CAD入门必备(一)移动和复制新手必看

cad也疯狂前言&#xff1a;CAD绘图之所以能够取代手工绘图&#xff0c;很大的一部分原因是因为它可以很方便的修改和重复利用&#xff0c;例如外参可以节省很大部分时间。而我们在使用CAD中&#xff0c;用得最频繁的功能就是移动和复制了&#xff0c;当然这也是新手必备的其中一…

H.264软件解码器在PXA270平台上的优化

罗 嵘&#xff0c;何 苦 时间:2009年04月24日摘 要&#xff1a; 研究了嵌入式系统中H.264 Baseline软件解码器设计和优化的问题&#xff0c;提出了四种有效的优化方法&#xff0c;并在PXA270平台上进行了测试。测试结果显示&#xff0c;综合使用提出的四种方法&#xff0c;H.26…

EF架构~codeFirst从初始化到数据库迁移

一些介绍 CodeFirst是EntityFrameworks的一种开发模式&#xff0c;即代码优先&#xff0c;它以业务代码为主&#xff0c;通过代码来生成数据库&#xff0c;并且加上migration的强大数据表比对功能来生成数据库版本&#xff0c;让程序开发人员不用维护数据库的变更&#xff0c;而…