@@ -134,6 +134,8 @@ namespace cuda {
134134 }
135135 }
136136
137+ is_yuv444 = (hwframe_ctx->sw_format == AV_PIX_FMT_YUV444P );
138+
137139 auto cuda_ctx = (AVCUDADeviceContext *) hwframe_ctx->device_ctx ->hwctx ;
138140
139141 stream = make_stream ();
@@ -180,11 +182,10 @@ namespace cuda {
180182 return ;
181183 }
182184
183- // frame->data[2] not null on YUV444 conversion
184- if (frame->data [2 ]) {
185+ if (is_yuv444) {
185186 sws.convert_yuv444 (frame->data [0 ], frame->data [1 ], frame->data [2 ], frame->linesize [0 ], tex->texture .linear , stream.get (), {frame->width , frame->height , 0 , 0 });
186187 } else {
187- sws.convert (frame->data [0 ], frame->data [1 ], frame->linesize [0 ], frame->linesize [1 ], tex->texture .linear , stream.get (), {frame->width , frame->height , 0 , 0 });
188+ sws.convert_nv12 (frame->data [0 ], frame->data [1 ], frame->linesize [0 ], frame->linesize [1 ], tex->texture .linear , stream.get (), {frame->width , frame->height , 0 , 0 });
188189 }
189190 }
190191
@@ -201,18 +202,19 @@ namespace cuda {
201202 // When height and width don't change, it's not necessary to use linear interpolation
202203 bool linear_interpolation;
203204
205+ bool is_yuv444;
206+
204207 sws_t sws;
205208 };
206209
207210 class cuda_ram_t : public cuda_t {
208211 public:
209212 int convert (platf::img_t &img) override {
210213
211- // frame->data[2] not null on YUV444 conversion
212- if (frame->data [2 ]) {
214+ if (is_yuv444) {
213215 return sws.load_ram (img, tex.array ) || sws.convert_yuv444 (frame->data [0 ], frame->data [1 ], frame->data [2 ], frame->linesize [0 ], tex_obj (tex), stream.get ());
214216 }
215- return sws.load_ram (img, tex.array ) || sws.convert (frame->data [0 ], frame->data [1 ], frame->linesize [0 ], frame->linesize [1 ], tex_obj (tex), stream.get ());
217+ return sws.load_ram (img, tex.array ) || sws.convert_nv12 (frame->data [0 ], frame->data [1 ], frame->linesize [0 ], frame->linesize [1 ], tex_obj (tex), stream.get ());
216218 }
217219
218220 int set_frame (AVFrame *frame, AVBufferRef *hw_frames_ctx) override {
@@ -237,11 +239,10 @@ namespace cuda {
237239 public:
238240 int convert (platf::img_t &img) override {
239241
240- // frame->data[2] not null on YUV444 conversion
241- if (frame->data [2 ]) {
242+ if (is_yuv444) {
242243 return sws.convert_yuv444 (frame->data [0 ], frame->data [1 ], frame->data [2 ], frame->linesize [0 ], tex_obj (((img_t *) &img)->tex ), stream.get ());
243244 }
244- return sws.convert (frame->data [0 ], frame->data [1 ], frame->linesize [0 ], frame->linesize [1 ], tex_obj (((img_t *) &img)->tex ), stream.get ());
245+ return sws.convert_nv12 (frame->data [0 ], frame->data [1 ], frame->linesize [0 ], frame->linesize [1 ], tex_obj (((img_t *) &img)->tex ), stream.get ());
245246 }
246247 };
247248
@@ -352,24 +353,32 @@ namespace cuda {
352353 this ->hwframe .reset (frame);
353354 this ->frame = frame;
354355
356+ auto hw_frames_ctx = (AVHWFramesContext *) hw_frames_ctx_buf->data ;
357+
358+ if (hw_frames_ctx->sw_format != AV_PIX_FMT_NV12 &&
359+ hw_frames_ctx->sw_format != AV_PIX_FMT_YUV444P ) {
360+ BOOST_LOG (error) << " cuda::gl_cuda_vram_t doesn't support any format other than AV_PIX_FMT_NV12 and AV_PIX_FMT_YUV444P" sv;
361+ return -1 ;
362+ }
363+
355364 if (!frame->buf [0 ]) {
356365 if (av_hwframe_get_buffer (hw_frames_ctx_buf, frame, 0 )) {
357- BOOST_LOG (error) << " Couldn't get hwframe for VAAPI " sv;
366+ BOOST_LOG (error) << " Couldn't get hwframe for NVENC_GL " sv;
358367 return -1 ;
359368 }
360369 }
361370
362- auto hw_frames_ctx = (AVHWFramesContext *) hw_frames_ctx_buf->data ;
363371 sw_format = hw_frames_ctx->sw_format ;
372+ is_yuv444 = (sw_format == AV_PIX_FMT_YUV444P );
364373
365- auto sws_opt = egl::sws_t::make (width, height, frame->width , frame->height , sw_format);
374+ auto sws_opt = egl::sws_t::make (width, height, frame->width , frame->height , sw_format, is_yuv444 );
366375 if (!sws_opt) {
367376 return -1 ;
368377 }
369378
370379 this ->sws = std::move (*sws_opt);
371380
372- if (sw_format == AV_PIX_FMT_YUV444P ) {
381+ if (is_yuv444 ) {
373382 auto yuv444_opt = egl::create_yuv444_target (frame->width , frame->height , sw_format);
374383 if (!yuv444_opt) {
375384 return -1 ;
@@ -392,7 +401,7 @@ namespace cuda {
392401
393402 cuda_ctx->stream = stream.get ();
394403
395- if (sw_format == AV_PIX_FMT_YUV444P ) {
404+ if (is_yuv444 ) {
396405 CU_CHECK (cdf->cuGraphicsGLRegisterImage (&y_res,yuv444->tex [0 ], GL_TEXTURE_2D , CU_GRAPHICS_REGISTER_FLAGS_READ_ONLY ), " Couldn't register Y texture" );
397406 CU_CHECK (cdf->cuGraphicsGLRegisterImage (&u_res,yuv444->tex [1 ], GL_TEXTURE_2D , CU_GRAPHICS_REGISTER_FLAGS_READ_ONLY ), " Couldn't register U texture" );
398407 CU_CHECK (cdf->cuGraphicsGLRegisterImage (&v_res,yuv444->tex [2 ], GL_TEXTURE_2D , CU_GRAPHICS_REGISTER_FLAGS_READ_ONLY ), " Couldn't register V texture" );
@@ -428,18 +437,14 @@ namespace cuda {
428437 rgb = std::move (*rgb_opt);
429438 }
430439
431- // Perform the color conversion and scaling in GL
432- if (sw_format == AV_PIX_FMT_YUV444P ) {
433- sws.load_vram (descriptor, offset_x, offset_y, rgb->tex [0 ], true );
434- sws.convert_yuv444 (yuv444->buf );
435- } else {
436- sws.load_vram (descriptor, offset_x, offset_y, rgb->tex [0 ], false );
437- sws.convert_nv12 (nv12->buf );
438- }
439-
440440 auto fmt_desc = av_pix_fmt_desc_get (sw_format);
441+
442+ sws.load_vram (descriptor, offset_x, offset_y, rgb->tex [0 ], is_yuv444);
441443
442- if (sw_format == AV_PIX_FMT_YUV444P ) {
444+ if (is_yuv444) {
445+
446+ // Perform the color conversion and scaling in GL
447+ sws.convert_yuv444 (yuv444->buf );
443448
444449 // Map the GL textures to read for CUDA
445450 std::array<CUgraphicsResource, 3 > resources = {{y_res.get (), u_res.get (), v_res.get ()}};
@@ -463,6 +468,11 @@ namespace cuda {
463468 CU_CHECK (cdf->cuGraphicsUnmapResources (resources.size (), resources.data (), stream.get ()), " Couldn't unmap GL textures from CUDA" );
464469
465470 } else {
471+
472+ // Perform the color conversion and scaling in GL
473+ sws.convert_nv12 (nv12->buf );
474+
475+ // Map the GL textures to read for CUDA
466476 std::array<CUgraphicsResource, 2 > resources = {{y_res.get (), uv_res.get ()}};
467477 CU_CHECK (cdf->cuGraphicsMapResources (resources.size (), resources.data (), stream.get ()), " Couldn't map GL textures in CUDA" );
468478
@@ -522,6 +532,8 @@ namespace cuda {
522532
523533 int offset_x;
524534 int offset_y;
535+
536+ bool is_yuv444;
525537 };
526538
527539 std::unique_ptr<platf::avcodec_encode_device_t > make_avcodec_encode_device (int width, int height, bool vram) {
0 commit comments