ffmpeg中提供了avcodec_send_frame和avcodec_receive_packet用于编码,avcodec_send_packet和avcodec_receive_frame用于解码。
encode
libavcodec/encode.c
中:
int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame)
int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
- For encoding, call avcodec_send_frame() to give the encoder an AVFrame containing uncompressed audio or video.
In both cases, it is recommended that AVPackets and AVFrames are refcounted, or libavcodec might have to copy the input data. (libavformat always returns refcounted AVPackets, and av_frame_get_buffer() allocates refcounted AVFrames.)
avcodec_send_frame() 负责将未压缩的AVFrame音视频数据给编码器。
- For encoding, call avcodec_receive_packet().
On success, it will return an AVPacket with a compressed frame.
Repeat this call until it returns AVERROR(EAGAIN) or an error.
The AVERROR(EAGAIN) return value means that new input data is required to return new output.
In this case, continue with sending input.
For each input frame/packet, the codec will typically return 1 output frame/packet, but it can also be 0 or more than 1.
avcodec_receive_packet负责返回保存在AVPacket中的压缩数据(编码数据)。
image.pngdecode
libavcodec/decode.c
中:
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
- For decoding, call avcodec_send_packet() to give the decoder raw compressed data in an AVPacket.
avcodec_send_packet负责将AVPacket压缩数据给解码器。
- For decoding, call avcodec_receive_frame().
On success, it will return an AVFrame containing uncompressed audio or video data.
avcodec_receive_frame可获取到解码后的AVFrame数据。
image.pngUsing the API as outlined above is highly recommended.
Using the API as outlined above is highly recommended.
But it is also possible to call functions outside of this rigid schema.
For example, you can call avcodec_send_packet() repeatedly without calling avcodec_receive_frame().
In this case, avcodec_send_packet() will succeed until the codec's internal buffer has been filled up (which is typically of size 1 per output frame, after initial input), and then reject input with AVERROR(EAGAIN). Once it starts rejecting input, you have no choice but to read at least some output.
高度推荐使用以上的函数。
除非编码器的内部buffer满了,否则avcodec_send_packet会成功。
如果编码器的内部buffer满了,这时调用avcodec_send_packet会返回 AVERROR(EAGAIN)。
这时就需要读取一些数据进行处理。
This API replaces the following legacy functions:
这些函数替代就老版本的函数。
This API replaces the following legacy functions:
avcodec_decode_video2() and avcodec_decode_audio4():
Use avcodec_send_packet() to feed input to the decoder, then use avcodec_receive_frame() to receive decoded frames after each packet.
Unlike with the old video decoding API, multiple frames might result from a packet.
For audio, splitting the input packet into frames by partially decoding packets becomes transparent to the API user.
You never need to feed an AVPacket to the API twice (unless it is rejected with AVERROR(EAGAIN) - then no data was read from the packet). Additionally, sending a flush/draining packet is required only once.avcodec_encode_video2()/avcodec_encode_audio2():
Use avcodec_send_frame() to feed input to the encoder, then use avcodec_receive_packet() to receive encoded packets.
Providing user-allocated buffers for avcodec_receive_packet() is not possible.
The new API does not handle subtitles yet.
Mixing new and old function calls on the same AVCodecContext is not allowed, and will result in undefined behavior.
针对同一个AVCodecContext,新旧函数不可混着用。
网友评论