ffmepg (avformat.h里的说明)

Libavformat (lavf)是用于处理多种媒体容器格式的库。

其主要目的有两个:一是多路分配(demuxing)分离一个流媒体文件成多个组件 ;二是多路复用的反转过程,将提供的数据写进指定容器格式。

其也有一个IO模块,支持多种协议访问数据(例如:file,tcp,http 等等 )。在使用lavf之前,我们需要调用 av_register_all()来注册所用已编译的muxers and demuxer(多路)信号分离器 和协议(protocols).

除非你明确你将不会用到libavformat的网络能力,否则你还要调用 avformat_network_init().

AVInputFormat结构体用来描述一种被支持的输入格式,相反的AVOutputFormat结构体用来描述一种输出格式。你能通过av_iformat_next()和av_oformat_next()函数来递归取得所有的已注册的输入/输出格式。

协议层并不是pubinc API的一部分,因此你只能通过 avio_enum_protocols()来获得被支持协议的名称。

用于muxer和demuxer主要的lavf结构是AVFormatContext,它输出正在被读取或写入的文件的所用信息。相比于大多数libavformat结构,它并不是pubinc API的一部分,因此它不能被分配在堆(stack)上,不能用 av_malloc()分配,而是使用 avformat_alloc_context()(一些像avformat_open_input()也许也能)。

最重要的AVFormatContext包含:

1.        AVFormatContext.iformat "input"格式和AVFormatContext.oformat "output"格式:input格式可以自动检测或者用户设置,而"output"格式只能由用户设置。

2.        AVFormatContext.streams AVString数组 描述储存于文件的所有初始流。AVStreams数组通常是通过他们的数组下标调用。

3.          AVFormatContext.pb I/O 上下文(I/O context),输入(input)可以由lavf打开也可以由用户设置,输出只能由用户设置(除非你正在处理一个 AVFMT_NOFILE格式)。

Lavf允许我们使用 采用机制(avoptions mechan)配置muxers and demuxers。

AVFormatContext提供的一般(独立于格式的)libavformat ,对于一个已分配好的AVFormatContext或者来自avformat_get_class()函数的 AVClass),能通过一个调用 av_opt_next()的用户进程检查这些选项。 只有在AVInputFormat.priv_class /AVOutputFormat.priv_class 相关格式结构为非空的情况下,AVFormatContext.priv_data提供特殊(与格式相关的)选项。

如果它的AVClass非空, 可以从AVFormatContext.pb获取更多选项。看在nesting上关于avoptions 文件的讨论学习如何访问它。

@defgroup lavf_decoding Demuxing

{

demuxers读取一个流媒体文件将其分割成多个数据包。一个AV数据包(AVPacket)包含一个或多个属于单个基本流的已编码的帧(encoded frames),在lavf 接口中,这个过程由avformat_open_input()打开一个文件,av_read_frame()读取单个数据包,最后avformat_close_input()进行清除来表示。

}

@section lavf_decoding_open 打开一个流媒体文件

打开一个文件的最少信息就是文件的URL或者文件名,由avformat_open_input()返回,例如下面的一段代码:

const char * url="in.mp3";

AVFormatContext *s = NULL;

int ret = acformat_open_input(&s,url,NULL,NULL);

if(ret<0)

about();

上述代码试图分配一个AVFormatContext,打开一个指定文件(自动探测格式),读取文件头,导出储存在 s 里的信息。一些格式没有头部或者没有储存足够的信息,因此,建议你调用avformat_find_stream_info()函数,它会尝试读取并解码几帧以找到丢失的信息。

在一些情况下,你可能想通过avformat_alloc_context()函数自己预先分配一个AVFormatContext,在传给avformat_open_input()之前做一些调整。比如,当你想用自定义函数代替lavf internal I/O layer读取输入数据时,就要做这些,通过avio_alloc_context()建立你自己的AVIOContext,通过你的读取回调它,然后设置你的AVFormatContext的 pd字段(pd field)建立新的AVIOContext.

因为打开文件的格式在avformat_open_input()返回前一般是不知道的,所以在预先分配的上下文(context)里设置demuxer的私有选项是不可能的。相反的,选项应该包装在AVDictionary里然后传递给avformat_open_input().

@code

AVDictionary* options = NULL;

av_dict_set(&options,"video_size","640x483",0);

av_dict_set(&options,"pixel_format","rgb24",0);

if(avformat_open_input(&s,url,NULL,&options)<0)

abort();

av_dict_free(&options);

这段代码给demuxer传输了"video_size"和"pixel_format"这两个私人选项。他们将对 rawvideo demuxer有用,否则rawvideo demuxer将不能说明rawvideo数据(data)。假如这种格式产生不同与raw video的数据,这些选项将无法被rawvideo demuxer所识别导致不发使用。这些无法被识别的选项将被返回给选项目录(options dictionary)(识别选项会产生消耗).调用程序恩能够按其所希望的那样处理这种无法识别的选项。

@code

AVDictionaryEntry *e;

if(e = av_dict_get(options,"",NULL,AV_DICT_IGNORE_SUFFIX))

{

fprintf(stderr,"Option %s not recognized by the demuxer.\n",e->key);

about();

}

在你完成读取文件后,你必须用avformat_close_input()关闭它。这个函数将释放所有和该文件相关的东西。

@section lavf_decoding_read  从打开的文件中读取数据

反复的调用av_read_frame从打开的AVFormatContext读取数据。每次调用假如成功了,会返回包含一个AVStream的解码数据(encoded data)的AV包(AVPacket),由AVPacket.stream_index鉴别。假如调用者希望将包内数据解码,可以将包传递给the libavcodec decoding functions avcodec_decode_video2(), avcodec_decode_audio4() or avcodec_decode_subtitle2()。

AVPacket.pts,AVPacket.dts and AVPacket.duration 定时消息将被设置,如果已知。如果码流(stream)没有提供这些,那么他们也许未设置(即pts/dts的值为AV_NOPTS_VALUE,duration的值为0)。这些定时信息将放在AVStream.time_base 单元中,就是说,他们必须并联时基(timebase)来将自己转换成秒数。

属于当前demuxer的数据包在下次调用av_read_frame()后将变为无效。在下次调用av_read_frame()之前或者要关闭文件时,用户必须用av_free_packet()来释放数据包。

@defgroup metadata_api Public Metadata API

{

当demuxer时,元数据(metadata)API允许libavformat库将元数据标签(matadata tags)导出给客户端程序。相反的,当muxing时它允许客户端程序设置元数据。

在用于lavu_dict "AVDictionary"API的AVFormatContext, AVStream, AVChapter and AVProgram structs中的元数据域中,元数据被导出或者赋值成键值对串(pairs of key/value string),就像所用在ffmpeg中的字符串一样,元数据被设定为UTF-8双字节编码。注意:在大多数情况下,从demuxer导出的元数据不会检查是否对UTF-8编码有效。

应该记住的重要概念:

1. -key是独一无二的,不会出现2个不同的标签的key是一样的。语义上也是这样的,就是说一个demuxer不应该故意产生几个key,这些key字面上不同但语义上相同

-元数据是横向的 ,不是竖向的,它没有子标签。假如你想储存,举例:制片人Alice和演员鲍勃的孩子的电子邮件地址,可以有key=alice_and_bobs_childs_email_address

-一些修饰语可以被应用到标签名上。这是通过按顺序附加一个连字符和修饰名完成的。例如下面列表出列出的情况: foo-eng-sort, not foo-sort-eng。

-语言 - - 一个value被本地化为一特定语言的标签会被附加 the ISO 639-2/B 3-letter 语言编码。

例如: Author-ger=Michael, Author-eng=Mike 而原始/默认语言是不合格的"Author"标签。如果demuxer设置了任何一个解释标签,那么它应该设置一个默认值。

-排序(sorting)- - 一个被用于排序的标签的修改版本将有附加个"-sort"

举例:artist="The Beatles", artist-sort="Beatles, The"

-分路器尝试以一个通用的格式导出元数据,然而并没有通用的格式标签,因为他们储存在一个容器中。

下表列出了通用标签名:

@verbatim

album        -- name of the set this work belongs to

album_artist -- main creator of the set/album, if different from artist.

e.g. "Various Artists" for compilation albums.

artist       -- main creator of the work

comment      -- any additional description of the file.

composer     -- who composed the work, if different from artist.

copyright    -- name of copyright holder.

creation_time-- date when the file was created, preferably in ISO 8601.

date         -- date when the work was created, preferably in ISO 8601.

disc         -- number of a subset, e.g. disc in a multi-disc collection.

encoder      -- name/settings of the software/hardware that produced the file.

encoded_by   -- person/group who created the file.

filename     -- original name of the file.

genre        -- <self-evident>.

language     -- main language in which the work is performed, preferably

in ISO 639-2 format. Multiple languages can be specified by

separating them with commas.

performer    -- artist who performed the work, if different from artist.

E.g for "Also sprach Zarathustra", artist would be "Richard

Strauss" and performer "London Philharmonic Orchestra".

publisher    -- name of the label/publisher.

service_name     -- name of the service in broadcasting (channel name).

service_provider -- name of the service provider in broadcasting.

title        -- name of the work.

track        -- number of this work in the set, can be in form current/total.

variant_bitrate -- the total bitrate of the bitrate variant that the current stream is part of

@endverbatim

}

packet 函数

1.

分配读取加载的包并且将其段位(fields)初始化为默认值,

参数 size表示加载大小

成功 return>0,否则返回AVERROR_xxx .

int av_get_packet(AVIOContext* s,AVPacket* pkt,int size);

2.

