视频流畅度,封面,音频优化

This commit is contained in:
Sch 2023-10-18 14:51:40 +08:00
parent 483f6acef6
commit 71b226f25a
11 changed files with 156 additions and 24 deletions

View File

@ -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;
}

View File

@ -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());
}

View File

@ -0,0 +1,16 @@
#include "Utils/SchUtilsLib.h"
TSharedPtr<FSchTime> SchUtilsLib::CreateTimeCounter()
{
return MakeShared<FSchTime>();
}
TSharedPtr<FSchCounter> SchUtilsLib::CreateCounter()
{
return MakeShared<FSchCounter>();
}
void SchUtilsLib::PrintImmediately(const FString& Title)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, Title);
}

View File

@ -39,7 +39,7 @@ struct FDebugToolsByteOffsetStruct
}; };
class FSchUtilsModule : public IModuleInterface class SCHUTILS_API FSchUtilsModule : public IModuleInterface
{ {
public: public:
void OnSchDebugCommand(const TArray<FString>& Strings); void OnSchDebugCommand(const TArray<FString>& Strings);
@ -76,3 +76,5 @@ Type FSchUtilsModule::DebugValue(Type Value, const FString& Name, EDebugToolData
} }
return Type(); return Type();
} }

View File

@ -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;
};

View File

@ -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;
};

View File

@ -0,0 +1,12 @@
#pragma once
#include "SchCounter.h"
#include "SchTime.h"
class SCHUTILS_API SchUtilsLib
{
public:
static TSharedPtr<FSchTime> CreateTimeCounter();
static TSharedPtr<FSchCounter> CreateCounter();
static void PrintImmediately(const FString& Title);
};

View File

@ -2,6 +2,8 @@
#include "CutMainWidgetInterface.h" #include "CutMainWidgetInterface.h"
#include "Cut5/Utils/FFMPEGUtils.h" #include "Cut5/Utils/FFMPEGUtils.h"
#include "Utils/SchCounter.h"
#include "Utils/SchUtilsLib.h"
bool FVideoThread::Init() bool FVideoThread::Init()
{ {
@ -24,6 +26,9 @@ uint32 FVideoThread::Run()
{ {
if (CurrentSeekingFrame != -1) if (CurrentSeekingFrame != -1)
{ {
TSharedPtr<FSchTime> SchTime = SchUtilsLib::CreateTimeCounter();
int32 VideoFPS = NewPropertyData.VideoCodecContext->time_base.den; int32 VideoFPS = NewPropertyData.VideoCodecContext->time_base.den;
if (VideoFPS < FGlobalData::GlobalFPS) if (VideoFPS < FGlobalData::GlobalFPS)
{ {
@ -43,6 +48,7 @@ uint32 FVideoThread::Run()
if (CurrentSeekingFrame - LastSeekFrame > 1 || CurrentSeekingFrame - LastSeekFrame < 0 || LastSeekFrame == -1) if (CurrentSeekingFrame - LastSeekFrame > 1 || CurrentSeekingFrame - LastSeekFrame < 0 || LastSeekFrame == -1)
{ {
av_seek_frame(NewPropertyData.Context, NewPropertyData.VideoStream, Timestamp, AVSEEK_FLAG_BACKWARD); av_seek_frame(NewPropertyData.Context, NewPropertyData.VideoStream, Timestamp, AVSEEK_FLAG_BACKWARD);
SchUtilsLib::PrintImmediately(TEXT("Seeked"));
} }
@ -62,14 +68,17 @@ uint32 FVideoThread::Run()
AllocatedFrame = LastFrame; AllocatedFrame = LastFrame;
bNeedReadFrame = false; bNeedReadFrame = false;
} }
} }
SchTime->PrintCurrentTime(TEXT("点1"));
const TSharedPtr<FSchCounter> SchCounter = SchUtilsLib::CreateCounter();
bool IsFailed = false; bool IsFailed = false;
if (bNeedReadFrame) if (bNeedReadFrame)
{ {
while (av_read_frame(NewPropertyData.Context, Packet) >= 0) while (av_read_frame(NewPropertyData.Context, Packet) >= 0)
{ {
SchCounter->AddCount(1);
if (Packet->stream_index == NewPropertyData.VideoStream) if (Packet->stream_index == NewPropertyData.VideoStream)
{ {
int32 Response = avcodec_send_packet(NewPropertyData.VideoCodecContext, Packet); int32 Response = avcodec_send_packet(NewPropertyData.VideoCodecContext, Packet);
@ -97,12 +106,14 @@ uint32 FVideoThread::Run()
} }
} }
av_packet_unref(Packet); av_packet_unref(Packet);
SchCounter->PrintCount("AV_READ_FRAME", true);
if (IsFailed == true) if (IsFailed == true)
{ {
CurrentSeekingFrame = -1; CurrentSeekingFrame = -1;
continue;; continue;;
} }
SchTime->PrintCurrentTime(TEXT("点2"));
uint8* RawData = nullptr; uint8* RawData = nullptr;
@ -198,10 +209,13 @@ uint32 FVideoThread::Run()
sws_freeContext(SwsCtx); sws_freeContext(SwsCtx);
} }
SchTime->PrintCurrentTime(TEXT("点3"));
int32 X = AllocatedFrame->width; int32 X = AllocatedFrame->width;
int32 Y = AllocatedFrame->height; 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]() AsyncTask(ENamedThreads::GameThread, [this, X, Y, RawData, AllocatedFrame]()
{ {
if (ClipData.ClipType == ETrackType::VideoTrack) if (ClipData.ClipType == ETrackType::VideoTrack)
@ -222,6 +236,8 @@ uint32 FVideoThread::Run()
FMemory::Memcpy(ColorArray.GetData(), RawData, FGlobalData::LightArrayX * FGlobalData::LightArrayY * 4); FMemory::Memcpy(ColorArray.GetData(), RawData, FGlobalData::LightArrayX * FGlobalData::LightArrayY * 4);
MainInterface->OnUpdateLightBar(ColorArray); MainInterface->OnUpdateLightBar(ColorArray);
} }
}); });
// }); // });
@ -234,7 +250,7 @@ uint32 FVideoThread::Run()
} }
else else
{ {
FPlatformProcess::Sleep(0.1f); FPlatformProcess::Sleep(0.01f);
} }
} }
return 0; return 0;

