MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ load_into_container()

bool MayaFlux::IO::VideoFileReader::load_into_container ( std::shared_ptr< Kakshya::SignalSourceContainer container)
overridevirtual

Load file data into an existing container.

Parameters
containerTarget container (must be compatible type).
Returns
true if successful.

Implements MayaFlux::IO::FileReader.

Definition at line 253 of file VideoFileReader.cpp.

255{
256 if (!container) {
257 set_error("Invalid container");
258 return false;
259 }
260
261 auto vc = std::dynamic_pointer_cast<Kakshya::VideoFileContainer>(container);
262 if (!vc) {
263 set_error("Container is not a VideoFileContainer");
264 return false;
265 }
266
267 std::shared_ptr<VideoStreamContext> video;
268 std::shared_ptr<AudioStreamContext> audio;
269 std::shared_ptr<FFmpegDemuxContext> demux;
270 {
271 std::shared_lock lock(m_context_mutex);
272 if (!m_demux || !m_video) {
273 set_error("File not open");
274 return false;
275 }
276 video = m_video;
277 audio = m_audio;
278 demux = m_demux;
279 }
280
281 vc->set_source_path(m_filepath);
282 if (m_demux && m_demux->format_context)
283 vc->set_source_format(m_demux->format_context->iformat->name);
284
285 const uint64_t total = video->total_frames;
286 if (total == 0) {
287 set_error("Video stream reports 0 frames");
288 return false;
289 }
290
291 const uint32_t ring_cap = std::min(
293 static_cast<uint32_t>(total));
294
295 const uint32_t threshold = (m_refill_threshold > 0)
297 : ring_cap / 4;
298
299 const auto fmt = to_image_format(video->out_pixel_format);
300 if (!fmt) {
301 set_error("Video output pixel format has no ImageFormat equivalent");
302 return false;
303 }
304
305 vc->setup_ring(total, ring_cap,
306 video->out_width, video->out_height,
307 *fmt, video->frame_rate,
309
310 m_sws_buf.resize(
311 static_cast<size_t>(video->out_linesize) * video->out_height);
312
315 && demux->find_best_stream(AVMEDIA_TYPE_AUDIO) >= 0;
316
317 if (want_audio && audio && audio->is_valid()) {
318 {
319 std::unique_lock lock(m_context_mutex);
320 demux->seek(audio->stream_index, 0);
321 audio->flush_codec();
322 audio->drain_resampler_init();
323 }
324
325 SoundFileReader audio_reader;
326 audio_reader.set_audio_options(m_audio_options);
327 audio_reader.set_target_sample_rate(m_target_sample_rate);
328
329 if (audio_reader.open_from_demux(demux, audio, m_filepath, m_options)) {
330 auto sc = audio_reader.create_container();
331 if (audio_reader.load_into_container(sc)) {
332 m_audio_container = std::dynamic_pointer_cast<Kakshya::SoundFileContainer>(sc);
333 } else {
335 "VideoFileReader: audio load failed: {}",
336 audio_reader.get_last_error());
337 }
338 } else {
340 "VideoFileReader: open_from_demux failed: {}",
341 audio_reader.get_last_error());
342 }
343
344 {
345 std::unique_lock lock(m_context_mutex);
346 demux->seek(video->stream_index, 0);
347 video->flush_codec();
348 }
349 }
350
351 m_decode_head.store(0);
352 m_container_ref = vc;
353
354 const uint64_t preload = std::min(
355 static_cast<uint64_t>(ring_cap),
356 total);
357
358 uint64_t decoded = decode_batch(*vc, preload);
359
360 if (decoded == 0) {
361 set_error("Failed to decode any frames during preload");
362 return false;
363 }
364
366 "VideoFileReader: preloaded {}/{} frames ({}x{}, {:.1f} fps, ring={})",
367 decoded, total,
368 video->out_width, video->out_height,
369 video->frame_rate, ring_cap);
370
371 auto regions = get_regions();
372 auto region_groups = regions_to_groups(regions);
373 for (const auto& [name, group] : region_groups)
374 vc->add_region_group(group);
375
376 vc->create_default_processor();
377 vc->mark_ready_for_processing(true);
378
379 if (decoded < total)
381
382 return true;
383}
#define MF_INFO(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
std::string name
Definition VKDevice.cpp:143
float threshold
static std::unordered_map< std::string, Kakshya::RegionGroup > regions_to_groups(const std::vector< FileRegion > &regions)
Convert file regions to region groups.
uint64_t decode_batch(Kakshya::VideoFileContainer &vc, uint64_t batch_size)
Decode up to batch_size frames starting at m_decode_head.
void set_error(const std::string &msg) const
std::vector< FileRegion > get_regions() const override
Get semantic regions from the file.
std::vector< uint8_t > m_sws_buf
One-frame sws scratch buffer (padded linesize, reused by decode thread).
std::weak_ptr< Kakshya::VideoFileContainer > m_container_ref
std::shared_ptr< FFmpegDemuxContext > m_demux
std::shared_ptr< VideoStreamContext > m_video
std::shared_ptr< AudioStreamContext > m_audio
std::shared_ptr< Kakshya::SoundFileContainer > m_audio_container
std::atomic< uint64_t > m_decode_head
std::optional< Portal::Graphics::ImageFormat > to_image_format(int av_pixel_format)
Map an AVPixelFormat to the Portal ImageFormat backing it.
@ FileIO
Filesystem I/O operations.
@ IO
Networking, file handling, streaming.
void add_region_group(std::unordered_map< std::string, RegionGroup > &groups, const RegionGroup &group)
Add a RegionGroup to a group map.

References MayaFlux::IO::SoundFileReader::create_container(), decode_batch(), MayaFlux::IO::EXTRACT_AUDIO, MayaFlux::Journal::FileIO, MayaFlux::IO::SoundFileReader::get_last_error(), get_regions(), MayaFlux::Journal::IO, MayaFlux::IO::SoundFileReader::load_into_container(), m_audio, m_audio_container, m_audio_options, m_container_ref, m_context_mutex, m_decode_head, m_demux, m_filepath, m_options, m_reader_id, m_refill_threshold, m_ring_capacity, m_sws_buf, m_target_sample_rate, m_video, m_video_options, MF_INFO, MF_WARN, name, MayaFlux::IO::NONE, MayaFlux::IO::SoundFileReader::open_from_demux(), MayaFlux::IO::FileReader::regions_to_groups(), MayaFlux::IO::SoundFileReader::set_audio_options(), set_error(), MayaFlux::IO::SoundFileReader::set_target_sample_rate(), start_decode_thread(), threshold, and MayaFlux::IO::to_image_format().

+ Here is the call graph for this function: