Skip to content

Commit 240c6f6

Browse files
authored
Update public API of multi-stream encoder (#1416)
1 parent 42c8e86 commit 240c6f6

4 files changed

Lines changed: 213 additions & 204 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
from ._audio_encoder import AudioEncoder # noqa
2+
from ._multi_stream_encoder import Encoder # noqa
23
from ._video_encoder import VideoEncoder # noqa

src/torchcodec/encoders/_multi_stream_encoder.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from pathlib import Path
12
from typing import Any
23

34
from torch import Tensor
@@ -16,7 +17,7 @@ def __init__(self, encoder_tensor: Tensor, stream_index: int):
1617
self._encoder_tensor = encoder_tensor
1718
self._stream_index = stream_index
1819

19-
def write(self, frames: Tensor) -> None:
20+
def add_frames(self, frames: Tensor) -> None:
2021
_core.streaming_encoder_add_frames(
2122
self._encoder_tensor, frames, self._stream_index
2223
)
@@ -27,13 +28,13 @@ def __init__(self, encoder_tensor: Tensor, stream_index: int):
2728
self._encoder_tensor = encoder_tensor
2829
self._stream_index = stream_index
2930

30-
def write(self, samples: Tensor) -> None:
31+
def add_samples(self, samples: Tensor) -> None:
3132
_core.streaming_encoder_add_samples(
3233
self._encoder_tensor, samples, self._stream_index
3334
)
3435

3536

36-
class StreamingEncoder:
37+
class Encoder:
3738
def __init__(self):
3839
self._encoder_tensor = _core.create_streaming_encoder()
3940

@@ -73,33 +74,31 @@ def add_audio(
7374
sample_rate: int,
7475
num_channels: int,
7576
bit_rate: int | None = None,
76-
# TODO MultiStreamEncoder: Decide on public API for 'output' params
77-
output_num_channels: int | None = None,
78-
output_sample_rate: int | None = None,
77+
out_num_channels: int | None = None,
78+
out_sample_rate: int | None = None,
7979
) -> _AudioStream:
8080
stream_index = _core.streaming_encoder_add_audio_stream(
8181
self._encoder_tensor,
8282
sample_rate=sample_rate,
8383
num_channels=num_channels,
8484
bit_rate=bit_rate,
85-
output_num_channels=output_num_channels,
86-
output_sample_rate=output_sample_rate,
85+
output_num_channels=out_num_channels,
86+
output_sample_rate=out_sample_rate,
8787
)
8888
return _AudioStream(self._encoder_tensor, stream_index)
8989

90-
# TODO MultiStreamEncoder: Maybe there should 2 separate methods, one for
91-
# file, one for file-like.
92-
def open(self, dest, *, format: str | None = None) -> "StreamingEncoder":
93-
if format is not None:
94-
_core.streaming_encoder_open_file_like(self._encoder_tensor, format, dest)
95-
else:
96-
_core.streaming_encoder_open_file(self._encoder_tensor, str(dest))
90+
def open_file(self, dest: str | Path) -> "Encoder":
91+
_core.streaming_encoder_open_file(self._encoder_tensor, str(dest))
92+
return self
93+
94+
def open_file_like(self, dest, *, format: str) -> "Encoder":
95+
_core.streaming_encoder_open_file_like(self._encoder_tensor, format, dest)
9796
return self
9897

9998
def close(self) -> None:
10099
_core.streaming_encoder_close(self._encoder_tensor)
101100

102-
def __enter__(self) -> "StreamingEncoder":
101+
def __enter__(self) -> "Encoder":
103102
return self
104103

105104
def __exit__(self, exc_type, exc_val, exc_tb) -> None:

test/smoke_test.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
from torchcodec import ffmpeg_major_version
99
from torchcodec._frame import AudioSamples, Frame, FrameBatch
1010
from torchcodec.decoders import AudioDecoder, VideoDecoder
11-
from torchcodec.encoders import AudioEncoder, VideoEncoder
12-
from torchcodec.encoders._multi_stream_encoder import StreamingEncoder
11+
from torchcodec.encoders import AudioEncoder, Encoder, VideoEncoder
1312

1413

1514
NUM_FRAMES = 10
@@ -300,7 +299,7 @@ def test_resample_on_encode(self, tmp_path):
300299
assert abs(decoded.data.shape[1] - expected_num_samples) <= 1
301300

302301

303-
class TestStreamingEncoder:
302+
class TestEncoder:
304303
def test_video_and_audio_chunked(self, tmp_path):
305304
frames = torch.randint(
306305
0, 256, (NUM_FRAMES, 3, HEIGHT, WIDTH), dtype=torch.uint8
@@ -309,7 +308,7 @@ def test_video_and_audio_chunked(self, tmp_path):
309308
samples = torch.rand(NUM_AUDIO_CHANNELS, NUM_SAMPLES) * 2 - 1
310309
path = tmp_path / "av.mkv"
311310

312-
enc = StreamingEncoder()
311+
enc = Encoder()
313312
video = enc.add_video(
314313
height=HEIGHT,
315314
width=WIDTH,
@@ -318,12 +317,12 @@ def test_video_and_audio_chunked(self, tmp_path):
318317
crf=0,
319318
)
320319
audio = enc.add_audio(sample_rate=sr, num_channels=NUM_AUDIO_CHANNELS)
321-
enc.open(dest=path)
320+
enc.open_file(path)
322321
with enc:
323-
video.write(frames[:5])
324-
audio.write(samples[:, : NUM_SAMPLES // 2])
325-
video.write(frames[5:])
326-
audio.write(samples[:, NUM_SAMPLES // 2 :])
322+
video.add_frames(frames[:5])
323+
audio.add_samples(samples[:, : NUM_SAMPLES // 2])
324+
video.add_frames(frames[5:])
325+
audio.add_samples(samples[:, NUM_SAMPLES // 2 :])
327326

328327
video_dec = VideoDecoder(path)
329328
assert len(video_dec) == NUM_FRAMES
@@ -358,18 +357,18 @@ def test_cuda_encoding(self, tmp_path):
358357
frames = frames.cuda()
359358

360359
cuda_path = tmp_path / "cuda.mp4"
361-
enc = StreamingEncoder()
360+
enc = Encoder()
362361
video = enc.add_video(
363362
height=HEIGHT,
364363
width=WIDTH,
365364
frame_rate=FRAME_RATE,
366365
device="cuda",
367366
)
368-
with enc.open(dest=cuda_path):
369-
video.write(frames)
367+
with enc.open_file(cuda_path):
368+
video.add_frames(frames)
370369

371370
cpu_path = tmp_path / "cpu.mp4"
372-
cpu_enc = StreamingEncoder()
371+
cpu_enc = Encoder()
373372
cpu_video = cpu_enc.add_video(
374373
height=HEIGHT,
375374
width=WIDTH,

0 commit comments

Comments
 (0)