-
Notifications
You must be signed in to change notification settings - Fork 71
Refactor pybind_ops to only deal with file like context holders #889
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
2828dc5
f57fc00
fa32ece
c6e07ae
497f68b
167212f
0a68ef7
97224ba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,13 +7,8 @@ | |
| #include <pybind11/pybind11.h> | ||
| #include <pybind11/stl.h> | ||
| #include <cstdint> | ||
| #include <string> | ||
|
|
||
| #include "src/torchcodec/_core/AVIOFileLikeContext.h" | ||
| #include "src/torchcodec/_core/Encoder.h" | ||
| #include "src/torchcodec/_core/SingleStreamDecoder.h" | ||
| #include "src/torchcodec/_core/StreamOptions.h" | ||
| #include "src/torchcodec/_core/ValidationUtils.h" | ||
|
|
||
| namespace py = pybind11; | ||
|
|
||
|
|
@@ -26,62 +21,18 @@ namespace facebook::torchcodec { | |
| // | ||
| // So we instead launder the pointer through an int, and then use a conversion | ||
| // function on the custom ops side to launder that int into a tensor. | ||
| int64_t create_from_file_like( | ||
| py::object file_like, | ||
| std::optional<std::string_view> seek_mode) { | ||
| SingleStreamDecoder::SeekMode realSeek = SingleStreamDecoder::SeekMode::exact; | ||
| if (seek_mode.has_value()) { | ||
| realSeek = seekModeFromString(seek_mode.value()); | ||
| } | ||
|
|
||
| auto avioContextHolder = | ||
| std::make_unique<AVIOFileLikeContext>(file_like, /*isForWriting=*/false); | ||
|
|
||
| SingleStreamDecoder* decoder = | ||
| new SingleStreamDecoder(std::move(avioContextHolder), realSeek); | ||
| return reinterpret_cast<int64_t>(decoder); | ||
| } | ||
|
|
||
| void encode_audio_to_file_like( | ||
| int64_t data_ptr, | ||
| const std::vector<int64_t>& shape, | ||
| int64_t sample_rate, | ||
| std::string_view format, | ||
| py::object file_like, | ||
| std::optional<int64_t> bit_rate = std::nullopt, | ||
| std::optional<int64_t> num_channels = std::nullopt, | ||
| std::optional<int64_t> desired_sample_rate = std::nullopt) { | ||
| // We assume float32 *and* contiguity, this must be enforced by the caller. | ||
| auto tensor_options = torch::TensorOptions().dtype(torch::kFloat32); | ||
| auto samples = torch::from_blob( | ||
| reinterpret_cast<void*>(data_ptr), shape, tensor_options); | ||
|
|
||
| AudioStreamOptions audioStreamOptions; | ||
| audioStreamOptions.bitRate = validateOptionalInt64ToInt(bit_rate, "bit_rate"); | ||
| audioStreamOptions.numChannels = | ||
| validateOptionalInt64ToInt(num_channels, "num_channels"); | ||
| audioStreamOptions.sampleRate = | ||
| validateOptionalInt64ToInt(desired_sample_rate, "desired_sample_rate"); | ||
|
|
||
| auto avioContextHolder = | ||
| std::make_unique<AVIOFileLikeContext>(file_like, /*isForWriting=*/true); | ||
|
|
||
| AudioEncoder encoder( | ||
| samples, | ||
| validateInt64ToInt(sample_rate, "sample_rate"), | ||
| format, | ||
| std::move(avioContextHolder), | ||
| audioStreamOptions); | ||
| encoder.encode(); | ||
| int64_t create_file_like_context(py::object file_like, bool is_for_writing) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment above was meant to be about "laundering into into tensors" because it was about the decoder object itself. Now we're laundering an int into an Separately from the comment, and since we shouldn't need the intermediate tensor representation, I wonder if we could actually work around all that by "cleanly" binding the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe py::objects need to be existing kinds of objects Python already knows about. I thought about what you're suggesting, and I think that would mean actually defining a new kind of Python to C++ object through pybind. We can do it, but it will take some work to figure out if it's worth it.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I improved the comment, referenced and created #896 |
||
| AVIOFileLikeContext* context = | ||
| new AVIOFileLikeContext(file_like, is_for_writing); | ||
| return reinterpret_cast<int64_t>(context); | ||
| } | ||
|
|
||
| #ifndef PYBIND_OPS_MODULE_NAME | ||
| #error PYBIND_OPS_MODULE_NAME must be defined! | ||
| #endif | ||
|
|
||
| PYBIND11_MODULE(PYBIND_OPS_MODULE_NAME, m) { | ||
| m.def("create_from_file_like", &create_from_file_like); | ||
| m.def("encode_audio_to_file_like", &encode_audio_to_file_like); | ||
| m.def("create_file_like_context", &create_file_like_context); | ||
| } | ||
|
|
||
| } // namespace facebook::torchcodec | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine, but if we can, we might as well set the hidden visibility flag for the whole pybind_ops lib and remove the
VISIBILITY_HIDDENstuff:This seems to work OK locally
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's what I did, I can confirm this compiles locally
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NicolasHug, yeah, I did the same. The one difference is that I put both of them under the same
if(NOT WIN32)and explaining comment. It breaks the convention of only doing one library at a time, but I think it helps understanding. All of the visibility stuff, with the same cause, are all in one place.