View File

@ -20,4 +20,6 @@ public:
std::atomic<int32> LastSeekFrame = -1; std::atomic<int32> LastSeekFrame = -1;
AVFrame* LastFrame = nullptr; AVFrame* LastFrame = nullptr;
bool IsStop = false; bool IsStop = false;
float LastTime = 0.0f;
}; };

View File

@ -32,8 +32,10 @@ uint32 FVideoThumbnailThread::Run()
{ {
if (i < BrushCount && ClipData->ResourcePropertyDataPtr && ClipData->ResourcePropertyDataPtr->Context && ClipData->ResourcePropertyDataPtr->VideoStream != -1) 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); av_seek_frame(Info.Context, Info.VideoStream, Timestamp, AVSEEK_FLAG_BACKWARD);
AVPacket Packet; AVPacket Packet;
av_init_packet(&Packet); av_init_packet(&Packet);

View File

@ -698,7 +698,17 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe
return SCompoundWidget::OnPaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, return SCompoundWidget::OnPaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle,
bParentEnabled); 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) 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 // 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; int32 CropStartFrameOffset = ((CurrentStartRange * -1) + RangeStart > 0 ? (CurrentStartRange * -1) + RangeStart : 0) / FGlobalData::DefaultTimeTickSpace;
if (CurrentEndRange < RangeStart) if (CurrentEndRange < RangeStart)
@ -734,7 +735,7 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe
CropEndFrameOffset = CropStartFrameOffset * FGlobalData::DefaultTimeTickSpace + (RangeEnd - RangeStart); 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) const int32 StartOffset = (ClipData->ResourcePropertyDataPtr->AudioSample / FGlobalData::GlobalFPS)
* ClipData->VideoStartFrame * ClipData->VideoStartFrame
@ -768,6 +769,8 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe
// //
const int32 Interval = (EndOffset - StartOffset) / NeedDrawCount; const int32 Interval = (EndOffset - StartOffset) / NeedDrawCount;
const float IndexRangeStart = RangeStart - CurrentStartRange;
const float IndexRangeLength = RangeEnd - RangeStart;
for (int32 i = 0; i < NeedDrawCount / DownSample; i++) for (int32 i = 0; i < NeedDrawCount / DownSample; i++)
{ {
const int32 CurrentIndex = (StartOffset * DownSample) + (i * (Interval * DownSample * 4)); 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<float*>(&ClipData->ResourcePropertyDataPtr->AudioData[CurrentIndex]); float NewFloat = *reinterpret_cast<float*>(&ClipData->ResourcePropertyDataPtr->AudioData[CurrentIndex]);
float Y = FMath::GetMappedRangeValueClamped(FVector2D(1.0, 0.0), FVector2D(0.0, AllottedGeometry.GetLocalSize().Y), float Y = FMath::GetMappedRangeValueClamped(FVector2D(1.0, 0.0), FVector2D(0.0, AllottedGeometry.GetLocalSize().Y),
FMath::Abs(NewFloat)); FMath::Abs(NewFloat));
TArray<FVector2D> NewLoc;
NewLoc.Add(FVector2D(i * DownSample, AllottedGeometry.GetLocalSize().Y)); if (i * DownSample > IndexRangeStart && i * DownSample < IndexRangeStart + IndexRangeLength)
NewLoc.Add(FVector2D(i * DownSample, Y)); {
FSlateDrawElement::MakeLines(OutDrawElements, LayerId + 6, AllottedGeometry.ToPaintGeometry(), NewLoc, ESlateDrawEffect::None, TArray<FVector2D> NewLoc;
FColor(45, 214, 153, 255), true, DownSample * 1.2); 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 || if (ClipData->MovieBrushNum > 0 && (ClipData->ClipType == ETrackType::VideoTrack || ClipData->ClipType == ETrackType::LightArrayTrack ||
ClipData->ClipType == ETrackType::LightBarTrack)) ClipData->ClipType == ETrackType::LightBarTrack))
{ {
float Step = ClipData->MovieBrushNum; float Step = ClipData->MovieBrushNum;
const int32 PerImageLength = 128; const int32 PerImageLength = 128;
const int32 ShouldPerImageLength = TotalLength / PerImageLength; 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()); NewBrushes.Add(ClipData->MovieBrushes.Num() > 0 ? ClipData->MovieBrushes[0] : FSlateBrush());
} }
const float IndexRangeStart = RangeStart - CurrentStartRange;
const float IndexRangeLength = RangeEnd - RangeStart;
for (FSlateBrush& SlateBrush : NewBrushes) 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++; i++;
} }
} }