读取数据并将其附加到当前AVPacket内容的后面,类似于strcat这种在数据后面添加数据的作用。如果当前AVPacket的size为0,那么此函数的作用和av_get_packet一样。注意:这里用到了av_grow_packet ,因此涉及了重新分配,造成低效。因此这个函数只应该被用于当没有合适的方法获得包的最终大小时使用。

int av_append_packet(AVIOContext*s ,AVPacket* pkt,int size);

3.

用于处理精确小数点

小数的精确值是

typedef struct AVFrac {

int64_t val, num, den;

} AVFrac;

/**********************************/

以前自己学习ffmepg的时候翻译,有错误的地方期待大家不吝指出啊!!    后面待续..

时间: 2024-11-02 01:45:22

ffmepg (avformat.h里的说明)的相关文章

fileapi.h里的API函数(包括LockFileEx和FindFirstChangeNotification函数)

/** * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER within this package. */ #ifndef _APISETFILE_ #define _APISETFILE_ #include <apiset.h> #include <apisetcconv.h> #include <minwinde

掌握string.h里的常用函数

字符串输出函数 puts 格式:  puts(字符数组名) 功能:把字符数组中的字符串输出到显示器. 即在屏幕上显示该字符串. 字符串输入函数 gets 格式:  gets (字符数组名) 功能:从标准输入设备键盘上输入一个字符串. 本函数得到一个返回值,即为该字符数组的首地址. 1 #include"stdio.h" 2 main(){ 3 char st[15]; 4 printf("input string:\n"); 5 gets(st); 6 puts(s

头文件string.h里的函数

.strcpy 函数名: stpcpy 功 能: 拷贝一个字符串到另一个 用 法: char *stpcpy(char *destin, char *source); 程序例: #include <stdio.h> #include <string.h> int main(void) { char string[10]; char *str1 = "abcdefghi"; stpcpy(string, str1); printf("%s\n"

几大常用头文件stdio.h,stdio.h ,stdbool.h里的定义

C 标准库 - <stdio.h> 简介 stdio .h 头文件定义了三个变量类型.一些宏和各种函数来执行输入和输出. 库变量 下面是头文件 stdio.h 中定义的变量类型: 序号 变量 & 描述 1 size_t  这是无符号整数类型,它是 sizeof 关键字的结果. 2 FILE  这是一个适合存储文件流信息的对象类型. 3 fpos_t  这是一个适合存储文件中任何位置的对象类型. 库宏 下面是头文件 stdio.h 中定义的宏: 序号 宏 & 描述 1 NULL

/*基本算法实现*/Linux中string.h里几个函数的实现

string.h extern int strcmp(const char*,const char*); extern char* strcpy(char*,const char*); string.c int strcmp(const char *cs, const char *ct) { unsigned char c1, c2; while (1) { c1 = *cs++; c2 = *ct++; if (c1 != c2) return c1 < c2 ? -1 : 1; if (!c

在vc6里头文件sys/timeb.h里struct timeb各变量的具体含义?

timeb的定义:struct _timeb{         time_t time;          unsigned short millitm;          short timezone, dstflag;};           time是从UTC时间1970年1月1日午夜(00:00:00)起累计的秒数:      millitm是一秒内的毫秒数      dstflag不为0,说明这是夏令时时间      timezone是UTC时间和本地时间的相差分钟数

[ios]object-c math.h里的数学计算公式介绍

参考:http://blog.csdn.net/yuhuangc/article/details/7639117 1. 三角函数  double sin (double);正弦  double cos (double);余弦  double tan (double);正切  2 .反三角函数  double asin (double); 结果介于[-PI/2, PI/2]  double acos (double); 结果介于[0, PI]  double atan (double); 反正切(

FFMPEG音视频解码

1.播放多媒体文件步骤 通常情况下,我们下载的视频文件如MP4,MKV.FLV等都属于封装格式,就是把音视频数据按照相应的规范,打包成一个文本文件.我们可以使用MediaInfo这个工具查看媒体文件的相关信息. 所以当我们播放一个媒体文件时,通常需要经过以下几个步骤 ①解封装(Demuxing):就是将输入的封装格式的数据,分离成为音频流压缩编码数据和视频流压缩编码数据.封装格式种类很多,例如MP4,MKV,RMVB,TS,FLV,AVI等等,它的作用就是将已经压缩编码的视频数据和音频数据按照一

转:analyze ijkplayer code

看了很久的ijkplayer的视频播放,其实还是没有怎么看懂,只是个人浅浅的笔记 关键部分就是联网获取数据那部分,还没有搞定其实 从用户点击一个已有地址的网络视频开始,从源码分析播放流程. 1.        // init player  加载native底层库 IjkMediaPlayer.loadLibrariesOnce(null); IjkMediaPlayer.native_profileBegin("libijkplayer.so"); 第一句话是加载三个重要的so文件