diff mbox series

[FFmpeg-devel,2/2] avcodec/decode: don't discard the buffered packet if the underlying bsf can't take it

Message ID 20230712020644.22606-2-jamrial@gmail.com
State New
Headers show
Series [FFmpeg-devel,1/2] avcodec/decode: don't reject flush packets when buffer_pkt is not empty | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

James Almer July 12, 2023, 2:06 a.m. UTC
Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavcodec/decode.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Anton Khirnov July 12, 2023, 9:08 a.m. UTC | #1
Quoting James Almer (2023-07-12 04:06:44)
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  libavcodec/decode.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/libavcodec/decode.c b/libavcodec/decode.c
> index 239ad70b41..cd49cca7c2 100644
> --- a/libavcodec/decode.c
> +++ b/libavcodec/decode.c
> @@ -242,7 +242,8 @@ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
>              (!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);
> +                if (ret != AVERROR(EAGAIN))
> +                    av_packet_unref(avci->buffer_pkt);

It seems very wrong for ff_decode_get_packet() to return EAGAIN when
we have a buffered packet.
James Almer July 12, 2023, 11:40 a.m. UTC | #2
On 7/12/2023 6:08 AM, Anton Khirnov wrote:
> Quoting James Almer (2023-07-12 04:06:44)
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>>   libavcodec/decode.c | 3 ++-
>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/libavcodec/decode.c b/libavcodec/decode.c
>> index 239ad70b41..cd49cca7c2 100644
>> --- a/libavcodec/decode.c
>> +++ b/libavcodec/decode.c
>> @@ -242,7 +242,8 @@ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
>>               (!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);
>> +                if (ret != AVERROR(EAGAIN))
>> +                    av_packet_unref(avci->buffer_pkt);
> 
> It seems very wrong for ff_decode_get_packet() to return EAGAIN when
> we have a buffered packet.

The idea is preventing dropping a packet in the hypothetical case the 
bsf can't take it. Is this scenario possible, or is the call to 
av_bsf_receive_packet() within the loop ensuring it wont?
Anton Khirnov July 12, 2023, 1:32 p.m. UTC | #3
Quoting James Almer (2023-07-12 13:40:25)
> On 7/12/2023 6:08 AM, Anton Khirnov wrote:
> > Quoting James Almer (2023-07-12 04:06:44)
> >> Signed-off-by: James Almer <jamrial@gmail.com>
> >> ---
> >>   libavcodec/decode.c | 3 ++-
> >>   1 file changed, 2 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/libavcodec/decode.c b/libavcodec/decode.c
> >> index 239ad70b41..cd49cca7c2 100644
> >> --- a/libavcodec/decode.c
> >> +++ b/libavcodec/decode.c
> >> @@ -242,7 +242,8 @@ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
> >>               (!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);
> >> +                if (ret != AVERROR(EAGAIN))
> >> +                    av_packet_unref(avci->buffer_pkt);
> > 
> > It seems very wrong for ff_decode_get_packet() to return EAGAIN when
> > we have a buffered packet.
> 
> The idea is preventing dropping a packet in the hypothetical case the 
> bsf can't take it. Is this scenario possible, or is the call to 
> av_bsf_receive_packet() within the loop ensuring it wont?

This block can only be entered if decode_get_packet() returned EAGAIN,
which should always mean that the bsf is empty.
James Almer July 12, 2023, 1:33 p.m. UTC | #4
On 7/12/2023 10:32 AM, Anton Khirnov wrote:
> Quoting James Almer (2023-07-12 13:40:25)
>> On 7/12/2023 6:08 AM, Anton Khirnov wrote:
>>> Quoting James Almer (2023-07-12 04:06:44)
>>>> Signed-off-by: James Almer <jamrial@gmail.com>
>>>> ---
>>>>    libavcodec/decode.c | 3 ++-
>>>>    1 file changed, 2 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/libavcodec/decode.c b/libavcodec/decode.c
>>>> index 239ad70b41..cd49cca7c2 100644
>>>> --- a/libavcodec/decode.c
>>>> +++ b/libavcodec/decode.c
>>>> @@ -242,7 +242,8 @@ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
>>>>                (!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);
>>>> +                if (ret != AVERROR(EAGAIN))
>>>> +                    av_packet_unref(avci->buffer_pkt);
>>>
>>> It seems very wrong for ff_decode_get_packet() to return EAGAIN when
>>> we have a buffered packet.
>>
>> The idea is preventing dropping a packet in the hypothetical case the
>> bsf can't take it. Is this scenario possible, or is the call to
>> av_bsf_receive_packet() within the loop ensuring it wont?
> 
> This block can only be entered if decode_get_packet() returned EAGAIN,
> which should always mean that the bsf is empty.

Right, patch dropped then.
diff mbox series

Patch

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 239ad70b41..cd49cca7c2 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -242,7 +242,8 @@  int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
             (!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);
+                if (ret != AVERROR(EAGAIN))
+                    av_packet_unref(avci->buffer_pkt);
                 return ret;
             }