Skip to content

Commit 6b8765d

Browse files
milan-zhoufacebook-github-bot
authored andcommitted
[TorchAudio][stream_reader] Make StreamingMediaDecoderBytes available for C++ usage (pytorch#3742)
Summary: This diff moves `StreamingMediaDecoderBytes` from the `pybind` file to the `stream_reader` files, enabling usage for all C++ use cases. We can similarly migrate the `StreamingMediaDecoderFile` and `StreamingMediaEncoderFile` in the future. Interestingly we do not have a `StreamingMediaEncoderBytes` implementation. Reviewed By: jeremyteboul Differential Revision: D53585768 Pulled By: milan-zhou
1 parent 5286f9f commit 6b8765d

File tree

4 files changed

+77
-56
lines changed

4 files changed

+77
-56
lines changed

src/libtorio/ffmpeg/ffmpeg.h

+6
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,12 @@ struct StreamParams {
208208
AVRational time_base{};
209209
int stream_index{};
210210
};
211+
212+
struct BytesWrapper {
213+
std::string_view src;
214+
size_t index = 0;
215+
};
216+
211217
} // namespace io
212218
} // namespace torio
213219

src/libtorio/ffmpeg/pybind/pybind.cpp

-56
Original file line numberDiff line numberDiff line change
@@ -188,62 +188,6 @@ struct StreamingMediaEncoderFileObj : private FileObj,
188188
py::hasattr(fileobj, "seek") ? &seek_func : nullptr) {}
189189
};
190190

191-
//////////////////////////////////////////////////////////////////////////////
192-
// StreamingMediaDecoder/Encoder Bytes
193-
//////////////////////////////////////////////////////////////////////////////
194-
struct BytesWrapper {
195-
std::string_view src;
196-
size_t index = 0;
197-
};
198-
199-
static int read_bytes(void* opaque, uint8_t* buf, int buf_size) {
200-
BytesWrapper* wrapper = static_cast<BytesWrapper*>(opaque);
201-
202-
auto num_read = FFMIN(wrapper->src.size() - wrapper->index, buf_size);
203-
if (num_read == 0) {
204-
return AVERROR_EOF;
205-
}
206-
auto head = wrapper->src.data() + wrapper->index;
207-
memcpy(buf, head, num_read);
208-
wrapper->index += num_read;
209-
return num_read;
210-
}
211-
212-
static int64_t seek_bytes(void* opaque, int64_t offset, int whence) {
213-
BytesWrapper* wrapper = static_cast<BytesWrapper*>(opaque);
214-
if (whence == AVSEEK_SIZE) {
215-
return wrapper->src.size();
216-
}
217-
218-
if (whence == SEEK_SET) {
219-
wrapper->index = offset;
220-
} else if (whence == SEEK_CUR) {
221-
wrapper->index += offset;
222-
} else if (whence == SEEK_END) {
223-
wrapper->index = wrapper->src.size() + offset;
224-
} else {
225-
TORCH_INTERNAL_ASSERT(false, "Unexpected whence value: ", whence);
226-
}
227-
return static_cast<int64_t>(wrapper->index);
228-
}
229-
230-
struct StreamingMediaDecoderBytes : private BytesWrapper,
231-
public StreamingMediaDecoderCustomIO {
232-
StreamingMediaDecoderBytes(
233-
std::string_view src,
234-
const c10::optional<std::string>& format,
235-
const c10::optional<std::map<std::string, std::string>>& option,
236-
int64_t buffer_size)
237-
: BytesWrapper{src},
238-
StreamingMediaDecoderCustomIO(
239-
this,
240-
format,
241-
buffer_size,
242-
read_bytes,
243-
seek_bytes,
244-
option) {}
245-
};
246-
247191
#ifndef TORIO_FFMPEG_EXT_NAME
248192
#error TORIO_FFMPEG_EXT_NAME must be defined.
249193
#endif

