1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-26 19:01:44 +02:00

lavc/decode: move submitting input packets to bitstream filters

Do it from ff_decode_get_packet() rather than from
avcodec_send_packet(). This way all nontrivial stages of the decoding
pipeline (i.e. other than just placing a packet at its entrance) are
pull-based rather than a mix of push an pull.
This commit is contained in:
Anton Khirnov 2023-06-20 16:02:34 +02:00
parent 0f957cfba2
commit 69516ab3e9

View File

@ -48,6 +48,7 @@
#include "decode.h"
#include "hwconfig.h"
#include "internal.h"
#include "packet_internal.h"
#include "thread.h"
typedef struct DecodeContext {
@ -200,14 +201,11 @@ fail:
return ret;
}
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
static int decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
{
AVCodecInternal *avci = avctx->internal;
int ret;
if (avci->draining)
return AVERROR_EOF;
ret = av_bsf_receive_packet(avci->bsf, pkt);
if (ret == AVERROR_EOF)
avci->draining = 1;
@ -230,6 +228,31 @@ finish:
return ret;
}
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
{
AVCodecInternal *avci = avctx->internal;
DecodeContext *dc = decode_ctx(avci);
if (avci->draining)
return AVERROR_EOF;
while (1) {
int ret = decode_get_packet(avctx, pkt);
if (ret == AVERROR(EAGAIN) &&
(!AVPACKET_IS_EMPTY(avci->buffer_pkt) || dc->draining_started)) {
ret = av_bsf_send_packet(avci->bsf, avci->buffer_pkt);
if (ret < 0) {
av_packet_unref(avci->buffer_pkt);
return ret;
}
continue;
}
return ret;
}
}
/**
* Attempt to guess proper monotonic timestamps for decoded video frames
* which might have incorrect times. Input timestamps may wrap around, in
@ -651,12 +674,6 @@ int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacke
} else
dc->draining_started = 1;
ret = av_bsf_send_packet(avci->bsf, avci->buffer_pkt);
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)