@@ -84,7 +84,7 @@ cudaVideoSurfaceFormat get_preferred_surface_format(OutputDtype output_dtype) {
8484// when decoding happens, but this interface can be used in
8585// color-conversion-only mode.
8686bool is_cpu_fallback (int format) {
87- return format != AV_PIX_FMT_NV12 && format != AV_PIX_FMT_P016LE ;
87+ return format != AV_PIX_FMT_NV12 && ! is_nvdec_16bit_surface (format) ;
8888}
8989
9090static bool g_cuda_nvdec = register_device_interface(
@@ -825,9 +825,9 @@ UniqueAVFrame BetaCudaDeviceInterface::convert_cuda_frame_to_av_frame(
825825
826826 av_frame->width = width;
827827 av_frame->height = height;
828- av_frame->format = (surface_format_ == cudaVideoSurfaceFormat_P016)
829- ? AV_PIX_FMT_P016LE
830- : AV_PIX_FMT_NV12 ;
828+ av_frame->format = nvdec_pix_fmt (
829+ surface_format_ == cudaVideoSurfaceFormat_P016,
830+ static_cast < int >(video_format_. bit_depth_luma_minus8 ) + 8 ) ;
831831 av_frame->pts = disp_info.timestamp ;
832832
833833 // TODONVDEC P2: We compute the duration based on average frame rate info, so
@@ -1177,6 +1177,8 @@ void BetaCudaDeviceInterface::convert_av_frame_to_frame_output(
11771177
11781178 UniqueAVFrame transferred_frame;
11791179 if (cpu_fallback) {
1180+ // TODO: uploaded fallback frames stay tagged P016 even for 10-/12-bit
1181+ // sources, so they report 16 bits where an NVDEC frame reports the truth.
11801182 AVPixelFormat target_pix_fmt = (output_dtype_ == OutputDtype::FLOAT32 )
11811183 ? AV_PIX_FMT_P016LE
11821184 : AV_PIX_FMT_NV12 ;
@@ -1190,8 +1192,8 @@ void BetaCudaDeviceInterface::convert_av_frame_to_frame_output(
11901192
11911193 STD_TORCH_CHECK (
11921194 gpu_frame.format == AV_PIX_FMT_NV12 ||
1193- gpu_frame.format == AV_PIX_FMT_P016LE ,
1194- " Expected NV12 or P016LE format frame" );
1195+ is_nvdec_16bit_surface ( gpu_frame.format ) ,
1196+ " Expected NV12 or 16-bit semi-planar format frame" );
11951197
11961198 cudaStream_t producer_stream;
11971199 if (mode () == Mode::ColorConverterOnly) {
@@ -1210,21 +1212,13 @@ void BetaCudaDeviceInterface::convert_av_frame_to_frame_output(
12101212 // execrcized.
12111213 auto convert_frame = [&](std::optional<torch::stable::Tensor> pre_alloc)
12121214 -> torch::stable::Tensor {
1213- bool is_p016 = (gpu_frame.format == AV_PIX_FMT_P016LE );
1214- int bit_depth = 8 ;
1215- if (is_p016) {
1216- bit_depth = cpu_fallback
1217- ? codec_context_->bits_per_raw_sample
1218- : static_cast <int >(video_format_.bit_depth_luma_minus8 ) + 8 ;
1219- }
12201215 return convert_yuv_frame_to_rgb (
12211216 gpu_frame,
12221217 device_,
12231218 producer_stream,
12241219 pre_alloc,
12251220 original_dims,
1226- is_p016,
1227- bit_depth,
1221+ static_cast <AVPixelFormat>(gpu_frame.format ),
12281222 cached_color_matrix_);
12291223 };
12301224
0 commit comments