Skip to content

Commit 592f192

Browse files
authored
Merge branch 'meta-pytorch:main' into use-numFrames-cpp
2 parents f57bead + 1befed7 commit 592f192

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1321
-680
lines changed

.github/workflows/linux_wheel.yaml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,21 @@ jobs:
7171
name: meta-pytorch_torchcodec__${{ matrix.python-version }}_cpu_x86_64
7272
path: pytorch/torchcodec/dist/
7373
- name: Setup conda env
74-
uses: conda-incubator/setup-miniconda@v2
74+
uses: conda-incubator/setup-miniconda@v3
7575
with:
7676
auto-update-conda: true
77-
miniconda-version: "latest"
77+
# Using miniforge instead of miniconda ensures that the default
78+
# conda channel is conda-forge instead of main/default. This ensures
79+
# ABI consistency between dependencies:
80+
# https://conda-forge.org/docs/user/transitioning_from_defaults/
81+
miniforge-version: latest
7882
activate-environment: test
7983
python-version: ${{ matrix.python-version }}
8084
- name: Update pip
8185
run: python -m pip install --upgrade pip
8286
- name: Install PyTorch
8387
run: |
84-
python -m pip install --pre torch --index-url https://download.pytorch.org/whl/nightly/cpu
88+
python -m pip install --pre torch torchvision --index-url https://download.pytorch.org/whl/nightly/cpu
8589
- name: Install torchcodec from the wheel
8690
run: |
8791
wheel_path=`find pytorch/torchcodec/dist -type f -name "*.whl"`

.github/workflows/macos_wheel.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ jobs:
8686

8787
- name: Install PyTorch
8888
run: |
89-
python -m pip install --pre torch --index-url https://download.pytorch.org/whl/nightly/cpu
89+
python -m pip install --pre torch torchvision --index-url https://download.pytorch.org/whl/nightly/cpu
9090
9191
- name: Install torchcodec from the wheel
9292
run: |

.github/workflows/reference_resources.yaml

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,51 @@ defaults:
1414
shell: bash -l -eo pipefail {0}
1515

1616
jobs:
17+
generate-matrix:
18+
uses: pytorch/test-infra/.github/workflows/generate_binary_build_matrix.yml@main
19+
with:
20+
package-type: wheel
21+
os: linux
22+
test-infra-repository: pytorch/test-infra
23+
test-infra-ref: main
24+
with-xpu: disable
25+
with-rocm: disable
26+
with-cuda: disable
27+
build-python-only: "disable"
28+
29+
build:
30+
needs: generate-matrix
31+
strategy:
32+
fail-fast: false
33+
name: Build and Upload Linux wheel
34+
uses: pytorch/test-infra/.github/workflows/build_wheels_linux.yml@main
35+
with:
36+
repository: meta-pytorch/torchcodec
37+
ref: ""
38+
test-infra-repository: pytorch/test-infra
39+
test-infra-ref: main
40+
build-matrix: ${{ needs.generate-matrix.outputs.matrix }}
41+
pre-script: packaging/pre_build_script.sh
42+
post-script: packaging/post_build_script.sh
43+
smoke-test-script: packaging/fake_smoke_test.py
44+
package-name: torchcodec
45+
trigger-event: ${{ github.event_name }}
46+
build-platform: "python-build-package"
47+
build-command: "BUILD_AGAINST_ALL_FFMPEG_FROM_S3=1 python -m build --wheel -vvv --no-isolation"
48+
1749
test-reference-resource-generation:
50+
needs: build
1851
runs-on: ubuntu-latest
1952
strategy:
2053
fail-fast: false
2154
matrix:
2255
python-version: ['3.10']
2356
ffmpeg-version-for-tests: ['4.4.2', '5.1.2', '6.1.1', '7.0.1']
2457
steps:
58+
- uses: actions/download-artifact@v4
59+
with:
60+
name: meta-pytorch_torchcodec__${{ matrix.python-version }}_cpu_x86_64
61+
path: pytorch/torchcodec/dist/
2562
- name: Setup conda env
2663
uses: conda-incubator/setup-miniconda@v2
2764
with:
@@ -43,11 +80,16 @@ jobs:
4380
# Note that we're installing stable - this is for running a script where we're a normal PyTorch
4481
# user, not for building TorhCodec.
4582
python -m pip install torch --index-url https://download.pytorch.org/whl/cpu
46-
python -m pip install numpy pillow
83+
python -m pip install numpy pillow pytest
4784
85+
- name: Install torchcodec from the wheel
86+
run: |
87+
wheel_path=`find pytorch/torchcodec/dist -type f -name "*.whl"`
88+
echo Installing $wheel_path
89+
python -m pip install $wheel_path -vvv
4890
- name: Check out repo
4991
uses: actions/checkout@v3
5092

