|
22 | 22 |
|
23 | 23 | #include "openshot_catch.h" |
24 | 24 |
|
| 25 | +#define private public |
25 | 26 | #include "FFmpegReader.h" |
| 27 | +#undef private |
26 | 28 | #include "Exceptions.h" |
27 | 29 | #include "Frame.h" |
28 | 30 | #include "Timeline.h" |
@@ -528,6 +530,54 @@ TEST_CASE( "Attached_Picture_Audio_Does_Not_Stall_Early_Frames", "[libopenshot][ |
528 | 530 | std::remove(fixture_path.str().c_str()); |
529 | 531 | } |
530 | 532 |
|
| 533 | +TEST_CASE( "Missing_Image_Frame_Finalizes_Using_Previous_Image", "[libopenshot][ffmpegreader]" ) |
| 534 | +{ |
| 535 | + FFmpegReader r("synthetic-missing-image", DurationStrategy::VideoPreferred, false); |
| 536 | + |
| 537 | + r.info.has_video = true; |
| 538 | + r.info.has_audio = true; |
| 539 | + r.info.has_single_image = false; |
| 540 | + r.info.width = 320; |
| 541 | + r.info.height = 240; |
| 542 | + r.info.fps = Fraction(30, 1); |
| 543 | + r.info.sample_rate = 48000; |
| 544 | + r.info.channels = 2; |
| 545 | + r.info.channel_layout = LAYOUT_STEREO; |
| 546 | + r.info.video_length = 120; |
| 547 | + r.info.video_timebase = Fraction(1, 30); |
| 548 | + r.info.audio_timebase = Fraction(1, 48000); |
| 549 | + |
| 550 | + r.pts_offset_seconds = 0.0; |
| 551 | + r.last_frame = 58; |
| 552 | + r.video_pts_seconds = 2.233333; |
| 553 | + r.audio_pts_seconds = 3.100000; |
| 554 | + r.packet_status.video_eof = false; |
| 555 | + r.packet_status.audio_eof = false; |
| 556 | + r.packet_status.packets_eof = false; |
| 557 | + r.packet_status.end_of_file = false; |
| 558 | + |
| 559 | + const int samples_per_frame = Frame::GetSamplesPerFrame( |
| 560 | + 58, r.info.fps, r.info.sample_rate, r.info.channels); |
| 561 | + auto previous = std::make_shared<Frame>( |
| 562 | + 58, r.info.width, r.info.height, "#112233", samples_per_frame, r.info.channels); |
| 563 | + previous->AddColor(r.info.width, r.info.height, "#112233"); |
| 564 | + r.final_cache.Add(previous); |
| 565 | + r.last_final_video_frame = previous; |
| 566 | + |
| 567 | + auto missing = r.CreateFrame(59); |
| 568 | + r.working_cache.Add(missing); |
| 569 | + REQUIRE(missing != nullptr); |
| 570 | + REQUIRE_FALSE(missing->has_image_data); |
| 571 | + |
| 572 | + r.CheckWorkingFrames(59); |
| 573 | + |
| 574 | + auto finalized = r.final_cache.GetFrame(59); |
| 575 | + REQUIRE(finalized != nullptr); |
| 576 | + CHECK(finalized->has_image_data); |
| 577 | + CHECK(finalized->CheckPixel(0, 0, 17, 34, 51, 255, 0)); |
| 578 | + CHECK(r.final_cache.GetFrame(58) != nullptr); |
| 579 | +} |
| 580 | + |
531 | 581 | TEST_CASE( "HardwareDecodeSuccessful_IsFalse_WhenHardwareDecodeIsDisabled", "[libopenshot][ffmpegreader][hardware]" ) |
532 | 582 | { |
533 | 583 | HardwareDecoderSettingsGuard guard; |
|
0 commit comments