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()的使用说明: