Skip to content

Commit cb0c6a2

Browse files
authored
[Cherry-pick for 0.1.0 release] Docs and README update (#396) (#398)
1 parent bef7d2a commit cb0c6a2

File tree

3 files changed

+78
-69
lines changed

3 files changed

+78
-69
lines changed

README.md

+53-41
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
# TorchCodec
44

5-
TorchCodec is a Python library for decoding videos into PyTorch tensors. It aims
6-
to be fast, easy to use, and well integrated into the PyTorch ecosystem. If you
7-
want to use PyTorch to train ML models on videos, TorchCodec is how you turn
8-
those videos into data.
5+
TorchCodec is a Python library for decoding videos into PyTorch tensors, on CPU
6+
and CUDA GPU. It aims to be fast, easy to use, and well integrated into the
7+
PyTorch ecosystem. If you want to use PyTorch to train ML models on videos,
8+
TorchCodec is how you turn those videos into data.
99

1010
We achieve these capabilities through:
1111

@@ -19,21 +19,24 @@ We achieve these capabilities through:
1919
or used directly to train models.
2020

2121
> [!NOTE]
22-
> ⚠️ TorchCodec is still in early development stage and some APIs may be updated
23-
> in future versions without a deprecation cycle, depending on user feedback.
22+
> ⚠️ TorchCodec is still in development stage and some APIs may be updated
23+
> in future versions, depending on user feedback.
2424
> If you have any suggestions or issues, please let us know by
2525
> [opening an issue](https://github.com/pytorch/torchcodec/issues/new/choose)!
2626
2727
## Using TorchCodec
2828

29-
Here's a condensed summary of what you can do with TorchCodec. For a more
30-
detailed example, [check out our
29+
Here's a condensed summary of what you can do with TorchCodec. For more detailed
30+
examples, [check out our
3131
documentation](https://pytorch.org/torchcodec/stable/generated_examples/)!
3232

33+
#### Decoding
34+
3335
```python
3436
from torchcodec.decoders import VideoDecoder
3537

36-
decoder = VideoDecoder("path/to/video.mp4")
38+
device = "cpu" # or e.g. "cuda" !
39+
decoder = VideoDecoder("path/to/video.mp4", device=device)
3740

3841
decoder.metadata
3942
# VideoStreamMetadata:
@@ -44,39 +47,47 @@ decoder.metadata
4447
# average_fps: 25.0
4548
# ... (truncated output)
4649

47-
len(decoder) # == decoder.metadata.num_frames!
48-
# 250
49-
decoder.metadata.average_fps # Note: instantaneous fps can be higher or lower
50-
# 25.0
51-
5250
# Simple Indexing API
5351
decoder[0] # uint8 tensor of shape [C, H, W]
5452
decoder[0 : -1 : 20] # uint8 stacked tensor of shape [N, C, H, W]
5553

54+
# Indexing, with PTS and duration info:
55+
decoder.get_frames_at(indices=[2, 100])
56+
# FrameBatch:
57+
# data (shape): torch.Size([2, 3, 270, 480])
58+
# pts_seconds: tensor([0.0667, 3.3367], dtype=torch.float64)
59+
# duration_seconds: tensor([0.0334, 0.0334], dtype=torch.float64)
5660

57-
# Iterate over frames:
58-
for frame in decoder:
59-
pass
61+
# Time-based indexing with PTS and duration info
62+
decoder.get_frames_played_at(seconds=[0.5, 10.4])
63+
# FrameBatch:
64+
# data (shape): torch.Size([2, 3, 270, 480])
65+
# pts_seconds: tensor([ 0.4671, 10.3770], dtype=torch.float64)
66+
# duration_seconds: tensor([0.0334, 0.0334], dtype=torch.float64)
67+
```
6068

61-
# Indexing, with PTS and duration info
62-
decoder.get_frame_at(len(decoder) - 1)
63-
# Frame:
64-
# data (shape): torch.Size([3, 400, 640])
65-
# pts_seconds: 9.960000038146973
66-
# duration_seconds: 0.03999999910593033
69+
#### Clip sampling
6770

68-
decoder.get_frames_in_range(start=10, stop=30, step=5)
69-
# FrameBatch:
70-
# data (shape): torch.Size([4, 3, 400, 640])
71-
# pts_seconds: tensor([0.4000, 0.6000, 0.8000, 1.0000])
72-
# duration_seconds: tensor([0.0400, 0.0400, 0.0400, 0.0400])
71+
```python
7372

74-
# Time-based indexing with PTS and duration info
75-
decoder.get_frame_played_at(pts_seconds=2)
76-
# Frame:
77-
# data (shape): torch.Size([3, 400, 640])
78-
# pts_seconds: 2.0
79-
# duration_seconds: 0.03999999910593033
73+
from torchcodec.samplers import clips_at_regular_timestamps
74+
75+
clips_at_regular_timestamps(
76+
decoder,
77+
seconds_between_clip_starts=1.5,
78+
num_frames_per_clip=4,
79+
seconds_between_frames=0.1
80+
)
81+
# FrameBatch:
82+
# data (shape): torch.Size([9, 4, 3, 270, 480])
83+
# pts_seconds: tensor([[ 0.0000, 0.0667, 0.1668, 0.2669],
84+
# [ 1.4681, 1.5682, 1.6683, 1.7684],
85+
# [ 2.9696, 3.0697, 3.1698, 3.2699],
86+
# ... (truncated), dtype=torch.float64)
87+
# duration_seconds: tensor([[0.0334, 0.0334, 0.0334, 0.0334],
88+
# [0.0334, 0.0334, 0.0334, 0.0334],
89+
# [0.0334, 0.0334, 0.0334, 0.0334],
90+
# ... (truncated), dtype=torch.float64)
8091
```
8192

8293
You can use the following snippet to generate a video with FFmpeg and tryout
@@ -142,7 +153,7 @@ format you want. Refer to Nvidia's GPU support matrix for more details
142153
[official instructions](https://pytorch.org/get-started/locally/).
143154

144155
3. Install or compile FFmpeg with NVDEC support.
145-
TorchCodec with CUDA should work with FFmpeg versions in [4, 7].
156+
TorchCodec with CUDA should work with FFmpeg versions in [5, 7].
146157

147158
If FFmpeg is not already installed, or you need a more recent version, an
148159
easy way to install it is to use `conda`:
@@ -172,16 +183,17 @@ format you want. Refer to Nvidia's GPU support matrix for more details
172183
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i test/resources/nasa_13013.mp4 -f null -
173184
```
174185

175-
4. Install TorchCodec by passing in an `--index-url` parameter that corresponds to your CUDA
176-
Toolkit version, example:
186+
4. Install TorchCodec by passing in an `--index-url` parameter that corresponds
187+
to your CUDA Toolkit version, example:
177188

178189
```bash
179-
# This corresponds to CUDA Toolkit version 12.4 and nightly Pytorch.
180-
pip install torchcodec --index-url=https://download.pytorch.org/whl/nightly/cu124
190+
# This corresponds to CUDA Toolkit version 12.4. It should be the same one
191+
# you used when you installed PyTorch (If you installed PyTorch with pip).
192+
pip install torchcodec --index-url=https://download.pytorch.org/whl/cu124
181193
```
182194

183-
Note that without passing in the `--index-url` parameter, `pip` installs TorchCodec
184-
binaries from PyPi which are CPU-only and do not have CUDA support.
195+
Note that without passing in the `--index-url` parameter, `pip` installs
196+
the CPU-only version of TorchCodec.
185197

186198
## Benchmark Results
187199

docs/source/index.rst

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
Welcome to the TorchCodec documentation!
22
========================================
33

4-
TorchCodec is a Python library for decoding videos into PyTorch tensors. It aims
5-
to be fast, easy to use, and well integrated into the PyTorch ecosystem. If you
6-
want to use PyTorch to train ML models on videos, TorchCodec is how you turn
7-
those videos into data.
4+
TorchCodec is a Python library for decoding videos into PyTorch tensors, on CPU
5+
and CUDA GPU. It aims to be fast, easy to use, and well integrated into the
6+
PyTorch ecosystem. If you want to use PyTorch to train ML models on videos,
7+
TorchCodec is how you turn those videos into data.
88

99
We achieve these capabilities through:
1010

@@ -17,13 +17,6 @@ We achieve these capabilities through:
1717
* Returning data as PyTorch tensors, ready to be fed into PyTorch transforms
1818
or used directly to train models.
1919

20-
.. note::
21-
22-
TorchCodec is still in early development stage and we are actively seeking
23-
feedback. If you have any suggestions or issues, please let us know by
24-
`opening an issue <https://github.com/pytorch/torchcodec/issues/new/choose>`_
25-
on our `GitHub repository <https://github.com/pytorch/torchcodec/>`_.
26-
2720
.. grid:: 3
2821

2922
.. grid-item-card:: :octicon:`file-code;1em`
@@ -48,16 +41,23 @@ We achieve these capabilities through:
4841
:link: generated_examples/sampling.html
4942
:link-type: url
5043

51-
How to sample video clips
44+
How to sample regular and random clips from a video
5245

5346
.. grid-item-card:: :octicon:`file-code;1em`
54-
GPU decoding using TorchCodec
47+
GPU decoding
5548
:img-top: _static/img/card-background.svg
5649
:link: generated_examples/basic_cuda_example.html
5750
:link-type: url
5851

5952
A simple example demonstrating CUDA GPU decoding
6053

54+
.. note::
55+
56+
TorchCodec is still in development stage and we are actively seeking
57+
feedback. If you have any suggestions or issues, please let us know by
58+
`opening an issue <https://github.com/pytorch/torchcodec/issues/new/choose>`_
59+
on our `GitHub repository <https://github.com/pytorch/torchcodec/>`_.
60+
6161
.. toctree::
6262
:maxdepth: 1
6363
:caption: TorchCodec documentation

examples/basic_example.py

+12-15
Original file line numberDiff line numberDiff line change
@@ -120,22 +120,22 @@ def plot(frames: torch.Tensor, title : Optional[str] = None):
120120
# their :term:`pts` (Presentation Time Stamp), and their duration.
121121
# This can be achieved using the
122122
# :meth:`~torchcodec.decoders.VideoDecoder.get_frame_at` and
123-
# :meth:`~torchcodec.decoders.VideoDecoder.get_frames_in_range` methods, which
124-
# will return a :class:`~torchcodec.Frame` and
125-
# :class:`~torchcodec.FrameBatch` objects respectively.
123+
# :meth:`~torchcodec.decoders.VideoDecoder.get_frames_at` methods, which will
124+
# return a :class:`~torchcodec.Frame` and :class:`~torchcodec.FrameBatch`
125+
# objects respectively.
126126

127127
last_frame = decoder.get_frame_at(len(decoder) - 1)
128128
print(f"{type(last_frame) = }")
129129
print(last_frame)
130130

131131
# %%
132-
middle_frames = decoder.get_frames_in_range(start=10, stop=20, step=2)
133-
print(f"{type(middle_frames) = }")
134-
print(middle_frames)
132+
other_frames = decoder.get_frames_at([10, 0, 50])
133+
print(f"{type(other_frames) = }")
134+
print(other_frames)
135135

136136
# %%
137137
plot(last_frame.data, "Last frame")
138-
plot(middle_frames.data, "Middle frames")
138+
plot(other_frames.data, "Other frames")
139139

140140
# %%
141141
# Both :class:`~torchcodec.Frame` and
@@ -152,7 +152,7 @@ def plot(frames: torch.Tensor, title : Optional[str] = None):
152152
# So far, we have retrieved frames based on their index. We can also retrieve
153153
# frames based on *when* they are played with
154154
# :meth:`~torchcodec.decoders.VideoDecoder.get_frame_played_at` and
155-
# :meth:`~torchcodec.decoders.VideoDecoder.get_frames_played_in_range`, which
155+
# :meth:`~torchcodec.decoders.VideoDecoder.get_frames_played_at`, which
156156
# also returns :class:`~torchcodec.Frame` and :class:`~torchcodec.FrameBatch`
157157
# respectively.
158158

@@ -161,13 +161,10 @@ def plot(frames: torch.Tensor, title : Optional[str] = None):
161161
print(frame_at_2_seconds)
162162

163163
# %%
164-
first_two_seconds = decoder.get_frames_played_in_range(
165-
start_seconds=0,
166-
stop_seconds=2,
167-
)
168-
print(f"{type(first_two_seconds) = }")
169-
print(first_two_seconds)
164+
other_frames = decoder.get_frames_played_at(seconds=[10.1, 0.3, 5])
165+
print(f"{type(other_frames) = }")
166+
print(other_frames)
170167

171168
# %%
172169
plot(frame_at_2_seconds.data, "Frame played at 2 seconds")
173-
plot(first_two_seconds.data, "Frames played during [0, 2) seconds")
170+
plot(other_frames.data, "Other frames")

0 commit comments

Comments
 (0)