Commit 063d74b4 by wangguotao

v2.1.0版本

parent c01e48f0
objct name changed "deviceOutputPage3"
objct name changed "deviceOutputPage4"
available device "DeckLink 8K Pro (1)"
available device "DeckLink 8K Pro (2)"
"2024-05-16 14:18:31.039" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
available device "DeckLink 8K Pro (3)"
"2024-05-16 14:18:31.059" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
available device "DeckLink 8K Pro (4)"
"2024-05-16 14:18:31.097" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:18:31.117" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:18:31.137" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:18:31.157" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:18:31.177" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:18:31.197" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:18:31.217" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:18:31.275" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:18:32.299" decklink input fps 50
"2024-05-16 14:18:33.319" decklink input fps 51
"2024-05-16 14:18:33.385" decklink output fps 51 , qsize 0
"2024-05-16 14:18:34.319" decklink input fps 50
"2024-05-16 14:18:34.405" decklink output fps 51 , qsize 0
"2024-05-16 14:18:35.339" decklink input fps 51
"2024-05-16 14:18:35.405" decklink output fps 50 , qsize 0
"2024-05-16 14:18:36.339" decklink input fps 50
"2024-05-16 14:18:36.404" decklink output fps 50 , qsize 0
IDI_ICON1 ICON DISCARDABLE "4k-n.ico"
IDI_ICON1 ICON DISCARDABLE "figureOut.ico"
......@@ -66,6 +66,7 @@
<AdditionalIncludeDirectories>.\ThirdParty\stb_image\;.\ThirdParty\rabbitmq\include;.\ThirdParty\ffmpeg-master-latest-win64-gpl-shared\include;.\ThirdParty\libyuv\include;.\ThirdParty\OpenCV\include;.\ThirdParty\NewTek\include;.\ThirdParty\BlackmagicDesign\include;.\include;%(AdditionalIncludeDirectories);$(Qt_INCLUDEPATH_)</AdditionalIncludeDirectories>
<ShowIncludes>false</ShowIncludes>
<PreprocessorDefinitions>WIN32;_WINSOCKAPI_;AMQP_STATIC;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
<Link>
<AdditionalDependencies>Processing.NDI.Lib.Advanced.x64.lib;opencv_world460.lib;yuv.lib;jpeg.lib;avformat.lib;avcodec.lib;avutil.lib;swscale.lib;rabbitmq.4.lib;ws2_32.lib;%(AdditionalDependencies);$(Qt_LIBS_)</AdditionalDependencies>
......@@ -133,16 +134,19 @@
<QtMoc Include="include\Threads\ProcessMaskThread.h" />
<QtMoc Include="include\Threads\ReplayThread.h" />
<QtMoc Include="include\Network\UdpServer.h" />
<QtMoc Include="include\Network\UdpSend.h" />
<ClInclude Include="include\Record\Record.h" />
<ClInclude Include="include\Record\RecordStore.h" />
<ClInclude Include="include\Record\RecordThread.h" />
<ClInclude Include="include\Threads\ZoomThread.h" />
<QtMoc Include="include\Threads\ZoomThread.h" />
<ClInclude Include="include\Utils\Algorithm.h" />
<ClInclude Include="include\Utils\AudioConvert.h" />
<ClInclude Include="include\Utils\Base64.h" />
<ClInclude Include="include\Utils\MaskBuffer.h" />
<ClInclude Include="include\Utils\Memory4k.h" />
<ClInclude Include="include\Utils\SafeMap.h" />
<ClInclude Include="include\Utils\SampleDeque.h" />
<ClInclude Include="include\Utils\Settings.h" />
<ClInclude Include="include\Utils\SSEFunction.h" />
<ClInclude Include="include\Utils\yuv4k.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv.h" />
......@@ -219,6 +223,7 @@
<ClCompile Include="src\BlackMagicDesign\ProfileCallback.cpp" />
<ClCompile Include="src\BlackMagicDesign\ScreenPreviewCallback.cpp" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\Network\UdpSend.cpp" />
<ClCompile Include="src\Network\UdpServer.cpp" />
<ClCompile Include="src\Record\Record.cpp" />
<ClCompile Include="src\Record\RecordStore.cpp" />
......@@ -243,6 +248,7 @@
<ClCompile Include="src\Utils\LatencyStatistics.cpp" />
<ClCompile Include="src\Utils\MiniDumper.cpp" />
<ClCompile Include="src\Utils\Platform.cpp" />
<ClCompile Include="src\Utils\Settings.cpp" />
<ClCompile Include="src\Utils\VideoScale.cpp" />
<ClCompile Include="ThirdParty\BlackmagicDesign\include\DeckLinkAPI_i.c" />
</ItemGroup>
......@@ -250,6 +256,8 @@
<QtUic Include="Form\TimePlus.ui" />
</ItemGroup>
<ItemGroup>
<Image Include="Form\4K.ico" />
<Image Include="Form\figureOut.ico" />
<Image Include="Form\MomentaMedia.ico" />
</ItemGroup>
<ItemGroup>
......
......@@ -125,6 +125,12 @@
<QtMoc Include="include\Network\UdpServer.h">
<Filter>Header Files\Network</Filter>
</QtMoc>
<QtMoc Include="include\Threads\ZoomThread.h">
<Filter>Header Files\Threads</Filter>
</QtMoc>
<QtMoc Include="include\Network\UdpSend.h">
<Filter>Header Files\Network</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\stdafx.h">
......@@ -262,9 +268,6 @@
<ClInclude Include="include\Utils\MaskBuffer.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Threads\ZoomThread.h">
<Filter>Header Files\Threads</Filter>
</ClInclude>
<ClInclude Include="include\Utils\Algorithm.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
......@@ -289,6 +292,12 @@
<ClInclude Include="include\Utils\yuv4k.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\SampleDeque.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\Settings.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<QtRcc Include="Form\MomentaMedia.qrc">
......@@ -409,6 +418,12 @@
<ClCompile Include="src\Record\RecordThread.cpp">
<Filter>Source Files\Record</Filter>
</ClCompile>
<ClCompile Include="src\Utils\Settings.cpp">
<Filter>Source Files\Utils</Filter>
</ClCompile>
<ClCompile Include="src\Network\UdpSend.cpp">
<Filter>Source Files\Network</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtUic Include="Form\TimePlus.ui">
......@@ -419,6 +434,12 @@
<Image Include="Form\MomentaMedia.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="Form\4K.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="Form\figureOut.ico">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<Midl Include="ThirdParty\BlackmagicDesign\include\DeckLinkAPI.idl">
......
......@@ -14,11 +14,13 @@
#include "Utils/CustomEvents.h"
#include "Utils/Common.h"
#include "Utils/SampleQueue.h"
#include "Utils/SampleDeque.h"
#include "Utils/ComPtr.h"
#include "Utils/Platform.h"
#include "DeckLinkOutputVideoFrame.h"
#include "Utils/Image.h"
#include "Utils/AudioPacket.h"
#include "Utils/SafeMap.h"
class DeckLinkOutputDevice : public QObject, public IDeckLinkVideoOutputCallback
{
......@@ -57,15 +59,32 @@ public:
ComPtr<IDeckLink> GetDeckLinkInstance(void) const { return deckLink; }
ComPtr<IDeckLinkOutput> getDeckLinkOutput(void) const { return deckLinkOutput; }
void SetDeleyTime(qint32& deleyTime);
void SetSendSdiParams(SendSdiParams params);
public slots:
void AddAudioFrame(std::shared_ptr<AudioPacket> audio_packet);
void AddFrame(std::shared_ptr<Image> image);
void AddVideoFrameMask(std::shared_ptr<VideoFrameWithMask> frame);
void AddZoomFrame(std::shared_ptr<VideoFrameWithMask> frame);
signals:
void SendZoomResult(qint64 tm,bool ret);
private:
void InitResource();
HRESULT SetRP188VitcTimecodeOnFrame(IDeckLinkVideoFrame* videoFrame, uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t frames);
void ConvertFrameCountToTimecode(uint64_t frameCount, uint8_t* hours, uint8_t* minutes, uint8_t* seconds, uint8_t* frames);
void BGRAToUYVY(const std::shared_ptr<VideoFrameWithMask>& image);
// Private methods
void scheduleVideoFramesFunc(void);
void scheduleVideoFramesNoDeleyFunc(void);
void scheduleVideoFramesRealTimeFunc(void);
void scheduleVideoFramesWaitFunc(void);
void scheduleAudioFramesFunc(void);
void testWirteFileFrameFunc(void);
void scheduleAudioFramesFuncDeley(void);
void outputAudioFrameFunc(void);
bool waitForReferenceSignalToLock(void);
void checkEndOfPreroll(void);
private:
std::atomic<ULONG> RefCount;
PlaybackState state;
......@@ -78,6 +97,8 @@ private:
SampleQueue<std::shared_ptr<AudioPacket>> outputAudioFrameQueue;
SampleQueue<std::shared_ptr<Image>> writeVideoFrameQueue;
SampleQueue<std::shared_ptr<VideoFrameWithMask>> outputMaskVideoFrameQueue;
SampleDeque<std::shared_ptr<VideoFrameWithMask>> outputMaskVideoFrameDeque;
SampleQueue<std::shared_ptr<VideoFrameWithMask>> zoomVideoFrameQueue;
//ScheduledFramesList scheduledFramesList;
//
uint32_t videoPrerollSize;
......@@ -98,16 +119,6 @@ private:
//
ScheduledFrameCompletedCallback scheduledFrameCompletedCallback;
// Private methods
void scheduleVideoFramesFunc(void);
void scheduleVideoFramesNoDeleyFunc(void);
void scheduleAudioFramesFunc(void);
void testWirteFileFrameFunc(void);
void scheduleAudioFramesFuncDeley(void);
void outputAudioFrameFunc(void);
bool waitForReferenceSignalToLock(void);
void checkEndOfPreroll(void);
//
int64_t current_video_time = 0;
int64_t current_sleep_ms = 0;
......@@ -134,4 +145,13 @@ private:
uint64_t last_tm{ 0 };
std::map<uint64_t, std::shared_ptr<VideoFrameWithMask>> sort_map_;
//std::atomic<SendSDIStatus> send_sdi_status{ SSS_IDEL };
std::map<qint64, std::map<qint64, std::shared_ptr<VideoFrameWithMask>>*> masked_map;
std::map<qint64, SendSdiParams> masked_status_map;
SafeMap<qint64, std::shared_ptr<SampleQueue<std::shared_ptr<VideoFrameWithMask>>>> zoom_map;
qint64 send_sdi_start_time{0};
std::mutex sdi_clear_mutex;
std::atomic_bool send_zoom_frame_flag{ false };
SafeMap<qint64, std::shared_ptr<VideoFrameWithMask>> output_video_frame_map;
};
......@@ -15,7 +15,9 @@
#include "Threads/ConsumerMqThread.h"
class DeckLinkOutputPage : public QWidget,public DeckLinkInputPage::Listener
class DeckLinkOutputPage : public QWidget,
public DeckLinkInputPage::Listener,
public ConsumerMqThread::Listener
{
Q_OBJECT
......@@ -46,10 +48,14 @@ public:
Process->SetBlackBottomHeight(BlackBottomHeight);
InitControlValue(index + 1);
ProcessMask = process_mask;
ProcessMask->SetRecordStore(BindingInputPage->GetRecordStore());
if (ProcessMask) {
ProcessMask->SetRecordStore(BindingInputPage->GetRecordStore());
if (Zoom) ProcessMask->SetZoomThread(Zoom);
}
}
void OnRecvMsg(QByteArray data) override;
void OnRecvMqMsg(const QJsonDocument& document) override;
public slots:
void OutputDeviceChanged(int selectedDeviceIndex);
......@@ -69,7 +75,8 @@ public slots:
void RequestDeckLink(ComPtr<IDeckLink>& device);
void RequestDeckLinkIfAvailable(ComPtr<IDeckLink>& device);
void RelinquishDeckLink(ComPtr<IDeckLink>& device);
void PushMask(std::shared_ptr<MaskBuffer> buffer);
void PushAttribute(std::shared_ptr<SportAttribute> attr);
private:
void RestartOutput(void);
void SelectedDeviceChanged(void);
......@@ -80,6 +87,7 @@ private:
DeckLinkInputPage* BindingInputPage;
std::shared_ptr<ProcessThread> Process;
std::shared_ptr<ProcessMaskThread> ProcessMask;
std::shared_ptr<ZoomThread> Zoom;
qint32 Index;
std::unique_ptr<NDIOutputThread> NDIOutput;
......
......@@ -91,4 +91,6 @@ private:
uint8_t* uyvy_hd_buffer;
uint8_t* bgra_4k_buffer;
bool scale_to_hd;
qint64 normal_last_timestamp{0};
uint64_t last_recv_ts{ 0 };
};
\ No newline at end of file
#pragma once
#include <QThread>
#include <QUdpSocket>
#include <QHostAddress>
#include "Utils/SampleQueue.h"
class UdpSend : public QThread
{
Q_OBJECT
public:
static UdpSend& GetInstance();
void SendUdpMsg(const QString& msg, const QString serverAddr, const QString serverPort);
protected:
struct UdpPacket
{
QString msg;
QString serverAddr;
QString serverPort;
};
private:
UdpSend();
~UdpSend();
// ֹⲿ
UdpSend(const UdpSend& single) = delete;
// ֹⲿֵ
const UdpSend& operator=(const UdpSend& single) = delete;
void run() override;
private:
QUdpSocket* sendUdpSocket{NULL};
SampleQueue<UdpPacket> msg_queue;
};
\ No newline at end of file
#pragma once
#include <QObject>
#include <QUdpSocket>
#include <QHostAddress>
class UdpServer : public QObject
{
......@@ -10,10 +11,15 @@ public:
~UdpServer();
public:
void SetUpUDP(const QString hostAddr, const QString hostPort);
public slots:
void ReadDatagrams();
void HandleError(QAbstractSocket::SocketError err);
signals:
void SendMsg(QByteArray data);
private:
void SendUdpMsg(const QString& msg, const QString serverAddr, const QString serverPort);
private:
QUdpSocket* udpSocket{NULL};
QUdpSocket* sendUdpSocket{NULL};
};
\ No newline at end of file
......@@ -28,6 +28,7 @@ public:
public slots:
void AddFrame(ComPtr<IDeckLinkVideoInputFrame> videoFrame,const qint64& timestamp, const HDRMetadata& meta);
void recvReplay(bool& flag);
void RecvReplayStatus(const ReplayStatus& status);
signals:
//void PushFrame(std::shared_ptr<Image> image);
void PushFrame(std::shared_ptr<videoFrameData> frameData);
......@@ -57,6 +58,7 @@ private:
uint64_t m_lastRecvTS;
ComPtr<IDeckLinkVideoConversion> deckVideoConversion;
std::atomic_bool replay_flag{ false };
std::atomic<ReplayStatus> replay_status{RS_IDEL};
uint8_t* bgra_4k_data{ NULL };
std::shared_ptr<NDIOutputThread> NDIOutput{nullptr};
std::shared_ptr<RecordStore> RecordStorePtr{ nullptr };
......
......@@ -21,12 +21,18 @@ class ConsumerMqThread : public QThread
{
Q_OBJECT
public:
class Listener
{
public:
virtual void OnRecvMqMsg(const QJsonDocument& document) = 0;
};
public:
ConsumerMqThread(const std::string& queue_name, const std::string& exchange_name,
const std::string& ip, const std::string& user_id, const std::string& pwd);
const std::string& ip, const std::string& user_id, const std::string& pwd, Listener* listerner);
~ConsumerMqThread();
signals:
void PushMask(std::shared_ptr<MaskBuffer> buffer);
//signals:
// void PushMask(std::shared_ptr<MaskBuffer> buffer);
private:
void run() override;
bool setup_connection_and_channel();
......@@ -43,4 +49,6 @@ private:
uint32_t channel_id;
amqp_connection_state_t mq_connection;
Listener* mq_listener{ NULL };
};
\ No newline at end of file
......@@ -23,6 +23,7 @@ signals:
public:
void ClearQueue();
void SetRecordStore(RecordStore* store) { p_store = store; }
void SetZoomThread(std::shared_ptr<ZoomThread> thread) { zoom_thread = thread; }
void StartRecord(const uint64_t& start_time, const uint64_t& end_time);
protected:
......@@ -44,6 +45,7 @@ private:
void outputAlpha2(std::shared_ptr<MaskedBuffer> current, std::shared_ptr<MaskedBuffer> last,Rect& cross/*,uint8_t** cross_alpha*/);
void outputAlphaRect(std::shared_ptr<MaskedBuffer> current,const Rect& in_cross, Rect& out_cross);
void StartRecord_(const uint32_t& w,const uint32_t& h, const int32_t& fmt,const uint64_t& start_time,const uint64_t& end_time,const std::string& path);
void CropScale();
private:
//SampleQueue<MaskBuffer> mask_queue;
......@@ -52,6 +54,7 @@ private:
std::map<qint64, std::shared_ptr<MaskedBuffer>> tga_masked_map;
std::map<qint64, std::shared_ptr<MaskedBuffer>> store_masked_map;
SampleQueue<std::shared_ptr<videoFrameData>> taskImageQueue;
SampleQueue<std::shared_ptr<VideoFrameWithMask>> crop_queue;
bool once_save{ true };
uint8_t* tmp_bgra{NULL};
......@@ -76,4 +79,10 @@ private:
MaskStatus mask_status{MS_IDEL};
std::mutex mutex;
qint64 start_time{0};
uint64_t last_recv_ts{0};
std::thread crop_thread;
CropMessage crop_msg;
uint8_t* crop_data{NULL};
};
\ No newline at end of file
......@@ -21,167 +21,32 @@ const QString MODE_ACK = "checked_ok";
#define CROP720WIDTH 720
#define CROPHEIGHT 1080
extern int AspecNum;
extern int AspecDen;
//extern int AspecNum;
//extern int AspecDen;
class RoiMessage
{
public:
//#if USE_1080P
// RoiMessage() : w(CROP1080WIDTH), h(CROPHEIGHT)
// {
// x = 1920 / 2 - w / 2;
// y = 1080 / 2 - h / 2;
// timecode = 0;
// }
//#elif USE_4K_16_9
// RoiMessage() : w(CROP1080WIDTH2), h(CROPHEIGHT)
// {
// x = 1920 / 2 - w / 2;
// y = 1080 / 2 - h / 2;
// timecode = 0;
// }
//#else
// RoiMessage() : w(CROP720WIDTH), h(CROPHEIGHT)
// {
// x = 1920 / 2 - w / 2;
// y = 1080 / 2 - h / 2;
// timecode = 0;
// }
//#endif
RoiMessage() : h(CROPHEIGHT)
{
w = h * AspecDen / AspecNum;
w += w % 2;
x = 1920 / 2 - w / 2;
y = 1080 / 2 - h / 2;
centerX = 1920 / 2;
centerY = 0;
timecode = 0;
}
RoiMessage(QByteArray& data)
{
QJsonDocument document = QJsonDocument::fromJson(data);
QJsonObject object;
if (document.isObject())
{
object = document.object();
mode = object.value("signal").toString();
QJsonArray roi = object.value("roi").toArray();
int minx = roi[0].toInt();
int miny = roi[1].toInt();
int maxx = roi[2].toInt();
int maxy = roi[3].toInt();
id = object.value("id").toInt();
centerX = object.value("center_x").toInt();
centerY = object.value("center_y").toInt();
width = object.value("width").toInt();
height = object.value("height").toInt();
timecode = QString::number(object.value("timecode").toDouble(), 'f', 0).toLongLong();
h = CROPHEIGHT;
w = h * AspecDen / AspecNum;
x = minx;
y = miny;
}
}
RoiMessage(QByteArray&& data)
{
QJsonDocument document = QJsonDocument::fromJson(data);
QJsonObject object;
if (document.isObject())
{
object = document.object();
mode = object.value("signal").toString();
QJsonArray roi = object.value("roi").toArray();
int minx = roi[0].toInt();
int miny = roi[1].toInt();
int maxx = roi[2].toInt();
int maxy = roi[3].toInt();
id = object.value("id").toInt();
centerX = object.value("center_x").toInt();
centerY = object.value("center_y").toInt();
width = object.value("width").toInt();
height = object.value("height").toInt();
timecode = QString::number(object.value("timecode").toDouble(), 'f', 0).toLongLong();
h = CROPHEIGHT;
w = h * AspecDen / AspecNum;
x = minx;
y = miny;
}
}
RoiMessage(const RoiMessage& other) : x(other.x), y(other.y), w(other.w), h(other.h),
timecode(other.timecode),centerX(other.centerX),centerY(other.centerY)
{
}
RoiMessage(RoiMessage&& other)
{
x = other.x;
y = other.y;
w = other.w;
h = other.h;
timecode = other.timecode;
centerX = other.centerX;
centerY = other.centerY;
}
RoiMessage operator=(const RoiMessage& other)
{
x = other.x;
y = other.y;
w = other.w;
h = other.h;
timecode = other.timecode;
centerX = other.centerX;
centerY = other.centerY;
return *this;
}
RoiMessage operator=(RoiMessage&& other)
{
x = other.x;
y = other.y;
w = other.w;
h = other.h;
timecode = other.timecode;
centerX = other.centerX;
centerY = other.centerY;
return *this;
}
RoiMessage(int X, int Y, int W, int H)
:x(X),
y(Y),
w(W),
h(H),
timecode(0) {}
bool IsValid()
{
return x > 0 && y > 0 && w > 0 && h > 0;
}
void SetX(int x_)
{
this->x = x_;
}
int X() { return x; }
int Y() { return y; }
int CenterX() { return centerX; }
int CenterY() { return centerY; }
int Width() { return w; }
int Height() { return h; }
qint64 Timecode() { return timecode; }
RoiMessage();
RoiMessage(QByteArray& data);
RoiMessage(QByteArray&& data);
RoiMessage(const RoiMessage& other);
RoiMessage(RoiMessage&& other);
RoiMessage operator=(const RoiMessage& other);
RoiMessage operator=(RoiMessage&& other);
RoiMessage(int X, int Y, int W, int H);
bool IsValid();
void SetX(int x_);
int X();
int Y();
int CenterX();
int CenterY();
int Width();
int Height();
qint64 Timecode();
private:
int x;
......
......@@ -6,7 +6,7 @@
#include <queue>
#include <map>
class ReplayThread : public QThread
class ReplayThread : public QThread
{
Q_OBJECT
public:
......@@ -14,10 +14,12 @@ public:
~ReplayThread();
public slots:
void addFrame(std::shared_ptr<videoFrameData> frameData);
void recvReplayParams(ReplayParams& params,bool& flag);
signals:
//void PushFrame(std::shared_ptr<Image> image);
void PushFrame(std::shared_ptr<videoFrameData> frameData);
public:
bool CanReplay(const ReplayParams& params);
void recvReplayParams(const ReplayParams& params);
protected:
void run() override;
private:
......@@ -31,7 +33,9 @@ private:
std::queue<std::shared_ptr<videoFrameData>> replayVideoQueue2;*/
uint32_t max_store_size;
std::atomic_bool replay_flag{ false };
std::atomic<ReplayStatus> replay_status{ RS_IDEL };
uint32_t interval;
ReplayParams last_replay_params;
uint32_t replay_position{0};
uint32_t replay_position{ 0 };
qint64 current_seq{0};
};
\ No newline at end of file
#pragma once
#include <QThread>
#include <mutex>
#include <condition_variable>
#include <map>
#include <vector>
#include "Utils/Common.h"
#include "NDI/NDIOutputThread.h"
#include "Utils/SafeMap.h"
struct ZoomResultInfo
{
ZoomResultInfo() {}
~ZoomResultInfo()
{
if (frame) frame.reset();
}
std::atomic_bool drop{false};
std::shared_ptr<VideoFrameWithMask> frame {nullptr};
qint64 timestamp{0};
};
class ZoomThread : public QThread
{
Q_OBJECT
public:
ZoomThread();
~ZoomThread();
void setVideoFrame(const std::shared_ptr<VideoFrameWithMask>& frame);
void setResult(const ZoomResultInfo& info);
//void setPoints(const uint64_t& timecode,const QString& points);
signals:
void PushFrame(std::shared_ptr<VideoFrameWithMask> frame);
public slots:
void addSportAttr(std::shared_ptr<SportAttribute> attr);
void recvResult(qint64 tm, bool ret);
protected:
struct ScaleFrame
{
uint32_t scale_w;
uint32_t scale_h;
uint8_t* scale_data{NULL};
ScaleFrame(uint8_t* scale_data, uint8_t* crop_data, const uint32_t& scale_w, const uint32_t& scale_h,
const uint32_t& crop_w, const uint32_t& crop_h, const int32_t& offset_x, const int32_t& offset_y,const bool& repeat,const uint32_t& re_cnt):
scale_data(scale_data), crop_data(crop_data), scale_w(scale_w), scale_h(scale_h), crop_w(crop_w), crop_h(crop_h), offset_in_x(offset_x), offset_in_y(offset_y),
repeat(repeat), repeat_cnt(re_cnt)
{}
ScaleFrame(uint8_t* scale_data, uint8_t* crop_data, const uint32_t& scale_w, const uint32_t& scale_h,
const uint32_t& crop_w, const uint32_t& crop_h, const int32_t& offset_x, const int32_t& offset_y) :
scale_data(scale_data), crop_data(crop_data), scale_w(scale_w), scale_h(scale_h), crop_w(crop_w), crop_h(crop_h), offset_in_x(offset_x), offset_in_y(offset_y)
{}
ScaleFrame(uint8_t* scale_data, uint8_t* crop_data, const uint32_t& scale_w, const uint32_t& scale_h,
const uint32_t& crop_w, const uint32_t& crop_h, const int32_t& offset_x, const int32_t& offset_y,bool& reuse_scale) :
scale_data(scale_data), crop_data(crop_data), scale_w(scale_w), scale_h(scale_h), crop_w(crop_w), crop_h(crop_h), offset_in_x(offset_x), offset_in_y(offset_y),reuse_scale(reuse_scale)
{}
ScaleFrame(uint8_t* scale_data, uint8_t* crop_data, const uint32_t& scale_w, const uint32_t& scale_h,
const uint32_t& crop_w, const uint32_t& crop_h, const int32_t& offset_x, const int32_t& offset_y, const float_t& ration_x, const float_t& ration_y) :
scale_data(scale_data), crop_data(crop_data), scale_w(scale_w), scale_h(scale_h), crop_w(crop_w), crop_h(crop_h), offset_in_x(offset_x), offset_in_y(offset_y),
ration_x(ration_x), ration_y(ration_y)
{}
ScaleFrame(uint8_t* scale_data, uint8_t* crop_data, const uint32_t& scale_w, const uint32_t& scale_h,
const int32_t& offset_x, const int32_t& offset_y, const float_t& ration_x, const float_t& ration_y) :
scale_data(scale_data), crop_data(crop_data), scale_w(scale_w), scale_h(scale_h), crop_w(crop_w), crop_h(crop_h), offset_in_x(offset_x), offset_in_y(offset_y),
ration_x(ration_x), ration_y(ration_y)
{}
ScaleFrame(uint8_t* scale_data, uint8_t* crop_data, const uint32_t& scale_w, const uint32_t& scale_h,
const uint32_t& crop_w, const uint32_t& crop_h, const int32_t& offset_x, const int32_t& offset_y, const float_t& ration_x, const float_t& ration_y, const bool& repeat, const uint32_t& re_cnt) :
scale_data(scale_data), crop_data(crop_data), scale_w(scale_w), scale_h(scale_h), crop_w(crop_w), crop_h(crop_h), offset_in_x(offset_x), offset_in_y(offset_y),
ration_x(ration_x), ration_y(ration_y), repeat(repeat), repeat_cnt(re_cnt)
{}
bool reuse_scale{false};
bool repeat{ false };
uint8_t* scale_data{ NULL };
uint8_t* crop_data{ NULL };
uint32_t scale_w{ 0 };
uint32_t scale_h{ 0 };
uint32_t crop_w{ 0 };
uint32_t crop_h{ 0 };
int32_t offset_in_x{0};
int32_t offset_in_y{0};
uint32_t repeat_cnt{ 0 };
float_t ration_x{0.0};
float_t ration_y{ 0.0 };
};
//移动方向
enum ZoomDirect
{
ZD_IDEL = -1,
ZD_LTOR = 1,//从左到右
ZD_RTOL,
ZD_UTOD,//从上到下
ZD_DTOU,
};
enum ZoomStatus
{
ZS_IDEL = -1,
ZS_START = 1,
ZS_END,
};
struct FrameBuffer
{
uint8_t* buffer{NULL};
uint32_t width{0};
uint32_t height{0};
};
private:
void run() override;
bool DrawLine(std::vector<cv::Point>& points,uint32_t& min_x,uint32_t& max_x);
void ZoomIn(const int& index);
void ZoomIn(const int& index,const bool& omp,const bool& last_frame);
void CropAndScale(uint8_t* src_data,ScaleFrame& scale_frame, const qint64& seq);
void ScaleCrop(uint8_t* src_data, ScaleFrame& scale_frame, const qint64& seq);
void ScaleCrop(FrameBuffer& src_frame, ScaleFrame& scale_frame, const qint64& seq);
void SendFrameFunc();
private:
void ProcessWithRGBA();
void ProcessWithRGBANew();
void ProcessWithRGBASec();
void ProcessWithRGBALast();
void ProcessWithUYVY();
private:
bool PrepareZoom(std::shared_ptr<VideoFrameWithMask> src_frame);
bool ZoomIn(std::shared_ptr<ZoomResultInfo> p_info);
bool ZoomPan(std::shared_ptr<ZoomResultInfo> p_info);
bool ZoomOut(std::shared_ptr<ZoomResultInfo> p_info);
private:
std::shared_ptr<VideoFrameWithMask> src_frame_{nullptr};
uint8_t* scale_data_{NULL};
uint8_t* i422_data_ {NULL};
uint8_t* i422_4k_data_{NULL};//for move and zoom-out
std::condition_variable cv;
std::mutex mutex;
std::map<qint64, std::vector<Point>> map_points_;
std::map<qint64, std::shared_ptr<SportAttribute>> map_attrs_;
std::shared_ptr<NDIOutputThread> ndi_thread_{nullptr};
std::thread* p_send_thread{NULL};
SampleQueue<std::shared_ptr<videoFrameData>> send_queue_;
cv::Mat bgra_mat;
std::vector<ScaleFrame> vec_scale_frame;
std::vector<ScaleFrame> vec_in_frame;
std::vector<ScaleFrame> vec_move_scale;
std::vector<ScaleFrame> vec_out_scale;
float inc_ratio {0.0};
float increment_w{0.0};
float increment_h{0.0};
uint32_t increment_w;
uint32_t increment_h;
uint32_t scale_w{ 0 };
uint32_t scale_h{ 0 };
uint32_t scale_size{ 0 };
uint32_t src_w{ 0 };
uint32_t src_h{0};
qint64 start_time{0};
HDRMetadata meta;
cv::Point fir_point;
cv::Point end_point;
//std::atomic_bool zoom_end{ false };
int interval_ms{0};
uint32_t wait_cnt{0};
std::vector<cv::Point> sport_points;
ZoomDirect direct{ ZD_IDEL };
std::atomic<ZoomStatus> zoom_status{ ZS_IDEL };
std::map<int, std::shared_ptr<videoFrameData>> zoom_map;
uint32_t zoom_frame_count{0};
SafeMap<qint64, std::shared_ptr<ZoomResultInfo>> map_result;
cv::Point zoom_in_start;
uint32_t zoom_pan_len;
cv::Point zoom_out_start;
uint32_t in_frame_count;
uint32_t pan_frame_count;
uint32_t out_frame_count;
};
\ No newline at end of file
#pragma once
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include "DeckLinkAPI.h"
#include <QDateTime.h>
#include <sys/timeb.h>
#include "ComPtr.h"
#include "Memory4k.h"
#define USE_4K 1
#define USE_4K_16_9 1
......@@ -28,7 +33,9 @@
enum ReplayStatus
{
RS_IDEL = -1,
RS_END = 0,
RS_PRE_START,
RS_START,
RS_RE_START
};
......@@ -36,6 +43,7 @@ enum ReplayStatus
enum BlendStatus
{
BS_IDEL = -1,
BS_ZOOM,
BS_START = 1,
BS_ING,
BS_END
......@@ -48,6 +56,22 @@ enum FileType
FT_MOV,
};
enum SendSDIStatus
{
SSS_IDEL = -1,
SSS_CLEAR = 0,
SSS_SEND,
SSS_START,
SSS_FINISH,
};
enum CropDirection
{
CD_LEFT_TOP = 1,
CD_RIGHT_TOP,
CD_LEFT_LOW,
CD_RIGHT_LOW,
};
long GetRowBytesFromPixelFormat(long width, BMDPixelFormat pixelFormat);
......@@ -69,10 +93,16 @@ static uint64_t TimeMilliSecond()
typedef struct Point
{
int32_t x;
int32_t y;
uint32_t x;
uint32_t y;
}Point;
struct SendSdiParams
{
SendSDIStatus status;
qint64 start_time;
};
struct HDRMetadata {
INT64 EOTF;
......@@ -104,8 +134,8 @@ typedef struct videoFrameData
width = frame->GetWidth();
height = frame->GetHeight();
fmt = frame->GetPixelFormat();
size = height * frame->GetRowBytes();
capacity = height * width << 2;
uyvy_size = height * frame->GetRowBytes();
size = capacity = height * width << 2;
if (size > capacity) capacity = size;
void* src = NULL;
......@@ -113,31 +143,67 @@ typedef struct videoFrameData
if (src)
{
data = new uint8_t[capacity];
memcpy(data, src, size);
uyvy_data = new uint8_t[uyvy_size];
//memcpy(uyvy_data, src, uyvy_size);
Memory::MemoryCopy4k((uint8_t*)src,uyvy_data, uyvy_size >> 2);
}
}
}
videoFrameData(const uint32_t& w, const uint32_t& h, const qint64& ts, const qint64& seq, const BMDPixelFormat& format, uint8_t* buffer, const HDRMetadata& meta):
width(w),height(h),timestamp(ts),sequenceNum(seq),fmt(format),data(buffer),meta_(meta)
width(w),height(h),timestamp(ts),sequenceNum(seq),fmt(format)/*,data(buffer)*/,meta_(meta)
{
if (format == bmdFormat8BitYUV) uyvy_data = buffer;
else if (format == bmdFormat8BitBGRA) data = buffer;
}
videoFrameData(const uint32_t& w, const uint32_t& h, const qint64& ts, const qint64& seq, const BMDPixelFormat& format, uint8_t* buffer, const HDRMetadata& meta,const bool& last) :
width(w), height(h), timestamp(ts), sequenceNum(seq), fmt(format), /*data(buffer),*/ meta_(meta), zoom_last(last)
{
if (format == bmdFormat8BitYUV) uyvy_data = buffer;
else if (format == bmdFormat8BitBGRA) data = buffer;
}
videoFrameData(const uint32_t& w, const uint32_t& h, const qint64& ts, const qint64& seq, const BMDPixelFormat& format, uint8_t* buffer, const HDRMetadata& meta, const bool& last, const bool& repeat, const uint32_t& repeat_num) :
width(w), height(h), timestamp(ts), sequenceNum(seq), fmt(format), /*data(buffer),*/ meta_(meta), zoom_last(last), repeat(repeat), repeat_cnt(repeat_num)
{
if (format == bmdFormat8BitYUV) uyvy_data = buffer;
else if (format == bmdFormat8BitBGRA) data = buffer;
}
videoFrameData(const uint32_t& w, const uint32_t& h, const qint64& ts, const qint64& seq, const BMDPixelFormat& format, uint8_t* buffer, const HDRMetadata& meta, const bool& last, const bool& repeat, const uint32_t& repeat_num, const qint64& start_tm) :
width(w), height(h), timestamp(ts), sequenceNum(seq), fmt(format), /*data(buffer),*/ meta_(meta), zoom_last(last),repeat(repeat),repeat_cnt(repeat_num),start_tm(start_tm)
{
if (format == bmdFormat8BitYUV) uyvy_data = buffer;
else if (format == bmdFormat8BitBGRA) data = buffer;
}
~videoFrameData()
{
/*if (sequenceNum == 300)
{
qDebug() << "~videoFrameData " << "\n";
}*/
if (data) delete data;
if (uyvy_data) delete uyvy_data;
}
BMDPixelFormat fmt = bmdFormatUnspecified;
qint32 width = 0;
qint32 height = 0;
qint32 size = 0;
qint32 capacity = 0;
uint8_t* data = NULL;
bool zoom_last = false;
bool repeat = false;
BMDPixelFormat fmt{ bmdFormatUnspecified };
qint32 width{ 0 };
qint32 height{ 0 };
qint32 size{ 0 };
qint32 uyvy_size{ 0 };
qint32 capacity{ 0 };
qint32 repeat_cnt{ 0 };
uint8_t* data{ NULL };//store bgra data
uint8_t* uyvy_data{ NULL };//store uyvy data
qint64 timestamp;
qint64 sequenceNum = 0;
qint64 sequenceNum{ 0 };
qint64 replaySeq{ 0 };
qint64 start_tm{ 0 };
HDRMetadata meta_;
}videoFrameData;
......@@ -153,8 +219,14 @@ typedef struct VideoFrameWithMask
size_ = width_ * height_ << 2;
}
VideoFrameWithMask(const uint32_t& width, const uint32_t& height, const qint64& ts, const qint64& seq, uint8_t* data, const BMDPixelFormat& fmt, const BlendStatus& status, const HDRMetadata& meta) :
width_(width), height_(height), timestamp_(ts), sequenceNum_(seq), data_(data),fmt_(fmt), flag_(status),meta_(meta)
VideoFrameWithMask(const uint32_t& width, const uint32_t& height, const qint64& ts, const qint64& seq, uint8_t* data, const BlendStatus& status, const HDRMetadata& meta, const qint64& start_tm) :
width_(width), height_(height), timestamp_(ts), sequenceNum_(seq), data_(data), flag_(status), meta_(meta),start_tm_(start_tm)
{
size_ = width_ * height_ << 2;
}
VideoFrameWithMask(const uint32_t& width, const uint32_t& height, const qint64& ts, const qint64& seq, uint8_t* data, const BMDPixelFormat& fmt, const BlendStatus& status, const HDRMetadata& meta, const qint64& start_tm) :
width_(width), height_(height), timestamp_(ts), sequenceNum_(seq), data_(data),fmt_(fmt), flag_(status),meta_(meta), start_tm_(start_tm)
{
if(fmt_ == bmdFormat8BitBGRA) size_ = width_ * height_ << 2;
else if(fmt_ == bmdFormat8BitYUV) size_ = width_ * height_ << 1;
......@@ -168,14 +240,34 @@ typedef struct VideoFrameWithMask
fmt_ = pImage->fmt;
width_ = pImage->width;
height_ = pImage->height;
timestamp_ = pImage->timestamp;
timestamp_ = (pImage->replaySeq ? pImage->replaySeq : pImage->timestamp);
sequenceNum_ = pImage->sequenceNum;
meta_ = image->meta_;
zoom_last = image->zoom_last;
if (fmt_ == bmdFormat8BitBGRA) size_ = width_ * height_ << 2;
else if (fmt_ == bmdFormat8BitYUV) size_ = width_ * height_ << 1;
}
/*VideoFrameWithMask(videoFrameData* image, BlendStatus& status)
{
flag_ = status;
mask_flag = false;
fmt_ = pImage->fmt;
width_ = pImage->width;
height_ = pImage->height;
timestamp_ = (pImage->replaySeq ? pImage->replaySeq : pImage->timestamp);
sequenceNum_ = pImage->sequenceNum;
meta_ = image->meta_;
if (fmt_ == bmdFormat8BitBGRA) size_ = width_ * height_ << 2;
else if (fmt_ == bmdFormat8BitYUV) size_ = width_ * height_ << 1;
data_ = new uint8_t[size_];
if(fmt_ == bmdFormat8BitYUV) memcpy(data_, image->uyvy_data, size_);
else if (fmt_ == bmdFormat8BitBGRA) memcpy(data_, image->data, size_);
}*/
~VideoFrameWithMask()
{
if (data_)
......@@ -205,6 +297,7 @@ typedef struct VideoFrameWithMask
}
bool zoom_last = false;
bool mask_flag = true;
uint8_t* data_ = NULL;
std::shared_ptr<videoFrameData> pImage = nullptr;
......@@ -215,10 +308,97 @@ typedef struct VideoFrameWithMask
uint32_t size_ = 0;
qint64 sequenceNum_ = 0;
qint64 timestamp_;
qint64 start_tm_ = 0;
HDRMetadata meta_;
}VideoFrameWithMask;
class CropMessage
{
public:
CropMessage() :crop_x(0), crop_y(0), crop_w(0), crop_h(0) {}
CropMessage(const int32_t& x,const int32_t& y,const CropDirection& direction)
{
crop_x = x;
crop_y = y;
uint32_t crop_max_w = 0;
uint32_t crop_max_h = 0;
crop_direction = direction;
switch (crop_direction)
{
case CD_LEFT_TOP:
crop_max_w = K4WIDTH - crop_x;
crop_max_h = K4HEIGHT - crop_y;
break;
case CD_RIGHT_TOP:
crop_max_w = crop_x;
crop_max_h = K4HEIGHT - crop_y;
break;
case CD_LEFT_LOW:
crop_max_w = K4WIDTH - crop_x;
crop_max_h = crop_y;
break;
case CD_RIGHT_LOW:
crop_max_w = crop_x;
crop_max_h = crop_y;
break;
default:
break;
}
crop_w = crop_max_w;
crop_h = crop_w * 9 / 16;
if (crop_h > crop_max_h)
{
crop_h = crop_max_h;
crop_w = crop_h * 16 / 9;
}
switch (crop_direction)
{
case CD_LEFT_TOP:
break;
case CD_RIGHT_TOP:
crop_x = crop_max_w - crop_w;
break;
case CD_LEFT_LOW:
crop_y = crop_max_h - crop_h;
break;
case CD_RIGHT_LOW:
crop_x = crop_max_w - crop_w;
crop_y = crop_max_h - crop_h;
break;
default:
break;
}
}
CropMessage& operator=(const CropMessage& other)
{
crop_x = other.crop_x;
crop_y = other.crop_y;
crop_w = other.crop_w;
crop_h = other.crop_h;
crop_direction = other.crop_direction;
return *this;
}
CropMessage& operator=(CropMessage&& other)
{
crop_x = other.crop_x;
crop_y = other.crop_y;
crop_w = other.crop_w;
crop_h = other.crop_h;
crop_direction = other.crop_direction;
return *this;
}
uint32_t crop_x;
uint32_t crop_y;
uint32_t crop_w;
uint32_t crop_h;
CropDirection crop_direction;
};
static const HDRMetadata kDefaultHLGBT2020HDRMetadata = { static_cast<INT64>(EOTF::HLG), 0.708, 0.292, 0.170, 0.797, 0.131, 0.046, 0.3127, 0.3290, 1000.0, 0.0001, 1000.0, 50.0, bmdColorspaceRec2020 };
static const HDRMetadata kDefaultSDRBT709HDRMetadata = { static_cast<INT64>(EOTF::SDR), 0.64, 0.33, 0.3, 0.6, 0.15, 0.06, 0.3127, 0.329, 10, 0.0001, 1000.0, 30, bmdColorspaceRec709 };
......@@ -227,7 +407,25 @@ typedef struct ReplayParams
{
/*uint64_t timecode{0};
uint32_t durations{0};*/
ReplayStatus status{ RS_IDEL };
uint64_t start_time{0};
uint64_t end_time{ 0 };
}ReplayParams;
\ No newline at end of file
}ReplayParams;
typedef struct SportAttribute
{
SportAttribute() {}
SportAttribute(const QJsonObject& object)
{
speed = object["mean_speed"].toDouble();
max_height = object["max_height"].toDouble();
timecode = QString::number(object.value("timecode").toDouble(), 'f', 0).toLongLong();
points = object["motionDatas"].toString();
}
double speed {0.0};
double max_height{ 0.0 };
qint64 timecode{0};
QString points{""};
}SportAttribute;
\ No newline at end of file
......@@ -85,6 +85,38 @@ struct MaskBuffer
}
}
MaskBuffer(const QJsonObject& object)
{
if (!object.isEmpty())
{
//QJsonObject object = document.object();
signal = object["signal"].toInt();
if (signal != -1)
{
QString base_data = object["mask"].toString();
if (base_data != "") mask_data = Base64::base64_decode(base_data.toStdString());
//mask_data = QByteArray::fromBase64(base_data.toLatin1());
/*auto size = str.length();
auto siez1 = mask_data.size();*/
QJsonArray array = object["coordinate_xyxy"].toArray();
upper_left_point.x = array[0].toInt();
upper_left_point.y = array[1].toInt();
lower_right_point.x = array[2].toInt();
lower_right_point.y = array[3].toInt();
width = lower_right_point.x - upper_left_point.x;
height = lower_right_point.y - upper_left_point.y;
timecode = QString::number(object.value("timecode").toDouble(), 'f', 0).toLongLong();
}
/*cv::Mat gray = cv::Mat(lower_right_point.y - upper_left_point.y, lower_right_point.x - upper_left_point.x, CV_8UC1, (char*)str.c_str());
cv::cvtColor(gray, gray, cv::COLOR_GRAY2BGR);
cv::imshow("gray", gray);
cv::waitKey(0);*/
}
}
~MaskBuffer()
{
......
#pragma once
#include <condition_variable>
#include <memory>
#include <mutex>
#include <map>
#include <mutex>
#include <vector>
template <typename K, typename V>
class SafeMap {
public:
SafeMap() {}
~SafeMap() {}
SafeMap(const SafeMap& rhs)
{
map_ = rhs.map_;
}
SafeMap& operator=(const SafeMap& rhs)
{
if (&rhs != this) {
map_ = rhs.map_;
}
return *this;
}
V& operator[](const K& key)
{
return map_[key];
}
bool WaitFor(int size)
{
std::unique_lock<std::mutex> lock(mutex_);
condition_.wait(lock, [&] {return (!map_.empty() && map_.size() >= size); });
if (!map_.empty())
{
return true;
}
return false;
}
bool WaitFor()
{
std::unique_lock<std::mutex> lock(mutex_);
condition_.wait(lock, [&] {return !map_.empty(); });
if (!map_.empty()) return true;
else return false;
}
bool Pop(K& key, V& value)
{
std::unique_lock<std::mutex> lock(mutex_);
if (map_.empty()) return false;
key = map_.begin()->first;
value = map_.begin()->second;
map_.erase(key);
return true;
}
bool Begin(K& key, V& value)
{
std::unique_lock<std::mutex> lock(mutex_);
if (map_.empty()) return false;
key = map_.begin()->first;
value = map_.begin()->second;
return true;
}
// when multithread calling size() return a tmp status, some threads may insert just after size() call
int Size()
{
std::unique_lock<std::mutex> lock(mutex_);
return map_.size();
}
// when multithread calling Empty() return a tmp status, some threads may insert just after Empty() call
bool IsEmpty()
{
std::unique_lock<std::mutex> lock(mutex_);
return map_.empty();
}
bool Insert(const K& key, const V& value)
{
std::unique_lock<std::mutex> lock(mutex_);
auto ret = map_.insert(std::pair<K, V>(key, value));
condition_.notify_all();
return ret.second;
}
void EnsureInsert(const K& key, const V& value)
{
std::unique_lock<std::mutex> lock(mutex_);
auto ret = map_.insert(std::pair<K, V>(key, value));
// find key and cannot insert
if (!ret.second) {
map_.erase(ret.first);
map_.insert(std::pair<K, V>(key, value));
}
condition_.notify_all();
return;
}
bool Find(const K& key, V& value)
{
bool ret = false;
std::unique_lock<std::mutex> lock(mutex_);
auto iter = map_.find(key);
if (iter != map_.end()) {
value = iter->second;
ret = true;
}
return ret;
}
bool Find(const K& key)
{
bool ret = false;
std::unique_lock<std::mutex> lock(mutex_);
auto iter = map_.find(key);
if (iter != map_.end()) {
ret = true;
}
return ret;
}
bool FindOldAndSetNew(const K& key, V& oldValue, const V& newValue)
{
bool ret = false;
std::unique_lock<std::mutex> lock(mutex_);
if (map_.size() > 0) {
auto iter = map_.find(key);
if (iter != map_.end()) {
oldValue = iter->second;
map_.erase(iter);
map_.insert(std::pair<K, V>(key, newValue));
ret = true;
}
}
return ret;
}
void Erase(const K& key)
{
std::unique_lock<std::mutex> lock(mutex_);
map_.erase(key);
}
void Clear()
{
std::unique_lock<std::mutex> lock(mutex_);
map_.clear();
return;
}
template<typename T>
class SafeMap
{
std::vector<K> Keys() const {
std::unique_lock<std::mutex> lock(mutex_);
std::vector<K> result;
for (auto& pair : map_) {
result.push_back(pair.first);
}
return result;
}
private:
mutable std::mutex mutex_;
std::map<K, V> map_;
std::condition_variable condition_;
};
\ No newline at end of file
#pragma once
#include <condition_variable>
#include <memory>
#include <mutex>
#include <queue>
#include <QDebug>
#include <qdatetime.h>
#include <chrono>
#include "Common.h"
template<typename T>
class SampleDeque
{
public:
SampleDeque();
virtual ~SampleDeque();
void Push(const T& sample);
void Push(T&& sample);
void PushBack(const T& sample);
bool Pop(T& sample);
bool Pop();
bool PopBack(T& sample);
bool PopBack();
bool Front(T& sample);
bool WaitFor(T& sample);
bool WaitFor(int size);
bool WaitUntil(T& sample, int timeout);
bool WaitUntil(int timeout);
void CancelWaiters(void);
void Reset(void);
bool Empty();
long Size();
bool Put(int size, std::vector<T>& vec);
private:
std::deque<T> deque;
std::condition_variable dequeCondition;
std::mutex mutex;
bool waitCancelled;
};
template<typename T>
SampleDeque<T>::SampleDeque():waitCancelled(false)
{
}
template<typename T>
SampleDeque<T>::~SampleDeque()
{
CancelWaiters();
}
template<typename T>
void SampleDeque<T>::Push(const T& sample)
{
{
std::lock_guard<std::mutex> locker(mutex);
deque.push_front(sample);
}
dequeCondition.notify_all();
}
template<typename T>
void SampleDeque<T>::PushBack(const T& sample)
{
{
std::lock_guard<std::mutex> locker(mutex);
deque.push_back(sample);
}
dequeCondition.notify_all();
}
template<typename T>
void SampleDeque<T>::Push(T&& sample)
{
{
std::lock_guard<std::mutex> locker(mutex);
deque.push_front(sample);
}
dequeCondition.notify_all();
}
template<typename T>
bool SampleDeque<T>::Pop(T& sample)
{
std::lock_guard<std::mutex> locker(mutex);
if (deque.empty())
return false;
sample = std::move(deque.front());
deque.pop_front();
return true;
}
template<typename T>
bool SampleDeque<T>::Pop()
{
std::lock_guard<std::mutex> locker(mutex);
if (deque.empty())
return false;
deque.pop_front();
return true;
}
template<typename T>
bool SampleDeque<T>::PopBack(T& sample)
{
std::lock_guard<std::mutex> locker(mutex);
if (deque.empty())
return false;
sample = std::move(deque.back());
deque.pop_back();
return true;
}
template<typename T>
bool SampleDeque<T>::PopBack()
{
std::lock_guard<std::mutex> locker(mutex);
if (deque.empty())
return false;
deque.pop_back();
return true;
}
template<typename T>
bool SampleDeque<T>::Front(T& sample)
{
std::lock_guard<std::mutex> locker(mutex);
if (deque.empty())
return false;
//sample = std::move(queue.front());
sample = deque.front();
return true;
}
template<typename T>
bool SampleDeque<T>::WaitFor(T& sample)
{
std::unique_lock<std::mutex> locker(mutex);
dequeCondition.wait(locker, [&] {return !deque.empty() || waitCancelled; });
if (waitCancelled)
return false;
else if (!deque.empty())
{
sample = std::move(deque.front());
deque.pop_front();
}
return true;
}
template<typename T>
bool SampleDeque<T>::WaitFor(int size)
{
std::unique_lock<std::mutex> locker(mutex);
dequeCondition.wait(locker, [&] {return (!deque.empty() && deuqe.size() >= size) || waitCancelled; });
if (waitCancelled)
return false;
else if (!deuqe.empty())
{
return true;
}
return false;
}
template<typename T>
bool SampleDeque<T>::WaitUntil(T& sample, int timeout)
{
std::unique_lock<std::mutex> locker(mutex);
auto delay = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout);
dequeCondition.wait_until(locker, delay, [&] {return !deuqe.empty() || waitCancelled; });
if (waitCancelled || deque.empty())
return false;
else if (!deque.empty())
{
sample = std::move(deque.front());
deque.pop_front();
}
return true;
}
template<typename T>
bool SampleDeque<T>::WaitUntil(int timeout)
{
std::unique_lock<std::mutex> locker(mutex);
auto delay = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout);
dequeCondition.wait_until(locker, delay, [&] {return !deque.empty() || waitCancelled; });
if (waitCancelled || deque.empty())
return false;
else if (!deque.empty())
{
return true;
}
return true;
}
template<typename T>
void SampleDeque<T>::CancelWaiters(void)
{
{
// signal cancel flag to terminate wait condition
std::lock_guard<std::mutex> locker(mutex);
waitCancelled = true;
}
dequeCondition.notify_all();
}
template<typename T>
void SampleDeque<T>::Reset(void)
{
std::lock_guard<std::mutex> locker(mutex);
deque.clear();
waitCancelled = false;
}
template<typename T>
bool SampleDeque<T>::Empty()
{
std::lock_guard<std::mutex> locker(mutex);
return deque.empty();
}
template<typename T>
long SampleDeque<T>::Size()
{
std::lock_guard<std::mutex> locker(mutex);
return deque.size();
}
template <typename T>
bool SampleDeque<T>::Put(int size, std::vector<T>& vec)
{
std::lock_guard<std::mutex> locker(mutex);
if (deque.empty())
return false;
int count = 0;
for (auto itor = deque.rbegin(); itor != deque.rend();itor++)
{
vec.push_back(*itor);
count++;
if (count == size) return true;
}
}
\ No newline at end of file
......@@ -175,7 +175,7 @@ template <typename T>
bool SampleQueue<T>::WaitFor(int size)
{
std::unique_lock<std::mutex> locker(mutex);
queueCondition.wait(locker, [&] {return (!queue.empty() && queue.size()>= size) || waitCancelled; });
queueCondition.wait(locker, [&] {return (!queue.empty() && queue.size()> size) || waitCancelled; });
if (waitCancelled)
return false;
......@@ -183,7 +183,7 @@ bool SampleQueue<T>::WaitFor(int size)
{
return true;
}
return true;
return false;
}
template <typename T>
......@@ -253,4 +253,5 @@ bool SampleQueue<T>::Empty()
{
std::lock_guard<std::mutex> locker(mutex);
return queue.empty();
}
\ No newline at end of file
}
#pragma once
#include <iostream>
#include <QString>
class Settings
{
public:
static int32_t ReplayStoreTime ;//µ¥Î»ms
static int32_t FrontDeleyTime ;//µ¥Î»ms
static int32_t FrameRate;
static int32_t OutputPlayMode;
static int32_t AudioChannel;
static int32_t ScaleMode ;
static int32_t AspecNum ;
static int32_t AspecDen ;
static int32_t OneFrameDuration ; //FOR NDI
static int32_t SDIOneFrameDuration; //FOR SDI
static int32_t RecordStoreDuration ;
static int32_t RecordFlag;
static int32_t OpenOMP ;
static int32_t TimeoutFrames ;
static int32_t SdiOutWaitNums;
static bool HaveBlackDataFlag;
static int32_t DrawFlag;
static int32_t ZoomFlag;
static float ZoomScale;
static int32_t ZoomScaleN;
static int32_t ZoomScaleD;
static int32_t ZoomInDuration;
static int32_t ZoomOutDuration;
static int32_t ZoomMoveDuration;
static int32_t ZoomUseOmp;
static int32_t ZoomScaleType; //1.libyuv 2.opencv
static int32_t ZoomScaleFilter;//libyuv:0-3 opencv:0-4
static uint32_t ZoomInWaitCnt;
static uint32_t ZoomMoveWaitCnt;
static uint32_t ZoomOutWaitCnt;
static uint32_t ReplayForward;
static uint32_t ReplayDeley;
static uint32_t SDIOutputWaitNums;
static int32_t CropFlag;
static int32_t CropX;
static int32_t CropY;
static int32_t CropDirection;
static int32_t UIUdpPort;
static QString UIIpAddr;
};
#pragma once
#include <omp.h>
#include "libyuv.h"
#include "opencv2/opencv.hpp"
#define USELIBYUV 1
#define USEOPENCV 2
class Yuv4k
{
protected:
struct WH
{
size_t w;
size_t h;
};
public:
static void UYVYToARGB4K(uint8_t* src,const size_t& src_step,uint8_t* dst,const size_t& dst_step,const uint32_t& width,const uint32_t& height)
{
......@@ -45,12 +56,209 @@ public:
}
}
static void ARGBScale4K(uint8_t* src,const size_t& src_w, const size_t& src_h, uint8_t* dst, const size_t& scale_w, const size_t& scale_h)
static void ARGBToI422(uint8_t* src, uint8_t* dst, const uint32_t& width, const uint32_t& height)
{
size_t half_w = (width >> 1);
size_t half_h = (height >> 1);
uint8_t* src1 = src;
uint8_t* src2 = src + (half_w << 2);
uint8_t* src3 = src + (width * half_h << 2);
uint8_t* src4 = src + ((width * half_h << 2) + (half_w << 2));
uint32_t dst_y_size = width * height;
uint32_t dst_u_size = (width * height >> 1);
uint8_t* dst_y = dst;
uint8_t* dst_u = dst_y + dst_y_size;
uint8_t* dst_v = dst_u + dst_u_size;
uint8_t* dst_y_1 = dst_y;
uint8_t* dst_y_2 = dst_y + half_w;
uint8_t* dst_y_3 = dst_y + width * half_h;
uint8_t* dst_y_4 = dst_y + width * half_h + half_w;
uint8_t* dst_u_1 = dst_u;
uint8_t* dst_u_2 = dst_u + (half_w >> 1);
uint8_t* dst_u_3 = dst_u + (width * half_h >> 1);
uint8_t* dst_u_4 = dst_u + (width * half_h >> 1) + (half_w >> 1);
uint8_t* dst_v_1 = dst_v;
uint8_t* dst_v_2 = dst_v + (half_w >> 1);
uint8_t* dst_v_3 = dst_v + (width * half_h >> 1);
uint8_t* dst_v_4 = dst_v + (half_w >> 1) + (width * half_h >> 1);
{
libyuv::ARGBToI422(src1, width << 2, dst_y_1, width, dst_u_1, width >> 1, dst_v_1, width >> 1, half_w, half_h);
libyuv::ARGBToI422(src2, width << 2, dst_y_2, width, dst_u_2, width >> 1, dst_v_2, width >> 1, half_w, half_h);
libyuv::ARGBToI422(src3, width << 2, dst_y_3, width, dst_u_3, width >> 1, dst_v_3, width >> 1, half_w, half_h);
libyuv::ARGBToI422(src4, width << 2, dst_y_4, width, dst_u_4, width >> 1, dst_v_4, width >> 1, half_w, half_h);
}
}
static void I422ToUYVY(uint8_t* src, uint8_t* dst, const uint32_t& width, const uint32_t& height, const int32_t& omp)
{
size_t half_w = (width >> 1);
size_t half_h = (height >> 1);
uint32_t src_y_size = width * height;
uint32_t src_u_size = (width * height >> 1);
uint8_t* src_y = src;
uint8_t* src_u = src_y + src_y_size;
uint8_t* src_v = src_u + src_u_size;
uint8_t* src_y_1 = src_y;
uint8_t* src_y_2 = src_y + half_w;
uint8_t* src_y_3 = src_y + (width * half_h);
uint8_t* src_y_4 = src_y + (width * half_h) + half_w;
uint8_t* src_u_1 = src_u;
uint8_t* src_u_2 = src_u + (half_w >> 1);
uint8_t* src_u_3 = src_u + (width * half_h >> 1);
uint8_t* src_u_4 = src_u + (width * half_h >> 1) + (half_w >> 1);
uint8_t* src_v_1 = src_v;
uint8_t* src_v_2 = src_v + (half_w >> 1);
uint8_t* src_v_3 = src_v + (width * half_h >> 1);
uint8_t* src_v_4 = src_v + (width * half_h >> 1) + (half_w >> 1);
uint8_t* dst_1 = dst;
uint8_t* dst_2 = dst + (half_w << 1);
uint8_t* dst_3 = dst + (width * half_h << 1);
uint8_t* dst_4 = dst + (width * half_h << 1) + (half_w << 1);
if (omp)
{
uint8_t* src_data[4][3] = { {src_y_1,src_u_1,src_v_1},{src_y_2,src_u_2,src_v_2},{src_y_3,src_u_3,src_v_3},{src_y_4,src_u_4,src_v_4} };
uint8_t* dst_data[4] = { dst_1,dst_2,dst_3,dst_4 };
int thread_num = 4;
omp_set_num_threads(thread_num);
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < thread_num; i++)
{
uint8_t* src_y = src_data[i][0];
uint8_t* src_u = src_data[i][1];
uint8_t* src_v = src_data[i][2];
uint8_t* dst = dst_data[i];
libyuv::I422ToUYVY(src_y, width, src_u, width >> 1, src_v, width >> 1, dst, width << 1, half_w, half_h);
}
}
}
{
libyuv::I422ToUYVY(src_y_1, width, src_u_1, width >> 1, src_v_1, width >> 1, dst_1, width << 1, half_w, half_h);
libyuv::I422ToUYVY(src_y_2, width, src_u_2, width >> 1, src_v_2, width >> 1, dst_2, width << 1, half_w, half_h);
libyuv::I422ToUYVY(src_y_3, width, src_u_3, width >> 1, src_v_3, width >> 1, dst_3, width << 1, half_w, half_h);
libyuv::I422ToUYVY(src_y_4, width, src_u_4, width >> 1, src_v_4, width >> 1, dst_4, width << 1, half_w, half_h);
}
}
static void I422Scale4K(uint8_t* src, const size_t& src_w, const size_t& src_h, uint8_t* dst, const size_t& dst_w, const size_t& dst_h, const int32_t& omp)
{
size_t half_src_w = (src_w >> 1);
size_t half_src_h = (src_h >> 1);
size_t half_dst_w = (dst_w >> 1);
size_t half_dst_h = (dst_h >> 1);
uint32_t src_y_size = src_w * src_h;
uint32_t src_u_size = (src_w * src_h >> 1);
uint8_t* src_y = src;
uint8_t* src_u = src_y + src_y_size;
uint8_t* src_v = src_u + src_u_size;
uint8_t* src_y_1 = src_y;
uint8_t* src_y_2 = src_y + half_src_w;
uint8_t* src_y_3 = src_y + src_w * half_src_h;
uint8_t* src_y_4 = src_y + src_w * half_src_h + half_src_w;
uint8_t* src_u_1 = src_u;
uint8_t* src_u_2 = src_u + (half_src_w >> 1);
uint8_t* src_u_3 = src_u + (src_w * half_src_h >> 1);
uint8_t* src_u_4 = src_u + (src_w * half_src_h >> 1) + (half_src_w >> 1);
uint8_t* src_v_1 = src_v;
uint8_t* src_v_2 = src_v + (half_src_w >> 1);
uint8_t* src_v_3 = src_v + (src_w * half_src_h >> 1);
uint8_t* src_v_4 = src_v + (half_src_w >> 1) + (src_w * half_src_h >> 1);
uint32_t dst_y_size = dst_w * dst_h;
uint32_t dst_u_size = (dst_w * dst_h >> 1);
uint8_t* dst_y = dst;
uint8_t* dst_u = dst_y + dst_y_size;
uint8_t* dst_v = dst_u + dst_u_size;
uint8_t* dst_y_1 = dst_y;
uint8_t* dst_y_2 = dst_y + half_dst_w;
uint8_t* dst_y_3 = dst_y + dst_w * half_dst_h;
uint8_t* dst_y_4 = dst_y + dst_w * half_dst_h + half_dst_w;
uint8_t* dst_u_1 = dst_u;
uint8_t* dst_u_2 = dst_u + (half_dst_w >> 1);
uint8_t* dst_u_3 = dst_u + (dst_w * half_dst_h >> 1);
uint8_t* dst_u_4 = dst_u + (dst_w * half_dst_h >> 1) + (half_dst_w >> 1);
uint8_t* dst_v_1 = dst_v;
uint8_t* dst_v_2 = dst_v + (half_dst_w >> 1);
uint8_t* dst_v_3 = dst_v + (dst_w * half_dst_h >> 1);
uint8_t* dst_v_4 = dst_v + (half_dst_w >> 1) + (dst_w * half_dst_h >> 1);
if (omp)
{
uint8_t* src_data[4][3] = { {src_y_1,src_u_1,src_v_1},{src_y_2,src_u_2,src_v_2},{src_y_3,src_u_3,src_v_3},{src_y_4,src_u_4,src_v_4} };
uint8_t* dst_data[4][3] = { {dst_y_1,dst_u_1,dst_v_1},{dst_y_2,dst_u_2,dst_v_2},{dst_y_3,dst_u_3,dst_v_3},{dst_y_4,dst_u_4,dst_v_4} };
int thread_num = 4;
omp_set_num_threads(thread_num);
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < thread_num; i++)
{
uint8_t* src_y = src_data[i][0];
uint8_t* src_u = src_data[i][1];
uint8_t* src_v = src_data[i][2];
uint8_t* dst_y = dst_data[i][0];
uint8_t* dst_u = dst_data[i][1];
uint8_t* dst_v = dst_data[i][2];
libyuv::I422Scale(src_y, src_w, src_u, src_w >> 1, src_v, src_w >> 1, half_src_w, half_src_h,
dst_y, dst_w, dst_u, dst_w >> 1, dst_v, dst_w >> 1, half_dst_w, half_dst_h, libyuv::kFilterBilinear);
}
}
}
else
{
{
libyuv::I422Scale(src_y_1, src_w, src_u_1, src_w >> 1, src_v_1, src_w >> 1, half_src_w, half_src_h,
dst_y_1, dst_w, dst_u_1, dst_w >> 1, dst_v_1, dst_w >> 1, half_dst_w, half_dst_h, libyuv::kFilterBilinear);
libyuv::I422Scale(src_y_2, src_w, src_u_2, src_w >> 1, src_v_2, src_w >> 1, half_src_w, half_src_h,
dst_y_2, dst_w, dst_u_2, dst_w >> 1, dst_v_2, dst_w >> 1, half_dst_w, half_dst_h, libyuv::kFilterBilinear);
libyuv::I422Scale(src_y_3, src_w, src_u_3, src_w >> 1, src_v_3, src_w >> 1, half_src_w, half_src_h,
dst_y_3, dst_w, dst_u_3, dst_w >> 1, dst_v_3, dst_w >> 1, half_dst_w, half_dst_h, libyuv::kFilterBilinear);
libyuv::I422Scale(src_y_4, src_w, src_u_4, src_w >> 1, src_v_4, src_w >> 1, half_src_w, half_src_h,
dst_y_4, dst_w, dst_u_4, dst_w >> 1, dst_v_4, dst_w >> 1, half_dst_w, half_dst_h, libyuv::kFilterBilinear);
}
}
}
static void ARGBScale4K(uint8_t* src,const size_t& src_w, const size_t& src_h, uint8_t* dst, const size_t& dst_w, const size_t& dst_h,const int32_t& omp, int32_t& scale_type, int32_t& filter)
{
size_t half_src_w = (src_w >> 1);
size_t half_src_h = (src_h >> 1);
size_t half_scale_w = (scale_w >> 1);
size_t half_scale_h = (scale_h >> 1);
size_t half_dst_w = (dst_w >> 1);
size_t half_dst_h = (dst_h >> 1);
//size_t src_step = (half_src_w * half_src_h << 2);
uint8_t* src1 = src;
......@@ -60,25 +268,234 @@ public:
//size_t scale_step = (half_scale_w * half_scale_h << 2);
uint8_t* dst1 = dst;
uint8_t* dst2 = dst + (half_scale_w << 2);
uint8_t* dst3 = dst + (half_scale_h * scale_w << 2);
uint8_t* dst4 = dst + ((half_scale_h * scale_w << 2) + (half_scale_w << 2));
uint8_t* dst2 = dst + (half_dst_w << 2);
uint8_t* dst3 = dst + (half_dst_h * dst_w << 2);
uint8_t* dst4 = dst + ((half_dst_h * dst_w << 2) + (half_dst_w << 2));
size_t dst_mode_w = dst_w % 2;
size_t dst_mode_h = dst_h % 2;
size_t src_mode_w = src_w % 2;
size_t src_mode_h = src_h % 2;
std::vector<WH> src_wh_vec = { { half_src_w, half_src_h },{half_src_w + src_mode_w,half_src_h},{half_src_w,half_src_h + src_mode_h},{half_src_w + src_mode_w,half_src_h + src_mode_h} };
std::vector<WH> dst_wh_vec = { { half_dst_w, half_dst_h },{half_dst_w + dst_mode_w,half_dst_h},{half_dst_w,half_dst_h + dst_mode_h},{half_dst_w + dst_mode_w,half_dst_h + dst_mode_h} };
//std::vector<WH> src_wh_vec_o,dst_wh_vec_o;
//if (scale_type == USEOPENCV)
//{
// //uint32_t src_one_size = (half_src_w * half_src_h << 2);
// src1 = src;
// src2 = src + (half_src_w * half_src_h << 2);
// src3 = src + (src_w * half_src_h << 2);
// src4 = src3 + (half_src_w * (half_src_h + src_mode_h) << 2);
// //uint32_t dst_one_size = (half_dst_w * half_dst_h << 2);
// dst1 = dst;
// dst2 = dst + (half_dst_w * half_dst_h << 2);
// dst3 = dst + (dst_w * half_dst_h << 2);
// dst4 = dst3 + (half_dst_w * (half_dst_h + dst_mode_h) << 2);
// /*src_wh_vec_o = { { half_src_w, half_src_h },{half_src_w ,half_src_h},{half_src_w,half_src_h },{1,src_w * src_h - (half_src_w * half_src_h * 3)}};
// dst_wh_vec_o = { { half_dst_w, half_dst_h },{half_dst_w ,half_dst_h},{half_dst_w,half_dst_h },{1,dst_w * dst_h - (half_dst_w * half_dst_h * 3)}};*/
//}
if (omp)
{
std::vector<uint8_t*> src_vec = { src1,src2,src3,src4 };
std::vector<uint8_t*> dst_vec = { dst1,dst2,dst3,dst4 };
auto size = src_vec.size();
if (scale_type == USELIBYUV)
{
omp_set_num_threads(size);
#pragma omp parallel
{
#pragma omp for nowait
for (int i = 0; i < size; i++)
{
uint8_t* src = src_vec[i];
uint8_t* dst = dst_vec[i];
WH dst_wh = dst_wh_vec[i];
libyuv::ARGBScale(src, src_w << 2, src_wh_vec[i].w, src_wh_vec[i].h, dst, dst_w << 2, dst_wh.w, dst_wh.h, (libyuv::FilterMode)filter);
}
}
}
else if (scale_type == USEOPENCV)
{
/*omp_set_num_threads(size);
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < size; i++)
{
uint8_t* src = src_vec[i];
uint8_t* dst = dst_vec[i];
WH dst_wh = dst_wh_vec[i];
WH src_wh = src_wh_vec[i];
cv::Mat src_mat = cv::Mat(src_wh.h, src_wh.w, CV_8UC4, src);
cv::Mat dst_mat = cv::Mat(dst_wh.h, dst_wh.w, CV_8UC4, dst);
cv::resize(src_mat, dst_mat, dst_mat.size(), 0, 0, filter);
}
}*/
cv::Mat src_mat = cv::Mat(src_h, src_w, CV_8UC4, src);
cv::Mat dst_mat = cv::Mat(dst_h, dst_w, CV_8UC4, dst);
cv::resize(src_mat, dst_mat, dst_mat.size(), 0, 0, filter);
}
}
else
{
libyuv::ARGBScale(src1, src_w << 2, half_src_w, half_src_h, dst1, scale_w << 2, half_scale_w, half_scale_h, libyuv::kFilterNone);
libyuv::ARGBScale(src2, src_w << 2, half_src_w, half_src_h, dst2, scale_w << 2, half_scale_w, half_scale_h, libyuv::kFilterNone);
libyuv::ARGBScale(src3, src_w << 2, half_src_w, half_src_h, dst3, scale_w << 2, half_scale_w, half_scale_h, libyuv::kFilterNone);
libyuv::ARGBScale(src4, src_w << 2, half_src_w, half_src_h, dst4, scale_w << 2, half_scale_w, half_scale_h, libyuv::kFilterNone);
{
if (scale_type == USELIBYUV)
{
libyuv::ARGBScale(src1, src_w << 2, src_wh_vec[0].w, src_wh_vec[0].h, dst1, dst_w << 2, dst_wh_vec[0].w, dst_wh_vec[0].h, (libyuv::FilterMode)filter);
libyuv::ARGBScale(src2, src_w << 2, src_wh_vec[1].w, src_wh_vec[1].h, dst2, dst_w << 2, dst_wh_vec[1].w, dst_wh_vec[1].h, (libyuv::FilterMode)filter);
libyuv::ARGBScale(src3, src_w << 2, src_wh_vec[2].w, src_wh_vec[2].h, dst3, dst_w << 2, dst_wh_vec[2].w, dst_wh_vec[2].h, (libyuv::FilterMode)filter);
libyuv::ARGBScale(src4, src_w << 2, src_wh_vec[3].w, src_wh_vec[3].h, dst4, dst_w << 2, dst_wh_vec[3].w, dst_wh_vec[3].h, (libyuv::FilterMode)filter);
}
else if (scale_type == USEOPENCV)
{
int interpolation = cv::INTER_LANCZOS4;
cv::Mat src_mat = cv::Mat(src_h, src_w, CV_8UC4, src);
cv::Mat dst_mat = cv::Mat(dst_h, dst_w, CV_8UC4, dst);
cv::resize(src_mat, dst_mat, dst_mat.size(), 0, 0, filter);
/*cv::Mat src_mat_1 = cv::Mat(src_wh_vec[0].h, src_wh_vec[0].w, CV_8UC4, src1);
cv::Mat src_mat_2 = cv::Mat(src_wh_vec[1].h, src_wh_vec[1].w, CV_8UC4, src2);
cv::Mat src_mat_3 = cv::Mat(src_wh_vec[2].h, src_wh_vec[2].w, CV_8UC4, src3);
cv::Mat src_mat_4 = cv::Mat(src_wh_vec[3].h, src_wh_vec[3].w, CV_8UC4, src4);
cv::Mat dst_mat_1 = cv::Mat(dst_wh_vec[0].h, dst_wh_vec[0].w, CV_8UC4, dst1);
cv::Mat dst_mat_2 = cv::Mat(dst_wh_vec[1].h, dst_wh_vec[1].w, CV_8UC4, dst2);
cv::Mat dst_mat_3 = cv::Mat(dst_wh_vec[2].h, dst_wh_vec[2].w, CV_8UC4, dst3);
cv::Mat dst_mat_4 = cv::Mat(dst_wh_vec[3].h, dst_wh_vec[3].w, CV_8UC4, dst4);
cv::resize(src_mat_1, dst_mat_1, dst_mat_1.size(), 0, 0, filter);
cv::resize(src_mat_2, dst_mat_2, dst_mat_2.size(), 0, 0, filter);
cv::resize(src_mat_3, dst_mat_3, dst_mat_3.size(), 0, 0, filter);
cv::resize(src_mat_4, dst_mat_4, dst_mat_4.size(), 0, 0, filter);*/
}
}
}
}
static void I422Copy4k(uint8_t* src, const size_t& offset_x, const size_t& offset_y, const size_t& src_w, const size_t& src_h,
uint8_t* dst, const size_t& dst_w, const size_t& dst_h, const int32_t& omp)
{
size_t half_dst_w = (dst_w >> 1);
size_t half_dst_h = (dst_h >> 1);
uint32_t src_y_size = src_w * src_h;
uint32_t src_u_size = (src_w * src_h >> 1);
uint8_t* src_y = src;
uint8_t* src_u = src_y + src_y_size;
uint8_t* src_v = src_u + src_u_size;
size_t offset = offset_y * src_w + offset_x;
uint8_t* src_y_1 = src_y + offset;
offset += half_dst_w;
uint8_t* src_y_2 = src_y + offset;
offset = (offset_y + half_dst_h) * src_w + offset_x;
uint8_t* src_y_3 = src_y + offset;
offset += half_dst_w;
uint8_t* src_y_4 = src_y + offset;
offset = (offset_y * src_w >> 1) + (offset_x >> 1);
uint8_t* src_u_1 = src_u + offset;
uint8_t* src_v_1 = src_v + offset;
offset += (half_dst_w >> 1);
uint8_t* src_u_2 = src_u + offset;
uint8_t* src_v_2 = src_v + offset;
offset = ((offset_y + half_dst_h) * src_w >> 1) + (offset_x >> 1);
uint8_t* src_u_3 = src_u + offset;
uint8_t* src_v_3 = src_v + offset;
offset += (half_dst_w >> 1);
uint8_t* src_u_4 = src_u + offset;
uint8_t* src_v_4 = src_v + offset;
uint32_t dst_y_size = dst_w * dst_h;
uint32_t dst_u_size = (dst_w * dst_h >> 1);
uint8_t* dst_y = dst;
uint8_t* dst_u = dst_y + dst_y_size;
uint8_t* dst_v = dst_u + dst_u_size;
uint8_t* dst_y_1 = dst_y;
uint8_t* dst_u_1 = dst_u;
uint8_t* dst_v_1 = dst_v;
uint8_t* dst_y_2 = dst_y + half_dst_w;
uint8_t* dst_u_2 = dst_u + (half_dst_w >> 1);
uint8_t* dst_v_2 = dst_v + (half_dst_w >> 1);
uint8_t* dst_y_3 = dst_y + dst_w * half_dst_h;
uint8_t* dst_u_3 = dst_u + (dst_w * half_dst_h >> 1);
uint8_t* dst_v_3 = dst_v + (dst_w * half_dst_h >> 1);
uint8_t* dst_y_4 = dst_y + dst_w * half_dst_h + half_dst_w;
uint8_t* dst_u_4 = dst_u + (dst_w * half_dst_h >> 1) + (half_dst_w >> 1);
uint8_t* dst_v_4 = dst_v + (dst_w * half_dst_h >> 1) + (half_dst_w >> 1);
if (omp)
{
uint8_t* src_data[4][3] = { {src_y_1,src_u_1,src_v_1},{src_y_2,src_u_2,src_v_2},{src_y_3,src_u_3,src_v_3},{src_y_4,src_u_4,src_v_4} };
uint8_t* dst_data[4][3] = { {dst_y_1,dst_u_1,dst_v_1},{dst_y_2,dst_u_2,dst_v_2},{dst_y_3,dst_u_3,dst_v_3},{dst_y_4,dst_u_4,dst_v_4} };
int thread_num = 4;
omp_set_num_threads(thread_num);
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < thread_num; i++)
{
uint8_t* src_y = src_data[i][0];
uint8_t* src_u = src_data[i][1];
uint8_t* src_v = src_data[i][2];
uint8_t* dst_y = dst_data[i][0];
uint8_t* dst_u = dst_data[i][1];
uint8_t* dst_v = dst_data[i][2];
libyuv::I422Copy(src_y, src_w, src_u, src_w >> 1, src_v, src_w >> 1, dst_y, dst_w, dst_u, dst_w >> 1, dst_v, dst_w >> 1, half_dst_w, half_dst_h);
}
}
}
else
{
libyuv::I422Copy(src_y_1, src_w, src_u_1, src_w >> 1, src_v_1, src_w >> 1, dst_y_1, dst_w, dst_u_1, dst_w >> 1, dst_v_1, dst_w >> 1, half_dst_w, half_dst_h);
libyuv::I422Copy(src_y_2, src_w, src_u_2, src_w >> 1, src_v_2, src_w >> 1, dst_y_2, dst_w, dst_u_2, dst_w >> 1, dst_v_2, dst_w >> 1, half_dst_w, half_dst_h);
libyuv::I422Copy(src_y_3, src_w, src_u_3, src_w >> 1, src_v_3, src_w >> 1, dst_y_3, dst_w, dst_u_3, dst_w >> 1, dst_v_3, dst_w >> 1, half_dst_w, half_dst_h);
libyuv::I422Copy(src_y_4, src_w, src_u_4, src_w >> 1, src_v_4, src_w >> 1, dst_y_4, dst_w, dst_u_4, dst_w >> 1, dst_v_4, dst_w >> 1, half_dst_w, half_dst_h);
}
}
static void ARGBCopy4k(uint8_t* src,const size_t& offset_x, const size_t& offset_y, const size_t& src_w, const size_t& src_h,
uint8_t* dst,const size_t& dst_w,const size_t& dst_h)
uint8_t* dst,const size_t& dst_w,const size_t& dst_h, int32_t& omp,int32_t type = 1 )
{
if (type == USEOPENCV)
{
cv::Mat src_mat = cv::Mat(src_h, src_w, CV_8UC4, src);
cv::Mat dst_mat = cv::Mat(dst_h, dst_w, CV_8UC4, dst);
src_mat(cv::Rect(offset_x, offset_y, dst_w, dst_h)).copyTo(dst_mat(cv::Rect(0, 0, dst_w, dst_h)));
return;
}
size_t half_dst_w = (dst_w >> 1);
size_t half_dst_h = (dst_h >> 1);
size_t mode_w = dst_w % 2;
size_t mode_h = dst_h % 2;
size_t src1_offset = (offset_y * src_w << 2) + (offset_x << 2);
uint8_t* src1 = src + src1_offset;
size_t src2_offset = (offset_y * src_w << 2) + ((offset_x + half_dst_w) << 2);
......@@ -96,11 +513,31 @@ public:
dst_offset = ((dst_w * half_dst_h << 2) + (half_dst_w << 2));
uint8_t* dst4 = dst + dst_offset;
std::vector<WH> dst_wh_vec = { { half_dst_w, half_dst_h },{half_dst_w + mode_w,half_dst_h},{half_dst_w,half_dst_h + mode_h},{half_dst_w + mode_w,half_dst_h + mode_h} };
if (omp)
{
std::vector<uint8_t*> src_vec = { src1,src2,src3,src4 };
std::vector<uint8_t*> dst_vec = { dst1,dst2,dst3,dst4 };
auto size = src_vec.size();
omp_set_num_threads(size);
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < size; i++)
{
uint8_t* src = src_vec[i];
uint8_t* dst = dst_vec[i];
libyuv::ARGBCopy(src, src_w << 2, dst, dst_w << 2, dst_wh_vec[i].w, dst_wh_vec[i].h);
}
}
}
else
{
libyuv::ARGBCopy(src1, src_w << 2, dst1, dst_w << 2, half_dst_w, half_dst_h);
libyuv::ARGBCopy(src2, src_w << 2, dst2, dst_w << 2, half_dst_w, half_dst_h);
libyuv::ARGBCopy(src3, src_w << 2, dst3, dst_w << 2, half_dst_w, half_dst_h);
libyuv::ARGBCopy(src4, src_w << 2, dst4, dst_w << 2, half_dst_w, half_dst_h);
libyuv::ARGBCopy(src1, src_w << 2, dst1, dst_w << 2, dst_wh_vec[0].w, dst_wh_vec[0].h);
libyuv::ARGBCopy(src2, src_w << 2, dst2, dst_w << 2, dst_wh_vec[1].w, dst_wh_vec[1].h);
libyuv::ARGBCopy(src3, src_w << 2, dst3, dst_w << 2, dst_wh_vec[2].w, dst_wh_vec[2].h);
libyuv::ARGBCopy(src4, src_w << 2, dst4, dst_w << 2, dst_wh_vec[3].w, dst_wh_vec[3].h);
}
}
};
\ No newline at end of file
......@@ -5,10 +5,11 @@
#include "Utils/Platform.h"
#include "BlackMagicDesign/DeckLinkInputDevice.h"
#include "Utils/Common.h"
#include "Utils/Settings.h"
#include "BlackMagicDesign/DeckLinkInputPage.h"
#define NEED_AUDIO 0
extern int AudioChannel;
//extern int AudioChannel;
DeckLinkInputDevice::DeckLinkInputDevice(QObject* parent, ComPtr<IDeckLink>& device, int index)
: RefCount(1),
......@@ -89,6 +90,7 @@ HRESULT DeckLinkInputDevice::VideoInputFrameArrived(IDeckLinkVideoInputFrame* vi
ComPtr<IDeckLinkVideoInputFrame> frame = ComPtr<IDeckLinkVideoInputFrame>(videoFrame);
//emit ArrivedFrame(frame);
if (videoFrame && Capture) {
//qDebug() << GetCurrDateTimeStr() << " VideoInputFrameArrived"<< "\n";
//auto fmt = videoFrame->GetPixelFormat();
unsigned flags = videoFrame->GetFlags();
bool noInputSourceFlag = false;
......@@ -151,7 +153,7 @@ HRESULT DeckLinkInputDevice::VideoInputFrameArrived(IDeckLinkVideoInputFrame* vi
if (audioPacket)
{
auto cur_time = QDateTime::currentMSecsSinceEpoch();
std::shared_ptr<AudioPacket> audio_ptr = std::make_shared<AudioPacket>(audioPacket, cur_time, AudioChannel);
std::shared_ptr<AudioPacket> audio_ptr = std::make_shared<AudioPacket>(audioPacket, cur_time, Settings::AudioChannel);
emit PushAudioFrame(audio_ptr);
}
#endif // NEED_AUDIO
......@@ -298,7 +300,7 @@ bool DeckLinkInputDevice::StartCapture(BMDDisplayMode displayMode, IDeckLinkScre
if (DeckLinkInput->EnableVideoInput(bmdMode4K2160p50, bmdFormat8BitYUV, bmdVideoInputFlagDefault) != S_OK)
return false;
if (DeckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType32bitInteger, AudioChannel) != S_OK)
if (DeckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType32bitInteger, Settings::AudioChannel) != S_OK)
return false;
// Set the capture
......
......@@ -279,35 +279,27 @@ void DeckLinkInputPage::RecvMsg(QByteArray json)
auto status = (ReplayStatus)object["status"].toInt();
auto start_time = object["start_time"].toInt();
auto end_time = object["end_time"].toInt();
if (end_time <= start_time) return;
ReplayParams params{ status, start_time ,end_time };
//if (end_time <= start_time || !Replay || !Replay->CanReplay(params)) return;
//qint64 timecode = QString::number(obj.value("timecode").toDouble(), 'f', 0).toLongLong();
switch (status)
{
case RS_START:
case RS_RE_START:
{
bool status = true;
if (Capture) Capture->recvReplay(status);
if (Replay) {
ReplayParams params{ start_time ,end_time };
Replay->recvReplayParams(params,status);
if (!Replay || !Replay->CanReplay(params))
{
if (Capture) Capture->RecvReplayStatus(RS_END);
break;
}
break;
}
case RS_END:
default:
{
bool status = false;
if (Capture) Capture->recvReplay(status);
if (Replay) {
ReplayParams params{ start_time ,end_time };
Replay->recvReplayParams(params, status);
}
if (Capture) Capture->RecvReplayStatus(status);
Replay->recvReplayParams(params);
break;
}
default:
break;
}
}
......@@ -430,8 +422,8 @@ void DeckLinkInputPage::ObjectNameChanged(const QString& newName)
//SelectedDevice.Get()->SetNDIOutputThread(NDIOutput);
//connect(Capture.get(), SIGNAL(PushFrame(std::shared_ptr<videoFrameData>)), NDIOutput.get(), SLOT(AddFrame(std::shared_ptr<videoFrameData>)));
connect(Replay.get(), SIGNAL(PushFrame(std::shared_ptr<videoFrameData>)), NDIOutput.get(), SLOT(AddFrame(std::shared_ptr<videoFrameData>)));
connect(Capture.get(), SIGNAL(PushFrameToReplay(std::shared_ptr<videoFrameData>)), Replay.get(), SLOT(addFrame(std::shared_ptr<videoFrameData>)));
connect(Replay.get(), SIGNAL(PushFrame(std::shared_ptr<videoFrameData>)), NDIOutput.get(), SLOT(AddFrame(std::shared_ptr<videoFrameData>)), Qt::DirectConnection);
connect(Capture.get(), SIGNAL(PushFrameToReplay(std::shared_ptr<videoFrameData>)), Replay.get(), SLOT(addFrame(std::shared_ptr<videoFrameData>))/*, Qt::DirectConnection*/);
connect(udpServer.get(), SIGNAL(SendMsg(QByteArray)),this, SLOT(RecvMsg(QByteArray)));
//NDIOutput->moveToThread(Capture.get());
//connect(SelectedDevice.Get(), SIGNAL(ArrivedFrame(ComPtr<IDeckLinkVideoInputFrame>)), NDIOutput.get(), SLOT(AddFrame(ComPtr<IDeckLinkVideoInputFrame>)));
......
......@@ -6,13 +6,16 @@
#include "BlackMagicDesign/ReferenceTime.h"
#include "opencv2/opencv.hpp"
#include "Utils/yuv4k.h"
#include "Utils/Settings.h"
#include "Utils/DispatchQueue.h"
#include <omp.h>
//extern int OutputDeleyTime;
extern int OutputPlayMode;
extern int AudioChannel;
extern int SDIOneFrameDuration;
//extern int OutputPlayMode;
//extern int AudioChannel;
//extern int SDIOneFrameDuration;
//extern int ZoomFlag;
//extern int SdiOutWaitNums;
//extern std::map<qint32, qint32> map_output_delay;
#define OUTPUT_1080 1
......@@ -23,6 +26,8 @@ extern int SDIOneFrameDuration;
#define SORTMAPSIZE 4
#define VECTORSIZE 2
#define USEMUTABLE 0
#define USEWAITSEND 1
#define MASKEDMAXSIZE 2
DeckLinkOutputDevice::DeckLinkOutputDevice(ComPtr<IDeckLink>& decklink, int videoPrerollSize,int index,qint32 deleyTime)
: RefCount(1),
......@@ -148,7 +153,7 @@ bool DeckLinkOutputDevice::StartPlayback(BMDDisplayMode displayMode, bool enable
BMDDisplayMode outputDisplayMode;
#if OUTPUT_1080
switch (OutputPlayMode)
switch (Settings::OutputPlayMode)
{
case 1:
outputDisplayMode = bmdModeHD1080i50;
......@@ -219,7 +224,7 @@ bool DeckLinkOutputDevice::StartPlayback(BMDDisplayMode displayMode, bool enable
return false;
}
if (deckLinkOutput->EnableAudioOutput(bmdAudioSampleRate48kHz,bmdAudioSampleType32bitInteger, AudioChannel,bmdAudioOutputStreamTimestamped) != S_OK)
if (deckLinkOutput->EnableAudioOutput(bmdAudioSampleRate48kHz,bmdAudioSampleType32bitInteger, Settings::AudioChannel,bmdAudioOutputStreamTimestamped) != S_OK)
{
qDebug() << "call EnableAudioOutput fuc is failure" << "\n";
return false;
......@@ -240,8 +245,16 @@ bool DeckLinkOutputDevice::StartPlayback(BMDDisplayMode displayMode, bool enable
/*scheduleVideoFramesThread = std::thread(&DeckLinkOutputDevice::scheduleVideoFramesFunc, this);
scheduleAudioFramesThread = std::thread(&DeckLinkOutputDevice::scheduleAudioFramesFuncDeley, this);*/
if (Settings::SdiOutWaitNums)
{
scheduleVideoFramesThread = std::thread(&DeckLinkOutputDevice::scheduleVideoFramesWaitFunc, this);
}
else
{
if(Settings::SDIOutputWaitNums) scheduleVideoFramesThread = std::thread(&DeckLinkOutputDevice::scheduleVideoFramesRealTimeFunc, this);
else scheduleVideoFramesThread = std::thread(&DeckLinkOutputDevice::scheduleVideoFramesNoDeleyFunc, this);
}
scheduleVideoFramesThread = std::thread(&DeckLinkOutputDevice::scheduleVideoFramesNoDeleyFunc, this);
#if TESTWRITEFILE
testWriteFileThread = std::thread(&DeckLinkOutputDevice::testWirteFileFrameFunc, this);
#endif
......@@ -479,9 +492,536 @@ bool DeckLinkOutputDevice::getReferenceSignalMode(BMDDisplayMode* mode)
}
}
void DeckLinkOutputDevice::scheduleVideoFramesWaitFunc(void)
{
std::atomic_bool send_one_frame_flag = false;
bool send_zoom_frame_flag = false;
HRESULT ret = S_OK;
qint64 zoom_key = 0;
std::shared_ptr<SampleQueue<std::shared_ptr<VideoFrameWithMask>>> zoom_queue = nullptr;
std::map<qint64, std::shared_ptr<VideoFrameWithMask>>* inner_masked_map = NULL;
while (true)
{
if (state == PlaybackState::Stopping) break;
std::shared_ptr<VideoFrameWithMask> outputFrame;
std::vector<std::shared_ptr<VideoFrameWithMask>> frames;
if (outputMaskVideoFrameQueue.WaitFor(Settings::SdiOutWaitNums))
{
outputMaskVideoFrameQueue.Pop(outputFrame);
outputMaskVideoFrameDeque.Pop();
if (!outputFrame || (!outputFrame->data_ && !outputFrame->pImage && !outputFrame->pImage->data)) continue;
{
if (inner_masked_map)
{
auto key = inner_masked_map->begin()->first;
outputFrame = inner_masked_map->begin()->second;
auto out_key = outputFrame->start_tm_;
inner_masked_map->erase(key);
if (!inner_masked_map->size())
{
zoom_key = out_key;
delete inner_masked_map;
masked_map.erase(out_key);
inner_masked_map = NULL;
masked_status_map.erase(out_key);
}
}
else
{
auto status_size = masked_status_map.size();
auto masked_size = masked_map.size();
if (masked_size)
{
while (masked_map.size() > MASKEDMAXSIZE)
{
auto itor = masked_map.begin();
if (itor->second)
{
itor->second->clear();
delete itor->second;
}
masked_map.erase(itor->first);
}
if (!status_size)
{
if (send_zoom_frame_flag) send_zoom_frame_flag = false;
if (send_one_frame_flag)
{
send_one_frame_flag = false;
send_count = 0;
end_blend_frame_ = nullptr;
}
continue;
}
auto itor = masked_status_map.begin();
for (auto pair : masked_map)
{
if (pair.first < itor->first)
{
/*if (itor->first - pair.first > 100) {
masked_status_map.erase(itor->first);
continue;
}*/
std::lock_guard<std::mutex> locker(sdi_clear_mutex);
if (pair.second)
{
pair.second->clear();
delete pair.second;
}
masked_map.erase(pair.first);
}
else break;
}
if (itor->second.status == SSS_FINISH)
{
masked_status_map.erase(itor->first);
}
else
{
auto masked_itor = masked_map.find(itor->first);
if (masked_itor == masked_map.end())
{
masked_status_map.erase(itor->first);
continue;
}
else
{
if (!inner_masked_map) inner_masked_map = masked_itor->second;
if (itor->second.status == SSS_CLEAR)
{
std::lock_guard<std::mutex> locker(sdi_clear_mutex);
masked_map.erase(masked_itor->first);
inner_masked_map->clear();
delete inner_masked_map;
inner_masked_map = NULL;
masked_status_map.erase(itor->first);
continue;
}
else if (itor->second.status == SSS_SEND)
{
if (inner_masked_map)
{
auto key = inner_masked_map->begin()->first;
outputFrame = inner_masked_map->begin()->second;
auto out_key = outputFrame->start_tm_;
inner_masked_map->erase(key);
if (!inner_masked_map->size())
{
delete inner_masked_map;
masked_map.erase(out_key);
inner_masked_map = NULL;
masked_status_map.erase(itor->first);
}
}
}
}
}
}
}
}
if (!outputFrame || (!outputFrame->data_ && !outputFrame->pImage && !outputFrame->pImage->data)) continue;
if (Settings::SDIOneFrameDuration > 0 && outputFrame->flag_ == BS_END)
{
end_blend_frame_ = outputFrame;
}
if (end_blend_frame_ && Settings::SDIOneFrameDuration > 0 && send_count < Settings::SDIOneFrameDuration)
{
send_one_frame_flag = true;
send_count++;
}
else if (send_count >= Settings::SDIOneFrameDuration && end_blend_frame_ /*&& (outputFrame->flag_ == BS_IDEL || outputFrame->flag_ == BS_START)*/)
{
if (Settings::ZoomFlag && !send_zoom_frame_flag /*&& zoomVideoFrameQueue.Size()*/ && zoom_map.Find(zoom_key,zoom_queue))
{
/*if (zoomVideoFrameQueue.Size() >= VECTORSIZE)*/ send_zoom_frame_flag = true;
}
if (!Settings::ZoomFlag || send_zoom_frame_flag)
{
send_one_frame_flag = false;
send_count = 0;
end_blend_frame_ = nullptr;
}
}
if (send_one_frame_flag)
{
outputFrame = end_blend_frame_;
}
else if (send_zoom_frame_flag)
{
if (zoom_queue)
{
if (!zoom_queue->Pop(outputFrame) || !outputFrame->pImage)
{
continue;
}
if (outputFrame->zoom_last)
{
send_zoom_frame_flag = false;
auto keys = zoom_map.Keys();
for (auto key : keys)
{
if (key < zoom_key)
{
std::shared_ptr<SampleQueue<std::shared_ptr<VideoFrameWithMask>>> tmp_queue = nullptr;
if (zoom_map.Find(key, tmp_queue))
{
if (tmp_queue) tmp_queue->Reset();
zoom_map.Erase(key);
}
}
else break;
}
zoom_map.Erase(zoom_key);
zoom_queue->Reset();
zoom_queue = nullptr;
zoom_key = 0;
}
}
/*if (!zoomVideoFrameQueue.Pop(outputFrame) || !outputFrame->pImage)
{
continue;
}
if (outputFrame->pImage->last)
{
send_zoom_frame_flag = false;
}*/
}
if (!outputFrame || (!outputFrame->data_ && (!outputFrame->pImage || !outputFrame->pImage->data))) continue;
uint32_t w = outputFrame->width_;
uint32_t h = outputFrame->height_;
#if USETHREADS
#else
uint32_t uyvy_size = (w * h << 1);
if (!uyvy_4k_data) uyvy_4k_data = new uint8_t[uyvy_size];
uint8_t* src_data = NULL;
if (outputFrame->mask_flag) src_data = outputFrame->data_;
else src_data = outputFrame->pImage->data;
/*uint8_t* uyvy_data = new uint8_t[uyvy_size];
uint8_t* src_data = outputFrame->data_;
std::shared_ptr<VideoFrameWithMask> uyvy_frame= std::make_shared<VideoFrameWithMask>();
uyvy_frame->fmt_ = bmdFormat8BitYUV;
uyvy_frame->width_ = w;
uyvy_frame->height_ = h;
uyvy_frame->data_ = uyvy_data;
uyvy_frame->size_ = uyvy_size;
uyvy_frame->timestamp_ = outputFrame->timestamp_;*/
size_t once_size = w * h;
size_t num = outputFrame->size_ / once_size;
size_t yuv_size = once_size >> 1;
omp_set_num_threads(num);
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < num; i++)
{
auto src = src_data + i * once_size;
auto dst = uyvy_4k_data + i * yuv_size;
libyuv::ARGBToUYVY(src, w << 1, dst, w, w >> 1, h >> 1);
}
}
#endif
#if USEMUTABLE
if (!deckOutputFrame)
{
ret = deckLinkOutput->CreateVideoFrame(w, h,
GetRowBytesFromPixelFormat(w, bmdFormat8BitYUV), bmdFormat8BitYUV, bmdFrameFlagDefault, deckOutputFrame.GetAddressOf());
if (ret != S_OK)
{
qDebug() << "CreateVideoFrame is fail....." << "\n";
}
}
if (deckOutputFrame)
{
uint8_t* dstdata;
deckOutputFrame->GetBytes((void**)&dstdata);
#if USETHREADS
memcpy(dstdata, outputFrame->data_, outputFrame->size_);
#else
memcpy(dstdata, uyvy_4k_data, uyvy_size);
#endif
//auto ret = deckLinkOutput->DisplayVideoFrameSync(videoFrame.Get());
uint8_t hours;
uint8_t minutes;
uint8_t seconds;
uint8_t frames;
ConvertFrameCountToTimecode(gTotalFramesScheduled, &hours, &minutes, &seconds, &frames);
auto result = SetRP188VitcTimecodeOnFrame(deckOutputFrame.Get(), hours, minutes, seconds, frames);
ret = deckLinkOutput->DisplayVideoFrameSync(deckOutputFrame.Get());
}
#else
uint8_t hours;
uint8_t minutes;
uint8_t seconds;
uint8_t frames;
ConvertFrameCountToTimecode(gTotalFramesScheduled, &hours, &minutes, &seconds, &frames);
ComPtr<DeckLinkOutputVideoFrame> videoFrame = MakeComPtr<DeckLinkOutputVideoFrame>(outputFrame);
SetRP188VitcTimecodeOnFrame(videoFrame.Get(), hours, minutes, seconds, frames);
ret = deckLinkOutput->DisplayVideoFrameSync(videoFrame.Get());
#endif
if (ret != S_OK)
{
if (ret == E_ACCESSDENIED) {
qDebug() << "The video output is not enabled." << "\n";
}
else if (ret == E_INVALIDARG)
{
qDebug() << "The frame attributes are invalid." << "\n";
}
else if (ret == E_FAIL)
{
qDebug() << "Failure." << "\n";
deckLinkOutput->DisableVideoOutput();
deckLinkOutput->EnableVideoOutput(outputDisplayMode, bmdVideoOutputFlagDefault);
}
else
{
qDebug() << "other error code." << "\n";
}
}
else
{
m_fps++;
gTotalFramesScheduled++;
}
uint64_t currTime, deltaTime;
int qsize;
if (!m_lastRecvTS) m_lastRecvTS = TimeMilliSecond();
qsize = outputMaskVideoFrameQueue.Size();
currTime = TimeMilliSecond();
deltaTime = currTime - m_lastRecvTS;
if (deltaTime >= 1000)
{
qDebug() << GetCurrDateTimeStr() << " decklink output fps " << m_fps << ", qsize " << qsize << "\n";
m_fps = 0;
m_lastRecvTS = currTime;
}
}
}
}
void DeckLinkOutputDevice::scheduleVideoFramesRealTimeFunc(void)
{
std::atomic_bool send_one_frame_flag = false;
//bool send_zoom_frame_flag = false;
std::shared_ptr<VideoFrameWithMask> wait_zoom_frame = nullptr;
HRESULT ret = S_OK;
int wait_size = Settings::SDIOutputWaitNums;
while (true)
{
if (state == PlaybackState::Stopping) break;
std::shared_ptr<VideoFrameWithMask> outputFrame = nullptr;
qint64 key;
if (output_video_frame_map.WaitFor(wait_size))
{
//if (wait_size == Settings::SDIOutputWaitNums) wait_size = 1;
if (!output_video_frame_map.Pop(key, outputFrame)) continue;
if (!outputFrame || (!outputFrame->data_ && (!outputFrame->pImage || (!outputFrame->pImage->data && !outputFrame->pImage->uyvy_data))))
{
qDebug() << "scheduleVideoFramesRealTimeFunc get frame failed..." << "\n";
continue;
}
auto t1 = TimeMilliSecond();
//if (send_zoom_frame_flag) qDebug() << "cur time:" << GetCurrDateTimeStr() << ",tm:"<< outputFrame->timestamp_ << "\n";
/*if (last_tm > outputFrame->timestamp_)
{
qDebug() << "frame order is error! error num:" << outputFrame->timestamp_ << ",last num:" << last_tm << "\n";
}
last_tm = outputFrame->timestamp_;*/
//qDebug() << GetCurrDateTimeStr() << ":current frame tm:" << outputFrame->timestamp_ << "\n";
if (outputFrame->flag_ == BS_START)
{
send_sdi_start_time = outputFrame->start_tm_;
if (send_one_frame_flag)
{
send_one_frame_flag = false;
send_count = 0;
end_blend_frame_ = nullptr;
}
if (send_zoom_frame_flag)
{
send_zoom_frame_flag = false;
bool send_result = false;
while (true)
{
if (zoomVideoFrameQueue.Empty()) break;
std::shared_ptr<VideoFrameWithMask> tmp;
if (!zoomVideoFrameQueue.Front(tmp)) break;
if (tmp->start_tm_ >= outputFrame->start_tm_) break;
else
{
if (!send_result)
{
send_result = true;
emit SendZoomResult(tmp->start_tm_, true);
}
zoomVideoFrameQueue.Pop();
}
}
}
}
if (Settings::SDIOneFrameDuration > 0 && outputFrame->flag_ == BS_END)
{
end_blend_frame_ = outputFrame;
}
if (end_blend_frame_ && Settings::SDIOneFrameDuration > 0 && send_count < Settings::SDIOneFrameDuration)
{
send_one_frame_flag = true;
send_count++;
}
else if (send_count >= Settings::SDIOneFrameDuration && end_blend_frame_ && (outputFrame->flag_ == BS_IDEL || outputFrame->flag_ == BS_START))
{
if (Settings::ZoomFlag && !send_zoom_frame_flag)
{
send_zoom_frame_flag = true;
if (zoomVideoFrameQueue.Size() < Settings::FrameRate * Settings::ZoomInDuration)
{
wait_zoom_frame = end_blend_frame_;
}
qDebug() << "zoomVideoFrameQueue size:" << zoomVideoFrameQueue.Size() << "\n";
}
if (!Settings::ZoomFlag || send_zoom_frame_flag)
{
send_one_frame_flag = false;
send_count = 0;
end_blend_frame_ = nullptr;
}
}
if (send_one_frame_flag)
{
outputFrame = end_blend_frame_;
}
else if (send_zoom_frame_flag)
{
if (wait_zoom_frame && zoomVideoFrameQueue.Size() < Settings::FrameRate * Settings::ZoomInDuration)
{
outputFrame = wait_zoom_frame;
}
else
{
if (wait_zoom_frame) wait_zoom_frame = nullptr;
if (!zoomVideoFrameQueue.Pop(outputFrame) || !outputFrame->pImage)
{
qDebug() << "zoomVideoFrameQueue is empty" << "\n";
continue;
}
}
if (outputFrame->zoom_last)
{
send_zoom_frame_flag = false;
}
}
if (!outputFrame || (!outputFrame->data_ && (!outputFrame->pImage || !outputFrame->pImage->data)))
{
qDebug() << "outputFrame is empty" << "\n";
continue;
}
uint32_t w = outputFrame->width_;
uint32_t h = outputFrame->height_;
uint8_t hours;
uint8_t minutes;
uint8_t seconds;
uint8_t frames;
ConvertFrameCountToTimecode(gTotalFramesScheduled, &hours, &minutes, &seconds, &frames);
ComPtr<DeckLinkOutputVideoFrame> videoFrame = MakeComPtr<DeckLinkOutputVideoFrame>(outputFrame);
SetRP188VitcTimecodeOnFrame(videoFrame.Get(), hours, minutes, seconds, frames);
auto t2 = TimeMilliSecond();
ret = deckLinkOutput->DisplayVideoFrameSync(videoFrame.Get());
//if (send_zoom_frame_flag) qDebug() << GetCurrDateTimeStr() <<":all duration:"<< TimeMilliSecond() - t1 << ":current zoom tm:" << outputFrame->timestamp_ << ",DisplayVideoFrameSync duration:" << TimeMilliSecond() - t2 << "\n";
if (ret != S_OK)
{
if (ret == E_ACCESSDENIED) {
qDebug() << "The video output is not enabled." << "\n";
}
else if (ret == E_INVALIDARG)
{
qDebug() << "The frame attributes are invalid." << "\n";
}
else if (ret == E_FAIL)
{
qDebug() << "Failure." << "\n";
deckLinkOutput->DisableVideoOutput();
deckLinkOutput->EnableVideoOutput(outputDisplayMode, bmdVideoOutputFlagDefault);
}
else
{
qDebug() << "other error code." << "\n";
}
}
else
{
m_fps++;
gTotalFramesScheduled++;
}
uint64_t currTime, deltaTime;
int qsize;
if (!m_lastRecvTS) m_lastRecvTS = TimeMilliSecond();
qsize = outputMaskVideoFrameQueue.Size();
currTime = TimeMilliSecond();
deltaTime = currTime - m_lastRecvTS;
if (deltaTime >= 1000)
{
qDebug() << GetCurrDateTimeStr() << " decklink output fps " << m_fps << ", qsize " << qsize << "\n";
m_fps = 0;
m_lastRecvTS = currTime;
}
}
}
}
void DeckLinkOutputDevice::scheduleVideoFramesNoDeleyFunc(void)
{
std::atomic_bool send_one_frame_flag = false;
bool send_zoom_frame_flag = false;
std::shared_ptr<VideoFrameWithMask> wait_zoom_frame = nullptr;
HRESULT ret = S_OK;
while (true)
{
......@@ -504,7 +1044,7 @@ bool DeckLinkOutputDevice::getReferenceSignalMode(BMDDisplayMode* mode)
}
//if (outputMaskVideoFrameQueue.WaitFor(outputFrame))
for (int i = 0; i < 2; i++)
for (int i = 0; i < VECTORSIZE; i++)
{
/*auto now_time = QDateTime::currentMSecsSinceEpoch();
auto dever_time = now_time - outputFrame->timestamp_;
......@@ -522,26 +1062,98 @@ bool DeckLinkOutputDevice::getReferenceSignalMode(BMDDisplayMode* mode)
qDebug() << "frame order is error! error num:" << outputFrame->timestamp_ << ",last num:" << last_tm << "\n";
}
last_tm = outputFrame->timestamp_;*/
if (SDIOneFrameDuration > 0 && outputFrame->flag_ == BS_END)
qDebug() << GetCurrDateTimeStr() << ":current frame tm:" << outputFrame->timestamp_ << "\n";
if (outputFrame->flag_ == BS_START)
{
send_sdi_start_time = outputFrame->start_tm_;
if (send_one_frame_flag)
{
send_one_frame_flag = false;
send_count = 0;
end_blend_frame_ = nullptr;
}
if (send_zoom_frame_flag)
{
send_zoom_frame_flag = false;
bool send_result = false;
while (true)
{
if (zoomVideoFrameQueue.Empty()) break;
std::shared_ptr<VideoFrameWithMask> tmp;
if (!zoomVideoFrameQueue.Front(tmp)) break;
if (tmp->start_tm_ >= outputFrame->start_tm_) break;
else
{
if (!send_result)
{
send_result = true;
emit SendZoomResult(tmp->start_tm_, true);
}
zoomVideoFrameQueue.Pop();
}
}
}
}
if (Settings::SDIOneFrameDuration > 0 && outputFrame->flag_ == BS_END)
{
end_blend_frame_ = outputFrame;
}
if (SDIOneFrameDuration > 0 && send_count < SDIOneFrameDuration && end_blend_frame_)
if (end_blend_frame_ && Settings::SDIOneFrameDuration > 0 && send_count < Settings::SDIOneFrameDuration)
{
send_one_frame_flag = true;
send_count++;
}
else if (send_count >= SDIOneFrameDuration && end_blend_frame_ && (outputFrame->flag_ == BS_IDEL || outputFrame->flag_ == BS_START))
else if (send_count >= Settings::SDIOneFrameDuration && end_blend_frame_ && (outputFrame->flag_ == BS_IDEL || outputFrame->flag_ == BS_START))
{
send_one_frame_flag = false;
send_count = 0;
end_blend_frame_ = nullptr;
if(Settings::ZoomFlag && !send_zoom_frame_flag)
{
send_zoom_frame_flag = true;
if (zoomVideoFrameQueue.Size() < Settings::FrameRate * Settings::ZoomInDuration)
{
wait_zoom_frame = end_blend_frame_;
}
qDebug() << "zoomVideoFrameQueue size:" << zoomVideoFrameQueue.Size() << "\n";
}
if (!Settings::ZoomFlag || send_zoom_frame_flag)
{
send_one_frame_flag = false;
send_count = 0;
end_blend_frame_ = nullptr;
}
}
if (send_one_frame_flag)
{
outputFrame = end_blend_frame_;
}
if (!outputFrame || (!outputFrame->data_ && !outputFrame->pImage && !outputFrame->pImage->data)) continue;
else if (send_zoom_frame_flag)
{
if (wait_zoom_frame && zoomVideoFrameQueue.Size() < Settings::FrameRate * Settings::ZoomInDuration)
{
outputFrame = wait_zoom_frame;
}
else
{
if(wait_zoom_frame) wait_zoom_frame = nullptr;
if (!zoomVideoFrameQueue.Pop(outputFrame) || !outputFrame->pImage)
{
qDebug() << "zoomVideoFrameQueue is empty" << "\n";
continue;
}
}
if (outputFrame->zoom_last)
{
send_zoom_frame_flag = false;
}
}
if (!outputFrame || (!outputFrame->data_ && (!outputFrame->pImage || !outputFrame->pImage->data)))
{
qDebug() << "outputFrame is empty" << "\n";
continue;
}
uint32_t w = outputFrame->width_;
uint32_t h = outputFrame->height_;
......@@ -627,7 +1239,9 @@ bool DeckLinkOutputDevice::getReferenceSignalMode(BMDDisplayMode* mode)
ConvertFrameCountToTimecode(gTotalFramesScheduled, &hours, &minutes, &seconds, &frames);
ComPtr<DeckLinkOutputVideoFrame> videoFrame = MakeComPtr<DeckLinkOutputVideoFrame>(outputFrame);
SetRP188VitcTimecodeOnFrame(videoFrame.Get(), hours, minutes, seconds, frames);
auto t1 = TimeMilliSecond();
ret = deckLinkOutput->DisplayVideoFrameSync(videoFrame.Get());
if (send_zoom_frame_flag) qDebug()<< GetCurrDateTimeStr() <<":current zoom tm:"<< outputFrame->timestamp_ << ",DisplayVideoFrameSync duration:" << TimeMilliSecond() - t1 << "\n";
#endif
if (ret != S_OK)
{
......@@ -926,47 +1540,217 @@ void DeckLinkOutputDevice::checkEndOfPreroll()
}
}
void DeckLinkOutputDevice::AddZoomFrame(std::shared_ptr<VideoFrameWithMask> frame)
{
if (frame && (frame->data_ || (frame->pImage && (frame->pImage->data || frame->pImage->uyvy_data))))
{
if(Settings::SdiOutWaitNums)
{
auto start_time = frame->start_tm_;
//std::lock_guard<std::mutex> locker(sdi_clear_mutex);
std::shared_ptr<SampleQueue<std::shared_ptr<VideoFrameWithMask>>> queue = nullptr;
auto ret = zoom_map.Find(start_time, queue);
if (!ret)
{
queue = std::make_shared<SampleQueue<std::shared_ptr<VideoFrameWithMask>>>();
queue->Push(frame);
zoom_map.Insert(start_time, queue);
}
else
{
queue->Push(frame);
}
}
else
{
if(frame->start_tm_ >= send_sdi_start_time )
zoomVideoFrameQueue.Push(frame);
}
}
}
void DeckLinkOutputDevice::AddVideoFrameMask(std::shared_ptr<VideoFrameWithMask> frame)
{
if (outputMaskVideoFrameQueue.Size() > 50 * 3)
//auto t1 = TimeMilliSecond();
if (outputMaskVideoFrameQueue.Size() > (50 * 3 + Settings::SdiOutWaitNums) || output_video_frame_map.Size() > (50 * 3 + Settings::SdiOutWaitNums))
{
outputMaskVideoFrameQueue.Reset();
if(outputMaskVideoFrameQueue.Size()) outputMaskVideoFrameQueue.Reset();
if (output_video_frame_map.Size()) output_video_frame_map.Clear();
}
#if USETHREADS
if (frame && (frame->data_ || (frame->pImage && frame->pImage->data)))
if (frame && (frame->data_ || (frame->pImage && (frame->pImage->uyvy_data || frame->pImage->data))))
{
if(frame->fmt_ == bmdFormat8BitYUV) outputMaskVideoFrameQueue.Push(frame);
else if(frame->fmt_ == bmdFormat8BitBGRA)
if (send_zoom_frame_flag)
{
/*while (sort_map_.size() > SORTMAPSIZE)
{
auto first = sort_map_.begin();
outputMaskVideoFrameQueue.Push(first->second);
sort_map_.erase(first->first);
}*/
//qDebug() << "AddVideoFrameMask:" << "timestamp:" << frame->sequenceNum_ << GetCurrDateTimeStr() << "\n";
}
if (p_dispatch_queue)
if (Settings::SDIOutputWaitNums)
{
if (frame->fmt_ == bmdFormat8BitYUV)
{
output_video_frame_map.Insert(frame->timestamp_, frame);
}
else if (frame->fmt_ == bmdFormat8BitBGRA)
{
if (p_dispatch_queue)
{
DispatchQueue* dispath = (DispatchQueue*)p_dispatch_queue;
dispath->dispatch(std::bind(&DeckLinkOutputDevice::BGRAToUYVY, this, std::placeholders::_1), frame);
}
}
}
else
{
if (frame->fmt_ == bmdFormat8BitYUV)
{
outputMaskVideoFrameQueue.Push(frame);
if (Settings::SdiOutWaitNums) outputMaskVideoFrameDeque.PushBack(frame);
}
else if (frame->fmt_ == bmdFormat8BitBGRA)
{
DispatchQueue* dispath = (DispatchQueue*)p_dispatch_queue;
dispath->dispatch(std::bind(&DeckLinkOutputDevice::BGRAToUYVY, this, std::placeholders::_1), frame);
if (Settings::SdiOutWaitNums)
{
if (frame->flag_ == BS_START)
{
if (masked_map.find(frame->timestamp_) != masked_map.end())return;
else
{
auto tmp_map = new std::map<qint64, std::shared_ptr<VideoFrameWithMask>>();
/*auto tmp_tm = frame->timestamp_ - SdiOutWaitNums;
tmp_tm = (tmp_tm < 0 ? 0 : tmp_tm);*/
int size = outputMaskVideoFrameDeque.Size();
int nums = (size > Settings::SdiOutWaitNums ? Settings::SdiOutWaitNums : size);
std::vector<std::shared_ptr<VideoFrameWithMask>> tmp_vec;
outputMaskVideoFrameDeque.Put(nums, tmp_vec);
for (auto data : tmp_vec)
{
if (data)
{
data->start_tm_ = frame->timestamp_;
tmp_map->insert({ data->timestamp_,data });
}
}
masked_map.insert({ frame->timestamp_,tmp_map });
}
}
}
/*while (masked_map.size() > 2)
{
auto itor = masked_map.begin();
if (itor->second)
{
itor->second->clear();
delete itor->second;
}
masked_map.erase(itor->first);
}*/
if (p_dispatch_queue)
{
DispatchQueue* dispath = (DispatchQueue*)p_dispatch_queue;
dispath->dispatch(std::bind(&DeckLinkOutputDevice::BGRAToUYVY, this, std::placeholders::_1), frame);
}
}
}
}
#else
if(frame && (frame->data_ || (frame->pImage && frame->pImage->data)))
if (frame && (frame->data_ || (frame->pImage && frame->pImage->data)))
{
outputMaskVideoFrameQueue.Push(frame);
}
#endif
//qDebug() << "add video duration:" << TimeMilliSecond() - t1 << "\n";
}
//void DeckLinkOutputDevice::AddVideoFrameMask(std::shared_ptr<VideoFrameWithMask> frame)
//{
// if (outputMaskVideoFrameQueue.Size() > (50 * 3 + Settings::SdiOutWaitNums))
// {
// outputMaskVideoFrameQueue.Reset();
// }
//#if USETHREADS
// if (frame && (frame->data_ || (frame->pImage && frame->pImage->data)))
// {
//
// //qDebug() << frame->sequenceNum_ << "decklink out time:" << GetCurrDateTimeStr() << "\n";
// if (frame->fmt_ == bmdFormat8BitYUV)
// {
// outputMaskVideoFrameQueue.Push(frame);
// if (Settings::SdiOutWaitNums) outputMaskVideoFrameDeque.PushBack(frame);
// }
// else if(frame->fmt_ == bmdFormat8BitBGRA)
// {
// if (Settings::SdiOutWaitNums)
// {
// if (frame->flag_ == BS_START)
// {
// if (masked_map.find(frame->timestamp_) != masked_map.end())return;
// else
// {
// auto tmp_map = new std::map<qint64, std::shared_ptr<VideoFrameWithMask>>();
// /*auto tmp_tm = frame->timestamp_ - SdiOutWaitNums;
// tmp_tm = (tmp_tm < 0 ? 0 : tmp_tm);*/
// int size = outputMaskVideoFrameDeque.Size();
// int nums = (size > Settings::SdiOutWaitNums ? Settings::SdiOutWaitNums : size);
// std::vector<std::shared_ptr<VideoFrameWithMask>> tmp_vec;
// outputMaskVideoFrameDeque.Put(nums, tmp_vec);
// for (auto data : tmp_vec)
// {
//
// if (data)
// {
// data->start_tm_ = frame->timestamp_;
// tmp_map->insert({ data->timestamp_,data });
// }
// }
// masked_map.insert({ frame->timestamp_,tmp_map });
// }
// }
// }
// /*while (masked_map.size() > 2)
// {
// auto itor = masked_map.begin();
// if (itor->second)
// {
// itor->second->clear();
// delete itor->second;
// }
// masked_map.erase(itor->first);
// }*/
//
//
// if (p_dispatch_queue)
// {
// DispatchQueue* dispath = (DispatchQueue*)p_dispatch_queue;
// dispath->dispatch(std::bind(&DeckLinkOutputDevice::BGRAToUYVY, this, std::placeholders::_1), frame);
// }
// }
//
// }
//#else
// if(frame && (frame->data_ || (frame->pImage && frame->pImage->data)))
// {
// outputMaskVideoFrameQueue.Push(frame);
// }
//#endif
//}
void DeckLinkOutputDevice::BGRAToUYVY(const std::shared_ptr<VideoFrameWithMask>& image)
{
uint32_t src_w = 0, src_h = 0;
uint8_t* src_data = NULL;
src_w = image->width_;
src_h = image->height_;
auto& tm = image->timestamp_;
auto& flag = image->flag_;
auto& start_time = image->start_tm_;
if (image->mask_flag)
{
src_data = image->data_;
......@@ -987,11 +1771,42 @@ void DeckLinkOutputDevice::BGRAToUYVY(const std::shared_ptr<VideoFrameWithMask>&
Yuv4k::ARGBToUYVY4K(src_data,once_size,uyvy,yuv_size,width_,height_);
VideoFrameWithMask::VideoFrameWithMaskPtr video_frame =
std::make_shared<VideoFrameWithMask>(src_w,src_h,image->timestamp_,image->sequenceNum_,uyvy,bmdFormat8BitYUV,image->flag_,image->meta_);
std::make_shared<VideoFrameWithMask>(src_w,src_h,tm,image->sequenceNum_,uyvy,bmdFormat8BitYUV,image->flag_,image->meta_, start_time);
//sort_map_.insert({ image->timestamp_ ,video_frame });
if(Settings::SdiOutWaitNums)
{
std::lock_guard<std::mutex> locker(sdi_clear_mutex);
auto itor = masked_map.find(start_time);
if (itor != masked_map.end() && itor->second)
{
itor->second->insert({ tm,video_frame });
}
}
else
{
if (Settings::SDIOutputWaitNums)
{
output_video_frame_map.Insert(video_frame->timestamp_, video_frame);
}
else outputMaskVideoFrameQueue.Push(video_frame);
}
outputMaskVideoFrameQueue.Push(video_frame);
/*if(flag == BS_START)
{
if (itor == masked_map.end())
{
auto tmp_map = new std::map<qint64, std::shared_ptr<VideoFrameWithMask>>();
tmp_map->insert({ tm ,video_frame });
masked_map.insert({ tm,tmp_map });
}
}
else
{
}*/
}
void DeckLinkOutputDevice::AddFrame(std::shared_ptr<Image> image)
......@@ -1072,3 +1887,14 @@ void DeckLinkOutputDevice::SetDeleyTime(qint32& deleyTime)
output_deley_ms = deleyTime;
queue_max_size = (output_deley_ms / 1000 + 3) * 50;
}
void DeckLinkOutputDevice::SetSendSdiParams(SendSdiParams params)
{
if (masked_map.size() <= 0) return;
auto tm = params.start_time;
auto itor = masked_status_map.find(tm);
if (itor == masked_status_map.end())
{
masked_status_map.insert({ tm,params });
}
}
......@@ -7,7 +7,9 @@
#include "TimePlus.h"
#include "BlackMagicDesign/DeckLinkOutputPage.h"
#include "Utils/Platform.h"
#include "Utils/Settings.h"
//extern int ZoomFlag;
namespace
{
......@@ -100,6 +102,18 @@ DeckLinkOutputPage::DeckLinkOutputPage() : SelectedDevice(nullptr), Process(null
BlackBottomHeight = BlackHeightEdit->text().toInt();
PreviewView->GetOverlay()->SetDeleyTime(DeleyTime);
if (Settings::ZoomFlag)
{
if (!Zoom)
{
Zoom = std::make_shared<ZoomThread>();
Zoom->start();
if (Zoom)
{
connect(this, &DeckLinkOutputPage::PushAttribute, Zoom.get(), &ZoomThread::addSportAttr);
}
}
}
connect(DeviceListCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &DeckLinkOutputPage::OutputDeviceChanged);
connect(VideoFormatCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &DeckLinkOutputPage::VideoFormatChanged);
......@@ -287,11 +301,18 @@ void DeckLinkOutputPage::RequestedDeviceGranted(ComPtr<IDeckLink>& device)
// TODO: Connect
#if USE_TIMEPLUS
connect(BindingInputPage->GetCapture(), &CaptureThread::PushFrame, ProcessMask.get(), &ProcessMaskThread::AddFrame);
connect(BindingInputPage->GetReplay(), &ReplayThread::PushFrame, ProcessMask.get(), &ProcessMaskThread::AddFrame);
connect(ProcessMask.get(), &ProcessMaskThread::PushFrame, NDIOutput.get(), &NDIOutputThread::AddVideoFrameWithMask);
if (MqThread) connect(MqThread.get(), &ConsumerMqThread::PushMask, ProcessMask.get(), &ProcessMaskThread::addMaskBuffer);
connect(ProcessMask.get(), &ProcessMaskThread::PushFrame, SelectedDevice.Get(), &DeckLinkOutputDevice::AddVideoFrameMask);
connect(BindingInputPage->GetCapture(), &CaptureThread::PushFrame, ProcessMask.get(), &ProcessMaskThread::AddFrame, Qt::DirectConnection);
connect(BindingInputPage->GetReplay(), &ReplayThread::PushFrame, ProcessMask.get(), &ProcessMaskThread::AddFrame, Qt::DirectConnection);
connect(ProcessMask.get(), &ProcessMaskThread::PushFrame, NDIOutput.get(), &NDIOutputThread::AddVideoFrameWithMask, Qt::DirectConnection);
//if (MqThread) connect(MqThread.get(), &ConsumerMqThread::PushMask, ProcessMask.get(), &ProcessMaskThread::addMaskBuffer);
connect(this, &DeckLinkOutputPage::PushMask, ProcessMask.get(), &ProcessMaskThread::addMaskBuffer);
connect(ProcessMask.get(), &ProcessMaskThread::PushFrame, SelectedDevice.Get(), &DeckLinkOutputDevice::AddVideoFrameMask, Qt::DirectConnection);
if (Zoom)
{
connect(Zoom.get(), &ZoomThread::PushFrame, SelectedDevice.Get(), &DeckLinkOutputDevice::AddZoomFrame, Qt::DirectConnection);
connect(SelectedDevice.Get(), &DeckLinkOutputDevice::SendZoomResult, Zoom.get(), &ZoomThread::recvResult, Qt::DirectConnection);
}
#elif USE_H2V
connect(BindingInputPage->GetCapture(), &CaptureThread::PushFrame, Process.get(), &ProcessThread::AddFrame);
connect(Process.get(), &ProcessThread::PushFrame, SelectedDevice.Get(), &DeckLinkOutputDevice::AddFrame);
......@@ -339,6 +360,34 @@ void DeckLinkOutputPage::RequestedDeviceGranted(ComPtr<IDeckLink>& device)
END_SLOT_TIME_COUNTER
}
void DeckLinkOutputPage::OnRecvMqMsg(const QJsonDocument& document)
{
if (!document.isObject()) return;
QJsonObject object = document.object();
auto type = object["type"].toString();
if (!object["data"].isObject()) return;
auto obj = object["data"].toObject();
if (obj.isEmpty()) return;
if (type == "SENDMASK")
{
auto buffer = std::make_shared<MaskBuffer>(obj);
if (buffer && buffer->signal != -1)
{
emit PushMask(buffer);
}
}
else if (type == "SENDPOINTS")
{
if (!Zoom) return;
auto attr = std::make_shared<SportAttribute>(obj);
if (attr && attr->timecode)
{
emit PushAttribute(attr);
}
}
}
void DeckLinkOutputPage::OnRecvMsg(QByteArray data)
{
QJsonDocument document = QJsonDocument::fromJson(data);
......@@ -368,6 +417,20 @@ void DeckLinkOutputPage::OnRecvMsg(QByteArray data)
ProcessMask->StartRecord(start_time, end_time);
}
}
else if (type == "RECONFIRM")
{
auto start_time = object["start_time"].toInt();
auto status = (SendSDIStatus)object["status"].toInt();
SendSdiParams params{ status,start_time };
if (SelectedDevice) SelectedDevice->SetSendSdiParams(params);
if (Zoom && status == SSS_CLEAR)
{
ZoomResultInfo info;
info.drop = true;
info.timestamp = start_time;
Zoom->setResult(info);
}
}
}
}
......@@ -487,7 +550,7 @@ void DeckLinkOutputPage::ObjectNameChanged(const QString& newName)
std::string queue_name = "test" + index.toStdString();
std::string exchange_name = queue_name;
MqThread = std::make_shared<ConsumerMqThread>(queue_name, exchange_name, "127.0.0.1", "admin", "123456");
MqThread = std::make_shared<ConsumerMqThread>(queue_name, exchange_name, "127.0.0.1", "admin", "123456",this);
MqThread->start();
}
#elif USE_H2V
......
......@@ -287,9 +287,13 @@ long DeckLinkOutputVideoFrame::GetRowBytes()
HRESULT DeckLinkOutputVideoFrame::GetBytes(void** buf)
{
//*buf = m_img->GetBytes();
if (videoMask && videoMask->data_)
if (videoMask)
{
*buf = videoMask->data_;
if (videoMask->data_) *buf = videoMask->data_;
else if (videoMask->pImage && videoMask->pImage->uyvy_data) {
*buf = videoMask->pImage->uyvy_data;
}
else return S_FALSE;
}
else return S_FALSE;
......
......@@ -8,9 +8,10 @@
#include "NDI/NDIOutputThread.h"
#include "Utils/Common.h"
#include "libyuv.h"
#include "Utils/Settings.h"
extern qint64 StartTimeStamp;
extern int OneFrameDuration;
//extern qint64 StartTimeStamp;
//extern int OneFrameDuration;
#define SENDBGRA 1
#define MAXSIZE 30
......@@ -141,7 +142,7 @@ bool NDIOutputThread::Init()
#endif
//Frame.p_data = (uint8_t*)malloc(Frame.xres * Frame.yres * 2);
Frame.frame_rate_D = 1;
Frame.frame_rate_N = 50;
Frame.frame_rate_N = Settings::FrameRate;
Frame.frame_format_type = NDIlib_frame_format_type_progressive;
Frame.picture_aspect_ratio = 16.0 / 9;
//Frame.timecode = NDIlib_send_timecode_synthesize;
......@@ -150,9 +151,9 @@ bool NDIOutputThread::Init()
if (cropFlag)
{
AudioFrame.FourCC = NDIlib_FourCC_audio_type_FLTP;
AudioFrame.no_channels = 2;
AudioFrame.no_channels = Settings::AudioChannel;
AudioFrame.sample_rate = 48000;
AudioFrame.p_data = (uint8_t*)malloc(MAXCHANNEL * 1600 * sizeof(float));
AudioFrame.p_data = (uint8_t*)malloc(AudioFrame.no_channels * 9600 * sizeof(float));
AudioCvtPtr = std::make_shared<AudioConvert>(AudioFrame.no_channels, bmdAudioSampleType32bitInteger);
}
......@@ -232,21 +233,22 @@ void NDIOutputThread::run()
}
else if (timePlusFlag)
{
if (VideoMaskQueue.WaitFor(frame_mask))
if (VideoMaskQueue.WaitFor(Settings::SDIOutputWaitNums))
{
//if (!frame_mask ||(frame_mask->mask_flag && !frame_mask->data_)) continue;
VideoMaskQueue.Pop(frame_mask);
if (!frame_mask || (!frame_mask->data_ && !frame_mask->pImage && !frame_mask->pImage->data)) continue;
if (OneFrameDuration > 0 && frame_mask->flag_ == BS_END)
if (Settings::OneFrameDuration > 0 && frame_mask->flag_ == BS_END)
{
end_blend_frame_ = frame_mask;
}
if (OneFrameDuration > 0 && send_count < OneFrameDuration && end_blend_frame_)
if (Settings::OneFrameDuration > 0 && send_count < Settings::OneFrameDuration && end_blend_frame_)
{
send_one_frame_flag = true;
send_count++;
}
else if (send_count >= OneFrameDuration && end_blend_frame_ && (frame_mask->flag_ == BS_IDEL || frame_mask->flag_ == BS_START))
else if (send_count >= Settings::OneFrameDuration && end_blend_frame_ && (frame_mask->flag_ == BS_IDEL || frame_mask->flag_ == BS_START))
{
send_one_frame_flag = false;
send_count = 0;
......@@ -321,8 +323,15 @@ void NDIOutputThread::run()
// Frame.p_data = src_buffer;
//#endif
}
Frame.timestamp = frame->timestamp;
Frame.timestamp = (frame->replaySeq ? frame->replaySeq : frame->timestamp);
/*if (normal_last_timestamp && normal_last_timestamp >= frame->timestamp)
{
Frame.timecode = frame->timestamp;
}*/
Frame.timecode = frame->timestamp;;
NDIlib_send_send_video_v2(Instance, &Frame);
//normal_last_timestamp = frame->timestamp;
//qDebug() << GetCurrDateTimeStr()<<":send ndi Frame.timestamp->" << Frame.timestamp << "\n";
//av_free(dstBuff);
......@@ -407,6 +416,11 @@ void NDIOutputThread::AddFilterFrame(const std::shared_ptr<videoFrameData>& fram
void NDIOutputThread::AddFrame(std::shared_ptr<videoFrameData> frame)
{
/*if (last_recv_ts)
{
qDebug() << "NDIThread:AddFrame:" << frame->timestamp << ",last recv duration:" << TimeMilliSecond() - last_recv_ts << "\n";
}
last_recv_ts = TimeMilliSecond();*/
if (VideoQueue.Size() > MAXSIZE)
{
qDebug() << "ndi send VideoQueue size than maxsize ,queue size:" << VideoQueue.Size() << "\n";
......
#include "Network/UdpSend.h"
UdpSend& UdpSend::GetInstance()
{
static UdpSend udpsend;
return udpsend;
}
void UdpSend::SendUdpMsg(const QString& msg, const QString serverAddr, const QString serverPort)
{
if (sendUdpSocket)
{
UdpPacket packet{msg,serverAddr,serverPort};
msg_queue.Push(packet);
}
}
void UdpSend::run()
{
UdpPacket packet;
while (true)
{
if (msg_queue.WaitFor(packet))
{
QByteArray byteArray = packet.msg.toUtf8();
if (sendUdpSocket && sendUdpSocket->writeDatagram(byteArray, QHostAddress(packet.serverAddr), packet.serverPort.toInt()) == -1)
{
qDebug() << "send udp msg fail,msg:" << packet.msg << "\n";
}
}
}
}
UdpSend::UdpSend()
{
if (!sendUdpSocket) sendUdpSocket = new QUdpSocket(this);
}
UdpSend::~UdpSend()
{
if (sendUdpSocket)
{
sendUdpSocket->close();
sendUdpSocket->deleteLater();
}
}
\ No newline at end of file
......@@ -12,17 +12,58 @@ UdpServer::~UdpServer()
udpSocket->close();
udpSocket->deleteLater();
}
if(sendUdpSocket)
{
sendUdpSocket->close();
sendUdpSocket->deleteLater();
}
}
void UdpServer::SetUpUDP(const QString hostAddr, const QString hostPort)
{
if(!udpSocket) udpSocket = new QUdpSocket(this);
//if (!sendUdpSocket) sendUdpSocket = new QUdpSocket(this);
if (udpSocket)
{
udpSocket->bind(QHostAddress(hostAddr), hostPort.toInt());
connect(udpSocket, SIGNAL(readyRead()), this, SLOT(ReadDatagrams()), Qt::DirectConnection);
}
if (sendUdpSocket)
{
connect(sendUdpSocket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), this, SLOT(HandleError(QAbstractSocket::SocketError)));
}
}
void UdpServer::SendUdpMsg(const QString& msg, const QString serverAddr, const QString serverPort)
{
if (sendUdpSocket)
{
QByteArray byteArray = msg.toUtf8();
if (sendUdpSocket->writeDatagram(byteArray, QHostAddress(serverAddr), serverPort.toInt()) == -1)
{
qDebug() << "send udp msg fail,msg:" << msg << "\n";
}
}
}
void UdpServer::HandleError(QAbstractSocket::SocketError error)
{
// 根据错误类型处理问题
switch (error) {
case QAbstractSocket::ConnectionRefusedError:
// 处理错误
break;
case QAbstractSocket::RemoteHostClosedError:
// 处理错误
break;
// 更多错误处理...
default:
// 处理其他错误
break;
}
}
void UdpServer::ReadDatagrams()
......
#include "Record/Record.h"
#include "libyuv.h"
#include "Utils/Settings.h"
extern int FrameRate;
//extern int FrameRate;
#define CLOCKHZ 90000
#define BITRATENUM 500000000
#define TESTFILE 0
......@@ -61,7 +62,7 @@ int Record::Init(const std::string& outfile, const int& w, const int& h, const A
pAvCodecContext->codec_id = pavcodec->id;
pAvCodecContext->pix_fmt = AV_PIX_FMT_YUV422P10LE;
int fps = FrameRate;
int fps = Settings::FrameRate;
int64_t bit_rate = BITRATENUM; //ƽ500M/b
pAvCodecContext->codec_type = AVMEDIA_TYPE_VIDEO;
pAvCodecContext->width = w;
......@@ -273,7 +274,7 @@ int Record::WriteBuffer(unsigned char* pBuffer, long& size)
else
{
pYUVFrame->pts = iPTS;
iPTS += CLOCKHZ / FrameRate;
iPTS += CLOCKHZ / Settings::FrameRate;
}
......
#include "Record/RecordStore.h"
#include "Record/RecordThread.h"
#include "Utils/Settings.h"
extern int FrameRate;
extern int RecordStoreDuration;
//extern int FrameRate;
//extern int RecordStoreDuration;
RecordStore::RecordStore()
{
max_size = RecordStoreDuration * FrameRate / 1000;
max_size = Settings::RecordStoreDuration * Settings::FrameRate / 1000;
}
RecordStore::~RecordStore()
......@@ -17,7 +18,7 @@ RecordStore::~RecordStore()
void RecordStore::RecvFrame(const std::shared_ptr<videoFrameData>& frame)
{
if(frame && frame->data)
//if(frame && frame->data)
{
std::lock_guard<std::mutex> lock(mutex);
video_map.insert({ frame->timestamp,frame });
......
......@@ -27,15 +27,17 @@ int RecordThread::Init(const int& w, const int& h, const AVPixelFormat& fmt, con
void RecordThread::run()
{
//qDebug() << save_path.c_str() <<" start record time:"<< GetCurrDateTimeStr() << "\n";
auto t1 = TimeMilliSecond();
std::shared_ptr<videoFrameData> frame;
while (video_queue.Size())
{
video_queue.Pop(frame);
uint8_t* data = frame->data;
long size = frame->size;
auto data = frame->uyvy_data;
long size = frame->uyvy_size;
ptr_record->WriteBuffer(data, size);
}
ptr_record->Close();
qDebug() << save_path.c_str() << " record duration time:" << TimeMilliSecond() - t1 << "\n";
//delete this;
}
\ No newline at end of file
......@@ -4,12 +4,12 @@
#include "Utils/yuv4k.h"
#include "Utils/Memory4k.h"
#include <omp.h>
#include "Utils/Settings.h"
#pragma intrinsic(memcpy)
extern int RecordFlag;
extern int OpenOMP;
//extern int RecordFlag;
//extern int OpenOMP;
static int64_t GetCurrTimeMS()
{
......@@ -37,7 +37,7 @@ CaptureThread::CaptureThread()
m_lastRecvTS(TimeMilliSecond())
//taskQueue(std::string("task")+ std::to_string(idx))
{
if (!bgra_4k_data) bgra_4k_data = new uint8_t[3840 * 2160 << 2];
//if (!bgra_4k_data) bgra_4k_data = new uint8_t[3840 * 2160 << 2];
//idx = s_count++;
//m_scale = new VideoScale(3840, 2160, AV_PIX_FMT_UYVY422, 3840, 2160, AV_PIX_FMT_BGRA);
//HRESULT result = CoCreateInstance(CLSID_CDeckLinkVideoConversion, nullptr, CLSCTX_ALL, IID_IDeckLinkVideoConversion, (void**)deckVideoConversion.GetAddressOf());
......@@ -78,12 +78,12 @@ void CaptureThread::AddFrame(ComPtr<IDeckLinkVideoInputFrame> videoFrame, const
/*std::shared_ptr<videoFrameData> videoFrame1 = std::make_shared<videoFrameData>(videoFrame, timestamp, timestamp);
if (NDIOutput) NDIOutput->AddFrame(videoFrame1);*/
if (video_data && video_data->data) taskVideoQueue.Push(video_data);
if (video_data && video_data->uyvy_data) taskVideoQueue.Push(video_data);
if (RecordFlag && RecordStorePtr && !replay_flag) {
/*if (RecordFlag && RecordStorePtr && (replay_status == RS_IDEL || replay_status == RS_END)) {
std::shared_ptr<videoFrameData> video_frame = std::make_shared<videoFrameData>(videoFrame, sequenceNum, sequenceNum,meta);
RecordStorePtr->RecvFrame(video_frame);
}
}*/
sequenceNum++;
/*if(video_data && video_data->data)
{
......@@ -96,6 +96,10 @@ void CaptureThread::AddFrame(ComPtr<IDeckLinkVideoInputFrame> videoFrame, const
END_SLOT_TIME_COUNTER
}
void CaptureThread::RecvReplayStatus(const ReplayStatus& status)
{
replay_status = status;
}
void CaptureThread::recvReplay(bool& start)
{
......@@ -107,18 +111,21 @@ void CaptureThread::run()
{
while(true)
{
START_WAIT_TIME_COUNTER
std::shared_ptr<videoFrameData> videoFrame;
std::shared_ptr<videoFrameData> videoFrame = nullptr;
qint64 cur_time = 0;
qint64 sequence = 0;
auto t1 = TimeMilliSecond();
if (taskVideoQueue.WaitFor(videoFrame))
{
END_WAIT_TIME_COUNTER
if (videoFrame && videoFrame->data)
//qDebug() << "capture thread get frame duration:" << TimeMilliSecond() - t1 << "\n";
if (videoFrame && videoFrame->uyvy_data)
{
//auto t1 = TimeMilliSecond();
if (Settings::RecordFlag && RecordStorePtr && (replay_status == RS_IDEL || replay_status == RS_END)) {
//std::shared_ptr<videoFrameData> video_frame = std::make_shared<videoFrameData>(videoFrame, sequenceNum, sequenceNum, meta);
RecordStorePtr->RecvFrame(videoFrame);
}
//qDebug() << videoFrame->sequenceNum << "capture time:" << GetCurrDateTimeStr() << "\n";
t1 = TimeMilliSecond();
if(videoFrame->fmt == bmdFormat8BitYUV || videoFrame->fmt == bmdFormat10BitYUV)
{
......@@ -131,7 +138,7 @@ void CaptureThread::run()
//qDebug() << "UYVYToARGB duration:" << TimeMilliSecond() - t1 << "\n";
//auto t2 = TimeMilliSecond();
videoFrame->size = size;
videoFrame->fmt = bmdFormat8BitBGRA;
//videoFrame->fmt = bmdFormat8BitBGRA;
if(size > videoFrame->capacity)
{
delete videoFrame->data;
......@@ -140,92 +147,56 @@ void CaptureThread::run()
}
size_t once_size = width * height;
uint32_t width_ = 1920;
uint32_t height_ = 1080;
size_t yuv_size = width_ * height_ << 1;
if (!OpenOMP)
uint32_t width_ = width >> 1;
uint32_t height_ = height >> 1;
if (!Settings::OpenOMP)
{
/*libyuv::UYVYToARGB(videoFrame->data, width << 1, bgra_4k_data, width << 2, width, height);
memcpy(videoFrame->data, bgra_4k_data, size);*/
/*uint8_t* src1 = videoFrame->data;
uint8_t* src2 = src1 + yuv_size;
uint8_t* src3 = src2 + yuv_size;
uint8_t* src4 = src3 + yuv_size;
uint8_t* dst1 = bgra_4k_data;
uint8_t* dst2 = dst1 + once_size;
uint8_t* dst3 = dst2 + once_size;
uint8_t* dst4 = dst3 + once_size;
uint8_t* dst11 = videoFrame->data;
uint8_t* dst12 = dst11 + once_size;
uint8_t* dst13 = dst12 + once_size;
uint8_t* dst14 = dst13 + once_size;
{
libyuv::UYVYToARGB(src1, width_ << 1, dst1, width_ << 2, width_, height_);
libyuv::UYVYToARGB(src2, width_ << 1, dst2, width_ << 2, width_, height_);
libyuv::UYVYToARGB(src3, width_ << 1, dst3, width_ << 2, width_, height_);
libyuv::UYVYToARGB(src4, width_ << 1, dst4, width_ << 2, width_, height_);
memcpy(dst11, dst1, once_size);
memcpy(dst12, dst2, once_size);
memcpy(dst13, dst3, once_size);
memcpy(dst14, dst4, once_size);
}*/
Yuv4k::UYVYToARGB4K(videoFrame->data, yuv_size, bgra_4k_data, once_size, width_, height_);
//auto t3 = TimeMilliSecond();
Memory::MemoryCopy4k(bgra_4k_data, videoFrame->data, once_size);
//qDebug() << "4k memcpy duration:" << TimeMilliSecond() - t3 << "\n";
size_t yuv_size = width_ * height_ << 1;
Yuv4k::UYVYToARGB4K(videoFrame->uyvy_data, yuv_size, videoFrame->data, once_size, width_, height_);
}
else
{
size_t once_size = width * height;
size_t once_size = (width * height << 1);
size_t num = size / once_size;
uint32_t width_ = 1920;
uint32_t height_ = 1080;
uint32_t width_ = width;
uint32_t height_ = (height >> 1);
size_t yuv_size = width_ * height_ << 1;
omp_set_num_threads(num);
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < num; i++)
{
auto dst = videoFrame->data + i * yuv_size;
auto src = bgra_4k_data + i * once_size;
libyuv::UYVYToARGB(dst, width_ << 1, src, width_ << 2, width_, height_);
//memcpy(dst, src, once_size);
}
#pragma omp for
for (int i = 0; i < num; i++)
#pragma omp parallel
{
auto dst = videoFrame->data + i * once_size;
auto src = bgra_4k_data + i * once_size;
//libyuv::UYVYToARGB(dst, width_ << 1, src, width_ << 2, width_, height_);
memcpy(dst, src, once_size);
#pragma omp for nowait
for (int i = 0; i < num; i++)
{
auto dst = videoFrame->data + i * once_size;
auto src = videoFrame->uyvy_data + i * yuv_size;
libyuv::UYVYToARGB(src, width_ << 1, dst, width_ << 2, width_, height_);
//qDebug() << "get omp thread id:" << omp_get_thread_num() << "\n";
//memcpy(dst, src, once_size);
}
//#pragma omp for
//for (int i = 0; i < num; i++)
//{
// auto dst = videoFrame->data + i * once_size;
// auto src = bgra_4k_data + i * once_size;
// //libyuv::UYVYToARGB(dst, width_ << 1, src, width_ << 2, width_, height_);
// memcpy(dst, src, once_size);
//}
}
}
}
//libyuv::ARGBCopy(bgra_4k_data, width << 2, videoFrame->data, width << 2, width, height);
//qDebug() << "4k memcpy duration:" << TimeMilliSecond() - t2 << "\n";
}
if (!replay_flag) {
//qDebug() << GetCurrDateTimeStr()<<" 4k yuvtobgra:" << TimeMilliSecond() - t1 << "\n";
t1 = TimeMilliSecond();
if (replay_status == RS_IDEL || replay_status == RS_END || replay_status == RS_PRE_START) {
if (NDIOutput) NDIOutput->AddFrame(videoFrame);
emit PushFrame(videoFrame);
}
......@@ -234,5 +205,6 @@ void CaptureThread::run()
}
//DEBUG_FUNCTION("taskQeueue Size: ", taskQueue.size())
}
//qDebug() << "capture thread send video duration:" << TimeMilliSecond() - t1 << "\n";
}
}
\ No newline at end of file
......@@ -2,8 +2,8 @@
#include "Utils/MaskBuffer.h"
ConsumerMqThread::ConsumerMqThread(const std::string& queue_name, const std::string& exchange_name,
const std::string& ip, const std::string& user_id, const std::string& pwd):mq_queue_name(queue_name),
mq_exchange_name(exchange_name),mq_ip(ip),mq_user_id(user_id),mq_pwd(pwd), mq_port(5672), channel_id(1)
const std::string& ip, const std::string& user_id, const std::string& pwd, Listener* listerner):mq_queue_name(queue_name),
mq_exchange_name(exchange_name),mq_ip(ip),mq_user_id(user_id),mq_pwd(pwd), mq_port(5672), channel_id(1),mq_listener(listerner)
{
}
......@@ -57,28 +57,31 @@ void ConsumerMqThread::read_msg()
{
amqp_destroy_message(&message);
continue;
}
}
//char* body = new char[message.body.len];
//memcpy(body, message.body.bytes, message.body.len);
//amqp_destroy_message(&message);
//QByteArray decode = QByteArray::fromBase64(QString(body).toLatin1());
//delete body;
std::shared_ptr<MaskBuffer> buffer = nullptr;
//std::shared_ptr<MaskBuffer> buffer = nullptr;
QByteArray array(QByteArray::fromRawData((char*)message.body.bytes, message.body.len));
QJsonDocument document = QJsonDocument::fromJson(array);
if (document.isObject())
if (mq_listener) mq_listener->OnRecvMqMsg(document);
/*if (document.isObject())
{
buffer = std::make_shared<MaskBuffer>(document);
}
amqp_destroy_message(&message);
amqp_release_buffers(mq_connection);
if (buffer && buffer->signal != -1)
{
emit PushMask(buffer);
}
}*/
amqp_destroy_message(&message);
amqp_release_buffers(mq_connection);
}
}
......
......@@ -4,6 +4,9 @@
#include "Record/RecordThread.h"
#include "Utils/SSEFunction.h"
#include "Utils/Settings.h"
#include "Utils/yuv4k.h"
#include "Network/UdpSend.h"
#include<QCoreApplication>
#include <omp.h>
......@@ -13,11 +16,10 @@
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
extern int FrameRate;
extern int FrontDeleyTime;
extern int RecordFlag;
extern int ZoomFlag;
//extern int FrameRate;
//extern int FrontDeleyTime;
//extern int RecordFlag;
//extern int TimeoutFrames;
#define USE_I422 0
#define USE_BGRA 1
......@@ -33,15 +35,6 @@ ProcessMaskThread::ProcessMaskThread()
memset(tmp_bgra, 0, K4WIDTH * K4HEIGHT << 2);
memset(tmp_alpha,0, K4WIDTH * K4HEIGHT);
if (ZoomFlag)
{
if (!zoom_thread)
{
zoom_thread = std::make_shared<ZoomThread>();
zoom_thread->start();
}
}
if (!bk_argb)
{
bk_argb = new uint8_t[K4WIDTH * K4HEIGHT << 2];
......@@ -52,11 +45,27 @@ ProcessMaskThread::ProcessMaskThread()
bk_argb_attenuate = new uint8_t[K4WIDTH * K4HEIGHT << 2];
}
if (Settings::CropFlag)
{
crop_msg = CropMessage(Settings::CropX,Settings::CropY,(CropDirection)Settings::CropDirection);
if (crop_msg.crop_x || crop_msg.crop_y)
{
crop_thread = std::thread(&ProcessMaskThread::CropScale, this);
if (!crop_data)
{
crop_data = new uint8_t[crop_msg.crop_w * crop_msg.crop_h << 2];
}
}
}
}
ProcessMaskThread:: ~ProcessMaskThread()
{
if (tmp_bgra) delete tmp_bgra;
if (tmp_alpha) delete tmp_alpha;
if (bk_argb) delete bk_argb;
if (bk_argb_attenuate) delete bk_argb_attenuate;
if (crop_data) delete crop_data;
}
void ProcessMaskThread::addMaskBuffer(std::shared_ptr<MaskBuffer> buffer)
......@@ -76,6 +85,11 @@ void ProcessMaskThread::addMaskBuffer(std::shared_ptr<MaskBuffer> buffer)
void ProcessMaskThread::AddFrame(std::shared_ptr<videoFrameData> frame_data)
{
/*if (last_recv_ts)
{
qDebug() << "ProcessMaskThread:AddFrame:" << frame_data->timestamp << ",last_time_duration:" << TimeMilliSecond() - last_recv_ts << "\n";
}
last_recv_ts = TimeMilliSecond();*/
if(frame_data && frame_data->data)
{
taskImageQueue.Push(frame_data);
......@@ -95,13 +109,13 @@ void ProcessMaskThread::run()
void ProcessMaskThread::process()
{
int min_size = FrontDeleyTime * FrameRate / 1000;
int min_size = Settings::FrontDeleyTime * Settings::FrameRate / 1000;
qint64 timestamp = 0;
while (true)
{
std::shared_ptr<videoFrameData> image = nullptr;
if (taskImageQueue.WaitFor() && taskImageQueue.Size() >= min_size)//有横屏数据了
if (taskImageQueue.WaitFor(min_size - 1) /*&& taskImageQueue.Size() >= min_size*/)//有横屏数据了
{
if (taskImageQueue.Front(image))
{
......@@ -111,10 +125,10 @@ void ProcessMaskThread::process()
continue;
}
}
timestamp = image->timestamp;
timestamp = (image->replaySeq ? image->replaySeq : image->timestamp);
//auto sequence = image->sequenceNum;
//seqnum = sequence;
//qDebug() << "process mask process:" << timestamp << ",cur_time:" << GetCurrDateTimeStr() << "\n";
//qDebug() << GetCurrDateTimeStr()<<":process mask thread frame timestamp->" << timestamp << "\n";
auto itor = mask_map.find(timestamp);
if (itor != mask_map.end())
......@@ -141,7 +155,7 @@ void ProcessMaskThread::process()
}
}
while (taskImageQueue.Size() > (FrontDeleyTime * FrameRate / 1000 + 1 * FrameRate))
while (taskImageQueue.Size() > (Settings::FrontDeleyTime * Settings::FrameRate / 1000 + 1 * Settings::FrameRate))
{
qDebug() << "lost video frame-----------" << "\n";
taskImageQueue.Pop();
......@@ -170,6 +184,42 @@ void ProcessMaskThread::blend(uint8_t* src_argb, int& src_stride_width, uint8_t*
}
void ProcessMaskThread::CropScale()
{
while (true)
{
std::shared_ptr<VideoFrameWithMask> p_frame = nullptr;
if (crop_queue.WaitFor(p_frame))
{
if (p_frame)
{
uint8_t* bgra_data = NULL;
if (p_frame->fmt_ == bmdFormat8BitBGRA && p_frame->data_)
{
bgra_data = p_frame->data_;
//copy to crop_data
Yuv4k::ARGBCopy4k(bgra_data, crop_msg.crop_x, crop_msg.crop_y, p_frame->width_, p_frame->height_,
crop_data, crop_msg.crop_w, crop_msg.crop_h, Settings::ZoomUseOmp, Settings::ZoomScaleType);
Yuv4k::ARGBScale4K(crop_data, crop_msg.crop_w, crop_msg.crop_h,
bgra_data, p_frame->width_, p_frame->height_, Settings::ZoomUseOmp, Settings::ZoomScaleType, Settings::ZoomScaleFilter);
}
else if (p_frame->fmt_ == bmdFormat8BitYUV && p_frame->pImage && p_frame->pImage->data)
{
bgra_data = p_frame->pImage->data;
p_frame->fmt_ = bmdFormat8BitBGRA;
Yuv4k::ARGBCopy4k(bgra_data, crop_msg.crop_x, crop_msg.crop_y, p_frame->width_, p_frame->height_,
crop_data, crop_msg.crop_w, crop_msg.crop_h, Settings::ZoomUseOmp, Settings::ZoomScaleType);
Yuv4k::ARGBScale4K(crop_data, crop_msg.crop_w, crop_msg.crop_h,
bgra_data, p_frame->width_, p_frame->height_, Settings::ZoomUseOmp, Settings::ZoomScaleType, Settings::ZoomScaleFilter);
}
emit PushFrame(p_frame);
}
}
}
}
void ProcessMaskThread::workMaskModify(const std::shared_ptr<videoFrameData>& pImage, std::shared_ptr<MaskBuffer> mask_buffer, const bool& mask_flag)
{
auto startTime = TimeMilliSecond();
......@@ -182,7 +232,7 @@ void ProcessMaskThread::workMaskModify(const std::shared_ptr<videoFrameData>& pI
if (!src_bgra) return;
uint32_t width = pImage->width;
uint32_t height = pImage->height;
qint64 timestamp = pImage->timestamp;
qint64 timestamp = (pImage->replaySeq ? pImage->replaySeq : pImage->timestamp);
uint32_t crop_width = 0;
uint32_t crop_height = 0;
......@@ -280,6 +330,7 @@ void ProcessMaskThread::workMaskModify(const std::shared_ptr<videoFrameData>& pI
{
int32_t x_min = K4WIDTH, x_max = 0, y_min = K4HEIGHT, y_max = 0;
int32_t x_min_s = K4WIDTH, x_max_s = 0, y_min_s = K4HEIGHT, y_max_s = 0;
uint32_t map_size = 0;
for (auto& value : masked_map)
{
auto& mask = value.second;
......@@ -289,7 +340,7 @@ void ProcessMaskThread::workMaskModify(const std::shared_ptr<videoFrameData>& pI
auto x2 = x1 + mask->m_width;
auto y2 = y1 + mask->m_height;
map_size++;
if (1 == masked_map.size())
{
x_min = x1;
......@@ -309,7 +360,7 @@ void ProcessMaskThread::workMaskModify(const std::shared_ptr<videoFrameData>& pI
x_max = MAX(x_max, x2);
y_max = MAX(y_max, y2);
if (x1 != buffer->m_x && y1 != buffer->m_y)
if (map_size < masked_map.size())
{
x_min_s = MIN(x_min_s, x1);
y_min_s = MIN(y_min_s, y1);
......@@ -356,7 +407,7 @@ void ProcessMaskThread::workMaskModify(const std::shared_ptr<videoFrameData>& pI
bool clear_flag = false;
if (status == BS_END) status = BS_IDEL;
if (last_masked && last_masked->m_timecode < timestamp && (timestamp - last_masked->m_timecode) >= 50 && status != BS_IDEL)
if (last_masked && last_masked->m_timecode < timestamp && (timestamp - last_masked->m_timecode) >= Settings::TimeoutFrames && status != BS_IDEL)
{
memset(tmp_alpha, 0, width* height);
last_masked = nullptr;
......@@ -368,48 +419,60 @@ void ProcessMaskThread::workMaskModify(const std::shared_ptr<videoFrameData>& pI
auto map_size = masked_map.size();
if (map_size)
{
size_t src_argb_size = width * height << 2;
uint8_t* src_argb = new uint8_t[src_argb_size];
size_t dst_argb_size = width * height << 2;
uint8_t* dst_argb = new uint8_t[dst_argb_size];
auto t11 = TimeMilliSecond();
//memcpy(src_argb,src_bgra, src_argb_size);
//SSE::MemcpySSE(src_argb, src_bgra, src_argb_size);
//libyuv::ARGBCopy(src_bgra,width<<2,src_argb,width<<2,width,height);
size_t once_size = width * height;
size_t num = src_argb_size / once_size;
size_t once_size = (width * height);
size_t num = dst_argb_size / once_size;
omp_set_num_threads(num);
#pragma omp parallel
#pragma omp parallel
{
#pragma omp for
#pragma omp for nowait
for (int i = 0; i < num; i++)
{
auto dst = src_argb + i * once_size;
auto dst = dst_argb + i * once_size;
auto src = src_bgra + i * once_size;
memcpy(dst, src, once_size);
//SSE::MemcpySSE(dst, src, once_size);
}
}
//qDebug() << "memcpy 4k duration:" << TimeMilliSecond() - t11 << "\n";
int32_t end_flag = -11;
if (mask_buffer) end_flag = mask_buffer->signal;
if (map_size == 1 && status == BS_IDEL)
{
status = BS_START;
start_time = timestamp;
QString msg = "{\"type\":\"MaskMsg\",\"data\":{\"status\":" + QString::number(status) + ",\"timestamp\":" + QString::number(timestamp) + "}}";
UdpSend::GetInstance().SendUdpMsg(msg, Settings::UIIpAddr, QString::number(Settings::UIUdpPort));
//qDebug() << "start copy crop pic.......\n";
}
else if (end_flag == 1 && status == BS_ING)
{
status = BS_END;
clear_flag = true;
if (status == BS_END)
{
//send msg to ui with udp-protocol
QString msg = "{\"type\":\"MaskMsg\",\"data\":{\"status\":" + QString::number(status) + ",\"timestamp\":" + QString::number(timestamp) + "}}";
UdpSend::GetInstance().SendUdpMsg(msg, Settings::UIIpAddr, QString::number(Settings::UIUdpPort));
}
}
else status = BS_ING;
//libyuv::ARGBBlend(bk_argb_attenuate, width << 2, src_argb , width << 2, src_argb, width << 2, width, height);
uint32_t offset_b = (mask_rect.y * width << 2) + (mask_rect.x << 2);
libyuv::ARGBBlend(bk_argb + offset_b, width << 2, src_argb + offset_b, width << 2, src_argb + offset_b, width << 2, mask_rect.width, mask_rect.height);
std::shared_ptr<VideoFrameWithMask> video_frame = std::make_shared<VideoFrameWithMask>(width, height, pImage->timestamp, pImage->sequenceNum, src_argb, status,pImage->meta_);
emit PushFrame(video_frame);
libyuv::ARGBBlend(bk_argb + offset_b, width << 2, dst_argb + offset_b, width << 2, dst_argb + offset_b, width << 2, mask_rect.width, mask_rect.height);
std::shared_ptr<VideoFrameWithMask> video_frame = std::make_shared<VideoFrameWithMask>(width, height, timestamp, pImage->sequenceNum, dst_argb, status,pImage->meta_,start_time);
if(Settings::CropFlag && (crop_msg.crop_x || crop_msg.crop_y)) crop_queue.Push(video_frame);
else
{
emit PushFrame(video_frame);
}
if (clear_flag) {
......@@ -450,8 +513,35 @@ void ProcessMaskThread::workMaskModify(const std::shared_ptr<videoFrameData>& pI
}
else
{
std::shared_ptr<VideoFrameWithMask> video_frame = std::make_shared<VideoFrameWithMask>(pImage, status);
emit PushFrame(video_frame);
//emit PushFrame(video_frame);
if (Settings::CropFlag && (crop_msg.crop_x || crop_msg.crop_y))
{
//auto t2 = TimeMilliSecond();
size_t dst_argb_size = width * height << 2;
uint8_t* dst_argb = new uint8_t[dst_argb_size];
size_t once_size = width * height;
size_t num = dst_argb_size / once_size;
omp_set_num_threads(num);
#pragma omp parallel
{
#pragma omp for nowait
for (int i = 0; i < num; i++)
{
auto dst = dst_argb + i * once_size;
auto src = src_bgra + i * once_size;
memcpy(dst, src, once_size);
}
}
std::shared_ptr<VideoFrameWithMask> video_frame_i = std::make_shared<VideoFrameWithMask>(width, height, timestamp, pImage->sequenceNum, dst_argb, status, pImage->meta_);
crop_queue.Push(video_frame_i);
//qDebug() << "memcpy duration:" << TimeMilliSecond() - t2 << "\n";
}
else
{
std::shared_ptr<VideoFrameWithMask> video_frame = std::make_shared<VideoFrameWithMask>(pImage, status);
emit PushFrame(video_frame);
}
//qDebug() << "process mask frame:" << video_frame->timestamp_ << ",cur_time:" << GetCurrDateTimeStr() << "\n";
}
......@@ -1470,7 +1560,7 @@ void ProcessMaskThread::StartRecord(const uint64_t& start_time, const uint64_t&
void ProcessMaskThread::StartRecord_(const uint32_t& w, const uint32_t& h, const int32_t& fmt,const uint64_t& start_time, const uint64_t& end_time, const std::string& path)
{
if(p_store)
{
{
RecordThread* record = new RecordThread();
bool ret = p_store->SendDurationVideo(record, start_time - 3, end_time + 3);
if (!ret)
......
......@@ -2,21 +2,153 @@
#include "opencv2/opencv.hpp"
#include "libyuv.h"
#include "Utils//Common.h"
#include "Utils/Settings.h"
#define CUTBUFFERMAXSIZE 125*2
int ProcessThread::s_count = 0;
//extern int OutputDeleyTime;
extern int FrameRate;
extern int FrontDeleyTime;
//extern int BlackBottomHeight;
//extern int ScaleMode;
//extern std::map<qint32, qint32> map_output_delay;
extern bool HaveBlackDataFlag;
//extern int FrameRate;
//extern int FrontDeleyTime;
//extern bool HaveBlackDataFlag;
extern std::map<qint32, qint32> map_scale_mode;
RoiMessage::RoiMessage() : h(CROPHEIGHT)
{
w = h * Settings::AspecDen / Settings::AspecNum;
w += w % 2;
x = 1920 / 2 - w / 2;
y = 1080 / 2 - h / 2;
centerX = 1920 / 2;
centerY = 0;
timecode = 0;
}
RoiMessage::RoiMessage(QByteArray& data)
{
QJsonDocument document = QJsonDocument::fromJson(data);
QJsonObject object;
if (document.isObject())
{
object = document.object();
mode = object.value("signal").toString();
QJsonArray roi = object.value("roi").toArray();
int minx = roi[0].toInt();
int miny = roi[1].toInt();
int maxx = roi[2].toInt();
int maxy = roi[3].toInt();
id = object.value("id").toInt();
centerX = object.value("center_x").toInt();
centerY = object.value("center_y").toInt();
width = object.value("width").toInt();
height = object.value("height").toInt();
timecode = QString::number(object.value("timecode").toDouble(), 'f', 0).toLongLong();
h = CROPHEIGHT;
w = h * Settings::AspecDen / Settings::AspecNum;
x = minx;
y = miny;
}
}
RoiMessage::RoiMessage(QByteArray&& data)
{
QJsonDocument document = QJsonDocument::fromJson(data);
QJsonObject object;
if (document.isObject())
{
object = document.object();
mode = object.value("signal").toString();
QJsonArray roi = object.value("roi").toArray();
int minx = roi[0].toInt();
int miny = roi[1].toInt();
int maxx = roi[2].toInt();
int maxy = roi[3].toInt();
id = object.value("id").toInt();
centerX = object.value("center_x").toInt();
centerY = object.value("center_y").toInt();
width = object.value("width").toInt();
height = object.value("height").toInt();
timecode = QString::number(object.value("timecode").toDouble(), 'f', 0).toLongLong();
h = CROPHEIGHT;
w = h * Settings::AspecDen / Settings::AspecNum;
x = minx;
y = miny;
}
}
RoiMessage::RoiMessage(const RoiMessage& other) : x(other.x), y(other.y), w(other.w), h(other.h),
timecode(other.timecode), centerX(other.centerX), centerY(other.centerY)
{
}
RoiMessage::RoiMessage(RoiMessage&& other)
{
x = other.x;
y = other.y;
w = other.w;
h = other.h;
timecode = other.timecode;
centerX = other.centerX;
centerY = other.centerY;
}
RoiMessage RoiMessage::operator=(const RoiMessage& other)
{
x = other.x;
y = other.y;
w = other.w;
h = other.h;
timecode = other.timecode;
centerX = other.centerX;
centerY = other.centerY;
return *this;
}
RoiMessage RoiMessage::operator=(RoiMessage&& other)
{
x = other.x;
y = other.y;
w = other.w;
h = other.h;
timecode = other.timecode;
centerX = other.centerX;
centerY = other.centerY;
return *this;
}
RoiMessage::RoiMessage(int X, int Y, int W, int H)
:x(X),
y(Y),
w(W),
h(H),
timecode(0) {}
bool RoiMessage::IsValid()
{
return x > 0 && y > 0 && w > 0 && h > 0;
}
void RoiMessage::SetX(int x_)
{
this->x = x_;
}
int RoiMessage::X() { return x; }
int RoiMessage::Y() { return y; }
int RoiMessage::CenterX() { return centerX; }
int RoiMessage::CenterY() { return centerY; }
int RoiMessage::Width() { return w; }
int RoiMessage::Height() { return h; }
qint64 RoiMessage::Timecode() { return timecode; }
ProcessThread::ProcessThread()
: sendFrames(0),
......@@ -30,7 +162,7 @@ ProcessThread::ProcessThread()
idx = s_count++;
int key = idx + 1;
//output_deley_time = map_output_delay[key];
minTaskImageQueueSize = FrontDeleyTime / 1000 * FrameRate;
minTaskImageQueueSize = Settings::FrontDeleyTime / 1000 * Settings::FrameRate;
}
ProcessThread::~ProcessThread()
......@@ -80,6 +212,8 @@ void ProcessThread::AddFrame(std::shared_ptr<videoFrameData> frame_data)
// END_SLOT_TIME_COUNTER
//}
void ProcessThread::ReadDatagramsNew()
{
START_SLOT_TIME_COUNTER
......@@ -175,7 +309,7 @@ void ProcessThread::ReadDatagrams()
void ProcessThread::cutRunFront()
{
bool continue_flag = false;
int min_size = FrontDeleyTime * FrameRate / 1000;
int min_size = Settings::FrontDeleyTime * Settings::FrameRate / 1000;
qint64 seqnum = 0;
while (true)
{
......@@ -310,9 +444,9 @@ void ProcessThread::cutRunFront()
{
qDebug() << "idx:" << idx << "taskImageQueue size:"<< taskImageQueue.Size() <<",min_size:"<< min_size << endl;
}*/
while (taskImageQueue.Size() > (FrameRate * (output_deley_time / 1000 + FrontDeleyTime / 1000)))
while (taskImageQueue.Size() > (Settings::FrameRate * (output_deley_time / 1000 + Settings::FrontDeleyTime / 1000)))
{
qDebug() << "idx:" << idx << ",----------------lost Image size:" << taskImageQueue.Size() - FrameRate * (output_deley_time / 1000 + FrontDeleyTime / 1000) << endl;
qDebug() << "idx:" << idx << ",----------------lost Image size:" << taskImageQueue.Size() - Settings::FrameRate * (output_deley_time / 1000 + Settings::FrontDeleyTime / 1000) << endl;
taskImageQueue.Pop(image);
}
if (cutRuleMap.size() > CUTBUFFERMAXSIZE)
......@@ -580,9 +714,9 @@ void ProcessThread::WorkCutImage(std::shared_ptr<videoFrameData>& pImage, RoiMes
int dstw = 1920, dsth = 1080, scalew = 0, scaleh = 1080;
uint8_t* buff3 = NULL;
if (HaveBlackDataFlag)
if (Settings::HaveBlackDataFlag)
{
scalew = AspecNum * scaleh / AspecDen;
scalew = Settings::AspecNum * scaleh / Settings::AspecDen;
uint8_t* buff2 = new uint8_t[scalew * scaleh << 1];
uint8_t* scale_buffer_y = buff2;
uint8_t* scale_buffer_u = scale_buffer_y + scalew * scaleh;
......@@ -776,9 +910,9 @@ void ProcessThread::WorkCutImage(std::shared_ptr<Image>& pImage, RoiMessage& roi
int dstw = 1920, dsth = 1080, scalew = 0, scaleh = 1080;
uint8_t* buff3 = NULL;
if (HaveBlackDataFlag)
if (Settings::HaveBlackDataFlag)
{
scalew = AspecNum * scaleh / AspecDen;
scalew = Settings::AspecNum * scaleh / Settings::AspecDen;
uint8_t* buff2 = new uint8_t[scalew * scaleh << 2];
libyuv::ARGBScale(buff1, (roi.Height() << 2 << 1), roi.Height() << 1, roi.Width() << 1,
buff2, scalew << 2, scalew, scaleh, libyuv::FilterMode::kFilterNone);
......
#include "Threads/ReplayThread.h"
#include "Utils/Settings.h"
#include "Network/UdpSend.h"
extern int ReplayStoreTime;
extern int FrameRate;
//extern int ReplayStoreTime;
//extern int FrameRate;
ReplayThread::ReplayThread()
{
max_store_size = ReplayStoreTime / 1000 * FrameRate;
interval = 1000 / FrameRate;
max_store_size = Settings::ReplayStoreTime / 1000 * Settings::FrameRate;
interval = 1000 / Settings::FrameRate;
}
ReplayThread::~ReplayThread()
......@@ -18,106 +20,179 @@ void ReplayThread::addFrame(std::shared_ptr<videoFrameData> frameData)
{
if(frameData && frameData->data)
{
//qDebug()<< frameData->sequenceNum << "replay time:" << GetCurrDateTimeStr() << "\n";
{
std::unique_lock<std::mutex> ulock(mutex);
if(!replay_flag) storeVideoMap.insert({ frameData->timestamp,frameData });
if(storeVideoMap.size() > max_store_size)
{
current_seq = frameData->sequenceNum;
if (replay_params.status == RS_IDEL || replay_params.status == RS_END) storeVideoMap.insert({ frameData->timestamp,frameData });
if (storeVideoMap.size() > max_store_size)
{
storeVideoMap.erase(storeVideoMap.begin()->first);
}
if (replay_flag) {
if ((replay_params.status == RS_START || replay_params.status == RS_RE_START)) {
cv.notify_all();
}
}
}
}
void ReplayThread::recvReplayParams(ReplayParams& params, bool& flag)
void ReplayThread::recvReplayParams(const ReplayParams& params)
{
std::unique_lock<std::mutex> ulock(mutex);
replay_params = params;
if(replay_flag != flag) replay_flag = flag;
if(flag && !replayVideoVec.empty())
//if(replay_flag != flag) replay_flag = flag;
if((replay_params.status == RS_START || replay_params.status == RS_RE_START) && !replayVideoVec.empty())
{
replay_position = 0;
}
}
bool ReplayThread::CanReplay(const ReplayParams& params)
{
auto& start_time = params.start_time;
auto& end_time = params.end_time;
{
std::unique_lock<std::mutex> ulock(mutex);
if (end_time <= start_time ||
storeVideoMap.find(start_time) == storeVideoMap.end() ||
storeVideoMap.find(end_time) == storeVideoMap.end())
{
replay_params.status = RS_END;
return false;
}
else return true;
}
}
void ReplayThread::run()
{
std::shared_ptr<videoFrameData> resend_frame = nullptr;
qint32 resend_num = 0;
qint64 resend_tm = 0;
bool resend_start = false;
while (true)
{
{
std::unique_lock<std::mutex> ulock(mutex);
cv.wait(ulock);
if(last_replay_params.start_time != replay_params.start_time ||
last_replay_params.end_time != replay_params.end_time)
}
if (last_replay_params.start_time != replay_params.start_time ||
last_replay_params.end_time != replay_params.end_time)
{
/*std::queue<std::shared_ptr<videoFrameData>> empty;
if (!replayVideoQueue1.empty()) std::swap(empty, replayVideoQueue1);
if (!replayVideoQueue2.empty()) std::swap(empty, replayVideoQueue2);*/
if (!replayVideoVec.empty()) std::vector<std::shared_ptr<videoFrameData>>().swap(replayVideoVec);
replay_position = 0;
last_replay_params = replay_params;
}
if (replayVideoVec.empty())
{
//qint32 frame_nums = replay_params.end_time - replay_params.end_time + 1;
//auto t1 = TimeMilliSecond();
auto tm_begin = replay_params.start_time - Settings::ReplayForward;
auto tm_end = replay_params.end_time + Settings::ReplayDeley;
auto begin_tm = storeVideoMap.begin()->first;
auto end_tm = storeVideoMap.rbegin()->first;
if (tm_begin < begin_tm) tm_begin = begin_tm;
if (tm_end > end_tm) tm_end = end_tm;
size_t size = tm_end - tm_begin + 1;
/*auto& tm_end = replay_params.end_time;
auto& tm_begin = replay_params.start_time;*/
auto itor_end = storeVideoMap.find(tm_end);
auto itor_begin = storeVideoMap.find(tm_begin);
if (itor_end == storeVideoMap.end() || itor_begin == storeVideoMap.end() || tm_end <= tm_begin)
{
/*std::queue<std::shared_ptr<videoFrameData>> empty;
if (!replayVideoQueue1.empty()) std::swap(empty, replayVideoQueue1);
if (!replayVideoQueue2.empty()) std::swap(empty, replayVideoQueue2);*/
if(!replayVideoVec.empty()) std::vector<std::shared_ptr<videoFrameData>>().swap(replayVideoVec);
replay_position = 0;
last_replay_params = replay_params;
qint32 errNo = (itor_end == storeVideoMap.end() ? 2 : (itor_begin == storeVideoMap.end() ? 1 : 3));
QString msg = "{\"type\":\"ReplayResp\",\"data\":{\"inTime\":" + QString::number(replay_params.start_time) +",\"outTime\":" + QString::number(replay_params.end_time) +
",\"status\":0,\"errNo\":" + QString::number(errNo) +"}}";
UdpSend::GetInstance().SendUdpMsg(msg, Settings::UIIpAddr, QString::number(Settings::UIUdpPort));
qDebug() << "replay fail,errno:"<<errNo << "\n";
continue;
}
if(replayVideoVec.empty())
bool first = true;
resend_frame = nullptr;
resend_num = (Settings::SDIOneFrameDuration > Settings::SDIOneFrameDuration ? Settings::SDIOneFrameDuration : Settings::SDIOneFrameDuration);
for (auto itor = itor_begin;; itor++)
{
//qint32 frame_nums = replay_params.end_time - replay_params.end_time + 1;
auto& tm_end = replay_params.end_time;
auto& tm_begin = replay_params.start_time;
auto itor_end = storeVideoMap.find(tm_end);
auto itor_begin = storeVideoMap.find(tm_begin);
if(itor_end == storeVideoMap.end() || itor_begin == storeVideoMap.end() || tm_end <= tm_begin)
{
qDebug() << "replay fail ..................." << "\n";
continue;
}
for (auto itor = itor_begin;; itor++)
replayVideoVec.emplace_back(itor->second);
if (itor->first > replay_params.end_time && first)
{
replayVideoVec.emplace_back(itor->second);
if (itor == itor_end)
{
break;
}
resend_frame = itor->second;
first = false;
}
//replay_position = replayVideoVec.size() - 1;
/*auto itor_top = storeVideoMap.lower_bound(tm_top);
if(itor_tail == storeVideoMap.end() || itor_top == storeVideoMap.end())
{
qDebug() << "replay fail ..................." << "\n";
continue;
if (itor == itor_end)
{
break;
}
tm_top = itor_top->first;
tm_tail = itor_tail->first;
}
if (replayVideoVec.size() != size)
{
qDebug() << "replay find size err ..................." << "\n";
}
for(auto itor = itor_top;itor != itor_tail;itor++)
{
replayVideoVec.emplace_back(itor->second);
}
replayVideoVec.emplace_back(itor_top->second);*/
//qDebug() << "replay find duration:" << TimeMilliSecond() - t1 << "\n";
//replay_position = replayVideoVec.size() - 1;
/*auto itor_top = storeVideoMap.lower_bound(tm_top);
if(itor_tail == storeVideoMap.end() || itor_top == storeVideoMap.end())
{
qDebug() << "replay fail ..................." << "\n";
continue;
}
tm_top = itor_top->first;
tm_tail = itor_tail->first;
for(auto itor = itor_top;itor != itor_tail;itor++)
{
replayVideoVec.emplace_back(itor->second);
}
replayVideoVec.emplace_back(itor_top->second);*/
}
if (!replayVideoVec.empty())
{
std::shared_ptr<videoFrameData> frame = nullptr;
frame = (resend_frame ? (resend_start ? resend_frame : replayVideoVec[replay_position] ) : replayVideoVec[replay_position]);
frame->replaySeq = current_seq;
emit PushFrame(frame);
if ((!resend_start || !resend_frame) && replay_position < (replayVideoVec.size() - 1)) replay_position++;
if (!replayVideoVec.empty())
if (resend_frame)
{
auto frame = replayVideoVec[replay_position];
emit PushFrame(frame);
if(replay_position < (replayVideoVec.size() - 1)) replay_position++;
/*if (replay_position == 0)
if (resend_start && resend_num) resend_num--;
if (!resend_start && resend_num && frame->timestamp == resend_frame->timestamp)
{
resend_start = true;
}
if (resend_num <= 0 && resend_start)
{
replay_position = replayVideoVec.size();
}*/
//if(replay_position > replayVideoVec.size() - 1) replay_position++;
//else {
// //TODO 此处主要针对当次replay到最后一帧之后就结束发送数据 需要实际测试此处的情况
// replay_position = 0;//这个是为了下次还是重复当次的数据用
// //if (replay_flag) replay_flag = false; //这个是避免在不知道播控情况下 重头开始发送数据
//}
resend_start = false;
resend_num = (Settings::SDIOneFrameDuration > Settings::SDIOneFrameDuration ? Settings::SDIOneFrameDuration : Settings::SDIOneFrameDuration);
}
}
//qDebug() << "replay time:" << GetCurrDateTimeStr() << ",send frame timecode:" << frame->timestamp << ",replayseq:" << frame->replaySeq << "\n";
/*if (replay_position == 0)
{
replay_position = replayVideoVec.size();
}*/
//if(replay_position > replayVideoVec.size() - 1) replay_position++;
//else {
// //TODO 此处主要针对当次replay到最后一帧之后就结束发送数据 需要实际测试此处的情况
// replay_position = 0;//这个是为了下次还是重复当次的数据用
// //if (replay_flag) replay_flag = false; //这个是避免在不知道播控情况下 重头开始发送数据
//}
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -11,37 +11,43 @@
#include "Utils/Image.h"
#include "DeckLinkAPI.h"
#include "Utils/Common.h"
#include "Utils/Settings.h"
#include "Network/UdpSend.h"
//int OutputDeleyTime = 5;
int ReplayStoreTime = 10000;//单位ms
int FrontDeleyTime = 3000;//单位ms
int FrameRate = 50;
//int PrvwFlag = 0;
int OutputPlayMode = 0;
//int BlackBottomHeight = 240;
int AudioChannel = 2;
int ScaleMode = 0;
qint64 StartTimeStamp = 0;
//std::map<qint32, qint32> map_output_delay;
std::map<qint32, qint32> map_scale_mode;
int AspecNum = 0;
int AspecDen = 0;
bool HaveBlackDataFlag = true;
int ZoomFlag = 0;
float ZoomScale = 1.0;
int ZoomInDuration = 0;
int ZoomOutDuration = 0;
int ZoomMoveDuration = 0;
int OneFrameDuration = 50; //FOR NDI
int SDIOneFrameDuration = 50; //FOR SDI
int RecordStoreDuration = 10000;
int RecordFlag = 0;
int OpenOMP = 1;
int main_ver = 1;
int mid_ver = 0;
int small_ver = 1;
int main_ver = 2;
int mid_ver = 1;
int small_ver = 0;
//int ReplayStoreTime = 10000;//单位ms
//int FrontDeleyTime = 3000;//单位ms
//int FrameRate = 50;
//int OutputPlayMode = 0;
//int AudioChannel = 2;
//int ScaleMode = 0;
//int AspecNum = 0;
//int AspecDen = 0;
//bool HaveBlackDataFlag = true;
//int DrawFlag = 0;
//int ZoomFlag = 0;
//float ZoomScale = 1.0;
//int ZoomScaleN = 1;
//int ZoomScaleD = 2;
//int ZoomInDuration = 0;
//int ZoomOutDuration = 0;
//int ZoomMoveDuration = 0;
//int OneFrameDuration = 50; //FOR NDI
//int SDIOneFrameDuration = 50; //FOR SDI
//int RecordStoreDuration = 10000;
//int RecordFlag = 0;
//int OpenOMP = 1;
//int TimeoutFrames = 50;
//int SdiOutWaitNums = 100;
namespace
{
......@@ -61,10 +67,12 @@ MomentaMedia::MomentaMedia(QWidget *parent)
setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
InputDevicePages[0] = ui.devicePage1;
//InputDevicePages[1] = NULL;
InputDevicePages[1] = ui.devicePage2;
//InputDevicePages[2] = ui.devicePage3;
//InputDevicePages[3] = ui.devicePage4;
OutputDevicePages[0] = ui.deviceOutputPage3;
//OutputDevicePages[1] = NULL;
OutputDevicePages[1] = ui.deviceOutputPage4;
//OutputDevicePages[2] = ui.deviceOutputPage3;
//OutputDevicePages[3] = ui.deviceOutputPage4;
......@@ -84,7 +92,7 @@ MomentaMedia::MomentaMedia(QWidget *parent)
connect(DeleyTimeEdit,&QLineEdit::textChanged,this,&MomentaMedia::DeleyTimeTextChanged);*/
UdpSend::GetInstance().start();
QSize previewViewSize = ui.previewContainer->size();
PreviewLayout = new QGridLayout(ui.previewContainer);
......@@ -95,6 +103,7 @@ MomentaMedia::MomentaMedia(QWidget *parent)
for(size_t i = 0; i < InputDevicePages.size(); i++)
{
if (!InputDevicePages[i]) continue;
InputDevicePages[i]->SetPreviewSize(previewViewSize, i);
PreviewLayout->addWidget(InputDevicePages[i]->GetPreviewView(), (int)i / 2, (int)i % 2);
......@@ -105,6 +114,7 @@ MomentaMedia::MomentaMedia(QWidget *parent)
for(size_t i = 0; i < OutputDevicePages.size(); i++)
{
if (!OutputDevicePages[i]) continue;
OutputDevicePages[i]->SetPreviewSize(previewViewSize);
PreviewLayout->addWidget(OutputDevicePages[i]->GetPreviewView(), (int)i / 2 + 1, (int)i % 2);
......@@ -159,7 +169,7 @@ MomentaMedia::MomentaMedia(QWidget *parent)
PicAspectCombo->addItem(STR1B1);
connect(PicAspectCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MomentaMedia::PicAspectChanged);
auto selectText = std::to_string(AspecNum) + ":" + std::to_string(AspecDen);
auto selectText = std::to_string(Settings::AspecNum) + ":" + std::to_string(Settings::AspecDen);
for (int idx = 0; idx < PicAspectCombo->count(); idx++) {
QString itemName = PicAspectCombo->itemText(idx);
if (selectText == itemName.toStdString())
......@@ -334,7 +344,7 @@ void MomentaMedia::AddDevice(ComPtr<IDeckLink>& deckLink)
InputDevices[deckLink] = (active ? DeviceState::Available : DeviceState::Inactive);
for (auto& devicePage : InputDevicePages)
devicePage->AddDevice(deckLink, active);
if(devicePage) devicePage->AddDevice(deckLink, active);
// Get the profile manager interface
// Will return S_OK when the device has > 1 profiles
......@@ -351,7 +361,7 @@ void MomentaMedia::AddDevice(ComPtr<IDeckLink>& deckLink)
OutputDevices[deckLink] = (active ? DeviceState::Available : DeviceState::Inactive);
for (auto& devicePage : OutputDevicePages)
devicePage->AddDevice(deckLink, active);
if(devicePage) devicePage->AddDevice(deckLink, active);
// Get the profile manager interface
// Will return S_OK when the device has > 1 profiles
......@@ -490,6 +500,7 @@ void MomentaMedia::RequestInputDevice(DeckLinkInputPage* page, ComPtr<IDeckLink>
START_SLOT_TIME_COUNTER
for(auto& devicePage : InputDevicePages)
{
if (!devicePage) continue;
// Check each page (except itself) and stop/release device if already selected
if(devicePage == page)
continue;
......@@ -508,6 +519,7 @@ void MomentaMedia::RequestInputDeviceIfAvailable(DeckLinkInputPage* page, ComPtr
for(auto & devicePage : InputDevicePages)
{
// Check each page (except itself) to see if device is already selected
if (!devicePage) continue;
if(devicePage == page)
continue;
......@@ -537,6 +549,7 @@ void MomentaMedia::RequestOutputDevice(DeckLinkOutputPage* page, ComPtr<IDeckLin
START_SLOT_TIME_COUNTER
for(auto& devicePage : OutputDevicePages)
{
if (!devicePage) continue;
// Check each page (except itself) and stop / release device if already selected
if(devicePage == page)
continue;
......@@ -554,6 +567,7 @@ void MomentaMedia::RequestOutputDeviceIfAvailable(DeckLinkOutputPage* page, ComP
START_SLOT_TIME_COUNTER
for(auto & devicePage : OutputDevicePages)
{
if (!devicePage) continue;
// Check each page (except itself) to see if device is already selected
if(devicePage == page)
continue;
......@@ -692,25 +706,25 @@ void MomentaMedia::ReadSettings()
/*OutputDeleyTime = settings.value("DELEY_TIME", "").toInt();
if (OutputDeleyTime < 1 * 1000) OutputDeleyTime = 1 * 1000;
else if (OutputDeleyTime > 20 * 1000) OutputDeleyTime = 20 * 1000;*/
ReplayStoreTime = settings.value("REPLAY_STORE_TIME","").toInt();
if (ReplayStoreTime < 0) ReplayStoreTime = 10000;
Settings::ReplayStoreTime = settings.value("REPLAY_STORE_TIME","").toInt();
if (Settings::ReplayStoreTime < 0) Settings::ReplayStoreTime = 10000;
FrontDeleyTime = settings.value("FRONT_DELEY_TIME", "").toInt();
if (FrontDeleyTime < 0 ) FrontDeleyTime = 1000;
Settings::FrontDeleyTime = settings.value("FRONT_DELEY_TIME", "").toInt();
if (Settings::FrontDeleyTime < 0 ) Settings::FrontDeleyTime = 1000;
FrameRate = settings.value("FRAME_RATE", "").toInt();
if (FrameRate < 25) FrameRate = 25;
Settings::FrameRate = settings.value("FRAME_RATE", "").toInt();
if (Settings::FrameRate < 25) Settings::FrameRate = 25;
/*BlackBottomHeight = settings.value("BLACK_BOTTOM_HEIGHT").toInt();
if (BlackBottomHeight < 0) BlackBottomHeight = 0;
else if (BlackBottomHeight > 480) BlackBottomHeight = 480;*/
AudioChannel = settings.value("AUDIO_CHANNEL").toInt();
if (AudioChannel <= 0 || AudioChannel > 20) AudioChannel = 2;
Settings::AudioChannel = settings.value("AUDIO_CHANNEL","2").toInt();
//if (Settings::AudioChannel <= 0 || AudioChannel > 20) AudioChannel = 2;
//PrvwFlag = settings.value("PRVW_FLAG", "").toInt();
OutputPlayMode = settings.value("OUTPUT_PLAY_MODE", "").toInt();
Settings::OutputPlayMode = settings.value("OUTPUT_PLAY_MODE", "").toInt();
//for(int i = 1;i <= 4;i++)
//{
......@@ -721,9 +735,9 @@ void MomentaMedia::ReadSettings()
// map_output_delay[i] = value;
//}
ScaleMode = settings.value("SCALE_MODE", "").toInt();
if (ScaleMode < 0) ScaleMode = 0;
else if (ScaleMode > 3) ScaleMode = 3;
Settings::ScaleMode = settings.value("SCALE_MODE", "").toInt();
if (Settings::ScaleMode < 0) Settings::ScaleMode = 0;
else if (Settings::ScaleMode > 3) Settings::ScaleMode = 3;
for (int i = 1;i <= 4;i++)
{
std::string key = "SCALE_MODE_" + std::to_string(i);
......@@ -733,24 +747,50 @@ void MomentaMedia::ReadSettings()
map_scale_mode[i] = value;
}
AspecNum = settings.value("ASPEC_NUM", "").toInt();
AspecDen = settings.value("ASPEC_DEN", "").toInt();
auto selectText = std::to_string(AspecNum) + ":" + std::to_string(AspecDen);
if (selectText == STR16B9) HaveBlackDataFlag = false;
Settings::AspecNum = settings.value("ASPEC_NUM", "").toInt();
Settings::AspecDen = settings.value("ASPEC_DEN", "").toInt();
auto selectText = std::to_string(Settings::AspecNum) + ":" + std::to_string(Settings::AspecDen);
if (selectText == STR16B9) Settings::HaveBlackDataFlag = false;
//qDebug() << "deleyTime=" << deleyTime << endl;
ZoomFlag = settings.value("ZOOM_FLAG", "").toInt();
ZoomScale = settings.value("ZOOM_SCALE", "").toFloat();
ZoomInDuration = settings.value("ZOOM_IN_D", "").toInt();
ZoomOutDuration = settings.value("ZOOM_OUT_D", "").toInt();
ZoomMoveDuration = settings.value("ZOOM_MOVE_D", "").toInt();
OneFrameDuration = settings.value("NDIONEFRAMEDURATION").toInt();
RecordStoreDuration = settings.value("RECORD_STORE_TIME").toInt();
RecordFlag = settings.value("RECORDFLAG").toInt();
SDIOneFrameDuration = settings.value("SDIONEFRAMEDURATION").toInt();
OpenOMP = settings.value("OPENOMP").toInt();
Settings::DrawFlag = settings.value("ZOOM_DRAW", "").toInt();
Settings::ZoomFlag = settings.value("ZOOM_FLAG", "").toInt();
Settings::ZoomScale = settings.value("ZOOM_SCALE", "").toFloat();
Settings::ZoomScaleN = settings.value("ZOOM_SCALE_N", "").toInt();
Settings::ZoomScaleD = settings.value("ZOOM_SCALE_D", "").toInt();
Settings::ZoomInDuration = settings.value("ZOOM_IN_D", "").toInt();
Settings::ZoomOutDuration = settings.value("ZOOM_OUT_D", "").toInt();
Settings::ZoomMoveDuration = settings.value("ZOOM_MOVE_D", "").toInt();
Settings::ZoomUseOmp = settings.value("ZOOM_USE_OMP", "").toInt();
Settings::ZoomScaleType = settings.value("ZOOM_SCALE_TYPE", "").toInt();
Settings::ZoomScaleFilter = settings.value("ZOOM_SCALE_FILTER", "").toInt();
Settings::ZoomInWaitCnt = settings.value("ZOOM_IN_WAIT", "25").toInt();
Settings::ZoomMoveWaitCnt = settings.value("ZOOM_MOVE_WAIT", "25").toInt();
Settings::ZoomOutWaitCnt = settings.value("ZOOM_OUT_WAIT", "25").toInt();
Settings::OneFrameDuration = settings.value("NDIONEFRAMEDURATION").toInt();
Settings::RecordStoreDuration = settings.value("RECORD_STORE_TIME").toInt();
Settings::RecordFlag = settings.value("RECORDFLAG").toInt();
Settings::SDIOneFrameDuration = settings.value("SDIONEFRAMEDURATION").toInt();
Settings::OpenOMP = settings.value("OPENOMP").toInt();
Settings::TimeoutFrames = settings.value("TIMEOUTFRAMES").toInt();
if (Settings::TimeoutFrames <= 0) Settings::TimeoutFrames = 50;
Settings::SdiOutWaitNums = settings.value("DELEYSDINUMS",100).toInt();
Settings::ReplayForward = settings.value("REPLAY_START_FORWARD", 5).toInt();
Settings::ReplayDeley = settings.value("REPLAY_END_DELEY", 5).toInt();
Settings::SDIOutputWaitNums = settings.value("SDIOUTPUTWAITNUMS", 5).toInt();
Settings::CropFlag = settings.value("CROPRECORD", 0).toInt();
Settings::CropX = settings.value("CROP_X", 0).toInt();
Settings::CropY = settings.value("CROP_Y", 0).toInt();
Settings::CropDirection = settings.value("CROP_DIRECTION",1).toInt();
Settings::UIUdpPort = settings.value("UI_UDP_PORT", 8100).toInt();
Settings::UIIpAddr = settings.value("UI_IP_ADDR", "127.0.0.1").toString();
settings.endGroup();
}
\ No newline at end of file
#include "Utils/Settings.h"
int32_t Settings::ReplayStoreTime = 10000;
int32_t Settings::FrontDeleyTime = 3000;
int32_t Settings::FrameRate = 50;
int32_t Settings::OutputPlayMode = 0;
int32_t Settings::AudioChannel = 2;
int32_t Settings::ScaleMode = 0;
int32_t Settings::AspecNum = 0;
int32_t Settings::AspecDen = 0;
int32_t Settings::OneFrameDuration = 50;
int32_t Settings::SDIOneFrameDuration = 50;
int32_t Settings::RecordStoreDuration = 10000;
int32_t Settings::RecordFlag = 0;
int32_t Settings::OpenOMP = 1;
int32_t Settings::TimeoutFrames = 50;
int32_t Settings::SdiOutWaitNums = 100;
bool Settings::HaveBlackDataFlag = false;
int32_t Settings::DrawFlag = 0;
int32_t Settings::ZoomFlag = 0;
float Settings::ZoomScale = 1.0;
int32_t Settings::ZoomScaleN = 1;
int32_t Settings::ZoomScaleD = 2;
int32_t Settings::ZoomInDuration = 0;
int32_t Settings::ZoomOutDuration = 0;
int32_t Settings::ZoomMoveDuration = 0;
int32_t Settings::ZoomUseOmp = 1;
int32_t Settings::ZoomScaleType = 3;
int32_t Settings::ZoomScaleFilter = 4;
uint32_t Settings::ZoomInWaitCnt = 0;
uint32_t Settings::ZoomMoveWaitCnt = 0;
uint32_t Settings::ZoomOutWaitCnt = 0;
uint32_t Settings::ReplayForward = 0;
uint32_t Settings::ReplayDeley = 0;
uint32_t Settings::SDIOutputWaitNums = 0;
int32_t Settings::CropFlag = 0;
int32_t Settings::CropX = 0;
int32_t Settings::CropY = 0;
int32_t Settings::CropDirection = 1;
int32_t Settings::UIUdpPort = 8100;
QString Settings::UIIpAddr = "127.0.0.1";
\ No newline at end of file
......@@ -48,10 +48,17 @@ int main(int argc, char *argv[])
tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(tmpFlag);
HANDLE hMutex = CreateMutex(NULL, TRUE, L"FigureOut");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(hMutex);//
return 0;
}
CMiniDumper dumper(false);
log_fp = fopen("MomentaMedia.log", "w");
log_fp = fopen("FigureOut.log", "w");
OrbitScope("MomentaMedia");
OrbitScope("FigureOut");
qInstallMessageHandler(myMessageOutput);
QApplication a(argc, argv);
......@@ -74,6 +81,9 @@ int main(int argc, char *argv[])
qRegisterMetaType<MaskBuffer>("MaskBuffer");
qRegisterMetaType<MaskBuffer>("MaskBuffer&"); //
qRegisterMetaType<std::shared_ptr<MaskBuffer>>("std::shared_ptr<MaskBuffer>");
qRegisterMetaType<SportAttribute>("SportAttribute");
qRegisterMetaType<SportAttribute>("SportAttribute&"); //
qRegisterMetaType<std::shared_ptr<SportAttribute>>("std::shared_ptr<SportAttribute>");
qRegisterMetaType<ReplayParams>("ReplayParams");
qRegisterMetaType<ReplayParams>("ReplayParams&");
/*FILE* fp = fopen("D:/png/1.txt", "rb");
......
No preview for this file type
No preview for this file type
objct name changed "deviceOutputPage3"
objct name changed "deviceOutputPage4"
available device "DeckLink 8K Pro (1)"
available device "DeckLink 8K Pro (2)"
available device "DeckLink 8K Pro (3)"
available device "DeckLink 8K Pro (4)"
"2024-05-16 14:30:21.752" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:30:21.811" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:30:21.831" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:30:21.851" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:30:21.871" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:30:21.891" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:30:21.911" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:30:21.931" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:30:21.989" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-16 14:30:23.034" decklink input fps 51
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645491 ms
1111111111111> 0x5ac
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645497 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645522 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645529 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645531 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645555 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645563 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645564 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645589 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645596 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645597 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645622 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645629 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645630 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645655 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645663 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645664 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645689 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645696 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645698 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645722 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645729 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645731 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645755 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645763 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645764 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645788 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645796 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645797 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645822 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645829 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645831 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645855 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645863 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645865 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645889 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645896 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645898 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645922 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645930 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645931 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645955 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645963 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645965 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208645989 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208645997 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208645998 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646022 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646030 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646031 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646055 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646063 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646064 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646089 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646097 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646098 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646122 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646130 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646131 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646156 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646163 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646164 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646190 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646197 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646198 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646222 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646230 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646232 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646256 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646263 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646264 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646289 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646296 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646298 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646322 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646330 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646331 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646356 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646363 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646365 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646389 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646397 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646398 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646422 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646430 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646431 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646456 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646463 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646464 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646490 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646497 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646498 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646523 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646530 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646531 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646556 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646563 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646565 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646589 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646597 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646598 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646623 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646630 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646631 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646656 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646663 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646665 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646689 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646697 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646698 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646723 ms
CaptureThread::AddFrame::fps:: 0 19
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646730 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646732 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646756 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646764 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646766 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646789 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646798 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646799 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646823 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646831 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646832 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646856 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646864 ms
CaptureThread::AddFrame::fps:: 2 20
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646865 ms
CaptureThread::AddFrame::fps:: 1 21
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646890 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646898 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646898 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646923 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646930 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646932 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646956 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646964 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646966 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208646990 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208646998 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208646999 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647024 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647031 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647032 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647056 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647064 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647066 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647090 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647098 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647099 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647123 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647130 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647132 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647156 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647165 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647166 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647191 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647197 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647199 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647223 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647231 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647232 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647257 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647264 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647266 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647290 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647298 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647299 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647324 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647332 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647332 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647357 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647364 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647366 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647390 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647398 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647399 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647423 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647432 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647433 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647457 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647464 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647466 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647490 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647498 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647499 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647524 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647531 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647533 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647558 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647564 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647566 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647590 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647598 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647599 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647624 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647631 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647632 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647657 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647665 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647666 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647691 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647698 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647700 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647724 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647731 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647733 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647757 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647765 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647766 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647791 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647798 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647799 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647824 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647831 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647833 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647858 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647865 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647866 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647891 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647898 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647899 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647924 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647932 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647933 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647958 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647965 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208647966 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208647991 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208647998 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648000 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648024 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648032 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648034 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648057 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648065 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648066 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648091 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648099 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648100 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648125 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648132 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648133 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648158 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648165 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648166 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648191 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648199 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648200 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648224 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648232 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648233 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648258 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648266 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648267 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648291 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648298 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648300 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648324 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648333 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648333 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648358 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648365 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648367 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648392 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648398 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648400 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648424 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648432 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648434 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648458 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648465 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648467 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648491 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648499 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648500 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648525 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648532 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648533 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648559 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648565 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648567 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648591 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648599 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648600 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648625 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648632 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648633 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648658 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648666 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648667 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648691 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648699 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648700 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648725 ms
CaptureThread::AddFrame::fps:: 0 30
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648733 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648734 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648758 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648766 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648768 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648792 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648799 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648800 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648825 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648833 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648834 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648858 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648866 ms
CaptureThread::AddFrame::fps:: 2 30
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648868 ms
CaptureThread::AddFrame::fps:: 1 30
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648892 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648899 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648900 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648925 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648932 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648934 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648959 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648966 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208648967 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208648992 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208648999 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649001 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649025 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649033 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649034 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649058 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649066 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649067 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649092 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649099 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649101 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649125 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649133 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649134 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649159 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649166 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649168 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649192 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649200 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649201 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649226 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649233 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649234 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649258 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649266 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649267 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649292 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649300 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649301 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649325 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649333 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649334 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649359 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649366 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649368 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649392 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649399 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649401 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649425 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649433 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649434 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649459 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649466 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649468 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649492 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649500 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649501 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649526 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649534 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649535 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649559 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649566 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649568 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649592 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649600 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649601 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649626 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649633 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649634 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649659 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649667 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649668 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649692 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649700 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649701 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649726 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649734 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649735 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649759 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649767 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649768 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649792 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649800 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649801 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649826 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649833 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649835 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649859 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649867 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649868 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649892 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649900 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649902 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649926 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649934 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649935 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649960 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208649967 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208649968 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208649993 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208650000 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208650001 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208650026 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208650034 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208650035 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208650060 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208650068 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208650069 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208650093 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208650100 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208650102 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208650126 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208650134 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208650135 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208650160 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208650167 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208650168 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208650193 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208650201 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208650202 ms
1111111111111> 0x3784
2222222222222222> 0x5ac
CaptureThread::AddFrame::0 curr_time: 1660208650226 ms
1111111111111> 0x5ac
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208650234 ms
1111111111111> 0x2ac4
2222222222222222> 0x3784
CaptureThread::AddFrame::1 curr_time: 1660208650235 ms
1111111111111> 0x3784
2222222222222222> 0x2ac4
CaptureThread::AddFrame::2 curr_time: 1660208650267 ms
1111111111111> 0x2ac4
......@@ -23,12 +23,32 @@ BLACK_BOTTOM_HEIGHT_1=16
BLACK_BOTTOM_HEIGHT_2=20
BLACK_BOTTOM_HEIGHT_3=20
BLACK_BOTTOM_HEIGHT_4=30
ZOOM_DRAW=0
ZOOM_FLAG=0
ZOOM_SCALE=1.5
ZOOM_SCALE_N=1
ZOOM_SCALE_D=2
ZOOM_IN_D=2
ZOOM_MOVE_D=2
ZOOM_OUT_D=2
ZOOM_IN_WAIT=15
ZOOM_MOVE_WAIT=15
ZOOM_OUT_WAIT=15
ZOOM_USE_OMP=1
ZOOM_SCALE_TYPE=2
ZOOM_SCALE_FILTER=3
NDIONEFRAMEDURATION=50
SDIONEFRAMEDURATION=50
RECORDFLAG=1
OPENOMP=0
OPENOMP=1
TIMEOUTFRAMES=250
DELEYSDINUMS=0
REPLAY_START_FORWARD=50
REPLAY_END_DELEY=50
SDIOUTPUTWAITNUMS=5
CROPRECORD=0c
CROP_X=400
CROP_Y=1800
CROP_DIRECTION=3
UI_UDP_PORT=8100
UI_IP_ADDR=192.168.31.83
......@@ -23,12 +23,32 @@ BLACK_BOTTOM_HEIGHT_1=16
BLACK_BOTTOM_HEIGHT_2=20
BLACK_BOTTOM_HEIGHT_3=20
BLACK_BOTTOM_HEIGHT_4=30
ZOOM_DRAW=0
ZOOM_FLAG=0
ZOOM_SCALE=1.5
ZOOM_SCALE_N=1
ZOOM_SCALE_D=2
ZOOM_IN_D=2
ZOOM_MOVE_D=2
ZOOM_OUT_D=2
ZOOM_IN_WAIT=15
ZOOM_MOVE_WAIT=15
ZOOM_OUT_WAIT=15
ZOOM_USE_OMP=1
ZOOM_SCALE_TYPE=2
ZOOM_SCALE_FILTER=3
NDIONEFRAMEDURATION=50
SDIONEFRAMEDURATION=50
RECORDFLAG=1
OPENOMP=0
OPENOMP=1
TIMEOUTFRAMES=250
DELEYSDINUMS=0
REPLAY_START_FORWARD=50
REPLAY_END_DELEY=50
SDIOUTPUTWAITNUMS=5
CROPRECORD=0
CROP_X=400
CROP_Y=1800
CROP_DIRECTION=3
UI_UDP_PORT=8100
UI_IP_ADDR=127.0.0.1
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment