From 2c480233a4245224bed62b8f5752da5c0c4a0a99 Mon Sep 17 00:00:00 2001 From: Scott Schneider Date: Thu, 4 Sep 2025 08:51:10 -0700 Subject: [PATCH 1/2] Refactor context structs to use constructors --- src/torchcodec/_core/CpuDeviceInterface.cpp | 47 ++++++++++++--------- src/torchcodec/_core/CpuDeviceInterface.h | 8 ++++ src/torchcodec/_core/FilterGraph.cpp | 20 +++++++++ src/torchcodec/_core/FilterGraph.h | 15 ++++++- 4 files changed, 70 insertions(+), 20 deletions(-) diff --git a/src/torchcodec/_core/CpuDeviceInterface.cpp b/src/torchcodec/_core/CpuDeviceInterface.cpp index c4bcaf278..77eaf3d09 100644 --- a/src/torchcodec/_core/CpuDeviceInterface.cpp +++ b/src/torchcodec/_core/CpuDeviceInterface.cpp @@ -15,6 +15,18 @@ static bool g_cpu = registerDeviceInterface( } // namespace +CpuDeviceInterface::SwsFrameContext::SwsFrameContext( + int inputWidth, + int inputHeight, + AVPixelFormat inputFormat, + int outputWidth, + int outputHeight) + : inputWidth(inputWidth), + inputHeight(inputHeight), + inputFormat(inputFormat), + outputWidth(outputWidth), + outputHeight(outputHeight) {} + bool CpuDeviceInterface::SwsFrameContext::operator==( const CpuDeviceInterface::SwsFrameContext& other) const { return inputWidth == other.inputWidth && inputHeight == other.inputHeight && @@ -97,13 +109,12 @@ void CpuDeviceInterface::convertAVFrameToFrameOutput( // And we sometimes re-create them because it's possible for frame // resolution to change mid-stream. Finally, we want to reuse the colorspace // conversion objects as much as possible for performance reasons. - SwsFrameContext swsFrameContext; - - swsFrameContext.inputWidth = avFrame->width; - swsFrameContext.inputHeight = avFrame->height; - swsFrameContext.inputFormat = frameFormat; - swsFrameContext.outputWidth = expectedOutputWidth; - swsFrameContext.outputHeight = expectedOutputHeight; + SwsFrameContext swsFrameContext( + avFrame->width, + avFrame->height, + frameFormat, + expectedOutputWidth, + expectedOutputHeight); outputTensor = preAllocatedOutputTensor.value_or(allocateEmptyHWCTensor( expectedOutputHeight, expectedOutputWidth, torch::kCPU)); @@ -128,22 +139,20 @@ void CpuDeviceInterface::convertAVFrameToFrameOutput( } else if (colorConversionLibrary == ColorConversionLibrary::FILTERGRAPH) { // See comment above in swscale branch about the filterGraphContext_ // creation. creation - FiltersContext filtersContext; - - filtersContext.inputWidth = avFrame->width; - filtersContext.inputHeight = avFrame->height; - filtersContext.inputFormat = frameFormat; - filtersContext.inputAspectRatio = avFrame->sample_aspect_ratio; - filtersContext.outputWidth = expectedOutputWidth; - filtersContext.outputHeight = expectedOutputHeight; - filtersContext.outputFormat = AV_PIX_FMT_RGB24; - filtersContext.timeBase = timeBase; - std::stringstream filters; filters << "scale=" << expectedOutputWidth << ":" << expectedOutputHeight; filters << ":sws_flags=bilinear"; - filtersContext.filtergraphStr = filters.str(); + FiltersContext filtersContext( + avFrame->width, + avFrame->height, + frameFormat, + avFrame->sample_aspect_ratio, + expectedOutputWidth, + expectedOutputHeight, + AV_PIX_FMT_RGB24, + filters.str(), + timeBase); if (!filterGraphContext_ || prevFiltersContext_ != filtersContext) { filterGraphContext_ = diff --git a/src/torchcodec/_core/CpuDeviceInterface.h b/src/torchcodec/_core/CpuDeviceInterface.h index 5d1429135..ea33ef951 100644 --- a/src/torchcodec/_core/CpuDeviceInterface.h +++ b/src/torchcodec/_core/CpuDeviceInterface.h @@ -48,6 +48,14 @@ class CpuDeviceInterface : public DeviceInterface { AVPixelFormat inputFormat; int outputWidth; int outputHeight; + + SwsFrameContext() = default; + SwsFrameContext( + int inputWidth, + int inputHeight, + AVPixelFormat inputFormat, + int outputWidth, + int outputHeight); bool operator==(const SwsFrameContext&) const; bool operator!=(const SwsFrameContext&) const; }; diff --git a/src/torchcodec/_core/FilterGraph.cpp b/src/torchcodec/_core/FilterGraph.cpp index f4e53b1b6..43a12f092 100644 --- a/src/torchcodec/_core/FilterGraph.cpp +++ b/src/torchcodec/_core/FilterGraph.cpp @@ -13,6 +13,26 @@ extern "C" { namespace facebook::torchcodec { +FiltersContext::FiltersContext( + int inputWidth, + int inputHeight, + AVPixelFormat inputFormat, + AVRational inputAspectRatio, + int outputWidth, + int outputHeight, + AVPixelFormat outputFormat, + const std::string& filtergraphStr, + AVRational timeBase) + : inputWidth(inputWidth), + inputHeight(inputHeight), + inputFormat(inputFormat), + inputAspectRatio(inputAspectRatio), + outputWidth(outputWidth), + outputHeight(outputHeight), + outputFormat(outputFormat), + filtergraphStr(filtergraphStr), + timeBase(timeBase) {} + bool operator==(const AVRational& lhs, const AVRational& rhs) { return lhs.num == rhs.num && lhs.den == rhs.den; } diff --git a/src/torchcodec/_core/FilterGraph.h b/src/torchcodec/_core/FilterGraph.h index a99507dc9..4edff6c1b 100644 --- a/src/torchcodec/_core/FilterGraph.h +++ b/src/torchcodec/_core/FilterGraph.h @@ -19,11 +19,24 @@ struct FiltersContext { int outputWidth = 0; int outputHeight = 0; AVPixelFormat outputFormat = AV_PIX_FMT_NONE; - std::string filtergraphStr; AVRational timeBase = {0, 0}; UniqueAVBufferRef hwFramesCtx; + FiltersContext() = default; + FiltersContext(FiltersContext&&) = default; + FiltersContext& operator=(FiltersContext&&) = default; + FiltersContext( + int inputWidth, + int inputHeight, + AVPixelFormat inputFormat, + AVRational inputAspectRatio, + int outputWidth, + int outputHeight, + AVPixelFormat outputFormat, + const std::string& filtergraphStr, + AVRational timeBase); + bool operator==(const FiltersContext&) const; bool operator!=(const FiltersContext&) const; }; From d6e39e95bcdd4acc5d8243f2ebda420c6a2b57f4 Mon Sep 17 00:00:00 2001 From: Scott Schneider Date: Fri, 5 Sep 2025 12:05:00 -0700 Subject: [PATCH 2/2] Better defaults on SwsFrameContext --- src/torchcodec/_core/CpuDeviceInterface.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/torchcodec/_core/CpuDeviceInterface.h b/src/torchcodec/_core/CpuDeviceInterface.h index ea33ef951..d6004ca3b 100644 --- a/src/torchcodec/_core/CpuDeviceInterface.h +++ b/src/torchcodec/_core/CpuDeviceInterface.h @@ -43,11 +43,11 @@ class CpuDeviceInterface : public DeviceInterface { const UniqueAVFrame& avFrame); struct SwsFrameContext { - int inputWidth; - int inputHeight; - AVPixelFormat inputFormat; - int outputWidth; - int outputHeight; + int inputWidth = 0; + int inputHeight = 0; + AVPixelFormat inputFormat = AV_PIX_FMT_NONE; + int outputWidth = 0; + int outputHeight = 0; SwsFrameContext() = default; SwsFrameContext(