MCPcopy Create free account
hub / github.com/OpenShot/libopenshot / GetFrame

Method GetFrame

src/FrameMapper.cpp:434–690  ·  view source on GitHub ↗

Get an openshot::Frame object for a specific frame number of this reader.

Source from the content-addressed store, hash-verified

432
433// Get an openshot::Frame object for a specific frame number of this reader.
434std::shared_ptr<Frame> FrameMapper::GetFrame(int64_t requested_frame)
435{
436 // Check final cache, and just return the frame (if it's available)
437 std::shared_ptr<Frame> final_frame = final_cache.GetFrame(requested_frame);
438 if (final_frame) return final_frame;
439
440 // Create a scoped lock, allowing only a single thread to run the following code at one time
441 const std::lock_guard<std::recursive_mutex> lock(getFrameMutex);
442
443 // Find parent properties (if any)
444 Clip *parent = static_cast<Clip *>(ParentClip());
445 bool is_increasing = true;
446 bool direction_flipped = false;
447
448 {
449 const std::lock_guard<std::recursive_mutex> lock(directionMutex);
450
451 // One-shot: if a hint exists, consume it for THIS call, regardless of frame number.
452 if (have_hint) {
453 is_increasing = hint_increasing;
454 have_hint = false;
455 } else if (previous_frame > 0 && std::llabs(requested_frame - previous_frame) == 1) {
456 // Infer from request order when adjacent
457 is_increasing = (requested_frame > previous_frame);
458 } else if (last_dir_initialized) {
459 // Reuse last known direction if non-adjacent and no hint
460 is_increasing = last_is_increasing;
461 } else {
462 is_increasing = true; // default on first call
463 }
464
465 // Detect flips so we can reset SR context
466 if (!last_dir_initialized) {
467 last_is_increasing = is_increasing;
468 last_dir_initialized = true;
469 } else if (last_is_increasing != is_increasing) {
470 direction_flipped = true;
471 last_is_increasing = is_increasing;
472 }
473 }
474 if (parent) {
475 float position = parent->Position();
476 float start = parent->Start();
477 if (parent_position != position || parent_start != start) {
478 // Force dirty if parent clip has moved or been trimmed
479 // since this heavily affects frame #s and audio mappings
480 is_dirty = true;
481 }
482 }
483
484 // Check if mappings are dirty (and need to be recalculated)
485 if (is_dirty)
486 Init();
487
488 // Check final cache a 2nd time (due to potential lock already generating this frame)
489 final_frame = final_cache.GetFrame(requested_frame);
490 if (final_frame) return final_frame;
491

Callers 1

GetOrCreateFrameMethod · 0.45

Calls 15

AppendDebugMethodMethod · 0.80
GetAudioChannelsCountMethod · 0.80
GetAudioSamplesCountMethod · 0.80
AddImageMethod · 0.80
GetImageMethod · 0.80
ExtendMethod · 0.80
AddAudioSilenceMethod · 0.80
AddAudioMethod · 0.80
GetAudioSamplesMethod · 0.80
SetAudioDirectionMethod · 0.80
PositionMethod · 0.45
StartMethod · 0.45

Tested by

no test coverage detected