torchcodec 0.4.0__cp313-cp313-macosx_11_0_arm64.whl → 0.5__cp313-cp313-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of torchcodec might be problematic. Click here for more details.
- torchcodec/.dylibs/libc++.1.0.dylib +0 -0
- torchcodec/.dylibs/libpython3.13.dylib +0 -0
- torchcodec/_core/AVIOContextHolder.h +3 -2
- torchcodec/_core/AVIOTensorContext.cpp +121 -0
- torchcodec/_core/AVIOTensorContext.h +43 -0
- torchcodec/_core/CMakeLists.txt +27 -20
- torchcodec/_core/CpuDeviceInterface.cpp +30 -34
- torchcodec/_core/CudaDeviceInterface.cpp +2 -10
- torchcodec/_core/Encoder.cpp +233 -93
- torchcodec/_core/Encoder.h +86 -20
- torchcodec/_core/FFMPEGCommon.cpp +132 -55
- torchcodec/_core/FFMPEGCommon.h +12 -3
- torchcodec/_core/Metadata.h +12 -10
- torchcodec/_core/SingleStreamDecoder.cpp +256 -165
- torchcodec/_core/SingleStreamDecoder.h +30 -5
- torchcodec/_core/StreamOptions.h +4 -1
- torchcodec/_core/_metadata.py +56 -19
- torchcodec/_core/custom_ops.cpp +109 -60
- torchcodec/_core/ops.py +25 -11
- torchcodec/_core/pybind_ops.cpp +5 -1
- torchcodec/_frame.py +2 -2
- torchcodec/_internally_replaced_utils.py +11 -0
- torchcodec/_samplers/video_clip_sampler.py +11 -11
- torchcodec/decoders/_audio_decoder.py +3 -2
- torchcodec/decoders/_video_decoder.py +7 -2
- torchcodec/encoders/__init__.py +1 -0
- torchcodec/encoders/_audio_encoder.py +110 -0
- torchcodec/libtorchcodec_core4.dylib +0 -0
- torchcodec/libtorchcodec_core5.dylib +0 -0
- torchcodec/libtorchcodec_core6.dylib +0 -0
- torchcodec/libtorchcodec_core7.dylib +0 -0
- torchcodec/libtorchcodec_custom_ops4.dylib +0 -0
- torchcodec/libtorchcodec_custom_ops5.dylib +0 -0
- torchcodec/libtorchcodec_custom_ops6.dylib +0 -0
- torchcodec/libtorchcodec_custom_ops7.dylib +0 -0
- torchcodec/libtorchcodec_pybind_ops4.so +0 -0
- torchcodec/libtorchcodec_pybind_ops5.so +0 -0
- torchcodec/libtorchcodec_pybind_ops6.so +0 -0
- torchcodec/libtorchcodec_pybind_ops7.so +0 -0
- torchcodec/version.py +1 -1
- {torchcodec-0.4.0.dist-info → torchcodec-0.5.dist-info}/METADATA +10 -8
- torchcodec-0.5.dist-info/RECORD +64 -0
- torchcodec/_core/AVIOBytesContext.cpp +0 -137
- torchcodec/_core/AVIOBytesContext.h +0 -54
- torchcodec/libtorchcodec_decoder4.dylib +0 -0
- torchcodec/libtorchcodec_decoder5.dylib +0 -0
- torchcodec/libtorchcodec_decoder6.dylib +0 -0
- torchcodec/libtorchcodec_decoder7.dylib +0 -0
- torchcodec-0.4.0.dist-info/RECORD +0 -62
- {torchcodec-0.4.0.dist-info → torchcodec-0.5.dist-info}/WHEEL +0 -0
- {torchcodec-0.4.0.dist-info → torchcodec-0.5.dist-info}/licenses/LICENSE +0 -0
- {torchcodec-0.4.0.dist-info → torchcodec-0.5.dist-info}/top_level.txt +0 -0
|
Binary file
|
|
Binary file
|
|
@@ -27,8 +27,9 @@ namespace facebook::torchcodec {
|
|
|
27
27
|
// tracks the custom behavior of reading, seeking and writing. It is
|
|
28
28
|
// provided upon AVIOContext creation and to the read, seek and
|
|
29
29
|
// write callback functions.
|
|
30
|
-
//
|
|
31
|
-
//
|
|
30
|
+
// The callback functions do not need to be members of the derived class,
|
|
31
|
+
// but the derived class must have access to them. The context object must
|
|
32
|
+
// be a member of the derived class. Derived classes need to call
|
|
32
33
|
// createAVIOContext(), ideally in their constructor.
|
|
33
34
|
// 3. A generic handle for those that just need to manage having access to an
|
|
34
35
|
// AVIOContext, but aren't necessarily concerned with how it was customized:
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
// All rights reserved.
|
|
3
|
+
//
|
|
4
|
+
// This source code is licensed under the BSD-style license found in the
|
|
5
|
+
// LICENSE file in the root directory of this source tree.
|
|
6
|
+
|
|
7
|
+
#include "src/torchcodec/_core/AVIOTensorContext.h"
|
|
8
|
+
#include <torch/types.h>
|
|
9
|
+
|
|
10
|
+
namespace facebook::torchcodec {
|
|
11
|
+
|
|
12
|
+
namespace {
|
|
13
|
+
|
|
14
|
+
constexpr int64_t INITIAL_TENSOR_SIZE = 10'000'000; // 10 MB
|
|
15
|
+
constexpr int64_t MAX_TENSOR_SIZE = 320'000'000; // 320 MB
|
|
16
|
+
|
|
17
|
+
// The signature of this function is defined by FFMPEG.
|
|
18
|
+
int read(void* opaque, uint8_t* buf, int buf_size) {
|
|
19
|
+
auto tensorContext = static_cast<detail::TensorContext*>(opaque);
|
|
20
|
+
TORCH_CHECK(
|
|
21
|
+
tensorContext->current <= tensorContext->data.numel(),
|
|
22
|
+
"Tried to read outside of the buffer: current=",
|
|
23
|
+
tensorContext->current,
|
|
24
|
+
", size=",
|
|
25
|
+
tensorContext->data.numel());
|
|
26
|
+
|
|
27
|
+
int64_t numBytesRead = std::min(
|
|
28
|
+
static_cast<int64_t>(buf_size),
|
|
29
|
+
tensorContext->data.numel() - tensorContext->current);
|
|
30
|
+
|
|
31
|
+
TORCH_CHECK(
|
|
32
|
+
numBytesRead >= 0,
|
|
33
|
+
"Tried to read negative bytes: numBytesRead=",
|
|
34
|
+
numBytesRead,
|
|
35
|
+
", size=",
|
|
36
|
+
tensorContext->data.numel(),
|
|
37
|
+
", current=",
|
|
38
|
+
tensorContext->current);
|
|
39
|
+
|
|
40
|
+
if (numBytesRead == 0) {
|
|
41
|
+
return AVERROR_EOF;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
std::memcpy(
|
|
45
|
+
buf,
|
|
46
|
+
tensorContext->data.data_ptr<uint8_t>() + tensorContext->current,
|
|
47
|
+
numBytesRead);
|
|
48
|
+
tensorContext->current += numBytesRead;
|
|
49
|
+
return numBytesRead;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// The signature of this function is defined by FFMPEG.
|
|
53
|
+
int write(void* opaque, const uint8_t* buf, int buf_size) {
|
|
54
|
+
auto tensorContext = static_cast<detail::TensorContext*>(opaque);
|
|
55
|
+
|
|
56
|
+
int64_t bufSize = static_cast<int64_t>(buf_size);
|
|
57
|
+
if (tensorContext->current + bufSize > tensorContext->data.numel()) {
|
|
58
|
+
TORCH_CHECK(
|
|
59
|
+
tensorContext->data.numel() * 2 <= MAX_TENSOR_SIZE,
|
|
60
|
+
"We tried to allocate an output encoded tensor larger than ",
|
|
61
|
+
MAX_TENSOR_SIZE,
|
|
62
|
+
" bytes. If you think this should be supported, please report.");
|
|
63
|
+
|
|
64
|
+
// We double the size of the outpout tensor. Calling cat() may not be the
|
|
65
|
+
// most efficient, but it's simple.
|
|
66
|
+
tensorContext->data =
|
|
67
|
+
torch::cat({tensorContext->data, tensorContext->data});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
TORCH_CHECK(
|
|
71
|
+
tensorContext->current + bufSize <= tensorContext->data.numel(),
|
|
72
|
+
"Re-allocation of the output tensor didn't work. ",
|
|
73
|
+
"This should not happen, please report on TorchCodec bug tracker");
|
|
74
|
+
|
|
75
|
+
uint8_t* outputTensorData = tensorContext->data.data_ptr<uint8_t>();
|
|
76
|
+
std::memcpy(outputTensorData + tensorContext->current, buf, bufSize);
|
|
77
|
+
tensorContext->current += bufSize;
|
|
78
|
+
return buf_size;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// The signature of this function is defined by FFMPEG.
|
|
82
|
+
int64_t seek(void* opaque, int64_t offset, int whence) {
|
|
83
|
+
auto tensorContext = static_cast<detail::TensorContext*>(opaque);
|
|
84
|
+
int64_t ret = -1;
|
|
85
|
+
|
|
86
|
+
switch (whence) {
|
|
87
|
+
case AVSEEK_SIZE:
|
|
88
|
+
ret = tensorContext->data.numel();
|
|
89
|
+
break;
|
|
90
|
+
case SEEK_SET:
|
|
91
|
+
tensorContext->current = offset;
|
|
92
|
+
ret = offset;
|
|
93
|
+
break;
|
|
94
|
+
default:
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return ret;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
} // namespace
|
|
102
|
+
|
|
103
|
+
AVIOFromTensorContext::AVIOFromTensorContext(torch::Tensor data)
|
|
104
|
+
: tensorContext_{data, 0} {
|
|
105
|
+
TORCH_CHECK(data.numel() > 0, "data must not be empty");
|
|
106
|
+
TORCH_CHECK(data.is_contiguous(), "data must be contiguous");
|
|
107
|
+
TORCH_CHECK(data.scalar_type() == torch::kUInt8, "data must be kUInt8");
|
|
108
|
+
createAVIOContext(&read, nullptr, &seek, &tensorContext_);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
AVIOToTensorContext::AVIOToTensorContext()
|
|
112
|
+
: tensorContext_{torch::empty({INITIAL_TENSOR_SIZE}, {torch::kUInt8}), 0} {
|
|
113
|
+
createAVIOContext(nullptr, &write, &seek, &tensorContext_);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
torch::Tensor AVIOToTensorContext::getOutputTensor() {
|
|
117
|
+
return tensorContext_.data.narrow(
|
|
118
|
+
/*dim=*/0, /*start=*/0, /*length=*/tensorContext_.current);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
} // namespace facebook::torchcodec
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
// All rights reserved.
|
|
3
|
+
//
|
|
4
|
+
// This source code is licensed under the BSD-style license found in the
|
|
5
|
+
// LICENSE file in the root directory of this source tree.
|
|
6
|
+
|
|
7
|
+
#pragma once
|
|
8
|
+
|
|
9
|
+
#include <torch/types.h>
|
|
10
|
+
#include "src/torchcodec/_core/AVIOContextHolder.h"
|
|
11
|
+
|
|
12
|
+
namespace facebook::torchcodec {
|
|
13
|
+
|
|
14
|
+
namespace detail {
|
|
15
|
+
|
|
16
|
+
struct TensorContext {
|
|
17
|
+
torch::Tensor data;
|
|
18
|
+
int64_t current;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
} // namespace detail
|
|
22
|
+
|
|
23
|
+
// For Decoding: enables users to pass in the entire video or audio as bytes.
|
|
24
|
+
// Our read and seek functions then traverse the bytes in memory.
|
|
25
|
+
class AVIOFromTensorContext : public AVIOContextHolder {
|
|
26
|
+
public:
|
|
27
|
+
explicit AVIOFromTensorContext(torch::Tensor data);
|
|
28
|
+
|
|
29
|
+
private:
|
|
30
|
+
detail::TensorContext tensorContext_;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// For Encoding: used to encode into an output uint8 (bytes) tensor.
|
|
34
|
+
class AVIOToTensorContext : public AVIOContextHolder {
|
|
35
|
+
public:
|
|
36
|
+
explicit AVIOToTensorContext();
|
|
37
|
+
torch::Tensor getOutputTensor();
|
|
38
|
+
|
|
39
|
+
private:
|
|
40
|
+
detail::TensorContext tensorContext_;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
} // namespace facebook::torchcodec
|
torchcodec/_core/CMakeLists.txt
CHANGED
|
@@ -48,65 +48,63 @@ function(make_torchcodec_libraries
|
|
|
48
48
|
# We create three shared libraries per version of FFmpeg, where the version
|
|
49
49
|
# is denoted by N:
|
|
50
50
|
#
|
|
51
|
-
# 1.
|
|
51
|
+
# 1. libtorchcodec_coreN.{ext}: Base library which contains the
|
|
52
52
|
# implementation of VideoDecoder and everything VideoDecoder needs. On
|
|
53
53
|
# Linux, {ext} is so. On Mac, it is dylib.
|
|
54
54
|
#
|
|
55
55
|
# 2. libtorchcodec_custom_opsN.{ext}: Implementation of the PyTorch custom
|
|
56
|
-
# ops. Depends on
|
|
56
|
+
# ops. Depends on libtorchcodec_coreN.{ext}. On Linux, {ext} is so.
|
|
57
57
|
# On Mac, it is dylib.
|
|
58
58
|
#
|
|
59
59
|
# 3. libtorchcodec_pybind_opsN.{ext}: Implementation of the pybind11 ops. We
|
|
60
60
|
# keep these separate from the PyTorch custom ops because we have to
|
|
61
61
|
# load these libraries separately on the Python side. Depends on
|
|
62
|
-
#
|
|
62
|
+
# libtorchcodec_coreN.{ext}. On BOTH Linux and Mac {ext} is so.
|
|
63
63
|
|
|
64
|
-
# 1. Create
|
|
65
|
-
set(
|
|
66
|
-
set(
|
|
64
|
+
# 1. Create libtorchcodec_coreN.{ext}.
|
|
65
|
+
set(core_library_name "libtorchcodec_core${ffmpeg_major_version}")
|
|
66
|
+
set(core_sources
|
|
67
67
|
AVIOContextHolder.cpp
|
|
68
|
-
|
|
68
|
+
AVIOTensorContext.cpp
|
|
69
69
|
FFMPEGCommon.cpp
|
|
70
70
|
Frame.cpp
|
|
71
71
|
DeviceInterface.cpp
|
|
72
72
|
CpuDeviceInterface.cpp
|
|
73
73
|
SingleStreamDecoder.cpp
|
|
74
|
-
# TODO: lib name should probably not be "*_decoder*" now that it also
|
|
75
|
-
# contains an encoder
|
|
76
74
|
Encoder.cpp
|
|
77
75
|
)
|
|
78
76
|
|
|
79
77
|
if(ENABLE_CUDA)
|
|
80
|
-
list(APPEND
|
|
78
|
+
list(APPEND core_sources CudaDeviceInterface.cpp)
|
|
81
79
|
endif()
|
|
82
80
|
|
|
83
|
-
set(
|
|
81
|
+
set(core_library_dependencies
|
|
84
82
|
${ffmpeg_target}
|
|
85
83
|
${TORCH_LIBRARIES}
|
|
86
84
|
)
|
|
87
85
|
|
|
88
86
|
if(ENABLE_CUDA)
|
|
89
|
-
list(APPEND
|
|
87
|
+
list(APPEND core_library_dependencies
|
|
90
88
|
${CUDA_nppi_LIBRARY}
|
|
91
89
|
${CUDA_nppicc_LIBRARY}
|
|
92
90
|
)
|
|
93
91
|
endif()
|
|
94
92
|
|
|
95
93
|
make_torchcodec_sublibrary(
|
|
96
|
-
"${
|
|
94
|
+
"${core_library_name}"
|
|
97
95
|
SHARED
|
|
98
|
-
"${
|
|
99
|
-
"${
|
|
96
|
+
"${core_sources}"
|
|
97
|
+
"${core_library_dependencies}"
|
|
100
98
|
)
|
|
101
99
|
|
|
102
100
|
# 2. Create libtorchcodec_custom_opsN.{ext}.
|
|
103
101
|
set(custom_ops_library_name "libtorchcodec_custom_ops${ffmpeg_major_version}")
|
|
104
102
|
set(custom_ops_sources
|
|
105
|
-
|
|
103
|
+
AVIOTensorContext.cpp
|
|
106
104
|
custom_ops.cpp
|
|
107
105
|
)
|
|
108
106
|
set(custom_ops_dependencies
|
|
109
|
-
${
|
|
107
|
+
${core_library_name}
|
|
110
108
|
${Python3_LIBRARIES}
|
|
111
109
|
)
|
|
112
110
|
make_torchcodec_sublibrary(
|
|
@@ -123,7 +121,7 @@ function(make_torchcodec_libraries
|
|
|
123
121
|
pybind_ops.cpp
|
|
124
122
|
)
|
|
125
123
|
set(pybind_ops_dependencies
|
|
126
|
-
${
|
|
124
|
+
${core_library_name}
|
|
127
125
|
pybind11::module # This library dependency makes sure we have the right
|
|
128
126
|
# Python libraries included as well as all of the right
|
|
129
127
|
# settings so that we can successfully load the shared
|
|
@@ -151,6 +149,15 @@ function(make_torchcodec_libraries
|
|
|
151
149
|
PUBLIC
|
|
152
150
|
"-fvisibility=hidden"
|
|
153
151
|
)
|
|
152
|
+
# The value we use here must match the value we return from
|
|
153
|
+
# _get_pybind_ops_module_name() on the Python side. If the values do not
|
|
154
|
+
# match, then we will be unable to import the C++ shared library as a
|
|
155
|
+
# Python module at runtime.
|
|
156
|
+
target_compile_definitions(
|
|
157
|
+
${pybind_ops_library_name}
|
|
158
|
+
PRIVATE
|
|
159
|
+
PYBIND_OPS_MODULE_NAME=core_pybind_ops
|
|
160
|
+
)
|
|
154
161
|
# If we don't make sure this flag is set, we run into segfauls at import
|
|
155
162
|
# time on Mac. See:
|
|
156
163
|
# https://github.com/pybind/pybind11/issues/3907#issuecomment-1170412764
|
|
@@ -163,7 +170,7 @@ function(make_torchcodec_libraries
|
|
|
163
170
|
# Install all libraries.
|
|
164
171
|
set(
|
|
165
172
|
all_libraries
|
|
166
|
-
${
|
|
173
|
+
${core_library_name}
|
|
167
174
|
${custom_ops_library_name}
|
|
168
175
|
${pybind_ops_library_name}
|
|
169
176
|
)
|
|
@@ -240,7 +247,7 @@ else()
|
|
|
240
247
|
# Expose these values updwards so that the test compilation does not need
|
|
241
248
|
# to re-figure it out. FIXME: it's not great that we just copy-paste the
|
|
242
249
|
# library names.
|
|
243
|
-
set(libtorchcodec_library_name "
|
|
250
|
+
set(libtorchcodec_library_name "libtorchcodec_core${ffmpeg_major_version}" PARENT_SCOPE)
|
|
244
251
|
set(libtorchcodec_custom_ops_name "libtorchcodec_custom_ops${ffmpeg_major_version}" PARENT_SCOPE)
|
|
245
252
|
set(libav_include_dirs ${LIBAV_INCLUDE_DIRS} PARENT_SCOPE)
|
|
246
253
|
endif()
|
|
@@ -37,9 +37,8 @@ bool CpuDeviceInterface::DecodedFrameContext::operator!=(
|
|
|
37
37
|
CpuDeviceInterface::CpuDeviceInterface(const torch::Device& device)
|
|
38
38
|
: DeviceInterface(device) {
|
|
39
39
|
TORCH_CHECK(g_cpu, "CpuDeviceInterface was not registered!");
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
40
|
+
TORCH_CHECK(
|
|
41
|
+
device_.type() == torch::kCPU, "Unsupported device: ", device_.str());
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
// Note [preAllocatedOutputTensor with swscale and filtergraph]:
|
|
@@ -161,9 +160,10 @@ void CpuDeviceInterface::convertAVFrameToFrameOutput(
|
|
|
161
160
|
frameOutput.data = outputTensor;
|
|
162
161
|
}
|
|
163
162
|
} else {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
163
|
+
TORCH_CHECK(
|
|
164
|
+
false,
|
|
165
|
+
"Invalid color conversion library: ",
|
|
166
|
+
static_cast<int>(colorConversionLibrary));
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
|
|
@@ -189,9 +189,8 @@ torch::Tensor CpuDeviceInterface::convertAVFrameToTensorUsingFilterGraph(
|
|
|
189
189
|
const UniqueAVFrame& avFrame) {
|
|
190
190
|
int status = av_buffersrc_write_frame(
|
|
191
191
|
filterGraphContext_.sourceContext, avFrame.get());
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
192
|
+
TORCH_CHECK(
|
|
193
|
+
status >= AVSUCCESS, "Failed to add frame to buffer source context");
|
|
195
194
|
|
|
196
195
|
UniqueAVFrame filteredAVFrame(av_frame_alloc());
|
|
197
196
|
status = av_buffersink_get_frame(
|
|
@@ -241,11 +240,12 @@ void CpuDeviceInterface::createFilterGraph(
|
|
|
241
240
|
filterArgs.str().c_str(),
|
|
242
241
|
nullptr,
|
|
243
242
|
filterGraphContext_.filterGraph.get());
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
243
|
+
TORCH_CHECK(
|
|
244
|
+
status >= 0,
|
|
245
|
+
"Failed to create filter graph: ",
|
|
246
|
+
filterArgs.str(),
|
|
247
|
+
": ",
|
|
248
|
+
getFFMPEGErrorStringFromErrorCode(status));
|
|
249
249
|
|
|
250
250
|
status = avfilter_graph_create_filter(
|
|
251
251
|
&filterGraphContext_.sinkContext,
|
|
@@ -254,11 +254,10 @@ void CpuDeviceInterface::createFilterGraph(
|
|
|
254
254
|
nullptr,
|
|
255
255
|
nullptr,
|
|
256
256
|
filterGraphContext_.filterGraph.get());
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
257
|
+
TORCH_CHECK(
|
|
258
|
+
status >= 0,
|
|
259
|
+
"Failed to create filter graph: ",
|
|
260
|
+
getFFMPEGErrorStringFromErrorCode(status));
|
|
262
261
|
|
|
263
262
|
enum AVPixelFormat pix_fmts[] = {AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE};
|
|
264
263
|
|
|
@@ -268,11 +267,10 @@ void CpuDeviceInterface::createFilterGraph(
|
|
|
268
267
|
pix_fmts,
|
|
269
268
|
AV_PIX_FMT_NONE,
|
|
270
269
|
AV_OPT_SEARCH_CHILDREN);
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
}
|
|
270
|
+
TORCH_CHECK(
|
|
271
|
+
status >= 0,
|
|
272
|
+
"Failed to set output pixel formats: ",
|
|
273
|
+
getFFMPEGErrorStringFromErrorCode(status));
|
|
276
274
|
|
|
277
275
|
UniqueAVFilterInOut outputs(avfilter_inout_alloc());
|
|
278
276
|
UniqueAVFilterInOut inputs(avfilter_inout_alloc());
|
|
@@ -301,19 +299,17 @@ void CpuDeviceInterface::createFilterGraph(
|
|
|
301
299
|
nullptr);
|
|
302
300
|
outputs.reset(outputsTmp);
|
|
303
301
|
inputs.reset(inputsTmp);
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
302
|
+
TORCH_CHECK(
|
|
303
|
+
status >= 0,
|
|
304
|
+
"Failed to parse filter description: ",
|
|
305
|
+
getFFMPEGErrorStringFromErrorCode(status));
|
|
309
306
|
|
|
310
307
|
status =
|
|
311
308
|
avfilter_graph_config(filterGraphContext_.filterGraph.get(), nullptr);
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
309
|
+
TORCH_CHECK(
|
|
310
|
+
status >= 0,
|
|
311
|
+
"Failed to configure filter graph: ",
|
|
312
|
+
getFFMPEGErrorStringFromErrorCode(status));
|
|
317
313
|
}
|
|
318
314
|
|
|
319
315
|
void CpuDeviceInterface::createSwsContext(
|
|
@@ -166,9 +166,8 @@ AVBufferRef* getCudaContext(const torch::Device& device) {
|
|
|
166
166
|
CudaDeviceInterface::CudaDeviceInterface(const torch::Device& device)
|
|
167
167
|
: DeviceInterface(device) {
|
|
168
168
|
TORCH_CHECK(g_cuda, "CudaDeviceInterface was not registered!");
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
169
|
+
TORCH_CHECK(
|
|
170
|
+
device_.type() == torch::kCUDA, "Unsupported device: ", device_.str());
|
|
172
171
|
}
|
|
173
172
|
|
|
174
173
|
CudaDeviceInterface::~CudaDeviceInterface() {
|
|
@@ -228,7 +227,6 @@ void CudaDeviceInterface::convertAVFrameToFrameOutput(
|
|
|
228
227
|
NppiSize oSizeROI = {width, height};
|
|
229
228
|
Npp8u* input[2] = {avFrame->data[0], avFrame->data[1]};
|
|
230
229
|
|
|
231
|
-
auto start = std::chrono::high_resolution_clock::now();
|
|
232
230
|
NppStatus status;
|
|
233
231
|
if (avFrame->colorspace == AVColorSpace::AVCOL_SPC_BT709) {
|
|
234
232
|
status = nppiNV12ToRGB_709CSC_8u_P2C3R(
|
|
@@ -254,12 +252,6 @@ void CudaDeviceInterface::convertAVFrameToFrameOutput(
|
|
|
254
252
|
c10::cuda::getStreamFromExternal(nppGetStream(), device_.index());
|
|
255
253
|
nppDoneEvent.record(nppStreamWrapper);
|
|
256
254
|
nppDoneEvent.block(at::cuda::getCurrentCUDAStream());
|
|
257
|
-
|
|
258
|
-
auto end = std::chrono::high_resolution_clock::now();
|
|
259
|
-
|
|
260
|
-
std::chrono::duration<double, std::micro> duration = end - start;
|
|
261
|
-
VLOG(9) << "NPP Conversion of frame height=" << height << " width=" << width
|
|
262
|
-
<< " took: " << duration.count() << "us" << std::endl;
|
|
263
255
|
}
|
|
264
256
|
|
|
265
257
|
// inspired by https://github.com/FFmpeg/FFmpeg/commit/ad67ea9
|