zhngs

zhngs

ffmpeg常用api

一.libavformat
1.avformatopeninput
2.avformatfindstream_info
3.avfindbest_stream
4.avreadframe
5.avcodecsendpacket
6.avcodecreceiveframe
7.avparserparse2

一.libavformat

1.avformat_open_input

打开一个输入流并读取header,编码器并没有打开,需要使用avformat_close_input进行关闭

int avformat_open_input(AVFormatContext **ps, const char *url, const AVInputFormat *fmt, AVDictionary **options);

参数:

  • ps:指向用户提供的AVFormatContext(由avformat_alloc_context分配),可以是一个NULL指针,这种情况下avformat_open_input内部会分配ps的内存。需要注意在函数失败时,用户提供的ps会被释放
  • url:要打开的stream路径
  • fmt:如果不为NULL,该参数强制指定输入格式,否则自动检测格式
  • options:可以为NULL

返回值:

  • 0表示成功,失败返回负的AVERROR

2.avformat_find_stream_info

读取媒体文件的数据包以获取流信息,这对于没有标头的文件格式(如MPEG)很有用,读取过的数据包可能会被缓存供以后使用

int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);

参数:

  • ic:媒体文件句柄
  • options:可以为NULL

返回值:

  • 大于等于0表示成功,AVERROR_xxx表示失败

3.av_find_best_stream

找到文件中最符合期望的流

int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type, int wanted_stream_nb, int related_stream, const AVCodec **decoder_ret, int flags);

参数:

  • ic:媒体文件句柄
  • type:媒体文件类型,如音频,视频,字幕等
  • wanted_stream_nb:用户需要stream号,如果是-1则自动选择
  • related_stream:尝试找一个相关的流,如果是-1则忽略
  • decoder_ret:如果非空,返回选择的流的解码器
  • flags:目前未使用

返回值:

  • 成功返回非负的stream序号
  • AVERROR_STREAM_NOT_FOUND表示找不到相关的流
  • AVERROR_DECODER_NOT_FOUND表示找到相关的流,但是没有对应解码器

4.av_read_frame

返回流的下一帧

int av_read_frame(AVFormatContext *s, AVPacket *pkt);

参数:

  • s:媒体文件句柄
  • pkt:内部储存数据的buffer

返回值:

  • 0表示成功,小于0表示出错或者文件结束。当出错的时候,pkt会为空,如同来自av_packet_alloc()

注意:

  • 当成功的时候,返回的pkt将被引用计数,不再使用的时候必须手动使用av_packet_unref进行释放
  • 对于视频,pkt总是包含一帧
  • 对于音频,如果每个帧是固定长度(例如PCM或ADPCM),可能会包含多个帧。如果每个帧是可变大小(例如MPEG音频),pkt只会包含一个帧
  • pkt->pts, pkt->dts和pkt->duration 总是设置成正确的数值,单位使用AVStream.time_base。如果视频包含B帧,pkt->pts可以被设置成AV_NOPTS_VALUE,如果你没有解压数据,最好依赖pkt->dts

5.avcodec_send_packet

为解码器提供原始的数据包

int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);

参数:

  • avctx:编解码上下文
  • avpkt:通常这是一个视频帧或多个音频帧,avpkt的所有权属于调用者,解码器不会向avpkt中写入数据,但是可能会创建引用计数或者拷贝avpkt。avpkt总会被消耗完,必须多次调用avcodec_receive_frame后,才能重新调用avcodec_send_packet。avpkt可以为NULL(或者pkt内部的data为NULL,并且size为0),在这种情况下,avpkt会被认为是一个flush packet来标记流的结尾,第一次发送flush packet会返回成功,后续会返回AVERROR_EOF。如果解码器有帧缓存,在收到flush packet的时候会返回这些帧

返回值:

  • 0表示成功
  • AVERROR(EAGAIN):当前状态不接受输入,用户必须通过avcodec_receive_frame读取输出
  • AVERROR_EOF:解码器已经被flush,不再接受新的packet
  • AVERROR(EINVAL):解码器未打开,或者是编码器,或者需要flush
  • AVERROR(ENOMEM):向内部对列添加包失败,或者解码失败

6.avcodec_receive_frame

返回解码器的解码输出

int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);

参数:

  • avctx:编解码上下文
  • frame:解码器会分配引用计数的视频或音频frame,需要注意该函数开始的时候总会调用av_frame_unref(frame)

返回值:

  • 0表示成功
  • AVERROR(EAGAIN):当前状态已经读完所有输出,需要向解码器发送新的输入
  • AVERROR_EOF:解码器已经被flush,不会再有新的输出
  • AVERROR(EINVAL):解码器没有打开,或者是一个编码器
  • AVERROR_INPUT_CHANGED:相对于第一个解码帧,当前的解码帧已经改变参数

7.av_parser_parse2

解析一个packet

int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int64_t pts, int64_t dts, int64_t pos);

参数:

  • s:parser上下文
  • avctx:编解码器上下文
  • poutbuf:设置parsed缓冲区的指针,如果未完成则设置为NULL
  • poutbuf_size:设置parsed缓冲区的大小,如果未完成设置为0
  • buf:输入buf
  • buf_size:不包括padding大小的buf大小。为了表示EOF,应该设置为0
  • pts:显示时间戳
  • dts:解码时间戳
  • pos:在stream中的输入字节位置

返回值:

  • 输入比特流用到的字节数