5193
- name: Run generation reference resources
5294
run: |
53-
python test/generate_reference_resources.py
95+
python -m test.generate_reference_resources

.github/workflows/windows_wheel.yaml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@ jobs:
7171
# TODO: FFmpeg 5 on Windows segfaults in avcodec_open2() when passing
7272
# bad parameters.
7373
# See https://github.com/pytorch/torchcodec/pull/806
74-
# TODO: Support FFmpeg 8 on Windows
75-
ffmpeg-version-for-tests: ['4.4.2', '6.1.1', '7.0.1']
74+
ffmpeg-version-for-tests: ['4.4.2', '6.1.1', '7.0.1', '8.0']
7675
needs: build
7776
steps:
7877
- uses: actions/download-artifact@v4
@@ -83,14 +82,18 @@ jobs:
8382
uses: conda-incubator/setup-miniconda@v2
8483
with:
8584
auto-update-conda: true
86-
miniconda-version: "latest"
85+
# Using miniforge instead of miniconda ensures that the default
86+
# conda channel is conda-forge instead of main/default. This ensures
87+
# ABI consistency between dependencies:
88+
# https://conda-forge.org/docs/user/transitioning_from_defaults/
89+
miniforge-version: latest
8790
activate-environment: test
8891
python-version: ${{ matrix.python-version }}
8992
- name: Update pip
9093
run: python -m pip install --upgrade pip
9194
- name: Install PyTorch
9295
run: |
93-
python -m pip install --pre torch --index-url https://download.pytorch.org/whl/nightly/cpu
96+
python -m pip install --pre torch torchvision --index-url https://download.pytorch.org/whl/nightly/cpu
9497
- name: Install torchcodec from the wheel
9598
run: |
9699
wheel_path=`find pytorch/torchcodec/dist -type f -name "*.whl"`

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ ffmpeg -f lavfi -i \
107107
`torch` and `torchcodec`.
108108

109109
2. Install FFmpeg, if it's not already installed. Linux distributions usually
110-
come with FFmpeg pre-installed. TorchCodec supports all major FFmpeg versions
111-
in [4, 7].
110+
come with FFmpeg pre-installed. TorchCodec supports major FFmpeg versions
111+
in [4, 7] on all platforms, and FFmpeg version 8 is supported on Mac and Linux.
112112

113113
If FFmpeg is not already installed, or you need a more recent version, an
114114
easy way to install it is to use `conda`:
@@ -131,6 +131,7 @@ The following table indicates the compatibility between versions of
131131
| `torchcodec` | `torch` | Python |
132132
| ------------------ | ------------------ | ------------------- |
133133
| `main` / `nightly` | `main` / `nightly` | `>=3.10`, `<=3.13` |
134+
| `0.8` | `2.9` | `>=3.10`, `<=3.13` |
134135
| `0.7` | `2.8` | `>=3.9`, `<=3.13` |
135136
| `0.6` | `2.8` | `>=3.9`, `<=3.13` |
136137
| `0.5` | `2.7` | `>=3.9`, `<=3.13` |
@@ -147,7 +148,8 @@ format you want. Refer to Nvidia's GPU support matrix for more details
147148
[here](https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new).
148149

