[FFmpeg-devel] libavcodec/libdav1d: add libdav1d_get_format method to call ff_get_format

Submitted by Lukas Rusak on April 10, 2019, 10:33 p.m.

Details

Message ID 20190410223314.11735-1-lorusak@gmail.com
State New
Headers show

Commit Message

Lukas Rusak April 10, 2019, 10:33 p.m.
This will allow applications to properly init the decoder in
cases where a hardware decoder is tried first and and software
decoder is tried after by calling the get_format callback.

Even though there is no hardware pixel formats available
we still need to return the software pixel format.

Tested with Kodi by checking if multithreaded software
decoding is properly activated.
---
 libavcodec/libdav1d.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

Comments

Hendrik Leppkes April 10, 2019, 10:49 p.m.
On Thu, Apr 11, 2019 at 12:39 AM Lukas Rusak <lorusak@gmail.com> wrote:
>
> This will allow applications to properly init the decoder in
> cases where a hardware decoder is tried first and and software
> decoder is tried after by calling the get_format callback.
>
> Even though there is no hardware pixel formats available
> we still need to return the software pixel format.
>
> Tested with Kodi by checking if multithreaded software
> decoding is properly activated.
> ---
>  libavcodec/libdav1d.c | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
>

This doesn't make sense to m e. get_format isn't called on a wide
variety of decoders, and is only useful when there is a hardware
format of any kind.
Please elaborate what exactly this is trying to achieve.

- Hendrik
Peter F April 11, 2019, 5:41 p.m.
Hi,

Am Do., 11. Apr. 2019 um 00:50 Uhr schrieb Hendrik Leppkes
<h.leppkes@gmail.com>:
>
> On Thu, Apr 11, 2019 at 12:39 AM Lukas Rusak <lorusak@gmail.com> wrote:
> >
> > This will allow applications to properly init the decoder in
> > cases where a hardware decoder is tried first and and software
> > decoder is tried after by calling the get_format callback.
> >
> > Even though there is no hardware pixel formats available
> > we still need to return the software pixel format.
> >
> > Tested with Kodi by checking if multithreaded software
> > decoding is properly activated.
> > ---
> >  libavcodec/libdav1d.c | 12 +++++++++++-
> >  1 file changed, 11 insertions(+), 1 deletion(-)
> >
>
> This doesn't make sense to m e. get_format isn't called on a wide
> variety of decoders, and is only useful when there is a hardware
> format of any kind.
> Please elaborate what exactly this is trying to achieve.

Can you elaborate on how to use ffmpeg's API properly as a client to
decide if a decoder is a SW decoder and therefore howto properly setup
(multi-)threading, especially it cannot be changed once initialized?

Peter

>
> - Hendrik
> _______________________________________________
> 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".
Hendrik Leppkes April 11, 2019, 7:03 p.m.
On Thu, Apr 11, 2019 at 7:47 PM Peter F <peter.fruehberger@gmail.com> wrote:
>
> Hi,
>
> Am Do., 11. Apr. 2019 um 00:50 Uhr schrieb Hendrik Leppkes
> <h.leppkes@gmail.com>:
> >
> > On Thu, Apr 11, 2019 at 12:39 AM Lukas Rusak <lorusak@gmail.com> wrote:
> > >
> > > This will allow applications to properly init the decoder in
> > > cases where a hardware decoder is tried first and and software
> > > decoder is tried after by calling the get_format callback.
> > >
> > > Even though there is no hardware pixel formats available
> > > we still need to return the software pixel format.
> > >
> > > Tested with Kodi by checking if multithreaded software
> > > decoding is properly activated.
> > > ---
> > >  libavcodec/libdav1d.c | 12 +++++++++++-
> > >  1 file changed, 11 insertions(+), 1 deletion(-)
> > >
> >
> > This doesn't make sense to m e. get_format isn't called on a wide
> > variety of decoders, and is only useful when there is a hardware
> > format of any kind.
> > Please elaborate what exactly this is trying to achieve.
>
> Can you elaborate on how to use ffmpeg's API properly as a client to
> decide if a decoder is a SW decoder and therefore howto properly setup
> (multi-)threading, especially it cannot be changed once initialized?
>

