diff mbox

[FFmpeg-devel] lavc/cuvid: fail early if GPU can't handle given video resolution

Message ID 1483318859-13482-1-git-send-email-pkoshevoy@gmail.com
State Superseded
Headers show

Commit Message

Pavel Koshevoy Jan. 2, 2017, 1 a.m. UTC
From: Pavel Koshevoy <pkoshevoy@gmail.com>

NVDEC (CUVID) does not support unlimited video resolutions, so if the
resolution of the source is known it can be used during avcodec_open2
call to fail early, rather than failing later during
avcodec_send_packet call.

This problem surfaced when trying to decode 5120x2700 h246 video on
Geforce GT 730 -- avcodec_open2 succeeded but decoding failed.
---
 libavcodec/cuvid.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Pavel Koshevoy Jan. 2, 2017, 7:56 a.m. UTC | #1
On Sun, Jan 1, 2017 at 6:00 PM,  <pkoshevoy@gmail.com> wrote:
> From: Pavel Koshevoy <pkoshevoy@gmail.com>
>
> NVDEC (CUVID) does not support unlimited video resolutions, so if the
> resolution of the source is known it can be used during avcodec_open2
> call to fail early, rather than failing later during
> avcodec_send_packet call.
>
> This problem surfaced when trying to decode 5120x2700 h246 video on
> Geforce GT 730 -- avcodec_open2 succeeded but decoding failed.
> ---
>  libavcodec/cuvid.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/libavcodec/cuvid.c b/libavcodec/cuvid.c
> index 8fc713d..2e70b62 100644
> --- a/libavcodec/cuvid.c
> +++ b/libavcodec/cuvid.c
> @@ -625,8 +625,8 @@ static int cuvid_test_dummy_decoder(AVCodecContext *avctx, CUVIDPARSERPARAMS *cu
>      cuinfo.ChromaFormat = cudaVideoChromaFormat_420;
>      cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12;
>
> -    cuinfo.ulWidth = 1280;
> -    cuinfo.ulHeight = 720;
> +    cuinfo.ulWidth = avctx->coded_width ? avctx->coded_width : 1280;
> +    cuinfo.ulHeight = avctx->coded_height ? avctx->coded_height : 720;
>      cuinfo.ulTargetWidth = cuinfo.ulWidth;
>      cuinfo.ulTargetHeight = cuinfo.ulHeight;
>
> --
> 2.9.2
>


Perhaps a more comprehensive solution is needed.  I've run into the
same problem again (avcodec_open2 succeeds, decoding spits errors)
when I tried to play back an mpeg2 stream with YUV422P pixel format.

I have a new patch but I'd like to test it on a Pascal GPU first.  I
am still hoping that 422 decoding will work.  It looks like it should
be supported, but I've observed on Geforce GT 730 that even though I
can instantiate a cuvid decoder with cudaVideoChromaFormat_422 without
error -- the decoded video is garbage everywhere except for 16-pixel
wide column along the left edge of the frame.

In ee88dcb2 cuvid_handle_video_sequence was hard-coded to error-out if
the chroma format is not 420.  This looks like an NVIDIA driver/cuvid
bug... does anyone know how to bring it to their attention?

    Pavel
Philip Langdale Jan. 2, 2017, 4:37 p.m. UTC | #2
On Mon, 2 Jan 2017 00:56:18 -0700
Pavel Koshevoy <pkoshevoy@gmail.com> wrote:

> On Sun, Jan 1, 2017 at 6:00 PM,  <pkoshevoy@gmail.com> wrote:
> > From: Pavel Koshevoy <pkoshevoy@gmail.com>
> >
> > NVDEC (CUVID) does not support unlimited video resolutions, so if
> > the resolution of the source is known it can be used during
> > avcodec_open2 call to fail early, rather than failing later during
> > avcodec_send_packet call.
> >
> > This problem surfaced when trying to decode 5120x2700 h246 video on
> > Geforce GT 730 -- avcodec_open2 succeeded but decoding failed.
> > ---
> >  libavcodec/cuvid.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/libavcodec/cuvid.c b/libavcodec/cuvid.c
> > index 8fc713d..2e70b62 100644
> > --- a/libavcodec/cuvid.c
> > +++ b/libavcodec/cuvid.c
> > @@ -625,8 +625,8 @@ static int
> > cuvid_test_dummy_decoder(AVCodecContext *avctx, CUVIDPARSERPARAMS
> > *cu cuinfo.ChromaFormat = cudaVideoChromaFormat_420;
> > cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12;
> >
> > -    cuinfo.ulWidth = 1280;
> > -    cuinfo.ulHeight = 720;
> > +    cuinfo.ulWidth = avctx->coded_width ? avctx->coded_width :
> > 1280;
> > +    cuinfo.ulHeight = avctx->coded_height ? avctx->coded_height :
> > 720; cuinfo.ulTargetWidth = cuinfo.ulWidth;
> >      cuinfo.ulTargetHeight = cuinfo.ulHeight;
> >
> > --
> > 2.9.2
> >  
> 
> 
> Perhaps a more comprehensive solution is needed.  I've run into the
> same problem again (avcodec_open2 succeeds, decoding spits errors)
> when I tried to play back an mpeg2 stream with YUV422P pixel format.
> 
> I have a new patch but I'd like to test it on a Pascal GPU first.  I
> am still hoping that 422 decoding will work.  It looks like it should
> be supported, but I've observed on Geforce GT 730 that even though I
> can instantiate a cuvid decoder with cudaVideoChromaFormat_422 without
> error -- the decoded video is garbage everywhere except for 16-pixel
> wide column along the left edge of the frame.
> 
> In ee88dcb2 cuvid_handle_video_sequence was hard-coded to error-out if
> the chroma format is not 420.  This looks like an NVIDIA driver/cuvid
> bug... does anyone know how to bring it to their attention?

It is documented as only supporting 420, even though it doesn't return
an error, so it's not a bug per-se - it's just that they don't detect
and return an error, so we do it ourselves.

--phil
Pavel Koshevoy Jan. 2, 2017, 8:51 p.m. UTC | #3
On Mon, Jan 2, 2017 at 9:37 AM, Philip Langdale <philipl@overt.org> wrote:
> On Mon, 2 Jan 2017 00:56:18 -0700
> Pavel Koshevoy <pkoshevoy@gmail.com> wrote:

>> Perhaps a more comprehensive solution is needed.  I've run into the
>> same problem again (avcodec_open2 succeeds, decoding spits errors)
>> when I tried to play back an mpeg2 stream with YUV422P pixel format.
>>
>> I have a new patch but I'd like to test it on a Pascal GPU first.  I
>> am still hoping that 422 decoding will work.  It looks like it should
>> be supported, but I've observed on Geforce GT 730 that even though I
>> can instantiate a cuvid decoder with cudaVideoChromaFormat_422 without
>> error -- the decoded video is garbage everywhere except for 16-pixel
>> wide column along the left edge of the frame.
>>
>> In ee88dcb2 cuvid_handle_video_sequence was hard-coded to error-out if
>> the chroma format is not 420.  This looks like an NVIDIA driver/cuvid
>> bug... does anyone know how to bring it to their attention?
>
> It is documented as only supporting 420, even though it doesn't return
> an error, so it's not a bug per-se - it's just that they don't detect
> and return an error, so we do it ourselves.
>
> --phil


I don't recall seeing it mentioned that they do not support 422 and
444 in nvidia docs, but I haven't looked very hard yet.  I find it odd
that they have enum values to represent these chroma formats, yet they
don't work...  I'll see if I can file a bug with nvidia about this,
tomorrow.  I'll send another patch in about an hour to address the
original problem that got me looking in cuvid.c.

    Pavel.
Hendrik Leppkes Jan. 2, 2017, 9 p.m. UTC | #4
On Jan 3, 2017 07:52, "Pavel Koshevoy" <pkoshevoy@gmail.com> wrote:

On Mon, Jan 2, 2017 at 9:37 AM, Philip Langdale <philipl@overt.org> wrote:
> On Mon, 2 Jan 2017 00:56:18 -0700
> Pavel Koshevoy <pkoshevoy@gmail.com> wrote:

>> Perhaps a more comprehensive solution is needed.  I've run into the
>> same problem again (avcodec_open2 succeeds, decoding spits errors)
>> when I tried to play back an mpeg2 stream with YUV422P pixel format.
>>
>> I have a new patch but I'd like to test it on a Pascal GPU first.  I
>> am still hoping that 422 decoding will work.  It looks like it should
>> be supported, but I've observed on Geforce GT 730 that even though I
>> can instantiate a cuvid decoder with cudaVideoChromaFormat_422 without
>> error -- the decoded video is garbage everywhere except for 16-pixel
>> wide column along the left edge of the frame.
>>
>> In ee88dcb2 cuvid_handle_video_sequence was hard-coded to error-out if
>> the chroma format is not 420.  This looks like an NVIDIA driver/cuvid
>> bug... does anyone know how to bring it to their attention?
>
> It is documented as only supporting 420, even though it doesn't return
> an error, so it's not a bug per-se - it's just that they don't detect
> and return an error, so we do it ourselves.
>
> --phil


I don't recall seeing it mentioned that they do not support 422 and
444 in nvidia docs, but I haven't looked very hard yet.  I find it odd
that they have enum values to represent these chroma formats, yet they
don't work...  I'll see if I can file a bug with nvidia about this,
tomorrow.  I'll send another patch in about an hour to address the
original problem that got me looking in cuvid.c.


It's a rather well known limitation of the hardware. Only 4:2:0 and nothing
else.

Now what one has to keep in mind is that the parser is somewhat independent
of the hardware capabilities (and the decoder), so it can inform you about
stream properties even if the hardware doesn't support it, while the
decoder is of course more tightly coupled to the hardware and therefore
excludes it directly.

Feel free to open a bug if you must, but I don't see what good that's going
to do. The parser tells you what is in the stream, not if the hardware can
process it.

- Hendrik
Pavel Koshevoy Jan. 2, 2017, 10:08 p.m. UTC | #5
On Mon, Jan 2, 2017 at 2:00 PM, Hendrik Leppkes <h.leppkes@gmail.com> wrote:
> On Jan 3, 2017 07:52, "Pavel Koshevoy" <pkoshevoy@gmail.com> wrote:
>
> On Mon, Jan 2, 2017 at 9:37 AM, Philip Langdale <philipl@overt.org> wrote:

>> It is documented as only supporting 420, even though it doesn't return
>> an error, so it's not a bug per-se - it's just that they don't detect
>> and return an error, so we do it ourselves.
>>
>> --phil
>
>
> I don't recall seeing it mentioned that they do not support 422 and
> 444 in nvidia docs, but I haven't looked very hard yet.  I find it odd
> that they have enum values to represent these chroma formats, yet they
> don't work...  I'll see if I can file a bug with nvidia about this,
> tomorrow.  I'll send another patch in about an hour to address the
> original problem that got me looking in cuvid.c.
>
>
> It's a rather well known limitation of the hardware. Only 4:2:0 and nothing
> else.
>
> Now what one has to keep in mind is that the parser is somewhat independent
> of the hardware capabilities (and the decoder), so it can inform you about
> stream properties even if the hardware doesn't support it, while the
> decoder is of course more tightly coupled to the hardware and therefore
> excludes it directly.
>
> Feel free to open a bug if you must, but I don't see what good that's going
> to do. The parser tells you what is in the stream, not if the hardware can
> process it.
>
> - Hendrik


Actually, I have a 4:2:2 file that does decode "fine" with mjpeg_cuvid:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '422.mov':
  Metadata:
    creation_time   : 2004-04-12T14:27:11.000000Z
  Duration: 00:00:26.28, start: 0.000000, bitrate: 27683 kb/s
    Stream #0:0(eng): Video: mjpeg (jpeg / 0x6765706A), yuvj422p(pc,
bt470bg/unknown/unknown), 720x486 [SAR 72:72 DAR 40:27], 27538 kb/s,
29.97 fps, 29.97 tbr, 2997 tbn, 2997 tbc (default)
    Metadata:
      creation_time   : 2004-04-12T14:27:11.000000Z
      handler_name    : Apple Alias Data Handler
      encoder         : Photo - JPEG
    Stream #0:1(eng): Audio: mp3 (ms[0]U / 0x5500736D), 44100 Hz,
stereo, s16p, 128 kb/s (default)
    Metadata:
      creation_time   : 2004-04-12T14:27:11.000000Z
      handler_name    : Apple Alias Data Handler

It decodes "fine", except for one green line along the bottom edge of the frame.


The other file I have that decodes with severe artifacts with mpeg2_cuvid is:
Input #0, mxf, from '422.mxf':
  Metadata:
    uid             : 903476a1-f73c-11df-bbb6-001c23d05b47
    generation_uid  : 903476a2-f73c-11df-b56d-001c23d05b47
    company_name    : Telestream
    product_name    : FlipFactory
    product_version : 3.0
    application_platform: win32
    product_uid     : ffeeddcc-bbaa-9988-7766-554433221100
    modification_date: 2010-11-23T20:02:13.000000Z
    material_package_umid:
0x060A2B340101010501010D12134CFC7B94BB4C04235505834F1F001C23D05B47
    timecode        : 00:00:00:00
  Duration: 00:03:35.05, start: 0.000000, bitrate: 62607 kb/s
    Stream #0:0: Video: mpeg2video (4:2:2), yuv422p(tv,
bt470bg/bt470m/bt470m, top first), 720x512 [SAR 128:135 DAR 4:3],
50000 kb/s, 29.97 fps, 29.97 tbr, 29.97 tbn, 59.94 tbc
    Metadata:
      file_package_umid:
0x060A2B340101010501010D121360585A56BB4C0423550583575A001C23D05B47
      file_package_name: Source Package
      track_name      : Track 1
    Stream #0:1: Audio: pcm_s24le, 48000 Hz, 4 channels, s32 (24 bit), 4608 kb/s
    Metadata:
      file_package_umid:
0x060A2B340101010501010D121360585A56BB4C0423550583575A001C23D05B47
      file_package_name: Source Package
      track_name      : Track 2

Still feels like an NVIDIA bug,
    Pavel
Pavel Koshevoy Jan. 3, 2017, 12:24 a.m. UTC | #6
On Mon, Jan 2, 2017 at 3:08 PM, Pavel Koshevoy <pkoshevoy@gmail.com> wrote:
> On Mon, Jan 2, 2017 at 2:00 PM, Hendrik Leppkes <h.leppkes@gmail.com> wrote:
>> On Jan 3, 2017 07:52, "Pavel Koshevoy" <pkoshevoy@gmail.com> wrote:
>>
>> On Mon, Jan 2, 2017 at 9:37 AM, Philip Langdale <philipl@overt.org> wrote:
>
>>> It is documented as only supporting 420, even though it doesn't return
>>> an error, so it's not a bug per-se - it's just that they don't detect
>>> and return an error, so we do it ourselves.
>>>
>>> --phil
>>
>>
>> I don't recall seeing it mentioned that they do not support 422 and
>> 444 in nvidia docs, but I haven't looked very hard yet.  I find it odd
>> that they have enum values to represent these chroma formats, yet they
>> don't work...  I'll see if I can file a bug with nvidia about this,
>> tomorrow.  I'll send another patch in about an hour to address the
>> original problem that got me looking in cuvid.c.
>>
>>
>> It's a rather well known limitation of the hardware. Only 4:2:0 and nothing
>> else.
>>
>> Now what one has to keep in mind is that the parser is somewhat independent
>> of the hardware capabilities (and the decoder), so it can inform you about
>> stream properties even if the hardware doesn't support it, while the
>> decoder is of course more tightly coupled to the hardware and therefore
>> excludes it directly.
>>
>> Feel free to open a bug if you must, but I don't see what good that's going
>> to do. The parser tells you what is in the stream, not if the hardware can
>> process it.
>>
>> - Hendrik
>
>
> Actually, I have a 4:2:2 file that does decode "fine" with mjpeg_cuvid:
> Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '422.mov':
>   Metadata:
>     creation_time   : 2004-04-12T14:27:11.000000Z
>   Duration: 00:00:26.28, start: 0.000000, bitrate: 27683 kb/s
>     Stream #0:0(eng): Video: mjpeg (jpeg / 0x6765706A), yuvj422p(pc,
> bt470bg/unknown/unknown), 720x486 [SAR 72:72 DAR 40:27], 27538 kb/s,
> 29.97 fps, 29.97 tbr, 2997 tbn, 2997 tbc (default)
>     Metadata:
>       creation_time   : 2004-04-12T14:27:11.000000Z
>       handler_name    : Apple Alias Data Handler
>       encoder         : Photo - JPEG
>     Stream #0:1(eng): Audio: mp3 (ms[0]U / 0x5500736D), 44100 Hz,
> stereo, s16p, 128 kb/s (default)
>     Metadata:
>       creation_time   : 2004-04-12T14:27:11.000000Z
>       handler_name    : Apple Alias Data Handler
>
> It decodes "fine", except for one green line along the bottom edge of the frame.
>
>
> The other file I have that decodes with severe artifacts with mpeg2_cuvid is:
> Input #0, mxf, from '422.mxf':
>   Metadata:
>     uid             : 903476a1-f73c-11df-bbb6-001c23d05b47
>     generation_uid  : 903476a2-f73c-11df-b56d-001c23d05b47
>     company_name    : Telestream
>     product_name    : FlipFactory
>     product_version : 3.0
>     application_platform: win32
>     product_uid     : ffeeddcc-bbaa-9988-7766-554433221100
>     modification_date: 2010-11-23T20:02:13.000000Z
>     material_package_umid:
> 0x060A2B340101010501010D12134CFC7B94BB4C04235505834F1F001C23D05B47
>     timecode        : 00:00:00:00
>   Duration: 00:03:35.05, start: 0.000000, bitrate: 62607 kb/s
>     Stream #0:0: Video: mpeg2video (4:2:2), yuv422p(tv,
> bt470bg/bt470m/bt470m, top first), 720x512 [SAR 128:135 DAR 4:3],
> 50000 kb/s, 29.97 fps, 29.97 tbr, 29.97 tbn, 59.94 tbc
>     Metadata:
>       file_package_umid:
> 0x060A2B340101010501010D121360585A56BB4C0423550583575A001C23D05B47
>       file_package_name: Source Package
>       track_name      : Track 1
>     Stream #0:1: Audio: pcm_s24le, 48000 Hz, 4 channels, s32 (24 bit), 4608 kb/s
>     Metadata:
>       file_package_umid:
> 0x060A2B340101010501010D121360585A56BB4C0423550583575A001C23D05B47
>       file_package_name: Source Package
>       track_name      : Track 2
>
> Still feels like an NVIDIA bug,
>     Pavel