149150
1. Install FFmpeg with NVDEC support.
150-
TorchCodec with CUDA should work with FFmpeg versions in [4, 7].
151+
TorchCodec with CUDA should work with FFmpeg versions in [4, 7] on all platforms,
152+
and FFmpeg version 8 is supported on Linux.
151153

152154
If FFmpeg is not already installed, or you need a more recent version, an
153155
easy way to install it is to use `conda`:

docs/source/api_ref_decoders.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ For an audio decoder tutorial, see: :ref:`sphx_glr_generated_examples_decoding_a
1919
VideoDecoder
2020
AudioDecoder
2121

22+
.. autosummary::
23+
:toctree: generated/
24+
:nosignatures:
25+
:template: function.rst
26+
27+
set_cuda_backend
2228

2329
.. autosummary::
2430
:toctree: generated/

examples/decoding/basic_cuda_example.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,10 @@
9494
#
9595
# To use CUDA decoder, you need to pass in a cuda device to the decoder.
9696
#
97-
from torchcodec.decoders import VideoDecoder
97+
from torchcodec.decoders import set_cuda_backend, VideoDecoder
9898

99-
decoder = VideoDecoder(video_file, device="cuda")
99+
with set_cuda_backend("beta"): # Use the BETA backend, it's faster!
100+
decoder = VideoDecoder(video_file, device="cuda")
100101
frame = decoder[0]
101102

102103
# %%
@@ -120,7 +121,8 @@
120121
# against equivalent results from the CPU decoders.
121122
timestamps = [12, 19, 45, 131, 180]
122123
cpu_decoder = VideoDecoder(video_file, device="cpu")
123-
cuda_decoder = VideoDecoder(video_file, device="cuda")
124+
with set_cuda_backend("beta"):
125+
cuda_decoder = VideoDecoder(video_file, device="cuda")
124126
cpu_frames = cpu_decoder.get_frames_played_at(timestamps).data
125127
cuda_frames = cuda_decoder.get_frames_played_at(timestamps).data
126128

src/torchcodec/_core/AVIOTensorContext.cpp

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,34 @@ constexpr int64_t MAX_TENSOR_SIZE = 320'000'000; // 320 MB
1818
int read(void* opaque, uint8_t* buf, int buf_size) {
1919
auto tensorContext = static_cast<detail::TensorContext*>(opaque);
2020
TORCH_CHECK(
21-
tensorContext->current <= tensorContext->data.numel(),
22-
"Tried to read outside of the buffer: current=",
23-
tensorContext->current,
21+
tensorContext->current_pos <= tensorContext->data.numel(),
22+
"Tried to read outside of the buffer: current_pos=",
23+
tensorContext->current_pos,
2424
", size=",
2525
tensorContext->data.numel());
2626

2727
int64_t numBytesRead = std::min(
2828
static_cast<int64_t>(buf_size),
29-
tensorContext->data.numel() - tensorContext->current);
29+
tensorContext->data.numel() - tensorContext->current_pos);
3030

3131
TORCH_CHECK(
3232
numBytesRead >= 0,
3333
"Tried to read negative bytes: numBytesRead=",
3434
numBytesRead,
3535
", size=",
3636
tensorContext->data.numel(),
37-
", current=",
38-
tensorContext->current);
37+
", current_pos=",
38+
tensorContext->current_pos);
3939

4040
if (numBytesRead == 0) {
4141
return AVERROR_EOF;
4242
}
4343

4444
std::memcpy(
4545
buf,
46-
tensorContext->data.data_ptr<uint8_t>() + tensorContext->current,
46+
tensorContext->data.data_ptr<uint8_t>() + tensorContext->current_pos,
4747
numBytesRead);
48-
tensorContext->current += numBytesRead;
48+
tensorContext->current_pos += numBytesRead;
4949
return numBytesRead;
5050
}
5151

@@ -54,7 +54,7 @@ int write(void* opaque, const uint8_t* buf, int buf_size) {
5454
auto tensorContext = static_cast<detail::TensorContext*>(opaque);
5555

5656
int64_t bufSize = static_cast<int64_t>(buf_size);
57-
if (tensorContext->current + bufSize > tensorContext->data.numel()) {
57+
if (tensorContext->current_pos + bufSize > tensorContext->data.numel()) {
5858
TORCH_CHECK(
5959
tensorContext->data.numel() * 2 <= MAX_TENSOR_SIZE,
6060
"We tried to allocate an output encoded tensor larger than ",
@@ -68,13 +68,17 @@ int write(void* opaque, const uint8_t* buf, int buf_size) {
6868
}
6969

7070
TORCH_CHECK(
71-
tensorContext->current + bufSize <= tensorContext->data.numel(),
71+
tensorContext->current_pos + bufSize <= tensorContext->data.numel(),
7272
"Re-allocation of the output tensor didn't work. ",
7373
"This should not happen, please report on TorchCodec bug tracker");
7474

7575
uint8_t* outputTensorData = tensorContext->data.data_ptr<uint8_t>();
76-
std::memcpy(outputTensorData + tensorContext->current, buf, bufSize);
77-
tensorContext->current += bufSize;
76+
std::memcpy(outputTensorData + tensorContext->current_pos, buf, bufSize);
77+
tensorContext->current_pos += bufSize;
78+
// Track the maximum position written so getOutputTensor's narrow() does not
79+
// truncate the file if final seek was backwards
80+
tensorContext->max_pos =
81+
std::max(tensorContext->current_pos, tensorContext->max_pos);
7882
return buf_size;
7983
}
8084

@@ -88,7 +92,7 @@ int64_t seek(void* opaque, int64_t offset, int whence) {
8892
ret = tensorContext->data.numel();
8993
break;
9094
case SEEK_SET:
91-
tensorContext->current = offset;
95+
tensorContext->current_pos = offset;
9296
ret = offset;
9397
break;
9498
default:
@@ -101,7 +105,7 @@ int64_t seek(void* opaque, int64_t offset, int whence) {
101105
} // namespace
102106

103107
AVIOFromTensorContext::AVIOFromTensorContext(torch::Tensor data)
104-
: tensorContext_{data, 0} {
108+
: tensorContext_{data, 0, 0} {
105109
TORCH_CHECK(data.numel() > 0, "data must not be empty");
106110
TORCH_CHECK(data.is_contiguous(), "data must be contiguous");
107111
TORCH_CHECK(data.scalar_type() == torch::kUInt8, "data must be kUInt8");
@@ -110,14 +114,17 @@ AVIOFromTensorContext::AVIOFromTensorContext(torch::Tensor data)
110114
}
111115

112116
AVIOToTensorContext::AVIOToTensorContext()
113-
: tensorContext_{torch::empty({INITIAL_TENSOR_SIZE}, {torch::kUInt8}), 0} {
117+
: tensorContext_{
118+
torch::empty({INITIAL_TENSOR_SIZE}, {torch::kUInt8}),
119+
0,
120+
0} {
114121
createAVIOContext(
115122
nullptr, &write, &seek, &tensorContext_, /*isForWriting=*/true);
116123
}
117124

118125
torch::Tensor AVIOToTensorContext::getOutputTensor() {
119126
return tensorContext_.data.narrow(
120-
/*dim=*/0, /*start=*/0, /*length=*/tensorContext_.current);
127+
/*dim=*/0, /*start=*/0, /*length=*/tensorContext_.max_pos);
121128
}
122129

123130
} // namespace facebook::torchcodec

src/torchcodec/_core/AVIOTensorContext.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ namespace detail {
1515

1616
struct TensorContext {
1717
torch::Tensor data;
18-
int64_t current;
18+
int64_t current_pos;
19+
int64_t max_pos;
1920
};
2021

2122
} // namespace detail

0 commit comments

Comments
 (0)