ios vlc封装了ffmpeg h264封装mp4吗

14527人阅读
FFMPEG(137)
IOS多媒体(4)
=====================================================最简单的基于FFmpeg的移动端例子系列文章列表:=====================================================本文记录IOS平台下基于FFmpeg的视频转码器。该转码器实际上移植自ffmpeg工程中的ffmpeg.c源代码。有关ffmpeg.c的源代码可以参考文章《f》,在这里就不重复记录了。源代码项目的目录结构如图所示。下列C语言文件拷贝自FFmpeg源代码:cmdutils.ccmdutils.hcmdutils_common_opts.hconfig.hffmpeg.hffmpeg_filter.cffmpeg_opt.c此外在编译ffmpeg.c的时候,除了需要FFmpeg SDK中的头文件之外,还需要从源代码中拷贝下面头文件。libavformat/ffm.hlibavformat/network.hlibavformat/os_support.hlibavformat/url.hlibavutil/libm.hfmpeg_mod.c是修改后的ffmpeg.c文件。ffmpeg.c本身是用于命令行使用的程序,因此在改为类库调用的时候需要对源代码做一些修改。例如去掉一些exit(0),释放一些变量,main()函数改名为ffmpegmain()等。Objective-C调用FFmpeg的代码位于ViewController.m文件中,内容如下所示。/**
* 最简单的基于FFmpeg的转码器-IOS
* Simplest FFmpeg IOS Transcoder
* 雷霄骅 Lei Xiaohua
* 马小雨 Ma Xiaoyu
* 中国传媒大学/数字电视技术
* Communication University of China / Digital TV Technology
* http://blog.csdn.net/leixiaohua1020
* 本程序是IOS平台下的转码器。它移植于ffmpeg.c命令行工具。
* This software is a Transcoder in IOS. It is transplanted from ffmpeg.c
* command line tools.
#import &ViewController.h&
#include &ffmpeg.h&
int ffmpegmain(int argc, char **argv);
@interface ViewController ()
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
- (IBAction)clickRunButton:(id)sender {
char command_str_full[1024]={0};
NSString *command_str= [NSString stringWithFormat:@&%@&,mand.text];
NSArray *argv_array=[command_str componentsSeparatedByString:(@& &)];
int argc=argv_array.
char** argv=(char**)malloc(sizeof(char*)*argc);
for(int i=0;i&i++)
argv[i]=(char*)malloc(sizeof(char)*1024);
strcpy(argv[i],[[argv_array objectAtIndex:i] UTF8String]);
ffmpegmain(argc, argv);
for(int i=0;i&i++)
free(argv[i]);
free(argv);
运行结果App在手机上运行后的结果如下图所示。单击“Run”按钮之后,程序会根据输入的命令进行转码。例如对于上述截图的情况,就会将/Users/leixiaohua1020/Desktop/test.mp4转码为/Users/leixiaohua1020/Desktop/test.mov。生成的视频文件如下图所示。下载simplest ffmpeg mobile项目主页Github:开源中国:SourceForge:CSDN工程下载地址:本解决方案包含了使用FFmpeg在移动端处理多媒体的各种例子:[Android]simplest_android_player: 基于安卓接口的视频播放器simplest_ffmpeg_android_helloworld: 安卓平台下基于FFmpeg的HelloWorld程序simplest_ffmpeg_android_decoder: 安卓平台下最简单的基于FFmpeg的视频解码器simplest_ffmpeg_android_decoder_onelib: 安卓平台下最简单的基于FFmpeg的视频解码器-单库版simplest_ffmpeg_android_streamer: 安卓平台下最简单的基于FFmpeg的推流器simplest_ffmpeg_android_transcoder: 安卓平台下移植的FFmpeg命令行工具simplest_sdl_android_helloworld: 移植SDL到安卓平台的最简单程序[IOS]simplest_ios_player: 基于IOS接口的视频播放器simplest_ffmpeg_ios_helloworld: IOS平台下基于FFmpeg的HelloWorld程序simplest_ffmpeg_ios_decoder: IOS平台下最简单的基于FFmpeg的视频解码器simplest_ffmpeg_ios_streamer: IOS平台下最简单的基于FFmpeg的推流器simplest_ffmpeg_ios_transcoder: IOS平台下移植的ffmpeg.c命令行工具simplest_sdl_ios_helloworld: 移植SDL到IOS平台的最简单程序
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:7943466次
积分:57791
积分:57791
排名:第44名
原创:373篇
转载:157篇
译文:28篇
评论:6644条
姓名:雷霄骅
网名:leixiaohua1020
中国传媒大学-广播电视工程
中国传媒大学-数字电视技术
中国传媒大学-数字视频技术
[注1:QQ消息较多,难以一一回复,见谅]
[注2:CSDN私信功能使用很少,有问题可以直接在博客评论处留言]
主要从事与广播电视有关的视音频技术的研究。包括视音频质量评价,视音频编解码,流媒体,媒资检索等。
【SourceForge】【主】
【Github】
【开源中国】
欢迎转载本博客原创或翻译文章,但请声明出处,谢谢!
本QQ群旨在为视音频技术同行方便交流提供一个平台。无论是实验室,电视台,互联网视频,安防,播放器,媒体中心等等都可以加入讨论。欢迎新手和大牛,多交流可以更快的进步~1号群【2000人】:2号群【1000人】:通知:1号群成员容量为2000人,目前已经接近上限,为了给新成员入群讨论的机会,会定期清理不发言的用户,希望大家理解,谢谢支持! 2号群为新创建的群,欢迎加入~ 针对近期出现的各种问题,为保障本群和谐发展制定了《群规》,新成员入群后请阅读位于群公告中的《群规》了解本群的规则
文章:135篇
阅读:3658718
文章:91篇
阅读:934280
文章:41篇
阅读:344592拒绝访问 | www.she.vc | 百度云加速
请打开cookies.
此网站 (www.she.vc) 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(385aeb-ua98).
重新安装浏览器,或使用别的浏览器之前接触VLC是因为Winrt的项目,后来似乎ARM版本的始终搞不定(没有针对于ARM-COFF的GCC编译器),vlc for winrt的项目好久没有更新了,自己也没有深入研究。有一天跟同事聊,他们说android和ios都没有一个像Media Foundation那样的多媒体框架,我就想到了是不是可以基于VLC这套框架来开发。研究完之后我才发现,VLC真的是一个伟大的项目。
我用了大概一周的时间来研究VLC的编译,文档上说的很简单,你git下来之后,运行脚本,喝杯咖啡,就编译好了(https://wiki.videolan.org/iOSCompile)。但赐予天朝的网络,很多依赖库下载不下来。所以在编译之前,必须要有给力的FQ环境才可以。
ios这边会有几个分支
http://git.videolan.org/?p=vlc-ports/ios.a=summary 这个是带有VLC for ios全部功能的分支,里面有包含UI和vlc的SDK,还有其他第三方库。
http://git.videolan.org/?p=vlc-bindings/VLCKit.a=summary&这个只是有vlc的sdk和一个简单的sample
如果你不想编译整个VLC,只是用他们的SDK,我建议从http://nightlies.videolan.org/build/ios/ 这边下载SDK,解压下载的文件,引用进vlc_for_ios.xcodeproj的项目里,直接生成就可以。
如果想编译VLC,我建议还是先已编译SDK 比较好,编译SDK的文档在这里(https://wiki.videolan.org/VLCKit/)
首先要用git clone 代码&git://git.videolan.org/vlc-bindings/VLCKit.git
如果你的MAC中已经安装了autoconf等工具,这里强烈建议把这些工具从PATH中移除再去跑脚本,VLC会下载对应的编译工具,如果不移除系统中的工具,会因为环境,或者版本冲突,报各种莫名其妙的错误。修改PATH用export就好。
然后执行./buildMobileVLCKit.sh&
如果你的VPN给力的话,确实如文档所说喝个咖啡就好了。
但是我这边有好多包&curl下载不下来,比如freetype2等。这个时候可以通过浏览器下载,或者从别的地方copy过来,然后把把tar.gz文件放到 {vlckit主目录}/MobileVLCKit/ImportedSources/vlc/contrib/tarballs 下面。curl下载完之后会校验一下shasum的值。很奇怪的是浏览器下载的文件,这个值居然和curl下载下来的不一致。
这个时候要去修改{vlckit主目录}/MobileVLCKit/ImportedSources/vlc/contrib/src/{对应库的名字}/SHA512SUMS 文件。 我们先要修改下载文件的后缀名,我这里的环境.tar.gz被修改成了.tar,然后再用shasum -a 512 {文件名} 算出SHA的值,SHA512SUMS的值替换成我们算出来的。
还有些文件会被改名字,比如pkg-config-lite-0.27.1-1 会被改成pkg-config-0.27.1-1。这种情况会发生在curl无法下载的情况下,如果能正常下载,请忽略。这段逻辑在(vlckit主目录}/MobileVLCKit/ImportedSources/vlc/extras/tools/tools.mak 中描述)
接着再运行./buildMobileVLCKit.sh -n 切记要加-n的参数,这个参数是告诉脚本禁用网络,这样我们做的修改就不会被git给覆盖掉。当然如果你想checkout也行,但是我觉得这种方法简单有效。
如果你之前没有删除PATH,编译到后来会有莫名其妙的错误。这个时候把PATH改掉后,再去编译,有好多已经编译好的,autoconf不会再去给你配置一遍,所以还是会报错。这个时候你可以删除所有代码,重新clone一遍。再此之前,你可以尝试删除根目录的aclocal.m4 和configure文件,这样脚本就会再去configure一遍,或许能解决问题。
./buildMobileVLCKit.sh 是编译真机的&-s 是编译模拟器的 -d 是编译debug的
我所遇到的问题大概就这些,祝大家都能编译成功。
最后说几句题外话,vlc确实是一个伟大的项目,我尝试的是给vlc写一个demux的插件,个人感觉在虚拟机里面的性能还不错,由于公司比较抠,自己比较屌丝,没有真机测试。。。。但是我相信效果应该不是很差。
开源的那套编译器速度很快,比VS快多了。同样代码规格的项目在VS里面要等半天,而这套编译器刷个微博就好了。而且VS的这套东西也不兼容开源的代码,之前编译ffmpeg遇到的最大问题就是,VS的这套东西无法编译GNU风格的汇编。然后呢GCC又没有ARM-COFF的编译器,本来这个编译器应该是微软提供的,就像android那样,但是微软没出。。VS的C编译器本身也有问题,有些代码GCC能编译过,cl却不行。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:532840次
积分:7467
积分:7467
排名:第2804名
原创:53篇
转载:1092篇
评论:29条
(18)(12)(27)(23)(17)(10)(9)(19)(16)(21)(21)(10)(11)(8)(21)(22)(48)(7)(13)(20)(38)(43)(26)(10)(17)(27)(14)(42)(13)(2)(22)(16)(33)(20)(26)(31)(53)(64)(21)(26)(43)(7)(4)(3)(21)(11)(15)(7)(27)(16)(26)(28)(34)(6)1584人阅读
认识FFmpeg
FFMPEG堪称自由软件中最完备的一套多媒体支持库,它几乎实现了所有当下常见的数据封装格式、多媒体传输协议以及音视频编解码器。因此,对于从事多媒体技术开发的工程师来说,深入研究FFMPEG成为一门必不可少的工作,可以这样说,FFMPEG之于多媒体开发工程师的重要性正如kernel之于嵌入式系统工程师一般。
几个小知识:
FFMPEG项目是由法国人Fabrice Bellard发起的,此人也是著名的CPU模拟器项目QEMU的发起者,同时还是的保持者。
FF是Fast Forward的意思,翻译成中文是“快进”。
是一个”Z字扫描”示意图,Z字扫描用于将图像的二维频域数据一维化,同时保证了一维化的数据具备良好的统计特性,从而提高其后要进行的一维熵编码的效率。
关于耻辱柱(Hall of Shame):FFMpeg大部分代码遵循LGPL许可证,如果使用者对FFMpeg进行了修改,要求公布修改的源代码;有少部分代码遵循GPL许可证,要求使用者同时公开使用FFMpeg的软件的源代码。实际上,除去部分大的系统软件开发商(Microsoft、Apple等)以及某些著名的音视频服务提供商(Divx、Real等)提供的自有播放器之外,绝大部分第三方开发的播放器都离不开FFMpeg的支持,像Linux桌面环境中的开源播放器VLC、MPlayer,Windows下的KMPlayer、暴风影音以及Android下几乎全部第三方播放器都是基于FFMpeg的。也有许多看似具备自主技术的播放器,其实也都不声不响地使用了FFMpeg,这种行为被称为“盗窃”,参与“盗窃”的公司的名字则被刻在上,国产播放器暴风影音、QQ影音于2009年上榜。
这一小段代码可以实现的功能包括:
打开一个多媒体文件并获取基本的媒体信息。
获取编码器句柄。
根据给定的时间标签进行一个跳转。
读取数据帧。
解码音频帧或者视频帧。
关闭多媒体文件。
这些功能足以支持一个功能强大的多媒体播放器,因为最复杂的解复用、解码、数据分析过程已经在FFMpeg内部实现了,需要关注的仅剩同步问题。
编解码器、数据帧、媒体流和容器是数字媒体处理系统的四个基本概念。
首先需要统一术语:
容器/文件(Conainer/File):即特定格式的多媒体文件。
媒体流(Stream):指时间轴上的一段连续数据,如一段声音数据,一段视频数据或一段字幕数据,可以是压缩的,也可以是非压缩的,压缩的数据需要关联特定的编解码器。
数据帧/数据包(Frame/Packet):通常,一个媒体流由大量的数据帧组成,对于压缩数据,帧对应着编解码器的最小处理单元。通常,分属于不同媒体流的数据帧交错复用于容器之中,参见。
编解码器:编解码器以帧为单位实现压缩数据和原始数据之间的相互转换。
在FFMPEG中,使用AVFormatContext、AVStream、AVCodecContext、AVCodec及AVPacket等结构来抽象这些基本要素,它们的关系如下图所示:
这是一个描述编解码器上下文的数据结构,包含了众多编解码器需要的参数信息,如下列出了部分比较重要的域:
如果是单纯使用libavcodec,这部分信息需要调用者进行初始化;如果是使用整个FFMPEG库,这部分信息在调用avformat_open_input和avformat_find_stream_info的过程中根据文件的头信息及媒体流内的头部信息完成初始化。其中几个主要域的释义如下:
extradata/extradata_size:这个buffer中存放了解码器可能会用到的额外信息,在av_read_frame中填充。一般来说,首先,某种具体格式的demuxer在读取格式头信息的时候会填充extradata,其次,如果demuxer没有做这个事情,比如可能在头部压根儿就没有相关的编解码信息,则相应的parser会继续从已经解复用出来的媒体流中继续寻找。在没有找到任何额外信息的情况下,这个buffer指针为空。
time_base:
width/height:视频的宽和高。
sample_rate/channels:音频的采样率和信道数目。
sample_fmt: 音频的原始采样格式。
codec_name/codec_type/codec_id/codec_tag:编解码器的信息。
该结构体描述一个媒体流,定义如下:
主要域的释义如下,其中大部分域的值可以由avformat_open_input根据文件头的信息确定,缺少的信息需要通过调用avformat_find_stream_info读帧及软解码进一步获取:
index/id:index对应流的索引,这个数字是自动生成的,根据index可以从AVFormatContext::streams表中索引到该流;而id则是流的标识,依赖于具体的容器格式。比如对于MPEG TS格式,id就是pid。
time_base:流的时间基准,是一个实数,该流中媒体数据的pts和dts都将以这个时间基准为粒度。通常,使用av_rescale/av_rescale_q可以实现不同时间基准的转换。
start_time:流的起始时间,以流的时间基准为单位,通常是该流中第一个帧的pts。
duration:流的总时间,以流的时间基准为单位。
need_parsing:对该流parsing过程的控制域。
nb_frames:流内的帧数目。
r_frame_rate/framerate/avg_frame_rate:帧率相关。
codec:指向该流对应的AVCodecContext结构,调用avformat_open_input时生成。
parser:指向该流对应的AVCodecParserContext结构,调用avformat_find_stream_info时生成。。
这个结构体描述了一个媒体文件或媒体流的构成和基本信息,定义如下:
这是FFMpeg中最为基本的一个结构,是其他所有结构的根,是一个多媒体文件或流的根本抽象。其中:
nb_streams和streams所表示的AVStream结构指针数组包含了所有内嵌媒体流的描述;
iformat和oformat指向对应的demuxer和muxer指针;
pb则指向一个控制底层数据读写的ByteIOContext结构。
start_time和duration是从streams数组的各个AVStream中推断出的多媒体文件的起始时间和长度,以微妙为单位。
通常,这个结构由avformat_open_input在内部创建并以缺省值初始化部分成员。但是,如果调用者希望自己创建该结构,则需要显式为该结构的一些成员置缺省值——如果没有缺省值的话,会导致之后的动作产生异常。以下成员需要被关注:
packet_size
max_analyze_duration
max_index_size
max_picture_buffer
AVPacket定义在avcodec.h中,如下:
FFMPEG使用AVPacket来暂存解复用之后、解码之前的媒体数据(一个音/视频帧、一个字幕包等)及附加信息(解码时间戳、显示时间戳、时长等)。其中:
dts表示解码时间戳,pts表示显示时间戳,它们的单位是所属媒体流的时间基准。
stream_index给出所属媒体流的索引;
data为数据缓冲区指针,size为长度;
duration为数据的时长,也是以所属媒体流的时间基准为单位;
pos表示该数据在媒体流中的字节偏移量;
destruct为用于释放数据缓冲区的函数指针;
flags为标志域,其中,最低为置1表示该数据是一个关键帧。
AVPacket结构本身只是个容器,它使用data成员引用实际的数据缓冲区。这个缓冲区通常是由av_new_packet创建的,但也可能由FFMPEG的API创建(如av_read_frame)。当某个AVPacket结构的数据缓冲区不再被使用时,要需要通过调用av_free_packet释放。av_free_packet调用的是结构体本身的destruct函数,它的值有两种情况:1)av_destruct_packet_nofree或0;2)av_destruct_packet,其中,情况1)仅仅是将data和size的值清0而已,情况2)才会真正地释放缓冲区。
FFMPEG内部使用AVPacket结构建立缓冲区装载数据,同时提供destruct函数,如果FFMPEG打算自己维护缓冲区,则将destruct设为av_destruct_packet_nofree,用户调用av_free_packet清理缓冲区时并不能够将其释放;如果FFMPEG打算将该缓冲区彻底交给调用者,则将destruct设为av_destruct_packet,表示它能够被释放。安全起见,如果用户希望自由地使用一个FFMPEG内部创建的AVPacket结构,最好调用av_dup_packet进行缓冲区的克隆,将其转化为缓冲区能够被释放的AVPacket,以免对缓冲区的不当占用造成异常错误。av_dup_packet会为destruct指针为av_destruct_packet_nofree的AVPacket新建一个缓冲区,然后将原缓冲区的数据拷贝至新缓冲区,置data的值为新缓冲区的地址,同时设destruct指针为av_destruct_packet。
时间信息用于实现多媒体同步。
同步的目的在于展示多媒体信息时,能够保持媒体对象之间固有的时间关系。同步有两类,一类是流内同步,其主要任务是保证单个媒体流内的时间关系,以满足感知要求,如按照规定的帧率播放一段视频;另一类是流间同步,主要任务是保证不同媒体流之间的时间关系,如音频和视频之间的关系(lipsync)。
对于固定速率的媒体,如固定帧率的视频或固定比特率的音频,可以将时间信息(帧率或比特率)置于文件首部(header),如,还有一种相对复杂的方案是将时间信息嵌入媒体流的内部,如MPEG TS和Real video,这种方案可以处理变速率的媒体,亦可有效避免同步过程中的时间漂移。
FFMPEG会为每一个数据包打上时间标签,以更有效地支持上层应用的同步机制。时间标签有两种,一种是DTS,称为解码时间标签,另一种是PTS,称为显示时间标签。对于声音来说 ,这两个时间标签是相同的,但对于某些视频编码格式,由于采用了双向预测技术,会造成DTS和PTS的不一致。
无双向预测帧的情况:
图像类型: I
100 101 102
100 101 102
有双向预测帧的情况:
图像类型: I
100 101 102
100 104 102
对于存在双向预测帧的情况,通常要求解码器对图像重排序,以保证输出的图像顺序为显示顺序:
解码器输入:I
解码器输出:X
时间信息的获取:
通过调用avformat_find_stream_info,多媒体应用可以从AVFormatContext对象中拿到媒体文件的时间信息:主要是总时间长度和开始时间,此外还有与时间信息相关的比特率和文件大小。其中时间信息的单位是AV_TIME_BASE:微秒。
以上4个成员变量都是只读的,基于FFMpeg的中间件需要将其封装到某个接口中,如:
&span class=&kw4&&int&/span& avformat_open_input&span class=&br0&&(&/span&AVFormatContext &span class=&sy0&&**&/span&ic_ptr&span class=&sy0&&,&/span& &span class=&kw4&&const&/span& &span class=&kw4&&char&/span& &span class=&sy0&&*&/span&filename&span class=&sy0&&,&/span& AVInputFormat &span class=&sy0&&*&/span&fmt&span class=&sy0&&,&/span& AVDictionary &span class=&sy0&&**&/span&options&span class=&br0&&)&/span&&span class=&sy0&&;&/span&
avformat_open_input完成两个任务:
打开一个文件或URL,基于字节流的底层输入模块得到初始化。
解析多媒体文件或多媒体流的头信息,创建AVFormatContext结构并填充其中的关键字段,依次为各个原始流建立AVStream结构。
一个多媒体文件或多媒体流与其包含的原始流的关系如下:
多媒体文件/多媒体流 (movie.mkv)
(h.264 video)
(aac audio for Chinese)
(aac audio for english)
(Chinese Subtitle)
(English Subtitle)
关于输入参数:
ic_ptr,这是一个指向指针的指针,用于返回avformat_open_input内部构造的一个AVFormatContext结构体。
filename,指定文件名。
fmt,用于显式指定输入文件的格式,如果设为空则自动判断其输入格式。
这个函数通过解析多媒体文件或流的头信息及其他辅助数据,能够获取足够多的关于文件、流和编解码器的信息,但由于任何一种多媒体格式提供的信息都是有限的,而且不同的多媒体内容制作软件对头信息的设置不尽相同,此外这些软件在产生多媒体内容时难免会引入一些错误,因此这个函数并不保证能够获取所有需要的信息,在这种情况下,则需要考虑另一个函数:avformat_find_stream_info。
&span class=&kw4&&int&/span& avformat_find_stream_info&span class=&br0&&(&/span&AVFormatContext &span class=&sy0&&*&/span&ic&span class=&sy0&&,&/span& AVDictionary &span class=&sy0&&**&/span&options&span class=&br0&&)&/span&&span class=&sy0&&;&/span&
这个函数主要用于获取必要的编解码器参数,设置到ic→streams[i]→codec中。
首先必须得到各媒体流对应编解码器的类型和id,这是两个定义在avutils.h和avcodec.h中的枚举:
通常,如果某种媒体格式具备完备而正确的头信息,调用avformat_open_input即可以得到这两个参数,但若是因某种原因avformat_open_input无法获取它们,这一任务将由avformat_find_stream_info完成。
其次还要获取各媒体流对应编解码器的时间基准。
此外,对于音频编解码器,还需要得到:
帧长度(对于某些编解码器是必要的),
对于视频编解码器,则是:
图像大小,
色彩空间及格式,
&span class=&kw4&&int&/span& av_read_frame&span class=&br0&&(&/span&AVFormatContext &span class=&sy0&&*&/span&s&span class=&sy0&&,&/span& AVPacket &span class=&sy0&&*&/span&pkt&span class=&br0&&)&/span&&span class=&sy0&&;&/span&
这个函数用于从多媒体文件或多媒体流中读取媒体数据,获取的数据由AVPacket结构pkt来存放。对于音频数据,如果是固定比特率,则pkt中装载着一个或多个音频帧;如果是可变比特率,则pkt中装载有一个音频帧。对于视频数据,pkt中装载有一个视频帧。需要注意的是:再次调用本函数之前,必须使用av_free_packet释放pkt所占用的资源。
通过pkt→stream_index可以查到获取的媒体数据的类型,从而将数据送交相应的解码器进行后续处理。
&span class=&kw4&&int&/span& av_seek_frame&span class=&br0&&(&/span&AVFormatContext &span class=&sy0&&*&/span&s&span class=&sy0&&,&/span& &span class=&kw4&&int&/span& stream_index&span class=&sy0&&,&/span& int64_t timestamp&span class=&sy0&&,&/span& &span class=&kw4&&int&/span& flags&span class=&br0&&)&/span&&span class=&sy0&&;&/span&
这个函数通过改变媒体文件的读写指针来实现对媒体文件的随机访问,支持以下三种方式:
基于时间的随机访问:具体而言就是将媒体文件读写指针定位到某个给定的时间点上,则之后调用av_read_frame时能够读到时间标签等于给定时间点的媒体数据,通常用于实现媒体播放器的快进、快退等功能。
基于文件偏移的随机访问:相当于普通文件的seek函数,timestamp也成为文件的偏移量。
基于帧号的随机访问:timestamp为要访问的媒体数据的帧号。
关于参数:
s:是个AVFormatContext指针,就是avformat_open_input返回的那个结构。
stream_index:指定媒体流,如果是基于时间的随机访问,则第三个参数timestamp将以此媒体流的时间基准为单位;如果设为负数,则相当于不指定具体的媒体流,FFMPEG会按照特定的算法寻找缺省的媒体流,此时,timestamp的单位为AV_TIME_BASE(微秒)。
timestamp:时间标签,单位取决于其他参数。
flags:定位方式,AVSEEK_FLAG_BYTE表示基于字节偏移,AVSEEK_FLAG_FRAME表示基于帧号,其它表示基于时间。
&span class=&kw4&&void&/span& av_close_input_file&span class=&br0&&(&/span&AVFormatContext &span class=&sy0&&*&/span&s&span class=&br0&&)&/span&&span class=&sy0&&;&/span&
关闭一个媒体文件:释放资源,关闭物理IO。
AVCodec &span class=&sy0&&*&/span&avcodec_find_decoder&span class=&br0&&(&/span&&span class=&kw2&&enum&/span& CodecID id&span class=&br0&&)&/span&&span class=&sy0&&;&/span&
AVCodec &span class=&sy0&&*&/span&avcodec_find_decoder_by_name&span class=&br0&&(&/span&&span class=&kw4&&const&/span& &span class=&kw4&&char&/span& &span class=&sy0&&*&/span&name&span class=&br0&&)&/span&&span class=&sy0&&;&/span&
根据给定的codec id或解码器名称从系统中搜寻并返回一个AVCodec结构的指针。
&span class=&kw4&&int&/span& avcodec_open&span class=&br0&&(&/span&AVCodecContext &span class=&sy0&&*&/span&avctx&span class=&sy0&&,&/span& AVCodec &span class=&sy0&&*&/span&codec&span class=&br0&&)&/span&&span class=&sy0&&;&/span&
此函数根据输入的AVCodec指针具体化AVCodecContext结构。在调用该函数之前,需要首先调用avcodec_alloc_context分配一个AVCodecContext结构,或调用avformat_open_input获取媒体文件中对应媒体流的AVCodecContext结构;此外还需要通过avcodec_find_decoder获取AVCodec结构。
这一函数还将初始化对应的解码器。
&span class=&kw4&&int&/span& avcodec_decode_video2&span class=&br0&&(&/span&AVCodecContext &span class=&sy0&&*&/span&avctx&span class=&sy0&&,&/span& AVFrame &span class=&sy0&&*&/span&picture&span class=&sy0&&,&/span& &span class=&kw4&&int&/span& &span class=&sy0&&*&/span&got_picture_ptr&span class=&sy0&&,&/span& AVPacket &span class=&sy0&&*&/span&avpkt&span class=&br0&&)&/span&&span class=&sy0&&;&/span&
解码一个视频帧。got_picture_ptr指示是否有解码数据输出。
输入数据在AVPacket结构中,输出数据在AVFrame结构中。AVFrame是定义在avcodec.h中的一个数据结构:
&span class=&kw4&&typedef&/span& &span class=&kw4&&struct&/span& AVFrame &span class=&br0&&{&/span&
FF_COMMON_FRAME
&span class=&br0&&}&/span& AVFrame&span class=&sy0&&;&/span&
FF_COMMON_FRAME定义了诸多数据域,大部分由FFMpeg内部使用,对于用户来说,比较重要的主要包括:
&span class=&co2&&#define FF_COMMON_FRAME ......&/span&
uint8_t &span class=&sy0&&*&/span&data&span class=&br0&&[&/span&4&span class=&br0&&]&/span&&span class=&sy0&&;&/span&
&span class=&kw4&&int&/span& linesize&span class=&br0&&[&/span&4&span class=&br0&&]&/span&&span class=&sy0&&;&/span&
&span class=&kw4&&int&/span& key_frame&span class=&sy0&&;&/span&
&span class=&kw4&&int&/span& pict_type&span class=&sy0&&;&/span&
int64_t pts&span class=&sy0&&;&/span&\
&span class=&kw4&&int&/span& reference&span class=&sy0&&;&/span&\
FFMpeg内部以planar的方式存储原始图像数据,即将图像像素分为多个平面(R/G/B或Y/U/V),data数组内的指针分别指向四个像素平面的起始位置,linesize数组则存放各个存贮各个平面的缓冲区的行宽:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++data[0]-&#################################++++++++++++
++++++++++++###########picture data##########++++++++++++
++++++++++++#################################++++++++++++
++++++++++++#################################++++++++++++
........................
++++++++++++#################################++++++++++++
|&-------------------line_size[0]----------------------&|
此外,key_frame标识该图像是否是关键帧;pict_type表示该图像的编码类型:I(1)/P(2)/B(3)……;pts是以time_base为单位的时间标签,对于部分解码器如H.261、H.263和MPEG4,可以从头信息中获取;reference表示该图像是否被用作参考。
&span class=&kw4&&int&/span& avcodec_decode_audio4&span class=&br0&&(&/span&AVCodecContext &span class=&sy0&&*&/span&avctx&span class=&sy0&&,&/span& AVFrame &span class=&sy0&&*&/span&frame&span class=&sy0&&,&/span& &span class=&kw4&&int&/span& &span class=&sy0&&*&/span&got_frame_ptr&span class=&sy0&&,&/span& AVPacket &span class=&sy0&&*&/span&avpkt&span class=&br0&&)&/span&&span class=&sy0&&;&/span&
解码一个音频帧。输入数据在AVPacket结构中,输出数据在frame中,got_frame_ptr表示是否有数据输出。
int avcodec_close(AVCodecContext *avctx);
关闭解码器,释放avcodec_open中分配的资源。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:18178次
排名:千里之外
原创:32篇
(1)(12)(8)(5)(2)(5)}

我要回帖

更多关于 vlc ffmpeg 关系 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信