diff --git a/Plugins/SchUtils/Source/SchUtils/Private/Utils/SchCounter.cpp b/Plugins/SchUtils/Source/SchUtils/Private/Utils/SchCounter.cpp new file mode 100644 index 0000000..cc22bec --- /dev/null +++ b/Plugins/SchUtils/Source/SchUtils/Private/Utils/SchCounter.cpp @@ -0,0 +1,27 @@ +#include "Utils/SchCounter.h" + +FSchCounter::FSchCounter() +{ + Count = 0; +} + +void FSchCounter::AddCount(int32 NewCount) +{ + Count += NewCount; +} + +void FSchCounter::RemoveCount(int32 NewCount) +{ + Count -= NewCount; +} + +int32 FSchCounter::GetCount() const +{ + return Count; +} + +void FSchCounter::PrintCount(const FString& Title, bool bRestartCounting) +{ + GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::White, FString::Printf(TEXT("%s: %d"), *Title, GetCount())); + if (bRestartCounting) Count = 0; +} diff --git a/Plugins/SchUtils/Source/SchUtils/Private/Utils/SchTime.cpp b/Plugins/SchUtils/Source/SchUtils/Private/Utils/SchTime.cpp new file mode 100644 index 0000000..65106ae --- /dev/null +++ b/Plugins/SchUtils/Source/SchUtils/Private/Utils/SchTime.cpp @@ -0,0 +1,18 @@ +#include "Utils/SchTime.h" + +FSchTime::FSchTime() +{ + StartMilliseconds = FPlatformTime::ToMilliseconds64(FPlatformTime::Cycles64()); +} + +double FSchTime::GetCurrentTime() const +{ + const double CurrentMilliseconds = FPlatformTime::ToMilliseconds64(FPlatformTime::Cycles64()); + return CurrentMilliseconds - StartMilliseconds; +} + +void FSchTime::PrintCurrentTime(const FString& Title, bool bRestartCounting) +{ + GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("%s: %f"), *Title, GetCurrentTime())); + if (bRestartCounting) StartMilliseconds = FPlatformTime::ToMilliseconds64(FPlatformTime::Cycles64()); +} diff --git a/Plugins/SchUtils/Source/SchUtils/Private/Utils/SchUtilsLib.cpp b/Plugins/SchUtils/Source/SchUtils/Private/Utils/SchUtilsLib.cpp new file mode 100644 index 0000000..627e511 --- /dev/null +++ b/Plugins/SchUtils/Source/SchUtils/Private/Utils/SchUtilsLib.cpp @@ -0,0 +1,16 @@ +#include "Utils/SchUtilsLib.h" + +TSharedPtr SchUtilsLib::CreateTimeCounter() +{ + return MakeShared(); +} + +TSharedPtr SchUtilsLib::CreateCounter() +{ + return MakeShared(); +} + +void SchUtilsLib::PrintImmediately(const FString& Title) +{ + GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, Title); +} diff --git a/Plugins/SchUtils/Source/SchUtils/Public/SchUtils.h b/Plugins/SchUtils/Source/SchUtils/Public/SchUtils.h index 5de978e..02739ef 100644 --- a/Plugins/SchUtils/Source/SchUtils/Public/SchUtils.h +++ b/Plugins/SchUtils/Source/SchUtils/Public/SchUtils.h @@ -39,7 +39,7 @@ struct FDebugToolsByteOffsetStruct }; -class FSchUtilsModule : public IModuleInterface +class SCHUTILS_API FSchUtilsModule : public IModuleInterface { public: void OnSchDebugCommand(const TArray& Strings); @@ -76,3 +76,5 @@ Type FSchUtilsModule::DebugValue(Type Value, const FString& Name, EDebugToolData } return Type(); } + + diff --git a/Plugins/SchUtils/Source/SchUtils/Public/Utils/SchCounter.h b/Plugins/SchUtils/Source/SchUtils/Public/Utils/SchCounter.h new file mode 100644 index 0000000..be12a0f --- /dev/null +++ b/Plugins/SchUtils/Source/SchUtils/Public/Utils/SchCounter.h @@ -0,0 +1,13 @@ +#pragma once + +class SCHUTILS_API FSchCounter +{ +public: + FSchCounter(); + void AddCount(int32 NewCount = 1); + void RemoveCount(int32 NewCount = 1); + int32 GetCount() const; + void PrintCount(const FString& Title, bool bRestartCounting = true); + + int32 Count = 0; +}; diff --git a/Plugins/SchUtils/Source/SchUtils/Public/Utils/SchTime.h b/Plugins/SchUtils/Source/SchUtils/Public/Utils/SchTime.h new file mode 100644 index 0000000..e0d0307 --- /dev/null +++ b/Plugins/SchUtils/Source/SchUtils/Public/Utils/SchTime.h @@ -0,0 +1,11 @@ +#pragma once + +class SCHUTILS_API FSchTime +{ +public: + FSchTime(); + double GetCurrentTime() const; + void PrintCurrentTime(const FString& Title, bool bRestartCounting = true); + + double StartMilliseconds = 0.0; +}; diff --git a/Plugins/SchUtils/Source/SchUtils/Public/Utils/SchUtilsLib.h b/Plugins/SchUtils/Source/SchUtils/Public/Utils/SchUtilsLib.h new file mode 100644 index 0000000..605897b --- /dev/null +++ b/Plugins/SchUtils/Source/SchUtils/Public/Utils/SchUtilsLib.h @@ -0,0 +1,12 @@ +#pragma once +#include "SchCounter.h" +#include "SchTime.h" + +class SCHUTILS_API SchUtilsLib +{ +public: + static TSharedPtr CreateTimeCounter(); + static TSharedPtr CreateCounter(); + static void PrintImmediately(const FString& Title); + +}; diff --git a/Source/Cut5/Interface/VideoInterface.cpp b/Source/Cut5/Interface/VideoInterface.cpp index 7680ad0..24e1121 100644 --- a/Source/Cut5/Interface/VideoInterface.cpp +++ b/Source/Cut5/Interface/VideoInterface.cpp @@ -2,6 +2,8 @@ #include "CutMainWidgetInterface.h" #include "Cut5/Utils/FFMPEGUtils.h" +#include "Utils/SchCounter.h" +#include "Utils/SchUtilsLib.h" bool FVideoThread::Init() { @@ -24,6 +26,9 @@ uint32 FVideoThread::Run() { if (CurrentSeekingFrame != -1) { + + TSharedPtr SchTime = SchUtilsLib::CreateTimeCounter(); + int32 VideoFPS = NewPropertyData.VideoCodecContext->time_base.den; if (VideoFPS < FGlobalData::GlobalFPS) { @@ -43,6 +48,7 @@ uint32 FVideoThread::Run() if (CurrentSeekingFrame - LastSeekFrame > 1 || CurrentSeekingFrame - LastSeekFrame < 0 || LastSeekFrame == -1) { av_seek_frame(NewPropertyData.Context, NewPropertyData.VideoStream, Timestamp, AVSEEK_FLAG_BACKWARD); + SchUtilsLib::PrintImmediately(TEXT("Seeked")); } @@ -62,14 +68,17 @@ uint32 FVideoThread::Run() AllocatedFrame = LastFrame; bNeedReadFrame = false; } - } + SchTime->PrintCurrentTime(TEXT("点1")); + + const TSharedPtr SchCounter = SchUtilsLib::CreateCounter(); bool IsFailed = false; if (bNeedReadFrame) { while (av_read_frame(NewPropertyData.Context, Packet) >= 0) { + SchCounter->AddCount(1); if (Packet->stream_index == NewPropertyData.VideoStream) { int32 Response = avcodec_send_packet(NewPropertyData.VideoCodecContext, Packet); @@ -97,12 +106,14 @@ uint32 FVideoThread::Run() } } av_packet_unref(Packet); + SchCounter->PrintCount("AV_READ_FRAME", true); if (IsFailed == true) { CurrentSeekingFrame = -1; continue;; } + SchTime->PrintCurrentTime(TEXT("点2")); uint8* RawData = nullptr; @@ -198,10 +209,13 @@ uint32 FVideoThread::Run() sws_freeContext(SwsCtx); } + SchTime->PrintCurrentTime(TEXT("点3")); int32 X = AllocatedFrame->width; int32 Y = AllocatedFrame->height; - + const float NewTime = 1 / ((FDateTime::Now().GetMillisecond() * 0.001f) - LastTime); + GEngine->AddOnScreenDebugMessage(0, 0.1f, FColor::Red, FString::SanitizeFloat(NewTime)); + LastTime = FDateTime::Now().GetMillisecond() * 0.001f; AsyncTask(ENamedThreads::GameThread, [this, X, Y, RawData, AllocatedFrame]() { if (ClipData.ClipType == ETrackType::VideoTrack) @@ -222,6 +236,8 @@ uint32 FVideoThread::Run() FMemory::Memcpy(ColorArray.GetData(), RawData, FGlobalData::LightArrayX * FGlobalData::LightArrayY * 4); MainInterface->OnUpdateLightBar(ColorArray); } + + }); // }); @@ -234,7 +250,7 @@ uint32 FVideoThread::Run() } else { - FPlatformProcess::Sleep(0.1f); + FPlatformProcess::Sleep(0.01f); } } return 0; diff --git a/Source/Cut5/Interface/VideoInterface.h b/Source/Cut5/Interface/VideoInterface.h index 060bd60..0260bc3 100644 --- a/Source/Cut5/Interface/VideoInterface.h +++ b/Source/Cut5/Interface/VideoInterface.h @@ -20,4 +20,6 @@ public: std::atomic LastSeekFrame = -1; AVFrame* LastFrame = nullptr; bool IsStop = false; + + float LastTime = 0.0f; }; diff --git a/Source/Cut5/Interface/VideoThumbnailThread.cpp b/Source/Cut5/Interface/VideoThumbnailThread.cpp index 022ad9f..c71c99f 100644 --- a/Source/Cut5/Interface/VideoThumbnailThread.cpp +++ b/Source/Cut5/Interface/VideoThumbnailThread.cpp @@ -32,8 +32,10 @@ uint32 FVideoThumbnailThread::Run() { if (i < BrushCount && ClipData->ResourcePropertyDataPtr && ClipData->ResourcePropertyDataPtr->Context && ClipData->ResourcePropertyDataPtr->VideoStream != -1) { - const int32 CurrentFrame = BrushCount - (BrushCount - i); - const int64 Timestamp = av_rescale_q(CurrentFrame / FGlobalData::GlobalFPS * AV_TIME_BASE, AVRational{1, AV_TIME_BASE}, Info.Context->streams[Info.VideoStream]->time_base); + + const int32 CurrentInterval = BrushCount - (BrushCount - i); + const int32 CurrentFrame = (Info.Context->duration / AV_TIME_BASE * Info.VideoCodecContext->time_base.den) / BrushCount * CurrentInterval; + const int64 Timestamp = av_rescale_q(CurrentFrame * AV_TIME_BASE, AVRational{1, AV_TIME_BASE}, Info.Context->streams[Info.VideoStream]->time_base); av_seek_frame(Info.Context, Info.VideoStream, Timestamp, AVSEEK_FLAG_BACKWARD); AVPacket Packet; av_init_packet(&Packet); diff --git a/Source/Cut5/Widgets/STimelineClip.cpp b/Source/Cut5/Widgets/STimelineClip.cpp index a078410..b43f74b 100644 --- a/Source/Cut5/Widgets/STimelineClip.cpp +++ b/Source/Cut5/Widgets/STimelineClip.cpp @@ -698,7 +698,17 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe return SCompoundWidget::OnPaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled); } - + + const float RangeStart = MainWidgetInterface->GetSelf()->GetCachedGeometry().AbsoluteToLocal( + MainWidgetInterface->GetCutTimeline()->TimelineMainContentVerticalBox->GetCachedGeometry().AbsolutePosition).X; + // MainWidgetInterface->GetCutTimeline()->TimelineMainContentVerticalBox->GetCachedGeometry().LocalToAbsolute(FVector2D(0, 0)).X; + + const float RangeEnd = MainWidgetInterface->GetSelf()->GetCachedGeometry().AbsoluteToLocal( + MainWidgetInterface->GetCutTimeline()->TimelineMainContentVerticalBox->GetCachedGeometry().AbsolutePosition + MainWidgetInterface->GetCutTimeline()->TimelineMainContentVerticalBox->GetCachedGeometry().GetAbsoluteSize()).X; + + const float CurrentStartRange = MainWidgetInterface->GetSelf()->GetCachedGeometry().AbsoluteToLocal(GetCachedGeometry().GetAbsolutePosition()).X; + const float CurrentEndRange = MainWidgetInterface->GetSelf()->GetCachedGeometry().AbsoluteToLocal(GetCachedGeometry().GetAbsolutePosition() + GetCachedGeometry().GetAbsoluteSize()).X; + if (ClipData->ClipType == ETrackType::AudioTrack || ClipData->ClipType == ETrackType::AudioTrackR || ClipData->ClipType == ETrackType::VideoTrack) { @@ -708,15 +718,6 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe // Draw Audio Waveform - const float RangeStart = MainWidgetInterface->GetSelf()->GetCachedGeometry().AbsoluteToLocal( - MainWidgetInterface->GetCutTimeline()->TimelineMainContentVerticalBox->GetCachedGeometry().AbsolutePosition).X; - // MainWidgetInterface->GetCutTimeline()->TimelineMainContentVerticalBox->GetCachedGeometry().LocalToAbsolute(FVector2D(0, 0)).X; - - const float RangeEnd = MainWidgetInterface->GetSelf()->GetCachedGeometry().AbsoluteToLocal( - MainWidgetInterface->GetCutTimeline()->TimelineMainContentVerticalBox->GetCachedGeometry().AbsolutePosition + MainWidgetInterface->GetCutTimeline()->TimelineMainContentVerticalBox->GetCachedGeometry().GetAbsoluteSize()).X; - - const float CurrentStartRange = MainWidgetInterface->GetSelf()->GetCachedGeometry().AbsoluteToLocal(GetCachedGeometry().GetAbsolutePosition()).X; - const float CurrentEndRange = MainWidgetInterface->GetSelf()->GetCachedGeometry().AbsoluteToLocal(GetCachedGeometry().GetAbsolutePosition() + GetCachedGeometry().GetAbsoluteSize()).X; int32 CropStartFrameOffset = ((CurrentStartRange * -1) + RangeStart > 0 ? (CurrentStartRange * -1) + RangeStart : 0) / FGlobalData::DefaultTimeTickSpace; if (CurrentEndRange < RangeStart) @@ -734,7 +735,7 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe CropEndFrameOffset = CropStartFrameOffset * FGlobalData::DefaultTimeTickSpace + (RangeEnd - RangeStart); } - int32 NeedDrawCount = ClipData->GetLength() * FGlobalData::DefaultTimeTickSpace; + int32 NeedDrawCount = ClipData->GetLength() * FGlobalData::DefaultTimeTickSpace * 2; const int32 StartOffset = (ClipData->ResourcePropertyDataPtr->AudioSample / FGlobalData::GlobalFPS) * ClipData->VideoStartFrame @@ -768,6 +769,8 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe // const int32 Interval = (EndOffset - StartOffset) / NeedDrawCount; + const float IndexRangeStart = RangeStart - CurrentStartRange; + const float IndexRangeLength = RangeEnd - RangeStart; for (int32 i = 0; i < NeedDrawCount / DownSample; i++) { const int32 CurrentIndex = (StartOffset * DownSample) + (i * (Interval * DownSample * 4)); @@ -777,11 +780,15 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe float NewFloat = *reinterpret_cast(&ClipData->ResourcePropertyDataPtr->AudioData[CurrentIndex]); float Y = FMath::GetMappedRangeValueClamped(FVector2D(1.0, 0.0), FVector2D(0.0, AllottedGeometry.GetLocalSize().Y), FMath::Abs(NewFloat)); - TArray NewLoc; - NewLoc.Add(FVector2D(i * DownSample, AllottedGeometry.GetLocalSize().Y)); - NewLoc.Add(FVector2D(i * DownSample, Y)); - FSlateDrawElement::MakeLines(OutDrawElements, LayerId + 6, AllottedGeometry.ToPaintGeometry(), NewLoc, ESlateDrawEffect::None, - FColor(45, 214, 153, 255), true, DownSample * 1.2); + + if (i * DownSample > IndexRangeStart && i * DownSample < IndexRangeStart + IndexRangeLength) + { + TArray NewLoc; + NewLoc.Add(FVector2D(i * DownSample, AllottedGeometry.GetLocalSize().Y)); + NewLoc.Add(FVector2D(i * DownSample, Y)); + FSlateDrawElement::MakeLines(OutDrawElements, LayerId + 6, AllottedGeometry.ToPaintGeometry(), NewLoc, ESlateDrawEffect::None, + FColor(45, 214, 153, 255), true, DownSample * 1.2); + } } } @@ -819,7 +826,6 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe if (ClipData->MovieBrushNum > 0 && (ClipData->ClipType == ETrackType::VideoTrack || ClipData->ClipType == ETrackType::LightArrayTrack || ClipData->ClipType == ETrackType::LightBarTrack)) { - float Step = ClipData->MovieBrushNum; const int32 PerImageLength = 128; const int32 ShouldPerImageLength = TotalLength / PerImageLength; @@ -842,9 +848,16 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe { NewBrushes.Add(ClipData->MovieBrushes.Num() > 0 ? ClipData->MovieBrushes[0] : FSlateBrush()); } + + const float IndexRangeStart = RangeStart - CurrentStartRange; + const float IndexRangeLength = RangeEnd - RangeStart; for (FSlateBrush& SlateBrush : NewBrushes) { - FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 5, AllottedGeometry.ToPaintGeometry(FVector2f(PerImageLength, AllottedGeometry.GetLocalSize().Y), FSlateLayoutTransform(FVector2f(i * PerImageLength, 0))), &SlateBrush); + if ((i * 128) > IndexRangeStart - 128 && (i * 128) < (IndexRangeStart + IndexRangeLength)) + { + FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 5, AllottedGeometry.ToPaintGeometry(FVector2f(PerImageLength, AllottedGeometry.GetLocalSize().Y), FSlateLayoutTransform(FVector2f(i * PerImageLength, 0))), &SlateBrush); + } + i++; } }