avcodec_send_packet函数解析

Posted helloc14

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了avcodec_send_packet函数解析相关的知识,希望对你有一定的参考价值。

avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt):

1)将原始数据包作为解码器的输入

2)该函数在内部会复制AVCodecContext的相关字段(具体有哪些字段,起什么用,俺也不知道。。。),这些字段会影响每个包的解析,并且在实际解码的过程中会使用到(例如:AVCodecContext.skip_frame的这个字段,会告诉解码直接抛弃该函数发送包中包含的帧数据)

3)@warning 输入缓冲区avpkt->数据必须是大于实际读取字节的AV_INPUT_BUFFER_PADDING_SIZE,因为一些优化的位流读取器一次读取32位或64位,可以在最后读取。

4)@warning 不要将此API与同一AVCodecContext上的遗留API(如avcodec_decode_video2())混合使用。在现在或未来的libavcodec版本,它将返回意想不到的结果(说白了,就是以前版本的的解码函数被弃用了,官方推荐使用新API)

5)@note AVCodecContext必须使用 avcodec_open2()打开,然后才可以将包提供给解码器(通过知道到解码器做参数alloc创建出解码器上下文后,还需要打开解码器上下文)

6)@param[in] avpkt 

AVPacket作为输入参数,一般情况下,它包含了一个视频帧或者几个完整的音频帧数据

该参数的所有权仍然归调用者所有(意思大概是ACPacket 是用户调用那个av_packet_alloc函数来创建的,它的内存释放,调用啥的操作仍然是用户来操作),并且解码器不会对该packet进行写入操作。解码器会创建一个包数据的引用(或者如果包没有被引用计数,则拷贝一份)

与以前的api不同,包总是被完全使用(啥叫被完全使用???),如果它包含多个帧(例如一些音频编解码器),在发送新的数据包之前,需要多次调用avcodec_receive_frame()

它可以被置成NULL(或者是一个AVPacket 的data字段设置成NULL,并且size字段设置成0),在这种情况下,它被识别为刷新包,表示数据流的结束,发送第一个刷新包将会返回成功,随后所有的操作都是不需要的,并且会返回AVERROR_EOF,如果解码器还有缓冲帧数据,它将会在发送一个刷新包之后返回这些缓冲帧数据

7)@return 返回0代表成功,否则返回错误编号

AVERROR(EAGAIN):当前状态不接受输入,用户必须调用avcodec_receive_frame()函数把数据帧读取完(一旦所有的输出数据被读取,该packet数据可以被重新发送,并且函数调用返回值不会是EAGAGIN)。说白了E-AGAIN e-again 读完,再试者发一次呗。。。。。。

AVERROR_EOF:解码器已经刷新了,不能再往解码器发送新的数据包(如果发送超过1个刷新包,也返回同样错误代码)

AVERROR(EINVAL):未打开的编解码器,它是一个编码器,或需要刷新

AVERROR(ENOMEM):未能将包添加到内部队列,或类似情况(NOMEM 是指 no memory ???)

other errors:合法的解码错误

以上是关于avcodec_send_packet函数解析的主要内容,如果未能解决你的问题,请参考以下文章

FFmpeg AVPacket剖析

FFmpeg3最新的解码接口avcodec_send_packet和avcodec_receive_frame分析

智能化视频开发神器来了,AV Pipeline Kit 架构解析

FFMpeg中seek函数解析

XML Parser 触发 AV 警报

ffmpeg中的时间单位以及时间转换函数(av_q2d av_rescale_q)