FFmpeg avcodec_send_packet壓縮包函數

首先看一下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

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.
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  avcodec_open2() before packets may be fed to the decoder.
Parameters
  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.
Returns
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

看一下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

相關文章
相關標籤/搜索