FFmpeg编解码处理系列笔记:
[0]. FFmpeg时间戳详解
[1]. FFmpeg编解码处理1-转码全流程简介
[2]. FFmpeg编解码处理3-编解码API详解
[3]. FFmpeg编解码处理4-视频编码
[4]. FFmpeg编解码处理5-音频编码
基于FFmpeg 4.1版本。
4. 编解码API详解
解码使用avcodec_send_packet()和avcodec_receive_frame()两个函数。
编码使用avcodec_send_frame()和avcodec_receive_packet()两个函数。
4.1 API定义
4.1.1 avcodec_send_packet()
/**
* Supply raw packet data as input to a decoder.
*
* Internally, this call will copy relevant AVCodecContext fields, which can
* influence decoding per-packet, and apply them when the packet is actually
* decoded. (For example AVCodecContext.skip_frame, which might direct the
* decoder to drop the frame contained by the packet sent with this function.)
*
* @warning The input buffer, avpkt->data must be AV_INPUT_BUFFER_PADDING_SIZE
*
larger than the actual read bytes because some optimized bitstream
*
readers read 32 or 64 bits at once and could read over the end.
*
* @warning Do not mix this API with the legacy API (like avcodec_decode_video2())
*
on the same AVCodecContext. It will return unexpected results now
*
or in future libavcodec versions.
*
* @note The AVCodecContext MUST have been opened with @ref avcodec_open2()
*
before packets may be fed to the decoder.
*
* @param avctx codec context
* @param[in] avpkt The input AVPacket. Usually, this will be a single video
*
frame, or several complete audio frames.
*
Ownership of the packet remains with the caller, and the
*
decoder will not write to the packet. The decoder may create
*
a reference to the packet data (or copy it if the packet is
*
not reference-counted).
*
Unlike with older APIs, the packet is always fully consumed,
*
and if it contains multiple frames (e.g. some audio codecs),
*
will require you to call avcodec_receive_frame() multiple
*
times afterwards before you can send a new packet.
*
It can be NULL (or an AVPacket with data set to NULL and
*
size set to 0); in this case, it is considered a flush
*
packet, which signals the end of the stream. Sending the
*
first flush packet will return success. Subsequent ones are
*
unnecessary and will return AVERROR_EOF. If the decoder
*
still has frames buffered, it will return them after sending
*
a flush packet.
*
* @return 0 on success, otherwise negative error code:
*
AVERROR(EAGAIN): input is not accepted in the current state - user
*
must read output with avcodec_receive_frame() (once
*
all output is read, the packet should be resent, and
*
the call will not fail with EAGAIN).
*
AVERROR_EOF:
the decoder has been flushed, and no new packets can
*
be sent to it (also returned if more than 1 flush
*
packet is sent)
*
AVERROR(EINVAL): codec not opened, it is an encoder, or requires flush
*
AVERROR(ENOMEM): failed to add packet to internal queue, or similar
*
other errors: legitimate decoding errors
*/
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);
4.1.2 avcodec_receive_frame()
/**
* Return decoded output data from a decoder.
*
* @param avctx codec context
* @param frame This will be set to a reference-counted video or audio
*
frame (depending on the decoder type) allocated by the
*
decoder. Note that the function will always call
*
av_frame_unref(frame) before doing anything else.
*
* @return
*
0:
success, a frame was returned
*
AVERROR(EAGAIN): output is not available in this state - user must try
*
to send new input
*
AVERROR_EOF:
the decoder has been fully flushed, and there will be
*
no more output frames
*
AVERROR(EINVAL): codec not opened, or it is an encoder
*
other negative values: legitimate decoding errors
*/
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);
4.1.3 avcodec_send_frame()
/**
* Supply a raw video or audio frame to the encoder. Use avcodec_receive_packet()
* to retrieve buffered output packets.
*
* @param avctx
codec context
* @param[in] frame AVFrame containing the raw audio or video frame to be encoded.
*
Ownership of the frame remains with the caller, and the
*
encoder will not write to the frame. The encoder may create
*
a reference to the frame data (or copy it if the frame is
*
not reference-counted).
*
It can be NULL, in which case it is considered a flush
*
packet. This signals the end of the stream. If the encoder
*
still has packets buffered, it will return them after this
*
call. Once flushing mode has been entered, additional flush
*
packets are ignored, and sending frames will return
*
AVERROR_EOF.
*
*
For audio:
*
If AV_CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame
*
can have any number of samples.
*
If it is not set, frame->nb_samples must be equal to
*
avctx->frame_size for all frames except the last.
*
The final frame may be smaller than avctx->frame_size.
* @return 0 on success, otherwise negative error code:
*
AVERROR(EAGAIN): input is not accepted in the current state - user
*
must read output with avcodec_receive_packet() (once
*
all output is read, the packet should be resent, and
*
the call will not fail with EAGAIN).
*
AVERROR_EOF:
the encoder has been flushed, and no new frames can
*
be sent to it
*
AVERROR(EINVAL): codec not opened, refcounted_frames not set, it is a
*
decoder, or requires flush
*
AVERROR(ENOMEM): failed to add packet to internal queue, or similar
*
other errors: legitimate decoding errors
*/
int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame);
4.1.4 avcodec_receive_packet()
/**
* Read encoded data from the encoder.
*
* @param avctx codec context
* @param avpkt This will be set to a reference-counted packet allocated by the
*
encoder. Note that the function will always call
*
av_frame_unref(frame) before doing anything else.
* @return 0 on success, otherwise negative error code:
*
AVERROR(EAGAIN): output is not available in the current state - user
*
must try to send input
*
AVERROR_EOF:
the encoder has been fully flushed, and there will be
*
no more output packets
*
AVERROR(EINVAL): codec not opened, or it is an encoder
*
other errors: legitimate decoding errors
*/
int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
4.2 API使用说明
4.2.1 解码API使用详解
关于avcodec_send_packet()与avcodec_receive_frame()的使用说明: