Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions src/torchcodec/_core/BetaCudaDeviceInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ void BetaCudaDeviceInterface::flush() {
}

UniqueAVFrame BetaCudaDeviceInterface::transfer_cpu_frame_to_gpu(
UniqueAVFrame& cpu_frame,
const UniqueAVFrame& cpu_frame,
AVPixelFormat target_pix_fmt) {
// This is called in the context of the CPU fallback: the frame was decoded on
// the CPU, and in this function we convert that frame into NV12 or P016
Expand Down Expand Up @@ -967,7 +967,7 @@ UniqueAVFrame BetaCudaDeviceInterface::transfer_cpu_frame_to_gpu(
}

void BetaCudaDeviceInterface::convert_av_frame_to_frame_output(
UniqueAVFrame& av_frame,
const UniqueAVFrame& av_frame,
FrameOutput& frame_output,
std::optional<torch::stable::Tensor> pre_allocated_output_tensor) {
if (cpu_fallback_) {
Expand Down Expand Up @@ -1003,15 +1003,14 @@ void BetaCudaDeviceInterface::convert_av_frame_to_frame_output(
// may round them up to even.
FrameDims original_dims(av_frame->height, av_frame->width);

UniqueAVFrame gpu_frame;
UniqueAVFrame transferred_frame;
if (cpu_fallback_) {
AVPixelFormat target_pix_fmt = (output_dtype_ == OutputDtype::FLOAT32)
? AV_PIX_FMT_P016LE
: AV_PIX_FMT_NV12;
gpu_frame = transfer_cpu_frame_to_gpu(av_frame, target_pix_fmt);
} else {
gpu_frame = std::move(av_frame);
transferred_frame = transfer_cpu_frame_to_gpu(av_frame, target_pix_fmt);
}
const UniqueAVFrame& gpu_frame = cpu_fallback_ ? transferred_frame : av_frame;

STD_TORCH_CHECK(
gpu_frame->format == AV_PIX_FMT_NV12 ||
Expand Down
4 changes: 2 additions & 2 deletions src/torchcodec/_core/BetaCudaDeviceInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class BetaCudaDeviceInterface : public DeviceInterface {
OutputDtype requested_dtype) const override;

void convert_av_frame_to_frame_output(
UniqueAVFrame& av_frame,
const UniqueAVFrame& av_frame,
FrameOutput& frame_output,
std::optional<torch::stable::Tensor> pre_allocated_output_tensor)
override;
Expand Down Expand Up @@ -92,7 +92,7 @@ class BetaCudaDeviceInterface : public DeviceInterface {
const CUVIDPARSERDISPINFO& disp_info);

UniqueAVFrame transfer_cpu_frame_to_gpu(
UniqueAVFrame& cpu_frame,
const UniqueAVFrame& cpu_frame,
AVPixelFormat target_pix_fmt);

void apply_rotation(
Expand Down
2 changes: 1 addition & 1 deletion src/torchcodec/_core/ColorConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ ColorConverter::ColorConverter(
/*resized_output_dims=*/std::nullopt);
}

torch::stable::Tensor ColorConverter::convert(UniqueAVFrame& av_frame) {
torch::stable::Tensor ColorConverter::convert(const UniqueAVFrame& av_frame) {
FrameOutput frame_output;
device_interface_->convert_av_frame_to_frame_output(
av_frame, frame_output, std::nullopt);
Expand Down
2 changes: 1 addition & 1 deletion src/torchcodec/_core/ColorConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class FORCE_PUBLIC_VISIBILITY ColorConverter {
const StableDevice& device = StableDevice(kStableCPU),
std::string_view device_variant = "default");

torch::stable::Tensor convert(UniqueAVFrame& av_frame);
torch::stable::Tensor convert(const UniqueAVFrame& av_frame);

private:
std::unique_ptr<DeviceInterface> device_interface_;
Expand Down
6 changes: 3 additions & 3 deletions src/torchcodec/_core/CpuDeviceInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ ColorConversionLibrary CpuDeviceInterface::get_color_conversion_library(
}

void CpuDeviceInterface::convert_av_frame_to_frame_output(
UniqueAVFrame& av_frame,
const UniqueAVFrame& av_frame,
FrameOutput& frame_output,
std::optional<torch::stable::Tensor> pre_allocated_output_tensor) {
STD_TORCH_CHECK(initialized_, "CpuDeviceInterface was not initialized.");
Expand All @@ -223,7 +223,7 @@ void CpuDeviceInterface::convert_av_frame_to_frame_output(
// Dimension order of the preAllocatedOutputTensor must be HWC, regardless of
// `dimension_order` parameter. It's up to callers to re-shape it if needed.
void CpuDeviceInterface::convert_video_av_frame_to_frame_output(
UniqueAVFrame& av_frame,
const UniqueAVFrame& av_frame,
FrameOutput& frame_output,
std::optional<torch::stable::Tensor> pre_allocated_output_tensor) {
// Note that we ignore the dimensions from the metadata; we don't even bother
Expand Down Expand Up @@ -350,7 +350,7 @@ CpuDeviceInterface::convert_av_frame_to_tensor_using_filter_graph(
}

void CpuDeviceInterface::convert_audio_av_frame_to_frame_output(
UniqueAVFrame& src_av_frame,
const UniqueAVFrame& src_av_frame,
FrameOutput& frame_output) {
AVSampleFormat src_sample_format =
static_cast<AVSampleFormat>(src_av_frame->format);
Expand Down
6 changes: 3 additions & 3 deletions src/torchcodec/_core/CpuDeviceInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class CpuDeviceInterface : public DeviceInterface {
override;

void convert_av_frame_to_frame_output(
UniqueAVFrame& av_frame,
const UniqueAVFrame& av_frame,
FrameOutput& frame_output,
std::optional<torch::stable::Tensor> pre_allocated_output_tensor)
override;
Expand All @@ -59,11 +59,11 @@ class CpuDeviceInterface : public DeviceInterface {

private:
void convert_audio_av_frame_to_frame_output(
UniqueAVFrame& src_av_frame,
const UniqueAVFrame& src_av_frame,
FrameOutput& frame_output);

void convert_video_av_frame_to_frame_output(
UniqueAVFrame& av_frame,
const UniqueAVFrame& av_frame,
FrameOutput& frame_output,
std::optional<torch::stable::Tensor> pre_allocated_output_tensor);

Expand Down
15 changes: 9 additions & 6 deletions src/torchcodec/_core/CudaDeviceInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ void CudaDeviceInterface::register_hardware_device_with_codec(
}

UniqueAVFrame CudaDeviceInterface::maybe_convert_av_frame_to_nv12_or_rgb24(
UniqueAVFrame& av_frame) {
const UniqueAVFrame& av_frame) {
// We need FFmpeg filters to handle those conversion cases which are not
// directly implemented in CUDA or CPU device interface (in case of a
// fallback).
Expand All @@ -155,7 +155,7 @@ UniqueAVFrame CudaDeviceInterface::maybe_convert_av_frame_to_nv12_or_rgb24(
// skipping filters context as CPU device interface will handle everything for
// us.
if (av_frame->format != AV_PIX_FMT_CUDA) {
return std::move(av_frame);
return UniqueAVFrame{};
}

auto hw_frames_ctx =
Expand All @@ -169,7 +169,7 @@ UniqueAVFrame CudaDeviceInterface::maybe_convert_av_frame_to_nv12_or_rgb24(

// If the frame is already in NV12 format, we don't need to do anything.
if (actual_format == AV_PIX_FMT_NV12) {
return std::move(av_frame);
return UniqueAVFrame{};
}

AVPixelFormat output_format;
Expand Down Expand Up @@ -237,18 +237,21 @@ UniqueAVFrame CudaDeviceInterface::maybe_convert_av_frame_to_nv12_or_rgb24(
}

void CudaDeviceInterface::convert_av_frame_to_frame_output(
UniqueAVFrame& av_frame,
const UniqueAVFrame& input_av_frame,
FrameOutput& frame_output,
std::optional<torch::stable::Tensor> pre_allocated_output_tensor) {
validate_pre_allocated_tensor_shape(
pre_allocated_output_tensor,
FrameDims(av_frame->height, av_frame->width));
FrameDims(input_av_frame->height, input_av_frame->width));

has_decoded_frame_ = true;

// All of our CUDA decoding assumes NV12 format. We handle non-NV12 formats by
// converting them to NV12.
av_frame = maybe_convert_av_frame_to_nv12_or_rgb24(av_frame);
UniqueAVFrame converted_av_frame =
maybe_convert_av_frame_to_nv12_or_rgb24(input_av_frame);
const UniqueAVFrame& av_frame =
converted_av_frame ? converted_av_frame : input_av_frame;

if (av_frame->format != AV_PIX_FMT_CUDA) {
// The frame's format is AV_PIX_FMT_CUDA if and only if its content is on
Expand Down
7 changes: 4 additions & 3 deletions src/torchcodec/_core/CudaDeviceInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class CudaDeviceInterface : public DeviceInterface {
AVCodecContext* codec_context) override;

void convert_av_frame_to_frame_output(
UniqueAVFrame& av_frame,
const UniqueAVFrame& av_frame,
FrameOutput& frame_output,
std::optional<torch::stable::Tensor> pre_allocated_output_tensor)
override;
Expand All @@ -63,9 +63,10 @@ class CudaDeviceInterface : public DeviceInterface {
private:
// Our CUDA decoding code assumes NV12 format. In order to handle other
// kinds of input, we need to convert them to NV12. Our current implementation
// does this using filtergraph.
// does this using filtergraph. Returns a null frame when no conversion is
// needed, i.e. when the input frame can be used as-is.
UniqueAVFrame maybe_convert_av_frame_to_nv12_or_rgb24(
UniqueAVFrame& av_frame);
const UniqueAVFrame& av_frame);

// We sometimes encounter frames that cannot be decoded on the CUDA device.
// Rather than erroring out, we decode them on the CPU.
Expand Down
2 changes: 1 addition & 1 deletion src/torchcodec/_core/DeviceInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class DeviceInterface {
}

virtual void convert_av_frame_to_frame_output(
UniqueAVFrame& av_frame,
const UniqueAVFrame& av_frame,
FrameOutput& frame_output,
std::optional<torch::stable::Tensor> pre_allocated_output_tensor =
std::nullopt) = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/torchcodec/_core/SingleStreamDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1573,7 +1573,7 @@ UniqueAVFrame SingleStreamDecoder::decode_av_frame(
// --------------------------------------------------------------------------

FrameOutput SingleStreamDecoder::convert_av_frame_to_frame_output(
UniqueAVFrame& av_frame,
const UniqueAVFrame& av_frame,
std::optional<torch::stable::Tensor> pre_allocated_output_tensor) {
// Convert the frame to tensor.
FrameOutput frame_output;
Expand Down
2 changes: 1 addition & 1 deletion src/torchcodec/_core/SingleStreamDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ class FORCE_PUBLIC_VISIBILITY SingleStreamDecoder {
torch::stable::Tensor& tensor);

FrameOutput convert_av_frame_to_frame_output(
UniqueAVFrame& av_frame,
const UniqueAVFrame& av_frame,
std::optional<torch::stable::Tensor> pre_allocated_output_tensor =
std::nullopt);

Expand Down
2 changes: 1 addition & 1 deletion src/torchcodec/_core/color_conversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ void compute_rgb_to_yuv_matrix(
}

torch::stable::Tensor convert_yuv_frame_to_rgb(
UniqueAVFrame& av_frame,
const UniqueAVFrame& av_frame,
const StableDevice& device,
cudaStream_t nvdec_stream,
std::optional<torch::stable::Tensor> pre_allocated_output_tensor,
Expand Down
2 changes: 1 addition & 1 deletion src/torchcodec/_core/color_conversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void launch_p016_to_rgb16_kernel(
// outputDims: desired output size; if the frame was rounded up to even
// dimensions, the result is cropped back to outputDims.
torch::stable::Tensor convert_yuv_frame_to_rgb(
UniqueAVFrame& av_frame,
const UniqueAVFrame& av_frame,
const StableDevice& device,
cudaStream_t nvdec_stream,
std::optional<torch::stable::Tensor> pre_allocated_output_tensor,
Expand Down
2 changes: 1 addition & 1 deletion test/third-party-interface/ThirdPartyInterfaceTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class DummyDeviceInterface : public DeviceInterface {
}

void convert_av_frame_to_frame_output(
UniqueAVFrame& av_frame,
const UniqueAVFrame& av_frame,
FrameOutput& frame_output,
std::optional<torch::stable::Tensor> pre_allocated_output_tensor =
std::nullopt) override {}
Expand Down
Loading