src/libtorio/ffmpeg/stream_reader/stream_reader.cpp

+49
Original file line numberDiff line numberDiff line change
@@ -610,4 +610,53 @@ StreamingMediaDecoderCustomIO::StreamingMediaDecoderCustomIO(
610610
: CustomInput(opaque, buffer_size, read_packet, seek),
611611
StreamingMediaDecoder(io_ctx, format, option) {}
612612

613+
namespace {
614+
static int read_bytes(void* opaque, uint8_t* buf, int buf_size) {
615+
BytesWrapper* wrapper = static_cast<BytesWrapper*>(opaque);
616+
617+
auto num_read = FFMIN(wrapper->src.size() - wrapper->index, buf_size);
618+
if (num_read == 0) {
619+
return AVERROR_EOF;
620+
}
621+
auto head = wrapper->src.data() + wrapper->index;
622+
memcpy(buf, head, num_read);
623+
wrapper->index += num_read;
624+
return num_read;
625+
}
626+
627+
static int64_t seek_bytes(void* opaque, int64_t offset, int whence) {
628+
BytesWrapper* wrapper = static_cast<BytesWrapper*>(opaque);
629+
if (whence == AVSEEK_SIZE) {
630+
return wrapper->src.size();
631+
}
632+
633+
if (whence == SEEK_SET) {
634+
wrapper->index = offset;
635+
} else if (whence == SEEK_CUR) {
636+
wrapper->index += offset;
637+
} else if (whence == SEEK_END) {
638+
wrapper->index = wrapper->src.size() + offset;
639+
} else {
640+
TORCH_INTERNAL_ASSERT(false, "Unexpected whence value: ", whence);
641+
}
642+
return static_cast<int64_t>(wrapper->index);
643+
}
644+
} // namespace
645+
646+
//////////////////////////////////////////////////////////////////////////////
647+
// StreamingMediaDecoder Bytes
648+
//////////////////////////////////////////////////////////////////////////////
649+
StreamingMediaDecoderBytes::StreamingMediaDecoderBytes(
650+
std::string_view src,
651+
const c10::optional<std::string>& format,
652+
const c10::optional<std::map<std::string, std::string>>& option,
653+
int64_t buffer_size)
654+
: BytesWrapper{src},
655+
StreamingMediaDecoderCustomIO(
656+
this,
657+
format,
658+
buffer_size,
659+
read_bytes,
660+
seek_bytes,
661+
option) {}
613662
} // namespace torio::io

src/libtorio/ffmpeg/stream_reader/stream_reader.h

+22
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,28 @@ class StreamingMediaDecoderCustomIO : private detail::CustomInput,
386386
const c10::optional<OptionDict>& option = c10::nullopt);
387387
};
388388

389+
//////////////////////////////////////////////////////////////////////////////
390+
// StreamingMediaDecoder Bytes
391+
//////////////////////////////////////////////////////////////////////////////
392+
struct StreamingMediaDecoderBytes : private BytesWrapper,
393+
public StreamingMediaDecoderCustomIO {
394+
public:
395+
///
396+
/// Construct StreamingMediaDecoder with read and seek functions that read
397+
/// from in memory buffer
398+
///
399+
/// @param src In memory bytes buffer
400+
/// @param format Specify input format.
401+
/// @param option Custom option passed when initializing format context.
402+
/// @param buffer_size The size of the intermediate buffer, which FFmpeg uses
403+
/// to pass data to function read_packet.
404+
StreamingMediaDecoderBytes(
405+
std::string_view src,
406+
const c10::optional<std::string>& format,
407+
const c10::optional<std::map<std::string, std::string>>& option,
408+
int64_t buffer_size);
409+
};
410+
389411
// For BC
390412
using StreamReader = StreamingMediaDecoder;
391413
using StreamReaderCustomIO = StreamingMediaDecoderCustomIO;

0 commit comments

Comments
 (0)