I think you are approaching this from the wrong side. Even if the
decoder would support hardware, generally hardware support is limited.
So if someone plays a 10-bit  H264 file, which no consumer hardware
supports, or even worse, a very high resolution file which is beyond
hardware limits, do you want to run single-threaded and slow? I hope
not.

The way I solve that is to just close the decoder and re-open it if
needed, so I can change such settings. You also fare much  better if
you accept that you might  need to hard-code which codecs support
hardware at all. Considering thats one new one every 4 years or so,
it'll probably be fine.

- Hendrik
Lukas Rusak April 12, 2019, 11:16 p.m.
On Thu, 2019-04-11 at 21:03 +0200, Hendrik Leppkes wrote:
> On Thu, Apr 11, 2019 at 7:47 PM Peter F <peter.fruehberger@gmail.com>
> wrote:
> > Hi,
> > 
> > Am Do., 11. Apr. 2019 um 00:50 Uhr schrieb Hendrik Leppkes
> > <h.leppkes@gmail.com>:
> > > On Thu, Apr 11, 2019 at 12:39 AM Lukas Rusak <lorusak@gmail.com>
> > > wrote:
> > > > This will allow applications to properly init the decoder in
> > > > cases where a hardware decoder is tried first and and software
> > > > decoder is tried after by calling the get_format callback.
> > > > 
> > > > Even though there is no hardware pixel formats available
> > > > we still need to return the software pixel format.
> > > > 
> > > > Tested with Kodi by checking if multithreaded software
> > > > decoding is properly activated.
> > > > ---
> > > >  libavcodec/libdav1d.c | 12 +++++++++++-
> > > >  1 file changed, 11 insertions(+), 1 deletion(-)
> > > > 
> > > 
> > > This doesn't make sense to m e. get_format isn't called on a wide
> > > variety of decoders, and is only useful when there is a hardware
> > > format of any kind.
> > > Please elaborate what exactly this is trying to achieve.
> > 
> > Can you elaborate on how to use ffmpeg's API properly as a client
> > to
> > decide if a decoder is a SW decoder and therefore howto properly
> > setup
> > (multi-)threading, especially it cannot be changed once
> > initialized?
> > 
> 
> I think you are approaching this from the wrong side. Even if the
> decoder would support hardware, generally hardware support is
> limited.
> So if someone plays a 10-bit  H264 file, which no consumer hardware
> supports, or even worse, a very high resolution file which is beyond
> hardware limits, do you want to run single-threaded and slow? I hope
> not.
> 
> The way I solve that is to just close the decoder and re-open it if
> needed, so I can change such settings. You also fare much  better if
> you accept that you might  need to hard-code which codecs support
> hardware at all. Considering thats one new one every 4 years or so,
> it'll probably be fine.
> 
> - Hendrik

So why don't the software only formats follow the api and also call
ff_get_format like is done here? That would stop from applications
having to hardcode the hardware decoding formats.

What we do currently is open the codec single threaded to try
hardware formats. The get_format callback will return a hardware format
for the decoder and if not we reopen the codec with multithreading
enabled. Is there a better method to do this initialization?

