<html><head></head><body style="zoom: 0%;"><div dir="auto">Well, my use case would benefit greatly from outputting CPU chromas, for the exact reason you mention.<br><br></div>
<div dir="auto">The idea behind this patch was rather to remove unused code...</div>
<div class="gmail_quote" >On Mar 20, 2020, at 08:38, Steve Lhomme <<a href="mailto:robux4@ycbcr.xyz" target="_blank">robux4@ycbcr.xyz</a>> wrote:<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<pre class="blue">The code looks correct and mostly removes dead code, as in real life <br>there's not a case where the opaque output is refused.<br><br>My main concern is the timing of when this conversion is done. Moving it <br>in the display thread just before displaying a picture is not optimal <br>and could result in frame drops. It's a bit different than other <br>hardware acceleration as we usually pair them with a display module that <br>can handle them with no converter. This is not possible with NVDEC.<br><br>Until we have CUDA filters we would be better off only outputting CPU <br>chromas. The same amount of computatation would be done but it would <br>free up some time in the display thread to better drop late frames.<br><br>In the long run this patch is the way to go and we should do chroma <br>conversions/deinterlacing outside of the display thread.<br><br>On 2020-03-19 17:42, quentin.chateau@deepskycorp.com wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;"> From: Quentin Chateau <quentin.chateau@deepskycorp.com><br> <br> MapSurfaceChroma now maps cudaChroma to opaque chromas<br> ---<br> modules/hw/nvdec/nvdec.c | 95 +++<hr><br> modules/hw/nvdec/nvdec_fmt.h | 9 ----<br> modules/hw/nvdec/nvdec_gl.c | 3 --<br> 3 files changed, 6 insertions(+), 101 deletions(-)<br> <br> diff --git a/modules/hw/nvdec/nvdec.c b/modules/hw/nvdec/nvdec.c<br> index 321815071d..9ee61e8c5e 100644<br> --- a/modules/hw/nvdec/nvdec.c<br> +++ b/modules/hw/nvdec/nvdec.c<br> @@ -112,14 +112,14 @@ static vlc_fourcc_t MapSurfaceChroma(cudaVideoChromaFormat chroma, unsigned bitD<br> switch (chroma) {<br> case cudaVideoChromaFormat_420:<br> if (bitDepth <= 8)<br> - return VLC_CODEC_NV12;<br> + return VLC_CODEC_NVDEC_OPAQUE;<br> if (bitDepth <= 10)<br> - return VLC_CODEC_P010;<br> - return VLC_CODEC_P016;<br> + return VLC_CODEC_NVDEC_OPAQUE_10B;<br> + return VLC_CODEC_NVDEC_OPAQUE_16B;<br> case cudaVideoChromaFormat_444:<br> if (bitDepth <= 8)<br> - return VLC_CODEC_I444;<br> - return VLC_CODEC_I444_16L;<br> + return VLC_CODEC_NVDEC_OPAQUE_444;<br> + return VLC_CODEC_NVDEC_OPAQUE_444_16B;<br> default:<br> return 0;<br> }<br> @@ -130,17 +130,12 @@ static cudaVideoSurfaceFormat MapSurfaceFmt(int i_vlc_fourcc)<br> switch (i_vlc_fourcc) {<br> case VLC_CODEC_NVDEC_OPAQUE_10B:<br> case VLC_CODEC_NVDEC_OPAQUE_16B:<br> - case VLC_CODEC_P010:<br> - case VLC_CODEC_P016:<br> return cudaVideoSurfaceFormat_P016;<br> case VLC_CODEC_NVDEC_OPAQUE:<br> - case VLC_CODEC_NV12:<br> return cudaVideoSurfaceFormat_NV12;<br> case VLC_CODEC_NVDEC_OPAQUE_444:<br> - case VLC_CODEC_I444:<br> return cudaVideoSurfaceFormat_YUV444;<br> case VLC_CODEC_NVDEC_OPAQUE_444_16B:<br> - case VLC_CODEC_I444_16L:<br> return cudaVideoSurfaceFormat_YUV444_16Bit;<br> default: vlc_assert_unreachable();<br> }<br> @@ -150,15 +145,6 @@ static int CUtoFMT(video_format_t *fmt, const CUVIDEOFORMAT *p_format)<br> {<br> // bit depth and chroma<br> unsigned int i_bpp = p_format->bit_depth_luma_minus8 + 8;<br> - vlc_fourcc_t i_chroma;<br> - if (is_nvdec_opaque(fmt->i_chroma))<br> - i_chroma = fmt->i_chroma;<br> - else<br> - i_chroma = MapSurfaceChroma(p_format->chroma_format, i_bpp);<br> - if (i_chroma == 0)<br> - return VLC_EGENERIC;<br> -<br> - fmt->i_chroma = i_chroma;<br> // use the real padded size when we know it fmt->i_width = p_format->coded_width;<br> fmt->i_height = p_format->coded_height;<br> fmt->i_x_offset = p_format->display_area.left;<br> @@ -178,8 +164,6 @@ static int CUDAAPI HandleVideoSequence(void *p_opaque, CUVIDEOFORMAT *p_format)<br> nvdec_ctx_t *p_sys = p_dec->p_sys;<br> int ret;<br> <br> - if ( is_nvdec_opaque(p_dec->fmt_out.video.i_chroma) )<br> - {<br> for (size_t i=0; i < ARRAY_SIZE(p_sys->outputDevicePtr); i++)<br> {<br> CALL_CUDA_DEC(cuMemFree, p_sys->outputDevicePtr[i]);<br> @@ -191,7 +175,6 @@ static int CUDAAPI HandleVideoSequence(void *p_opaque, CUVIDEOFORMAT *p_format)<br> picture_pool_Release(p_sys->out_pool);<br> p_sys->out_pool = NULL;<br> }<br> - }<br> <br> // update vlc's output format using NVDEC parser's output<br> ret = CUtoFMT(&p_dec->fmt_out.video, p_format);<br> @@ -230,8 +213,6 @@ static int CUDAAPI HandleVideoSequence(void *p_opaque, CUVIDEOFORMAT *p_format)<br> goto error;<br> <br> // ensure the output surfaces have the same pitch so copies can work properly<br> - if ( is_nvdec_opaque(p_dec->fmt_out.video.i_chroma) )<br> - {<br> // get the real decoder pitch<br> CUdeviceptr frameDevicePtr = 0;<br> CUVIDPROCPARAMS params = {<br> @@ -297,8 +278,6 @@ clean_pics:<br> goto error;<br> <br> p_sys->out_pool = picture_pool_New( ARRAY_SIZE(p_sys->outputDevicePtr), pics );<br> - }<br> -<br> p_sys->decoderHeight = p_format->coded_height;<br> <br> CALL_CUDA_DEC(cuCtxPopCurrent, NULL);<br> @@ -359,8 +338,6 @@ static int CUDAAPI HandlePictureDisplay(void *p_opaque, CUVIDPARSERDISPINFO *p_d<br> };<br> int result;<br> <br> - if ( is_nvdec_opaque(p_dec->fmt_out.video.i_chroma) )<br> - {<br> p_pic = picture_pool_Wait(p_sys->out_pool);<br> if (unlikely(p_pic == NULL))<br> return 0;<br> @@ -449,49 +426,6 @@ static int CUDAAPI HandlePictureDisplay(void *p_opaque, CUVIDPARSERDISPINFO *p_d<br> }<br> p_pic->context = &picctx->ctx;<br> vlc_video_context_Hold(picctx->ctx.vctx);<br> - }<br> - else<br> - {<br> - p_pic = decoder_NewPicture(p_dec);<br> - if (unlikely(p_pic == NULL))<br> - return 0;<br> -<br> - result = CALL_CUDA_DEC(cuCtxPushCurrent, p_sys->devsys->cuCtx);<br> - if (unlikely(result != VLC_SUCCESS))<br> - {<br> - picture_Release(p_pic);<br> - return 0;<br> - }<br> -<br> - unsigned int i_pitch;<br> -<br> - // Map decoded frame to a device pointer<br> - result = CALL_CUVID( cuvidMapVideoFrame, p_sys->cudecoder, p_dispinfo->picture_index,<br> - &frameDevicePtr, &i_pitch, ¶ms );<br> - if (result != VLC_SUCCESS)<br> - goto error;<br> -<br> - // Copy decoded frame into a new VLC picture<br> - size_t srcY = 0;<br> - for (int i_plane = 0; i_plane < p_pic->i_planes; i_plane++) {<br> - plane_t plane = p_pic->p[i_plane];<br> - CUDA_MEMCPY2D cu_cpy = {<br> - .srcMemoryType = CU_MEMORYTYPE_DEVICE,<br> - .srcDevice = frameDevicePtr,<br> - .srcY = srcY,<br> - .srcPitch = i_pitch,<br> - .dstMemoryType = CU_MEMORYTYPE_HOST,<br> - .dstHost = plane.p_pixels,<br> - .dstPitch = plane.i_pitch,<br> - .WidthInBytes = i_pitch,<br> - .Height = plane.i_visible_lines,<br> - };<br> - result = CALL_CUDA_DEC(cuMemcpy2D, &cu_cpy);<br> - if (result != VLC_SUCCESS)<br> - goto error;<br> - srcY += p_sys->decoderHeight;<br> - }<br> - }<br> <br> // Release surface on GPU<br> result = CALL_CUVID(cuvidUnmapVideoFrame, p_sys->cudecoder, frameDevicePtr);<br> @@ -921,25 +855,8 @@ static int OpenDecoder(vlc_object_t *p_this)<br> goto error;<br> }<br> <br> - vlc_fourcc_t output_chromas[3];<br> + vlc_fourcc_t output_chromas[2];<br> size_t chroma_idx = 0;<br> - if (cudaChroma == cudaVideoChromaFormat_420)<br> - {<br> - if (i_depth_luma >= 16)<br> - output_chromas[chroma_idx++] = VLC_CODEC_NVDEC_OPAQUE_16B;<br> - else if (i_depth_luma > 8)<br> - output_chromas[chroma_idx++] = VLC_CODEC_NVDEC_OPAQUE_10B;<br> - else<br> - output_chromas[chroma_idx++] = VLC_CODEC_NVDEC_OPAQUE;<br> - }<br> - else if (cudaChroma == cudaVideoChromaFormat_444)<br> - {<br> - if (i_depth_luma > 8)<br> - output_chromas[chroma_idx++] = VLC_CODEC_NVDEC_OPAQUE_444_16B;<br> - else<br> - output_chromas[chroma_idx++] = VLC_CODEC_NVDEC_OPAQUE_444;<br> - }<br> -<br> output_chromas[chroma_idx++] = MapSurfaceChroma(cudaChroma, i_depth_luma);<br> output_chromas[chroma_idx++] = 0;<br> <br> diff --git a/modules/hw/nvdec/nvdec_fmt.h b/modules/hw/nvdec/nvdec_fmt.h<br> index 25784cca6d..d84672d8fb 100644<br> --- a/modules/hw/nvdec/nvdec_fmt.h<br> +++ b/modules/hw/nvdec/nvdec_fmt.h<br> @@ -51,15 +51,6 @@ static inline int CudaCheckErr(vlc_object_t *obj, CudaFunctions *cudaFunctions,<br> return VLC_SUCCESS;<br> }<br> <br> -static inline bool is_nvdec_opaque(vlc_fourcc_t fourcc)<br> -{<br> - return fourcc == VLC_CODEC_NVDEC_OPAQUE ||<br> - fourcc == VLC_CODEC_NVDEC_OPAQUE_10B ||<br> - fourcc == VLC_CODEC_NVDEC_OPAQUE_16B ||<br> - fourcc == VLC_CODEC_NVDEC_OPAQUE_444 ||<br> - fourcc == VLC_CODEC_NVDEC_OPAQUE_444_16B;<br> -}<br> -<br> /* for VLC_CODEC_NVDEC_OPAQUE / VLC_CODEC_NVDEC_OPAQUE_16B */<br> typedef struct<br> {<br> diff --git a/modules/hw/nvdec/nvdec_gl.c b/modules/hw/nvdec/nvdec_gl.c<br> index 137e730028..62a503a8e8 100644<br> --- a/modules/hw/nvdec/nvdec_gl.c<br> +++ b/modules/hw/nvdec/nvdec_gl.c<br> @@ -156,9 +156,6 @@ static void Close(vlc_object_t *obj)<br> static int Open(vlc_object_t *obj)<br> {<br> struct vlc_gl_interop *interop = (void *) obj;<br> - if (!is_nvdec_opaque(interop->fmt.i_chroma))<br> - return VLC_EGENERIC;<br> -<br> vlc_decoder_device *device = vlc_video_context_HoldDevice(interop->vctx);<br> if (device == NULL || device->type != VLC_DECODER_DEVICE_NVDEC)<br> return VLC_EGENERIC;<br> -- <br> 2.17.1<br> <br><hr><br> vlc-devel mailing list<br> To unsubscribe or modify your subscription options:<br> <a href="https://mailman.videolan.org/listinfo/vlc-devel">https://mailman.videolan.org/listinfo/vlc-devel</a><br> <br></blockquote><hr><br>vlc-devel mailing list<br>To unsubscribe or modify your subscription options:<br><a href="https://mailman.videolan.org/listinfo/vlc-devel">https://mailman.videolan.org/listinfo/vlc-devel</a></pre></blockquote></div></body></html>