I've tested three 4:2:2 mjpeg samples so far that decode fine with
mjpeg_cuvid, and one 4:4:4 mjpeg sample that also decoded correctly
with mjpeg_cuvid ... so it seems at least MJPEG support is not limited
to 4:2:0 by CUVID

    Pavel.
Ruta Gadkari Jan. 6, 2017, 6:15 a.m. UTC | #7
On Jan 3, 2017 03:38 AM, "Pavel Koshevoy" <pkoshevoy@gmail.com> wrote:

>> I don't recall seeing it mentioned that they do not support 422 and

>> 444 in nvidia docs


> It decodes "fine", except for one green line along the bottom edge of the frame.

> The other file I have that decodes with severe artifacts with mpeg2_cuvid is


Thank you for bringing this to notice. We are working on this and will update the thread again once the fixes are in place.

Thanks
Ruta 






-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------
diff mbox

Patch

diff --git a/libavcodec/cuvid.c b/libavcodec/cuvid.c
index 8fc713d..2e70b62 100644
--- a/libavcodec/cuvid.c
+++ b/libavcodec/cuvid.c
@@ -625,8 +625,8 @@  static int cuvid_test_dummy_decoder(AVCodecContext *avctx, CUVIDPARSERPARAMS *cu
     cuinfo.ChromaFormat = cudaVideoChromaFormat_420;
     cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12;
 
-    cuinfo.ulWidth = 1280;
-    cuinfo.ulHeight = 720;
+    cuinfo.ulWidth = avctx->coded_width ? avctx->coded_width : 1280;
+    cuinfo.ulHeight = avctx->coded_height ? avctx->coded_height : 720;
     cuinfo.ulTargetWidth = cuinfo.ulWidth;
     cuinfo.ulTargetHeight = cuinfo.ulHeight;