@@ -13,6 +13,15 @@ extern "C" {
1313#include < libavutil/pixdesc.h>
1414}
1515
16+ // TODONVDEC P1 Changes were made to this file to accomodate for the BETA CUDA
17+ // interface (see other TODONVDEC below). That's because the BETA CUDA interface
18+ // relies on this default CUDA interface to do the color conversion. That's
19+ // hacky, ugly, and leads to complicated code. We should refactor all this so
20+ // that an interface doesn't need to know anything about any other interface.
21+ // Note - this is more than just about the BETA CUDA interface: this default
22+ // interface already relies on the CPU interface to do software decoding when
23+ // needed, and that's already leading to similar complications.
24+
1625namespace facebook ::torchcodec {
1726namespace {
1827
@@ -216,10 +225,11 @@ std::unique_ptr<FiltersContext> CudaDeviceInterface::initializeFiltersContext(
216225 return nullptr ;
217226 }
218227
219- TORCH_CHECK (
220- avFrame->hw_frames_ctx != nullptr ,
221- " The AVFrame does not have a hw_frames_ctx. "
222- " That's unexpected, please report this to the TorchCodec repo." );
228+ if (avFrame->hw_frames_ctx == nullptr ) {
229+ // TODONVDEC P2 return early for for beta interface where avFrames don't
230+ // have a hw_frames_ctx. We should get rid of this or improve the logic.
231+ return nullptr ;
232+ }
223233
224234 auto hwFramesCtx =
225235 reinterpret_cast <AVHWFramesContext*>(avFrame->hw_frames_ctx ->data );
@@ -347,22 +357,23 @@ void CudaDeviceInterface::convertAVFrameToFrameOutput(
347357 // Above we checked that the AVFrame was on GPU, but that's not enough, we
348358 // also need to check that the AVFrame is in AV_PIX_FMT_NV12 format (8 bits),
349359 // because this is what the NPP color conversion routines expect.
350- TORCH_CHECK (
351- avFrame-> hw_frames_ctx != nullptr ,
352- " The AVFrame does not have a hw_frames_ctx. "
353- " That's unexpected, please report this to the TorchCodec repo. " ) ;
354-
355- auto hwFramesCtx =
356- reinterpret_cast <AVHWFramesContext*>(avFrame->hw_frames_ctx ->data );
357- AVPixelFormat actualFormat = hwFramesCtx->sw_format ;
360+ // TODONVDEC P2 this can be hit from the beta interface, but there's no
361+ // hw_frames_ctx in this case. We should try to understand how that affects
362+ // this validation.
363+ AVHWFramesContext* hwFramesCtx = nullptr ;
364+ if (avFrame-> hw_frames_ctx != nullptr ) {
365+ hwFramesCtx =
366+ reinterpret_cast <AVHWFramesContext*>(avFrame->hw_frames_ctx ->data );
367+ AVPixelFormat actualFormat = hwFramesCtx->sw_format ;
358368
359- TORCH_CHECK (
360- actualFormat == AV_PIX_FMT_NV12,
361- " The AVFrame is " ,
362- (av_get_pix_fmt_name (actualFormat) ? av_get_pix_fmt_name (actualFormat)
363- : " unknown" ),
364- " , but we expected AV_PIX_FMT_NV12. "
365- " That's unexpected, please report this to the TorchCodec repo." );
369+ TORCH_CHECK (
370+ actualFormat == AV_PIX_FMT_NV12,
371+ " The AVFrame is " ,
372+ (av_get_pix_fmt_name (actualFormat) ? av_get_pix_fmt_name (actualFormat)
373+ : " unknown" ),
374+ " , but we expected AV_PIX_FMT_NV12. "
375+ " That's unexpected, please report this to the TorchCodec repo." );
376+ }
366377
367378 auto frameDims =
368379 getHeightAndWidthFromOptionsOrAVFrame (videoStreamOptions, avFrame);
@@ -396,19 +407,23 @@ void CudaDeviceInterface::convertAVFrameToFrameOutput(
396407 // arbitrary, but unfortunately we know it's hardcoded to be the default
397408 // stream by FFmpeg:
398409 // https://github.com/FFmpeg/FFmpeg/blob/66e40840d15b514f275ce3ce2a4bf72ec68c7311/libavutil/hwcontext_cuda.c#L387-L388
399- TORCH_CHECK (
400- hwFramesCtx->device_ctx != nullptr ,
401- " The AVFrame's hw_frames_ctx does not have a device_ctx. " );
402- auto cudaDeviceCtx =
403- static_cast <AVCUDADeviceContext*>(hwFramesCtx->device_ctx ->hwctx );
404- at::cuda::CUDAEvent nvdecDoneEvent;
405- at::cuda::CUDAStream nvdecStream = // That's always the default stream. Sad.
406- c10::cuda::getStreamFromExternal (cudaDeviceCtx->stream , deviceIndex);
407- nvdecDoneEvent.record (nvdecStream);
408-
409- // Don't start NPP work before NVDEC is done decoding the frame!
410410 at::cuda::CUDAStream nppStream = at::cuda::getCurrentCUDAStream (deviceIndex);
411- nvdecDoneEvent.block (nppStream);
411+ if (hwFramesCtx) {
412+ // TODONVDEC P2 this block won't be hit from the beta interface because
413+ // there is no hwFramesCtx, but we should still make sure there's no CUDA
414+ // stream sync issue in the beta interface.
415+ TORCH_CHECK (
416+ hwFramesCtx->device_ctx != nullptr ,
417+ " The AVFrame's hw_frames_ctx does not have a device_ctx. " );
418+ auto cudaDeviceCtx =
419+ static_cast <AVCUDADeviceContext*>(hwFramesCtx->device_ctx ->hwctx );
420+ at::cuda::CUDAEvent nvdecDoneEvent;
421+ at::cuda::CUDAStream nvdecStream = // That's always the default stream. Sad.
422+ c10::cuda::getStreamFromExternal (cudaDeviceCtx->stream , deviceIndex);
423+ nvdecDoneEvent.record (nvdecStream);
424+ // Don't start NPP work before NVDEC is done decoding the frame!
425+ nvdecDoneEvent.block (nppStream);
426+ }
412427
413428 // Create the NPP context if we haven't yet.
414429 nppCtx_->hStream = nppStream.stream ();
0 commit comments