FFmpeg demuxing api 中文文档

来源:互联网 发布:js list对象 编辑:程序博客网 时间:2024/06/14 03:26

Demuxers 读取媒体文件并将其分解为小的数据块(packets)。

打开媒体文件

一个包(packet)包括一个或多个编码过得帧。ffmpeg使用avformat_open_input打开一个文件,使用av_read_frame读每一个包数据。使用avformat_close_input关闭文件并做清理工作。

const char *url = "in.mp3";AVFormatContext *s = NULL;int ret = avformat_open_input(&s, url, NULL, NULL);if (ret < 0)    abort();

上面的代码尝试分配AVFormatContext结构,自动侦测文件格式并且打开读头信息,信息被存入s中。一些格式没有头或者没有足够的信息,建议你调用avformat_find_stream_info函数尝试读头信息和少量的帧来找到错过的信息。
在一些情况下你也许想预先自己分配AVFormatContext通过avformat_alloc_context函数,在你传送给avformat_open_input前做一些调整。在这种情况你想使用自定义函数来读取输入数据替代lavf内部的I/O传输层,创建你自己的AVIOContext使用函数avio_alloc_context,传送你自己的读取回调函数。然后设置AVFormatContext的pb变量为你的AVIOContext变量。
通常在avformat_open_input返回前你不知道文件格式,也就不能为demuxer预先分配的上下文设置私有的操作选项,但是你可以将操作项作为AVDictionary传送给avformat_open_input。

AVDictionary *options = NULL;av_dict_set(&options, "video_size", "640x480", 0);av_dict_set(&options, "pixel_format", "rgb24", 0);if (avformat_open_input(&s, url, NULL, &options) < 0)    abort();av_dict_free(&options);

上面的代码传送私有操作项‘video_size’和’pixel_format’给demuxer。它们是必要例如,rawvideo demuxer,demuxer并不知道怎么解释rawvideo数据。如果格式和rawvideo的不同,操作项将不被识别因此也不被应用,这些不被识别的操作将被返回通过操作项字典表。你能处理不能识别的操作项如:

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);    abort();}

在你完成媒体文件读取操作,你必须通过调用avformat_close_input来关闭它。这将释放和文件关联的一切资源。

从一个打开的文件中读取

从AVFormatContext中读取帧可以通过反复调用av_read_frame函数。每次调用成功返回一个AVPacket包含编码的数据。在流中的位置有AVPacket.stream_index来确定。这个包也许直接传给libavcodec库的解码函数avcodec_decode_video2,avcodec_decode_audio4,或者avcodec_decode_subtitle2进行解码操作。
如果视频包括这些信息的话AVPacket.pts,AVPacket.dts,和AVPacket.duration等时间信息将被设置。如果文件没有提供这些信息也可能不被设置例如AV_NOPTS_VALUE 对于pts/dts,0为了duration。时间信息将以AVStream.time_base为单位,乘以这个时间基数来转换为秒。
如果在返回的包中包括AVPacket.buf(被设置),包是被动态分配的,使用者也许想一直保留它们。如果AVPacket.buf被设置为NULL,这个包将仅在下一次av_read_frame调用前有效。如果调用者需要一个长的什么生命周期,av_dup_packet可以用来复制。在这两种情况下包都必须调用av_free_packet函数当包不需要使用时。

demuxer函数

发现AVInputFormat基于输入格式的短文件名。

AVInputFormat* av_find_input_format (   const char *    short_name  )   

猜文件格式。

AVInputFormat* av_probe_input_format    (   AVProbeData *   pd,int     is_opened )   AVInputFormat* av_probe_input_format2   (   AVProbeData *   pd,int     is_opened,int *   score_max )   AVInputFormat* av_probe_input_format3   (   AVProbeData *   pd,int     is_opened,int *   score_ret )   

通过探测数据流来确定输入格式

int av_probe_input_buffer2  (   AVIOContext *   pb,AVInputFormat **    fmt,const char *    filename,void *  logctx,unsigned int    offset,unsigned int    max_probe_size )   int av_probe_input_buffer   (   AVIOContext *   pb,AVInputFormat **    fmt,const char *    filename,void *  logctx,unsigned int    offset,unsigned int    max_probe_size )   

打开输入流并且读头信
编码器不会被打开。流必须通过avformat_close_input进行关闭。

int avformat_open_input (   AVFormatContext **  ps,const char *    filename,AVInputFormat *     fmt,AVDictionary **     options )   /*    ps 指向一个使用提供的AVFormatContext(由avformat_alloc_context分配)。也可以是一个空指针NULL,在这种情况下AVFormatContext将会被分配并且写入到ps中。注意使用者提供的AVFormatContext在失败时将被释放。    filename 要打开的媒体文件    fmt 如果不为空,改参数强制指定的文件格式。其它情况将自动侦测。    options 一个字典为AVFormatContext和demuxer提供私有操作。当函数返回也许被销毁或者包含不被识别的操作项。*/

读媒体文件的包去获取流信息
这是有用的对于没有头信息的文件,例如MPEG。这个函数也计算真正的帧率,在MPEG-2 repeat frame mode下。此函数不改变文件的逻辑位置。

int avformat_find_stream_info   (   AVFormatContext *   ic,AVDictionary **     options )   ic 媒体文件句柄options 参见avformat_open_input   

找到给定流的程序

AVProgram* av_find_program_from_stream  (   AVFormatContext *   ic,AVProgram *     last,int     s )   ic 媒体文件句柄last 最后发现的程序,搜索将在这个程序后开始。或者头开始如果它是NULL。s 流索引

发现文件中的”best”流
‘best’流是用户最期待的结果。如果解码器参数是非NULL,av_find_bast_stream将发现流的默认解码器。

int av_find_best_stream (   AVFormatContext *   ic,enum AVMediaType    type,int     wanted_stream_nb,int     related_stream,AVCodec **  decoder_ret,int     flags )   /*Parametersic  media file handletype    stream type: video, audio, subtitles, etc.wanted_stream_nb    user-requested stream number, or -1 for automatic selectionrelated_stream  try to find a stream related (eg. in the same program) to this one, or -1 if nonedecoder_ret if non-NULL, returns the decoder for the selected streamflags   flags; none are currently defined*/

从流中读取下一帧
这个函数返回文件中的内容,并不验证对于解码器来说是不是有效的帧。它将分割文件进入帧每次调用。它不忽略无效的帧,给编码器最多的信息。
如果pkt->buf是NULL,这个数据包为有效的直到下一次调用av_read_frame或者直到avformat_close_input。除此这个包总是有效永远。这两种情况下不使用时都必须调用av_free_packet进行释放。对于视频一个包刚好包含一帧数据。对于音频包,如果帧是固定尺寸的(例如PCM,ADPCM),那么包含整数个帧。如果帧是变尺寸的(如:MPEG audio),包将包含一个帧。
pkt->pts,pkt->dts 和pkt->duration总是设置一个正确的值单位为AVStream.time_base。(如果视频没有给出它们将需要猜测)。pkt->pts可以是AV_NOPTS_VALUE如果这个视频有B帧,so it is better to rely on pkt->dts if you do not decompress the payload.
成功返回0,<0错误或者文件结尾

int av_read_frame   (   AVFormatContext *   s,AVPacket *  pkt )   

跳转到指定的关键帧’timestamp’ in ‘stream_index’.

int av_seek_frame   (   AVFormatContext *   s,int     stream_index,int64_t     timestamp,int     flags );/*Parameterss   media file handlestream_index    If stream_index is (-1), a default stream is selected, and timestamp is automatically converted from AV_TIME_BASE units to the stream specific time_base.timestamp   Timestamp in AVStream.time_base units or, if no stream is specified, in AV_TIME_BASE units.flags   flags which select direction and seeking mode*/
int avformat_seek_file  (   AVFormatContext *   s,int     stream_index,int64_t     min_ts,int64_t     ts,int64_t     max_ts,int     flags )   
int av_read_pause   (   AVFormatContext *   s   )//暂停读取网络数据void avformat_close_input   (   AVFormatContext **  s   )//关闭媒体文件int avformat_flush  (   AVFormatContext *   s   )   int av_read_play    (   AVFormatContext *   s   )   

原始链接:
http://www.ffmpeg.org/doxygen/2.8/group__lavf__decoding.html#gaa23f7619d8d4ea0857065d9979c75ac8

0 0
原创粉丝点击