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:
@ -48,6 +48,7 @@
|
|||||||
#include "decode.h"
|
#include "decode.h"
|
||||||
#include "hwconfig.h"
|
#include "hwconfig.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
#include "packet_internal.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
typedef struct DecodeContext {
|
typedef struct DecodeContext {
|
||||||
@ -200,14 +201,11 @@ fail:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
|
static int decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
|
||||||
{
|
{
|
||||||
AVCodecInternal *avci = avctx->internal;
|
AVCodecInternal *avci = avctx->internal;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (avci->draining)
|
|
||||||
return AVERROR_EOF;
|
|
||||||
|
|
||||||
ret = av_bsf_receive_packet(avci->bsf, pkt);
|
ret = av_bsf_receive_packet(avci->bsf, pkt);
|
||||||
if (ret == AVERROR_EOF)
|
if (ret == AVERROR_EOF)
|
||||||
avci->draining = 1;
|
avci->draining = 1;
|
||||||
@ -230,6 +228,31 @@ finish:
|
|||||||
return ret;
|
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
|
* Attempt to guess proper monotonic timestamps for decoded video frames
|
||||||
* which might have incorrect times. Input timestamps may wrap around, in
|
* 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
|
} else
|
||||||
dc->draining_started = 1;
|
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]) {
|
if (!avci->buffer_frame->buf[0]) {
|
||||||
ret = decode_receive_frame_internal(avctx, avci->buffer_frame);
|
ret = decode_receive_frame_internal(avctx, avci->buffer_frame);
|
||||||
if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
|
if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
|
||||||
|
Reference in New Issue
Block a user