首先看一下FFmpeg關於該packet函數的註釋:html
int avcodec_send_packet | ( | AVCodecContext * | avctx, |
const AVPacket * | avpkt | ||
) |
Supply raw packet data as input to a decoder.git
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.)app
avctx | codec context | |
[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. |
看一下FFmpeg4.1.3中相關代碼ide
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
{
AVCodecInternal *avci = avctx->internal;
int ret;函數
//檢查是否打開解碼器ui
if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec))
return AVERROR(EINVAL);this
//清空解碼器編碼
if (avctx->internal->draining)
return AVERROR_EOF;3d
if (avpkt && !avpkt->size && avpkt->data)
return AVERROR(EINVAL);code
//擦除緩衝區數據包==初始化
av_packet_unref(avci->buffer_pkt);
if (avpkt && (avpkt->data || avpkt->side_data_elems)) {
//copy packet
ret = av_packet_ref(avci->buffer_pkt, avpkt);
if (ret < 0)
return ret;
}
//packet去除編碼開始部分的冗餘信息,並加載到bsfs
ret = av_bsf_send_packet(avci->filter.bsfs[0], avci->buffer_pkt);//Submit a packet for filtering
if (ret < 0) {
av_packet_unref(avci->buffer_pkt);
return ret;
}
if (!avci->buffer_frame->buf[0]) {
//解碼核心
ret = decode_receive_frame_internal(avctx, avci->buffer_frame);
if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
return ret;
}
return 0;
}
具體的原理和解釋可參考https://www.cnblogs.com/TaigaCon/p/10041926.html