Regards,
Lukas Rusak
Hendrik Leppkes April 12, 2019, 11:27 p.m.
On Sat, Apr 13, 2019 at 1:17 AM Lukas Rusak <lorusak@gmail.com> wrote:
>
> On Thu, 2019-04-11 at 21:03 +0200, Hendrik Leppkes wrote:
> > On Thu, Apr 11, 2019 at 7:47 PM Peter F <peter.fruehberger@gmail.com>
> > wrote:
> > > Hi,
> > >
> > > Am Do., 11. Apr. 2019 um 00:50 Uhr schrieb Hendrik Leppkes
> > > <h.leppkes@gmail.com>:
> > > > On Thu, Apr 11, 2019 at 12:39 AM Lukas Rusak <lorusak@gmail.com>
> > > > wrote:
> > > > > This will allow applications to properly init the decoder in
> > > > > cases where a hardware decoder is tried first and and software
> > > > > decoder is tried after by calling the get_format callback.
> > > > >
> > > > > Even though there is no hardware pixel formats available
> > > > > we still need to return the software pixel format.
> > > > >
> > > > > Tested with Kodi by checking if multithreaded software
> > > > > decoding is properly activated.
> > > > > ---
> > > > >  libavcodec/libdav1d.c | 12 +++++++++++-
> > > > >  1 file changed, 11 insertions(+), 1 deletion(-)
> > > > >
> > > >
> > > > This doesn't make sense to m e. get_format isn't called on a wide
> > > > variety of decoders, and is only useful when there is a hardware
> > > > format of any kind.
> > > > Please elaborate what exactly this is trying to achieve.
> > >
> > > Can you elaborate on how to use ffmpeg's API properly as a client
> > > to
> > > decide if a decoder is a SW decoder and therefore howto properly
> > > setup
> > > (multi-)threading, especially it cannot be changed once
> > > initialized?
> > >
> >
> > I think you are approaching this from the wrong side. Even if the
> > decoder would support hardware, generally hardware support is
> > limited.
> > So if someone plays a 10-bit  H264 file, which no consumer hardware
> > supports, or even worse, a very high resolution file which is beyond
> > hardware limits, do you want to run single-threaded and slow? I hope
> > not.
> >
> > The way I solve that is to just close the decoder and re-open it if
> > needed, so I can change such settings. You also fare much  better if
> > you accept that you might  need to hard-code which codecs support
> > hardware at all. Considering thats one new one every 4 years or so,
> > it'll probably be fine.
> >
> > - Hendrik
>
> So why don't the software only formats follow the api and also call
> ff_get_format like is done here? That would stop from applications
> having to hardcode the hardware decoding formats.
>

Because the callback is useless if there is only one format.
Its meant to negotiate hardware formats, not inform the user that
there is no hardware acceleration. There is also dozens if not
hundreds of codecs, changing them all to add the callback would be a
lot of work for apparently no benefit.

If you just want to know if a decoder supports hardware acceleration
of any kind, then check AVCodec.hw_configs, it contains plenty
information to make such decisions without hardcoding anything.

- Hendrik

Patch hide | download patch | download mbox

diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
index 30c6eccfef..fa71834543 100644
--- a/libavcodec/libdav1d.c
+++ b/libavcodec/libdav1d.c
@@ -48,6 +48,16 @@  static const enum AVPixelFormat pix_fmt[][3] = {
     [DAV1D_PIXEL_LAYOUT_I444] = { AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12 },
 };
 
+static enum AVPixelFormat libdav1d_get_format(AVCodecContext *avctx, const Dav1dPicture *p)
+{
+   enum AVPixelFormat pix_fmts[2], *fmt = pix_fmts;
+
+   *fmt++ = pix_fmt[p->p.layout][p->seq_hdr->hbd];
+   *fmt = AV_PIX_FMT_NONE;
+
+   return ff_get_format(avctx, pix_fmts);
+}
+
 static void libdav1d_log_callback(void *opaque, const char *fmt, va_list vl)
 {
     AVCodecContext *c = opaque;
@@ -214,7 +224,7 @@  static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
     frame->linesize[2] = p->stride[1];
 
     c->profile = p->seq_hdr->profile;
-    frame->format = c->pix_fmt = pix_fmt[p->p.layout][p->seq_hdr->hbd];
+    frame->format = c->pix_fmt = libdav1d_get_format(c, p);
     frame->width = p->p.w;
     frame->height = p->p.h;
     if (c->width != p->p.w || c->height != p->p.h) {