diff mbox series

[FFmpeg-devel] avformat/adxdec: demux multiple blocks at once

Message ID 20200918101030.20626-1-onemda@gmail.com
State Superseded
Headers show
Series [FFmpeg-devel] avformat/adxdec: demux multiple blocks at once | expand

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Paul B Mahol Sept. 18, 2020, 10:10 a.m. UTC
Improves decoding speed by 24x

Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
 libavformat/adxdec.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

Comments

Andreas Rheinhardt Sept. 18, 2020, 10:16 a.m. UTC | #1
Paul B Mahol:
> Improves decoding speed by 24x
> 
> Signed-off-by: Paul B Mahol <onemda@gmail.com>
> ---
>  libavformat/adxdec.c | 23 +++++++++++++++--------
>  1 file changed, 15 insertions(+), 8 deletions(-)
> 
> diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c
> index ccd5049acd..0e4c251cfc 100644
> --- a/libavformat/adxdec.c
> +++ b/libavformat/adxdec.c
> @@ -53,6 +53,9 @@ static int adx_read_packet(AVFormatContext *s, AVPacket *pkt)
>      AVCodecParameters *par = s->streams[0]->codecpar;
>      int ret, size;
>  
> +    if (avio_feof(s->pb))
> +        return AVERROR_EOF;
> +
>      if (par->channels <= 0) {
>          av_log(s, AV_LOG_ERROR, "invalid number of channels %d\n", par->channels);
>          return AVERROR_INVALIDDATA;
> @@ -63,16 +66,20 @@ static int adx_read_packet(AVFormatContext *s, AVPacket *pkt)
>      pkt->pos = avio_tell(s->pb);
>      pkt->stream_index = 0;
>  
> -    ret = av_get_packet(s->pb, pkt, size);
> -    if (ret != size) {
> -        return ret < 0 ? ret : AVERROR(EIO);
> -    }
> -    if (AV_RB16(pkt->data) & 0x8000) {
> -        return AVERROR_EOF;
> +    ret = av_get_packet(s->pb, pkt, size * 128);
> +    if (ret < 0)
> +        return ret;
> +    if ((ret % size) && ret >= size) {

So if ret < size you don't set the corrupt flag. Why?

> +        size = ret - (ret % size);
> +        av_shrink_packet(pkt, size);
> +        pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
> +    } else {
> +        size = ret;
>      }
> +
>      pkt->size     = size;

This line makes no sense any more: If the first branch above is taken,
av_shrink_packet() will already set the size; in the other branch,
av_get_packet() already did.

> -    pkt->duration = 1;
> -    pkt->pts      = (pkt->pos - c->header_size) / size;
> +    pkt->duration = size / (BLOCK_SIZE * par->channels);
> +    pkt->pts      = (pkt->pos - c->header_size) / (BLOCK_SIZE * par->channels);
>  
>      return 0;
>  }
>
Paul B Mahol Sept. 18, 2020, 10:22 a.m. UTC | #2
On Fri, Sep 18, 2020 at 12:16:18PM +0200, Andreas Rheinhardt wrote:
> Paul B Mahol:
> > Improves decoding speed by 24x
> > 
> > Signed-off-by: Paul B Mahol <onemda@gmail.com>
> > ---
> >  libavformat/adxdec.c | 23 +++++++++++++++--------
> >  1 file changed, 15 insertions(+), 8 deletions(-)
> > 
> > diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c
> > index ccd5049acd..0e4c251cfc 100644
> > --- a/libavformat/adxdec.c
> > +++ b/libavformat/adxdec.c
> > @@ -53,6 +53,9 @@ static int adx_read_packet(AVFormatContext *s, AVPacket *pkt)
> >      AVCodecParameters *par = s->streams[0]->codecpar;
> >      int ret, size;
> >  
> > +    if (avio_feof(s->pb))
> > +        return AVERROR_EOF;
> > +
> >      if (par->channels <= 0) {
> >          av_log(s, AV_LOG_ERROR, "invalid number of channels %d\n", par->channels);
> >          return AVERROR_INVALIDDATA;
> > @@ -63,16 +66,20 @@ static int adx_read_packet(AVFormatContext *s, AVPacket *pkt)
> >      pkt->pos = avio_tell(s->pb);
> >      pkt->stream_index = 0;
> >  
> > -    ret = av_get_packet(s->pb, pkt, size);
> > -    if (ret != size) {
> > -        return ret < 0 ? ret : AVERROR(EIO);
> > -    }
> > -    if (AV_RB16(pkt->data) & 0x8000) {
> > -        return AVERROR_EOF;
> > +    ret = av_get_packet(s->pb, pkt, size * 128);
> > +    if (ret < 0)
> > +        return ret;
> > +    if ((ret % size) && ret >= size) {
> 
> So if ret < size you don't set the corrupt flag. Why?

Because data, that is not gonna be used at all, is discarded, instead of
pointlessly being passed to decoder and there errored out.
This happens at every single eof.

> 
> > +        size = ret - (ret % size);
> > +        av_shrink_packet(pkt, size);
> > +        pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
> > +    } else {
> > +        size = ret;
> >      }
> > +
> >      pkt->size     = size;
> 
> This line makes no sense any more: If the first branch above is taken,
> av_shrink_packet() will already set the size; in the other branch,
> av_get_packet() already did.

Removed that line locally.

> 
> > -    pkt->duration = 1;
> > -    pkt->pts      = (pkt->pos - c->header_size) / size;
> > +    pkt->duration = size / (BLOCK_SIZE * par->channels);
> > +    pkt->pts      = (pkt->pos - c->header_size) / (BLOCK_SIZE * par->channels);
> >  
> >      return 0;
> >  }
> > 
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Andreas Rheinhardt Sept. 18, 2020, 10:29 a.m. UTC | #3
Paul B Mahol:
> On Fri, Sep 18, 2020 at 12:16:18PM +0200, Andreas Rheinhardt wrote:
>> Paul B Mahol:
>>> Improves decoding speed by 24x
>>>
>>> Signed-off-by: Paul B Mahol <onemda@gmail.com>
>>> ---
>>>  libavformat/adxdec.c | 23 +++++++++++++++--------
>>>  1 file changed, 15 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c
>>> index ccd5049acd..0e4c251cfc 100644
>>> --- a/libavformat/adxdec.c
>>> +++ b/libavformat/adxdec.c
>>> @@ -53,6 +53,9 @@ static int adx_read_packet(AVFormatContext *s, AVPacket *pkt)
>>>      AVCodecParameters *par = s->streams[0]->codecpar;
>>>      int ret, size;
>>>  
>>> +    if (avio_feof(s->pb))
>>> +        return AVERROR_EOF;
>>> +
>>>      if (par->channels <= 0) {
>>>          av_log(s, AV_LOG_ERROR, "invalid number of channels %d\n", par->channels);
>>>          return AVERROR_INVALIDDATA;
>>> @@ -63,16 +66,20 @@ static int adx_read_packet(AVFormatContext *s, AVPacket *pkt)
>>>      pkt->pos = avio_tell(s->pb);
>>>      pkt->stream_index = 0;
>>>  
>>> -    ret = av_get_packet(s->pb, pkt, size);
>>> -    if (ret != size) {
>>> -        return ret < 0 ? ret : AVERROR(EIO);
>>> -    }
>>> -    if (AV_RB16(pkt->data) & 0x8000) {
>>> -        return AVERROR_EOF;
>>> +    ret = av_get_packet(s->pb, pkt, size * 128);
>>> +    if (ret < 0)
>>> +        return ret;
>>> +    if ((ret % size) && ret >= size) {
>>
>> So if ret < size you don't set the corrupt flag. Why?
> 
> Because data, that is not gonna be used at all, is discarded, instead of
> pointlessly being passed to decoder and there errored out.
> This happens at every single eof.
> 

But you don't return an error if the return value is in the range
0..size - 1; you return the packet with the incomplete and apparently
useless packet.

>>
>>> +        size = ret - (ret % size);
>>> +        av_shrink_packet(pkt, size);
>>> +        pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
>>> +    } else {
>>> +        size = ret;
>>>      }
>>> +
>>>      pkt->size     = size;
>>
>> This line makes no sense any more: If the first branch above is taken,
>> av_shrink_packet() will already set the size; in the other branch,
>> av_get_packet() already did.
> 
> Removed that line locally.
> 
>>
>>> -    pkt->duration = 1;
>>> -    pkt->pts      = (pkt->pos - c->header_size) / size;
>>> +    pkt->duration = size / (BLOCK_SIZE * par->channels);
>>> +    pkt->pts      = (pkt->pos - c->header_size) / (BLOCK_SIZE * par->channels);
>>>  
>>>      return 0;
>>>  }
>>>
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
Paul B Mahol Sept. 18, 2020, 11:04 a.m. UTC | #4
On Fri, Sep 18, 2020 at 12:29:41PM +0200, Andreas Rheinhardt wrote:
> Paul B Mahol:
> > On Fri, Sep 18, 2020 at 12:16:18PM +0200, Andreas Rheinhardt wrote:
> >> Paul B Mahol:
> >>> Improves decoding speed by 24x
> >>>
> >>> Signed-off-by: Paul B Mahol <onemda@gmail.com>
> >>> ---
> >>>  libavformat/adxdec.c | 23 +++++++++++++++--------
> >>>  1 file changed, 15 insertions(+), 8 deletions(-)
> >>>
> >>> diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c
> >>> index ccd5049acd..0e4c251cfc 100644
> >>> --- a/libavformat/adxdec.c
> >>> +++ b/libavformat/adxdec.c
> >>> @@ -53,6 +53,9 @@ static int adx_read_packet(AVFormatContext *s, AVPacket *pkt)
> >>>      AVCodecParameters *par = s->streams[0]->codecpar;
> >>>      int ret, size;
> >>>  
> >>> +    if (avio_feof(s->pb))
> >>> +        return AVERROR_EOF;
> >>> +
> >>>      if (par->channels <= 0) {
> >>>          av_log(s, AV_LOG_ERROR, "invalid number of channels %d\n", par->channels);
> >>>          return AVERROR_INVALIDDATA;
> >>> @@ -63,16 +66,20 @@ static int adx_read_packet(AVFormatContext *s, AVPacket *pkt)
> >>>      pkt->pos = avio_tell(s->pb);
> >>>      pkt->stream_index = 0;
> >>>  
> >>> -    ret = av_get_packet(s->pb, pkt, size);
> >>> -    if (ret != size) {
> >>> -        return ret < 0 ? ret : AVERROR(EIO);
> >>> -    }
> >>> -    if (AV_RB16(pkt->data) & 0x8000) {
> >>> -        return AVERROR_EOF;
> >>> +    ret = av_get_packet(s->pb, pkt, size * 128);
> >>> +    if (ret < 0)
> >>> +        return ret;
> >>> +    if ((ret % size) && ret >= size) {
> >>
> >> So if ret < size you don't set the corrupt flag. Why?
> > 
> > Because data, that is not gonna be used at all, is discarded, instead of
> > pointlessly being passed to decoder and there errored out.
> > This happens at every single eof.
> > 
> 
> But you don't return an error if the return value is in the range
> 0..size - 1; you return the packet with the incomplete and apparently
> useless packet.

I fixed that locally too.

> 
> >>
> >>> +        size = ret - (ret % size);
> >>> +        av_shrink_packet(pkt, size);
> >>> +        pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
> >>> +    } else {
> >>> +        size = ret;
> >>>      }
> >>> +
> >>>      pkt->size     = size;
> >>
> >> This line makes no sense any more: If the first branch above is taken,
> >> av_shrink_packet() will already set the size; in the other branch,
> >> av_get_packet() already did.
> > 
> > Removed that line locally.
> > 
> >>
> >>> -    pkt->duration = 1;
> >>> -    pkt->pts      = (pkt->pos - c->header_size) / size;
> >>> +    pkt->duration = size / (BLOCK_SIZE * par->channels);
> >>> +    pkt->pts      = (pkt->pos - c->header_size) / (BLOCK_SIZE * par->channels);
> >>>  
> >>>      return 0;
> >>>  }
> >>>
> >>
> >> _______________________________________________
> >> ffmpeg-devel mailing list
> >> ffmpeg-devel@ffmpeg.org
> >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >>
> >> To unsubscribe, visit link above, or email
> >> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> > 
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> > 
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff mbox series

Patch

diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c
index ccd5049acd..0e4c251cfc 100644
--- a/libavformat/adxdec.c
+++ b/libavformat/adxdec.c
@@ -53,6 +53,9 @@  static int adx_read_packet(AVFormatContext *s, AVPacket *pkt)
     AVCodecParameters *par = s->streams[0]->codecpar;
     int ret, size;
 
+    if (avio_feof(s->pb))
+        return AVERROR_EOF;
+
     if (par->channels <= 0) {
         av_log(s, AV_LOG_ERROR, "invalid number of channels %d\n", par->channels);
         return AVERROR_INVALIDDATA;
@@ -63,16 +66,20 @@  static int adx_read_packet(AVFormatContext *s, AVPacket *pkt)
     pkt->pos = avio_tell(s->pb);
     pkt->stream_index = 0;
 
-    ret = av_get_packet(s->pb, pkt, size);
-    if (ret != size) {
-        return ret < 0 ? ret : AVERROR(EIO);
-    }
-    if (AV_RB16(pkt->data) & 0x8000) {
-        return AVERROR_EOF;
+    ret = av_get_packet(s->pb, pkt, size * 128);
+    if (ret < 0)
+        return ret;
+    if ((ret % size) && ret >= size) {
+        size = ret - (ret % size);
+        av_shrink_packet(pkt, size);
+        pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
+    } else {
+        size = ret;
     }
+
     pkt->size     = size;
-    pkt->duration = 1;
-    pkt->pts      = (pkt->pos - c->header_size) / size;
+    pkt->duration = size / (BLOCK_SIZE * par->channels);
+    pkt->pts      = (pkt->pos - c->header_size) / (BLOCK_SIZE * par->channels);
 
     return 0;
 }