22#include <libavdevice/avdevice.h>
27IOManager::IOManager(uint64_t sample_rate, uint32_t buffer_size, uint32_t frame_rate,
const std::shared_ptr<Buffers::BufferManager>& buffer_manager)
28 : m_sample_rate(sample_rate)
29 , m_buffer_size(buffer_size)
30 , m_frame_rate(frame_rate)
31 , m_buffer_manager(buffer_manager)
33 m_io_service = std::make_shared<Registry::Service::IOService>();
35 m_io_service->request_decode = [
this](uint64_t reader_id) {
76std::shared_ptr<Kakshya::VideoFileContainer>
85 auto reader = std::make_shared<IO::VideoFileReader>();
87 if (!reader->can_read(filepath)) {
89 "Cannot read video file: {}", filepath);
103 "Failed to open video file: {}", reader->get_last_error());
108 reader->setup_io_service(reader_id);
110 auto video_container = std::dynamic_pointer_cast<Kakshya::VideoFileContainer>(reader->create_container());
112 if (!video_container) {
114 "Failed to create video container from: {}", filepath);
119 if (!reader->load_into_container(video_container)) {
121 "Failed to load video data: {}", reader->get_last_error());
129 result.
video = video_container;
132 auto audio_container = reader->get_audio_container();
133 if (audio_container) {
135 result.
audio = audio_container;
139 "No audio track found in: {}", filepath);
144 "Loaded video: {}", filepath);
153 "IOManager::register_video_reader called with null reader");
157 const uint64_t
id =
m_next_reader_id.fetch_add(1, std::memory_order_relaxed);
158 reader->set_reader_id(
id);
166 "IOManager: registered VideoFileReader id={}",
id);
178 "IOManager::release_video_reader: unknown id={}", reader_id);
185 "IOManager: released VideoFileReader id={}", reader_id);
195 "IOManager: dispatch_decode_request unknown reader_id={}", reader_id);
199 it->second->signal_decode();
209 "IOManager: dispatch_frame_request unknown reader_id={}", reader_id);
213 it->second->pull_frame_all();
218 auto reader = std::make_shared<IO::SoundFileReader>();
220 if (!reader->can_read(filepath)) {
233 auto container = reader->create_container();
234 auto sound_container = std::dynamic_pointer_cast<Kakshya::SoundFileContainer>(container);
235 if (!sound_container) {
240 if (!reader->load_into_container(sound_container)) {
249 return sound_container;
252std::shared_ptr<Kakshya::CameraContainer>
255 static std::once_flag s_avdevice_init;
256 std::call_once(s_avdevice_init, [] { avdevice_register_all(); });
258 auto reader = std::make_shared<CameraReader>();
260 if (!reader->open(config)) {
262 "open_camera: failed — {}", reader->last_error());
266 auto container = reader->create_container();
269 "open_camera: failed to create container — {}",
270 reader->last_error());
274 container->create_default_processor();
277 reader->set_container(container);
284 container->setup_io(rid);
285 container->mark_ready_for_processing(
true);
288 "open_camera: reader_id={} device='{}' {}x{} @{:.1f}fps",
290 reader->width(), reader->height(), reader->frame_rate());
295std::shared_ptr<Buffers::TextureBuffer>
298 auto reader = std::make_shared<IO::ImageReader>();
300 if (!reader->open(filepath)) {
302 "Failed to open image: {}", filepath);
306 auto texture_buffer = reader->create_texture_buffer();
308 if (!texture_buffer) {
310 "Failed to create texture buffer from: {}", filepath);
317 "Loaded image: {} ({}x{})",
318 std::filesystem::path(filepath).filename().
string(),
319 texture_buffer->get_width(),
320 texture_buffer->get_height());
322 return texture_buffer;
326 const std::shared_ptr<Kakshya::VideoFileContainer>& container)
328 auto existing = std::dynamic_pointer_cast<Kakshya::FrameAccessProcessor>(
329 container->get_default_processor());
335 "Configured existing FrameAccessProcessor");
337 auto processor = std::make_shared<Kakshya::FrameAccessProcessor>();
339 processor->set_auto_advance(
true);
340 container->set_default_processor(processor);
342 "Created and set FrameAccessProcessor");
347 const std::shared_ptr<Kakshya::SoundFileContainer>& container)
351 const std::vector<uint64_t> output_shape = {
353 container->get_num_channels()
356 auto existing = std::dynamic_pointer_cast<Kakshya::ContiguousAccessProcessor>(
357 container->get_default_processor());
360 existing->set_output_size(output_shape);
363 "Configured existing ContiguousAccessProcessor");
365 auto processor = std::make_shared<Kakshya::ContiguousAccessProcessor>();
366 processor->set_output_size(output_shape);
367 processor->set_auto_advance(
true);
368 container->set_default_processor(processor);
370 "Created and set ContiguousAccessProcessor");
374std::shared_ptr<Buffers::VideoContainerBuffer>
376 const std::shared_ptr<Kakshya::VideoFileContainer>& container)
380 "hook_video_container_to_buffer: null container");
384 auto stream_container = std::dynamic_pointer_cast<Kakshya::StreamContainer>(container);
386 if (!stream_container) {
388 "hook_video_container_to_buffer: container is not a VideoStreamContainer");
402 "Hooked VideoFileContainer to VideoContainerBuffer ({}x{})",
403 video_buffer->get_width(), video_buffer->get_height());
408std::vector<std::shared_ptr<Buffers::SoundContainerBuffer>>
410 const std::shared_ptr<Kakshya::SoundFileContainer>& container)
414 "hook_audio_container_to_buffers: null container");
418 uint32_t num_channels = container->get_num_channels();
419 std::vector<std::shared_ptr<Buffers::SoundContainerBuffer>> created_buffers;
424 "Setting up audio playback for {} channels...",
427 for (uint32_t channel = 0; channel < num_channels; ++channel) {
436 created_buffers.push_back(std::move(container_buffer));
441 "✓ Created buffer for channel {}",
447 return created_buffers;
450std::shared_ptr<Buffers::VideoContainerBuffer>
452 const std::shared_ptr<Kakshya::CameraContainer>& container)
456 "hook_camera_to_buffer: null container");
460 auto stream_container = std::dynamic_pointer_cast<Kakshya::StreamContainer>(container);
461 if (!stream_container) {
463 "hook_camera_to_buffer: container is not a StreamContainer");
473 "hook_camera_to_buffer: failed to create VideoContainerBuffer");
483 "Hooked CameraContainer to VideoContainerBuffer ({}x{})",
484 video_buffer->get_width(), video_buffer->get_height());
489std::shared_ptr<Buffers::VideoContainerBuffer>
491 const std::shared_ptr<Kakshya::VideoFileContainer>& container)
const
498std::vector<std::shared_ptr<Buffers::SoundContainerBuffer>>
500 const std::shared_ptr<Kakshya::SoundFileContainer>& container)
const
504 return it !=
m_audio_buffers.end() ? it->second : std::vector<std::shared_ptr<Buffers::SoundContainerBuffer>> {};
507std::shared_ptr<Kakshya::SoundFileContainer>
515std::shared_ptr<Buffers::VideoContainerBuffer>
517 const std::shared_ptr<Kakshya::CameraContainer>& container)
const
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_TRACE(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
Cycle Behavior: The for_cycles(N) configuration controls how many times the capture operation execute...
void initialize()
Initialize the buffer after construction.
AudioBuffer implementation backed by a StreamContainer.
TextureBuffer implementation backed by a VideoStreamContainer.
std::unordered_map< std::shared_ptr< Kakshya::VideoFileContainer >, std::shared_ptr< Kakshya::SoundFileContainer > > m_extracted_audio
std::shared_ptr< Kakshya::VideoFileContainer > load_video(const std::string &filepath)
Load a video file into a VideoFileContainer.
std::unordered_map< std::shared_ptr< Kakshya::CameraContainer >, std::shared_ptr< Buffers::VideoContainerBuffer > > m_camera_buffers
std::unordered_map< uint64_t, std::shared_ptr< CameraReader > > m_camera_readers
std::unordered_map< std::shared_ptr< Kakshya::SoundFileContainer >, std::vector< std::shared_ptr< Buffers::SoundContainerBuffer > > > m_audio_buffers
std::shared_ptr< Buffers::TextureBuffer > load_image(const std::string &filepath)
Load an image file into a TextureBuffer.
std::shared_ptr< Kakshya::CameraContainer > open_camera(const CameraConfig &config)
Open a camera device and create a CameraContainer.
std::vector< std::shared_ptr< Buffers::SoundContainerBuffer > > hook_audio_container_to_buffers(const std::shared_ptr< Kakshya::SoundFileContainer > &container)
Wire a SoundFileContainer to the audio buffer system.
void dispatch_frame_request(uint64_t reader_id)
IOService::request_frame target — shared-lock lookup + pull_frame_all().
void configure_frame_processor(const std::shared_ptr< Kakshya::VideoFileContainer > &container)
std::vector< std::shared_ptr< SoundFileReader > > m_audio_readers
std::vector< std::shared_ptr< Buffers::SoundContainerBuffer > > get_audio_buffers(const std::shared_ptr< Kakshya::SoundFileContainer > &container) const
Retrieve the SoundContainerBuffers created for a container.
std::shared_mutex m_camera_mutex
std::shared_ptr< Buffers::VideoContainerBuffer > hook_video_container_to_buffer(const std::shared_ptr< Kakshya::VideoFileContainer > &container)
Wire a VideoFileContainer to the graphics buffer system.
void configure_audio_processor(const std::shared_ptr< Kakshya::SoundFileContainer > &container)
std::shared_ptr< Kakshya::SoundFileContainer > get_extracted_audio(const std::shared_ptr< Kakshya::VideoFileContainer > &container) const
Retrieve the SoundFileContainer extracted from a video file.
std::shared_ptr< Buffers::VideoContainerBuffer > get_video_buffer(const std::shared_ptr< Kakshya::VideoFileContainer > &container) const
Retrieve the VideoContainerBuffer created for a container.
std::shared_ptr< Buffers::VideoContainerBuffer > get_camera_buffer(const std::shared_ptr< Kakshya::CameraContainer > &container) const
Retrieve the VideoContainerBuffer created for a camera container.
void release_video_reader(uint64_t reader_id)
Release ownership of the reader identified by reader_id.
void dispatch_decode_request(uint64_t reader_id)
IOService::request_decode target — shared-lock lookup + signal_decode().
std::shared_mutex m_buffers_mutex
uint64_t register_video_reader(std::shared_ptr< VideoFileReader > reader)
Assign a globally unique reader_id and take ownership of a reader.
std::shared_ptr< Buffers::VideoContainerBuffer > hook_camera_to_buffer(const std::shared_ptr< Kakshya::CameraContainer > &container)
Wire a CameraContainer to the graphics buffer system.
~IOManager()
Unregisters IOService, releases all owned readers, clears stored buffers.
std::shared_ptr< Buffers::BufferManager > m_buffer_manager
std::atomic< uint64_t > m_next_reader_id
IOManager(uint64_t sample_rate, uint32_t buffer_size, uint32_t frame_rate, const std::shared_ptr< Buffers::BufferManager > &buffer_manager)
Construct IOManager and register the IOService into BackendRegistry.
std::vector< std::shared_ptr< ImageReader > > m_image_readers
std::shared_ptr< Registry::Service::IOService > m_io_service
std::shared_mutex m_readers_mutex
std::unordered_map< uint64_t, std::shared_ptr< VideoFileReader > > m_video_readers
std::shared_ptr< Kakshya::SoundFileContainer > load_audio(const std::string &filepath, LoadConfig config={})
Load an audio file into a SoundFileContainer.
std::unordered_map< std::shared_ptr< Kakshya::VideoFileContainer >, std::shared_ptr< Buffers::VideoContainerBuffer > > m_video_buffers
void register_service(ServiceFactory factory)
Register a backend service capability.
static BackendRegistry & instance()
Get the global registry instance.
void unregister_service()
Unregister a service.
@ AUDIO_BACKEND
Standard audio processing backend configuration.
@ GRAPHICS_BACKEND
Standard graphics processing backend configuration.
@ ContainerProcessing
Container operations (Kakshya - file/stream/region processing)
@ BufferManagement
Buffer Management (Buffers::BufferManager, creating buffers)
@ FileIO
Filesystem I/O operations.
@ Init
Engine/subsystem initialization.
@ AsyncIO
Async I/O operations ( network, streaming)
@ Runtime
General runtime operations (default fallback)
@ Core
Core engine, backend, subsystems.
@ API
MayaFlux/API Wrapper and convenience functions.
@ ROW_MAJOR
C/C++ style (last dimension varies fastest)
std::string device_name
Platform device string.
Platform-specific FFmpeg input format string for camera devices.
FileReadOptions file_options
AudioReadOptions audio_options
VideoReadOptions video_options
std::shared_ptr< Kakshya::SoundFileContainer > audio
std::shared_ptr< Kakshya::VideoFileContainer > video
Result of load_video() when audio extraction is requested via VideoReadOptions::EXTRACT_AUDIO.
std::function< void(uint64_t reader_id)> request_frame
Request the identified camera reader to pull the next frame.
Backend IO streaming service interface.