Merge remote-tracking branch 'remotes/RedstoneRemote/master'
This commit is contained in:
commit
bb79be6d54
@ -2,8 +2,6 @@
|
||||
|
||||
#include "CutMainWidgetInterface.h"
|
||||
#include "Cut5/Utils/FFMPEGUtils.h"
|
||||
#include "Utils/SchCounter.h"
|
||||
#include "Utils/SchUtilsLib.h"
|
||||
|
||||
bool FVideoThread::Init()
|
||||
{
|
||||
@ -26,9 +24,6 @@ uint32 FVideoThread::Run()
|
||||
{
|
||||
if (CurrentSeekingFrame != -1)
|
||||
{
|
||||
|
||||
TSharedPtr<FSchTime> SchTime = SchUtilsLib::CreateTimeCounter();
|
||||
|
||||
int32 VideoFPS = NewPropertyData.VideoCodecContext->time_base.den;
|
||||
if (VideoFPS < FGlobalData::GlobalFPS)
|
||||
{
|
||||
@ -48,7 +43,6 @@ 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"));
|
||||
}
|
||||
|
||||
|
||||
@ -68,17 +62,14 @@ uint32 FVideoThread::Run()
|
||||
AllocatedFrame = LastFrame;
|
||||
bNeedReadFrame = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SchTime->PrintCurrentTime(TEXT("点1"));
|
||||
|
||||
const TSharedPtr<FSchCounter> 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);
|
||||
@ -106,14 +97,12 @@ 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;
|
||||
|
||||
@ -209,13 +198,10 @@ 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)
|
||||
@ -236,8 +222,6 @@ uint32 FVideoThread::Run()
|
||||
FMemory::Memcpy(ColorArray.GetData(), RawData, FGlobalData::LightArrayX * FGlobalData::LightArrayY * 4);
|
||||
MainInterface->OnUpdateLightBar(ColorArray);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
// });
|
||||
@ -250,7 +234,7 @@ uint32 FVideoThread::Run()
|
||||
}
|
||||
else
|
||||
{
|
||||
FPlatformProcess::Sleep(0.01f);
|
||||
FPlatformProcess::Sleep(0.1f);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -20,6 +20,4 @@ public:
|
||||
std::atomic<int32> LastSeekFrame = -1;
|
||||
AVFrame* LastFrame = nullptr;
|
||||
bool IsStop = false;
|
||||
|
||||
float LastTime = 0.0f;
|
||||
};
|
||||
|
@ -32,10 +32,8 @@ uint32 FVideoThumbnailThread::Run()
|
||||
{
|
||||
if (i < BrushCount && ClipData->ResourcePropertyDataPtr && ClipData->ResourcePropertyDataPtr->Context && ClipData->ResourcePropertyDataPtr->VideoStream != -1)
|
||||
{
|
||||
|
||||
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);
|
||||
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);
|
||||
av_seek_frame(Info.Context, Info.VideoStream, Timestamp, AVSEEK_FLAG_BACKWARD);
|
||||
AVPacket Packet;
|
||||
av_init_packet(&Packet);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "FFMPEGUtils.h"
|
||||
#include "FFMPEGUtils.h"
|
||||
#include "FFMPEGUtils.h"
|
||||
|
||||
|
||||
|
||||
@ -7,6 +8,8 @@
|
||||
#include "ImageUtils.h"
|
||||
#include "Utils.h"
|
||||
#include "Cut5/FFT/kiss_fft.h"
|
||||
#include "Cut5/Interface/CutMainWidgetInterface.h"
|
||||
#include "Cut5/Widgets/SCutMainWindow.h"
|
||||
#include "Engine/Canvas.h"
|
||||
#include "Engine/TextureRenderTarget2D.h"
|
||||
#include "Kismet/KismetRenderingLibrary.h"
|
||||
@ -661,6 +664,79 @@ TArray<FSlateBrush> FFFMPEGUtils::GetAudioBrush(FClipData* ClipData)
|
||||
return {};
|
||||
}
|
||||
|
||||
void FFFMPEGUtils::GenerateProjectorEvent(const FClipData* ClipData)
|
||||
{
|
||||
// Get Projector Track Data
|
||||
SCutTimeline* Timeline = FGlobalData::MainWidgetInterface->GetSelf()->GetCutTimeline();
|
||||
FTrackData* ProjectorTrackData = Timeline->GetTrackDataByType(ETrackType::ProjectorTrack);
|
||||
|
||||
if (ClipData->ClipType == ETrackType::VideoTrack
|
||||
&& ClipData->ResourcePropertyDataPtr)
|
||||
{
|
||||
FTimelinePropertyData Info;
|
||||
LoadContextPure(ToFullPath(ClipData->MoviePath), &Info);
|
||||
if (Info.Context == nullptr)
|
||||
return;
|
||||
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
AVPacket* Packet = av_packet_alloc();
|
||||
AVFrame* Frame = av_frame_alloc();
|
||||
|
||||
if (av_read_frame(Info.Context, Packet) < 0)
|
||||
{
|
||||
if (av_read_frame(Info.Context, Packet) < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (int32 Response = avcodec_send_packet(Info.VideoCodecContext, Packet) < 0)
|
||||
{
|
||||
check(false);
|
||||
};
|
||||
if (int32 Response = avcodec_receive_frame(Info.VideoCodecContext, Frame) >= 0)
|
||||
{
|
||||
if (Frame->width == 0 || Frame->height == 0)
|
||||
continue;
|
||||
|
||||
SwsContext* SwsConvert =
|
||||
sws_getContext(Frame->width, Frame->height, Info.VideoCodecContext->pix_fmt,
|
||||
128, 72, AV_PIX_FMT_RGBA, SWS_BICUBIC, nullptr, nullptr, nullptr);
|
||||
|
||||
uint8* RawData = new uint8[128 * 72 * 4];
|
||||
uint8* Dest[4] = {RawData, nullptr, nullptr, nullptr};
|
||||
constexpr int32 DestStride[4] = {128 * 4, 0, 0, 0};
|
||||
|
||||
sws_scale(SwsConvert, Frame->data, Frame->linesize, 0, Frame->height, Dest, DestStride);
|
||||
sws_freeContext(SwsConvert);
|
||||
|
||||
float RawDataFloat = RawData[0];
|
||||
|
||||
int32 GrayCount = 0;
|
||||
for (int32 i = 0; i < 128 * 72; i++)
|
||||
{
|
||||
float Gray = RawData[i * 4 + 0] * 0.299 + RawData[i * 4 + 1] * 0.587 + RawData[i * 4 + 2] * 0.114;
|
||||
}
|
||||
|
||||
|
||||
av_packet_free(&Packet);
|
||||
av_frame_free(&Frame);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
av_packet_free(&Packet);
|
||||
av_frame_free(&Frame);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
TArray<TArray<FColor>> FFFMPEGUtils::GetVideoFrameLightArray(FString VideoPath, int32 X, int32 Y)
|
||||
{
|
||||
@ -704,4 +780,4 @@ TArray<TArray<FColor>> FFFMPEGUtils::GetVideoFrameLightArray(FString VideoPath,
|
||||
}
|
||||
}
|
||||
return Colors;
|
||||
}
|
||||
}
|
||||
|
@ -24,4 +24,6 @@ struct FFFMPEGUtils
|
||||
|
||||
static TArray<FSlateBrush> GetMovieBrush(struct FClipData* ClipData, bool Regenerate = false);
|
||||
static TArray<FSlateBrush> GetAudioBrush(struct FClipData* ClipData);
|
||||
|
||||
static void GenerateProjectorEvent(const FClipData* ClipData);
|
||||
};
|
||||
|
@ -36,8 +36,8 @@ public:
|
||||
inline static FString ExportPath = "";
|
||||
|
||||
inline static bool Export_OnlyXML = false;
|
||||
|
||||
inline static TArray<FString> ExportErrorString;
|
||||
inline static class ICutMainWidgetInterface* MainWidgetInterface = nullptr;
|
||||
|
||||
inline static TArray<FColor> Colors =
|
||||
{
|
||||
|
@ -47,6 +47,9 @@ BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
|
||||
void SCutMainWindow::Construct(const FArguments& InArgs)
|
||||
{
|
||||
|
||||
FGlobalData::MainWidgetInterface = this;
|
||||
|
||||
SAssignNew(CutTimeline, SCutTimeline).MainWidgetInterface(this);
|
||||
SAssignNew(StatePanel, SStatePanel);
|
||||
SAssignNew(CustomPanel, SCustomPanel);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "ClipProxy.h"
|
||||
|
||||
#include "Cut5/Utils/FFMPEGUtils.h"
|
||||
#include "Cut5/Utils/Utils.h"
|
||||
#include "Cut5/Widgets/SCutMainWindow.h"
|
||||
#include "Cut5/Widgets/SCutTimeline.h"
|
||||
@ -653,6 +654,43 @@ TSharedPtr<SWidget> FClipProxy::GetPropertiesWidget()
|
||||
]
|
||||
];
|
||||
}
|
||||
if (ClipData->ClipType == ETrackType::VideoTrack)
|
||||
{
|
||||
VerticalBox->AddSlot()
|
||||
.SizeParam(FStretch(1.0))
|
||||
[
|
||||
SNew(SSpacer)
|
||||
];
|
||||
VerticalBox->AddSlot()
|
||||
.HAlign(HAlign_Center)
|
||||
.VAlign(VAlign_Bottom)
|
||||
.Padding(0, 0, 0, 24)
|
||||
[
|
||||
SNew(SBox).HeightOverride(40).WidthOverride(144)
|
||||
[
|
||||
SNew(SOverlay)
|
||||
+ SOverlay::Slot()
|
||||
.HAlign(HAlign_Fill)
|
||||
.VAlign(VAlign_Fill)
|
||||
[
|
||||
SNew(SButton)
|
||||
.OnClicked_Lambda([this]()
|
||||
{
|
||||
FFFMPEGUtils::GenerateProjectorEvent(ClipData);
|
||||
return FReply::Handled();
|
||||
})
|
||||
]
|
||||
+ SOverlay::Slot()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Visibility(EVisibility::HitTestInvisible)
|
||||
.Text(FText::FromString((TEXT("生成投影仪事件"))))
|
||||
.Font(NormalText.Font)
|
||||
.Justification(ETextJustify::Center)
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user