Commit 8306c261 by 景炳强

update

parent 2975e87f
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
</rect> </rect>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>7</number> <number>8</number>
</property> </property>
<widget class="DeckLinkInputPage" name="devicePage1"> <widget class="DeckLinkInputPage" name="devicePage1">
<property name="geometry"> <property name="geometry">
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>361</width> <width>361</width>
<height>235</height> <height>289</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>361</width> <width>361</width>
<height>235</height> <height>289</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>361</width> <width>361</width>
<height>235</height> <height>289</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>361</width> <width>361</width>
<height>235</height> <height>289</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
...@@ -105,7 +105,7 @@ ...@@ -105,7 +105,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>361</width> <width>361</width>
<height>235</height> <height>289</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
...@@ -118,7 +118,7 @@ ...@@ -118,7 +118,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>361</width> <width>361</width>
<height>235</height> <height>289</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
...@@ -131,7 +131,7 @@ ...@@ -131,7 +131,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>361</width> <width>361</width>
<height>235</height> <height>289</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
...@@ -144,7 +144,7 @@ ...@@ -144,7 +144,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>361</width> <width>361</width>
<height>235</height> <height>289</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
...@@ -157,7 +157,7 @@ ...@@ -157,7 +157,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>361</width> <width>361</width>
<height>235</height> <height>289</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
...@@ -189,6 +189,32 @@ ...@@ -189,6 +189,32 @@
<string>Timecode</string> <string>Timecode</string>
</property> </property>
</widget> </widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>141</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>延迟时间(单位:秒)</string>
</property>
</widget>
<widget class="QLineEdit" name="deleyTimeEdit">
<property name="geometry">
<rect>
<x>160</x>
<y>70</y>
<width>41</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>5</string>
</property>
</widget>
</widget> </widget>
</widget> </widget>
</widget> </widget>
......
...@@ -70,11 +70,11 @@ ...@@ -70,11 +70,11 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>.\ThirdParty\OpenCV\include;.\ThirdParty\NewTek\include;.\ThirdParty\BlackmagicDesign\include;.\include;%(AdditionalIncludeDirectories);$(Qt_INCLUDEPATH_)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>.\ThirdParty\libyuv\include;.\ThirdParty\OpenCV\include;.\ThirdParty\NewTek\include;.\ThirdParty\BlackmagicDesign\include;.\include;%(AdditionalIncludeDirectories);$(Qt_INCLUDEPATH_)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalLibraryDirectories>.\ThirdParty\OpenCV\x64\vc17\lib;.\ThirdParty\NewTek\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>.\ThirdParty\libyuv\lib;.\ThirdParty\OpenCV\x64\vc15\lib;.\ThirdParty\NewTek\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>Processing.NDI.Lib.Advanced.x64.lib;opencv_world460.lib;%(AdditionalDependencies);$(Qt_LIBS_)</AdditionalDependencies> <AdditionalDependencies>Processing.NDI.Lib.Advanced.x64.lib;opencv_world460.lib;yuv.lib;jpeg.lib;%(AdditionalDependencies);$(Qt_LIBS_)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
......
...@@ -4,10 +4,16 @@ ...@@ -4,10 +4,16 @@
#include <functional> #include <functional>
#include <QString> #include <QString>
#include <QObject> #include <QObject>
#include <condition_variable>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>
#include "DeckLinkAPI.h" #include "DeckLinkAPI.h"
#include "Utils/CustomEvents.h" #include "Utils/CustomEvents.h"
#include "Utils/ComPtr.h" #include "Utils/ComPtr.h"
#include "Utils/Image.h" #include "Utils/Image.h"
#include "Threads/CaptureThread.h"
class DeckLinkInputDevice : public QObject, public IDeckLinkInputCallback class DeckLinkInputDevice : public QObject, public IDeckLinkInputCallback
{ {
...@@ -46,6 +52,11 @@ public: ...@@ -46,6 +52,11 @@ public:
ComPtr<IDeckLinkInput> GetDeckLinkInput(void) const { return DeckLinkInput; } ComPtr<IDeckLinkInput> GetDeckLinkInput(void) const { return DeckLinkInput; }
ComPtr<IDeckLinkConfiguration> GetDeckLinkConfiguration(void) const { return DeckLinkConfig; } ComPtr<IDeckLinkConfiguration> GetDeckLinkConfiguration(void) const { return DeckLinkConfig; }
void SetCapture(const std::shared_ptr<CaptureThread>& capture) {
Capture = capture;
}
//void ForwardThread();
signals: signals:
void ArrivedFrame(ComPtr<IDeckLinkVideoInputFrame> videoFrame); void ArrivedFrame(ComPtr<IDeckLinkVideoInputFrame> videoFrame);
...@@ -64,6 +75,14 @@ private: ...@@ -64,6 +75,14 @@ private:
int64_t SupportedInputConnections; int64_t SupportedInputConnections;
BMDVideoConnection SelectedInputConnection; BMDVideoConnection SelectedInputConnection;
// //
std::shared_ptr<CaptureThread> Capture;
//std::queue<ComPtr<IDeckLinkVideoInputFrame>> taskQueue;
//std::condition_variable cv;
//std::mutex mutex;
//std::thread thd;
}; };
class DeckLinkInputFormatChangedEvent : public QEvent class DeckLinkInputFormatChangedEvent : public QEvent
......
...@@ -47,6 +47,8 @@ public slots: ...@@ -47,6 +47,8 @@ public slots:
void RequestDeckLinkIfAvailable(ComPtr<IDeckLink>& device); void RequestDeckLinkIfAvailable(ComPtr<IDeckLink>& device);
void RelinquishDeckLink(ComPtr<IDeckLink>& device); void RelinquishDeckLink(ComPtr<IDeckLink>& device);
void FormatChanged(BMDDisplayMode displayMode);
private slots: private slots:
void ObjectNameChanged(const QString& newName); void ObjectNameChanged(const QString& newName);
private: private:
......
...@@ -48,6 +48,9 @@ public slots: ...@@ -48,6 +48,9 @@ public slots:
void RequestedDeviceGranted(ComPtr<IDeckLink>& device); void RequestedDeviceGranted(ComPtr<IDeckLink>& device);
void ObjectNameChanged(const QString& newName); void ObjectNameChanged(const QString& newName);
void FormatChanged(BMDDisplayMode displayMode);
signals: signals:
void RequestDeckLink(ComPtr<IDeckLink>& device); void RequestDeckLink(ComPtr<IDeckLink>& device);
void RequestDeckLinkIfAvailable(ComPtr<IDeckLink>& device); void RequestDeckLinkIfAvailable(ComPtr<IDeckLink>& device);
......
...@@ -54,7 +54,9 @@ public slots: ...@@ -54,7 +54,9 @@ public slots:
private slots: private slots:
void DeviceLabelEnableChanged(bool enabled); void DeviceLabelEnableChanged(bool enabled);
void TimecodeEnableChanged(bool enabled); void TimecodeEnableChanged(bool enabled);
void DeleyTimeTextChanged(const QString&);
private:
void ReadSettings();
private: private:
Ui::MomentaMediaClass ui; Ui::MomentaMediaClass ui;
...@@ -63,6 +65,8 @@ private: ...@@ -63,6 +65,8 @@ private:
ComPtr<DeckLinkDeviceDiscovery> DeckLinkDiscovery; ComPtr<DeckLinkDeviceDiscovery> DeckLinkDiscovery;
ProfileCallback* pProfileCallback; ProfileCallback* pProfileCallback;
QLineEdit* DeleyTimeEdit;
std::array<DeckLinkInputPage*, kPreviewDevicesCount> InputDevicePages; std::array<DeckLinkInputPage*, kPreviewDevicesCount> InputDevicePages;
std::array<DeckLinkOutputPage*, kPreviewDevicesCount> OutputDevicePages; std::array<DeckLinkOutputPage*, kPreviewDevicesCount> OutputDevicePages;
std::array<std::shared_ptr<ProcessThread>, kPreviewDevicesCount> ProcessThreads; std::array<std::shared_ptr<ProcessThread>, kPreviewDevicesCount> ProcessThreads;
......
...@@ -5,6 +5,11 @@ ...@@ -5,6 +5,11 @@
#include "Utils/Image.h" #include "Utils/Image.h"
#include "Utils/SampleQueue.h" #include "Utils/SampleQueue.h"
#include <condition_variable>
#include <memory>
#include <mutex>
#include <queue>
class CaptureThread : public QThread class CaptureThread : public QThread
{ {
Q_OBJECT Q_OBJECT
...@@ -20,13 +25,16 @@ signals: ...@@ -20,13 +25,16 @@ signals:
void PushFrame(std::shared_ptr<Image> image); void PushFrame(std::shared_ptr<Image> image);
private: private:
SampleQueue<ComPtr<IDeckLinkVideoInputFrame>> taskQueue;
void run() override;
static int s_count; static int s_count;
int idx; int idx;
//SampleQueue<ComPtr<IDeckLinkVideoInputFrame>> taskQueue;
void run() override;
int recvFrames; int recvFrames;
int64_t recvStartTime; int64_t recvStartTime;
std::queue<ComPtr<IDeckLinkVideoInputFrame>> taskQueue;
std::condition_variable cv;
std::mutex mutex;
}; };
\ No newline at end of file
...@@ -15,6 +15,7 @@ public: ...@@ -15,6 +15,7 @@ public:
Image(); Image();
Image(IDeckLinkVideoInputFrame* videoFrame); Image(IDeckLinkVideoInputFrame* videoFrame);
Image(ComPtr<DeckLinkInputVideoFrame> videoFrame); Image(ComPtr<DeckLinkInputVideoFrame> videoFrame);
Image(ComPtr<IDeckLinkVideoInputFrame> videoFrame,qint64 curtimestamp);
Image(ComPtr<IDeckLinkVideoInputFrame> videoFrame); Image(ComPtr<IDeckLinkVideoInputFrame> videoFrame);
Image(const Image& other); Image(const Image& other);
Image(Image&& other); Image(Image&& other);
...@@ -52,7 +53,7 @@ public: ...@@ -52,7 +53,7 @@ public:
BMDTimeValue getOutputFrameScheduledReferenceTime() { return outputFrameScheduledReferenceTime; } BMDTimeValue getOutputFrameScheduledReferenceTime() { return outputFrameScheduledReferenceTime; }
BMDTimeValue getOutputFrameCompletedReferenceTime() { return outputFrameCompletedReferenceTime; } BMDTimeValue getOutputFrameCompletedReferenceTime() { return outputFrameCompletedReferenceTime; }
BMDOutputFrameCompletionResult getOutputCompletionResult() { return outputFrameCompletionResult; } BMDOutputFrameCompletionResult getOutputCompletionResult() { return outputFrameCompletionResult; }
int64_t getInputFrameCurTimeStamp() { return inputFrameCurTimeStamp; }
void GetMatByRoi(cv::Rect roi, cv::Mat& mat); void GetMatByRoi(cv::Rect roi, cv::Mat& mat);
...@@ -78,6 +79,8 @@ private: ...@@ -78,6 +79,8 @@ private:
BMDTimeValue outputFrameScheduledReferenceTime; BMDTimeValue outputFrameScheduledReferenceTime;
BMDTimeValue outputFrameCompletedReferenceTime; BMDTimeValue outputFrameCompletedReferenceTime;
qint64 inputFrameCurTimeStamp;//
BMDOutputFrameCompletionResult outputFrameCompletionResult; BMDOutputFrameCompletionResult outputFrameCompletionResult;
}; };
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <mutex> #include <mutex>
#include <queue> #include <queue>
#include <QDebug> #include <QDebug>
#include <qdatetime.h>
#include <chrono> #include <chrono>
...@@ -13,6 +14,7 @@ class SampleQueue ...@@ -13,6 +14,7 @@ class SampleQueue
{ {
public: public:
SampleQueue(); SampleQueue();
SampleQueue(const std::string& names);
virtual ~SampleQueue(); virtual ~SampleQueue();
void Push(const T& sample); void Push(const T& sample);
...@@ -29,10 +31,17 @@ private: ...@@ -29,10 +31,17 @@ private:
std::condition_variable queueCondition; std::condition_variable queueCondition;
std::mutex mutex; std::mutex mutex;
bool waitCancelled; bool waitCancelled;
std::string name;
}; };
template <typename T> template <typename T>
SampleQueue<T>::SampleQueue() : waitCancelled(false) SampleQueue<T>::SampleQueue() : waitCancelled(false), name("default")
{
}
template <typename T>
SampleQueue<T>::SampleQueue(const std::string& names) : waitCancelled(false), name(names)
{ {
} }
...@@ -56,11 +65,28 @@ void SampleQueue<T>::Push(T&& sample) ...@@ -56,11 +65,28 @@ void SampleQueue<T>::Push(T&& sample)
template <typename T> template <typename T>
void SampleQueue<T>::Push(const T& sample) void SampleQueue<T>::Push(const T& sample)
{ {
int64_t st = QDateTime::currentMSecsSinceEpoch();
int64_t elapse;
{ {
std::lock_guard<std::mutex> locker(mutex); std::lock_guard<std::mutex> locker(mutex);
elapse = QDateTime::currentMSecsSinceEpoch() - st;
//if (name == "task0" && elapse >= 10 ) {
//qDebug() << "SampleQueue<T>::Push::" << name.c_str() << "\t" << elapse << "\n";
//}
queue.push(std::move(sample)); queue.push(std::move(sample));
elapse = QDateTime::currentMSecsSinceEpoch() - st;
//qDebug() << "SampleQueue<T>::Push::" << name.c_str() << "\t" << elapse << "\n";
} }
queueCondition.notify_one(); queueCondition.notify_one();
elapse = QDateTime::currentMSecsSinceEpoch() - st;
//qDebug() << "SampleQueue<T>::Push::" << name.c_str() << "\t" << elapse << "\n";
} }
template <typename T> template <typename T>
......
...@@ -18,7 +18,7 @@ DeckLinkInputDevice::DeckLinkInputDevice(QObject* parent, ComPtr<IDeckLink>& dev ...@@ -18,7 +18,7 @@ DeckLinkInputDevice::DeckLinkInputDevice(QObject* parent, ComPtr<IDeckLink>& dev
SupportedInputConnections(bmdVideoConnectionUnspecified), SupportedInputConnections(bmdVideoConnectionUnspecified),
SelectedInputConnection(bmdVideoConnectionUnspecified) SelectedInputConnection(bmdVideoConnectionUnspecified)
{ {
//thd = std::thread(&DeckLinkInputDevice::ForwardThread, this);
} }
DeckLinkInputDevice::~DeckLinkInputDevice() DeckLinkInputDevice::~DeckLinkInputDevice()
...@@ -76,11 +76,38 @@ HRESULT DeckLinkInputDevice::VideoInputFrameArrived(IDeckLinkVideoInputFrame* vi ...@@ -76,11 +76,38 @@ HRESULT DeckLinkInputDevice::VideoInputFrameArrived(IDeckLinkVideoInputFrame* vi
{ {
// Since this application only previews, everything is driven from IDeckLinkScreenPreviewCallback::DrawFrame // Since this application only previews, everything is driven from IDeckLinkScreenPreviewCallback::DrawFrame
ComPtr<IDeckLinkVideoInputFrame> frame = ComPtr<IDeckLinkVideoInputFrame>(videoFrame); ComPtr<IDeckLinkVideoInputFrame> frame = ComPtr<IDeckLinkVideoInputFrame>(videoFrame);
emit ArrivedFrame(frame); //emit ArrivedFrame(frame);
if (Capture) {
Capture->AddFrame(frame);
}
/*std::unique_lock<std::mutex> ulock(mutex);
taskQueue.push(frame);
cv.notify_all();*/
return S_OK; return S_OK;
} }
/*void DeckLinkInputDevice::ForwardThread()
{
ComPtr<IDeckLinkVideoInputFrame> frame;
while (true) {
{
std::unique_lock<std::mutex> ulock(mutex);
while (taskQueue.empty()) {
cv.wait(ulock);
}
frame = taskQueue.front();
taskQueue.pop();
}
if (Capture) {
Capture->AddFrame(frame);
}
}
}*/
HRESULT DeckLinkInputDevice::VideoInputFormatChanged(BMDVideoInputFormatChangedEvents notificationEvents, IDeckLinkDisplayMode* newDisplayMode, BMDDetectedVideoInputFormatFlags detectedSignalFlags) HRESULT DeckLinkInputDevice::VideoInputFormatChanged(BMDVideoInputFormatChangedEvents notificationEvents, IDeckLinkDisplayMode* newDisplayMode, BMDDetectedVideoInputFormatFlags detectedSignalFlags)
{ {
HRESULT result; HRESULT result;
......
...@@ -252,7 +252,8 @@ void DeckLinkInputPage::RequestedDeviceGranted(ComPtr<IDeckLink>& device) ...@@ -252,7 +252,8 @@ void DeckLinkInputPage::RequestedDeviceGranted(ComPtr<IDeckLink>& device)
if (SelectedDevice) if (SelectedDevice)
SelectedDevice->Initialize(); SelectedDevice->Initialize();
connect(SelectedDevice.Get(), SIGNAL(ArrivedFrame(ComPtr<IDeckLinkVideoInputFrame>)), Capture.get(), SLOT(AddFrame(ComPtr<IDeckLinkVideoInputFrame>))); //connect(SelectedDevice.Get(), SIGNAL(ArrivedFrame(ComPtr<IDeckLinkVideoInputFrame>)), Capture.get(), SLOT(AddFrame(ComPtr<IDeckLinkVideoInputFrame>)));
SelectedDevice.Get()->SetCapture(Capture);
SelectedDeviceChanged(); SelectedDeviceChanged();
StartCapture(); StartCapture();
...@@ -302,6 +303,8 @@ void DeckLinkInputPage::DetectedVideoFormatChanged(BMDDisplayMode displayMode) ...@@ -302,6 +303,8 @@ void DeckLinkInputPage::DetectedVideoFormatChanged(BMDDisplayMode displayMode)
int index = VideoFormatCombo->findData(QVariant::fromValue((uint64_t)displayMode)); int index = VideoFormatCombo->findData(QVariant::fromValue((uint64_t)displayMode));
if (index >= 0) if (index >= 0)
VideoFormatCombo->setCurrentIndex(index); VideoFormatCombo->setCurrentIndex(index);
emit FormatChanged(displayMode);
} }
void DeckLinkInputPage::ObjectNameChanged(const QString& newName) void DeckLinkInputPage::ObjectNameChanged(const QString& newName)
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "BlackMagicDesign/ScreenPreviewCallback.h" #include "BlackMagicDesign/ScreenPreviewCallback.h"
#include "BlackMagicDesign/ReferenceTime.h" #include "BlackMagicDesign/ReferenceTime.h"
extern int OutputDeleyTime;
DeckLinkOutputDevice::DeckLinkOutputDevice(ComPtr<IDeckLink>& decklink, int videoPrerollSize) DeckLinkOutputDevice::DeckLinkOutputDevice(ComPtr<IDeckLink>& decklink, int videoPrerollSize)
: RefCount(1), : RefCount(1),
state(PlaybackState::Idle), state(PlaybackState::Idle),
...@@ -272,6 +274,15 @@ bool DeckLinkOutputDevice::getReferenceSignalMode(BMDDisplayMode* mode) ...@@ -272,6 +274,15 @@ bool DeckLinkOutputDevice::getReferenceSignalMode(BMDDisplayMode* mode)
if(outputVideoFrameQueue.WaitFor(outputImage)) if(outputVideoFrameQueue.WaitFor(outputImage))
{ {
auto now_time = QDateTime::currentMSecsSinceEpoch();
auto input_time = outputImage->getInputFrameCurTimeStamp();
auto dever_time = now_time - input_time;
qDebug() << "input frame cur time:" << input_time << " now time:" <<now_time << " dever time:"<<dever_time << "\n";
if (dever_time < OutputDeleyTime * 1000)
{
//qDebug() << "sleep ms:" << 5 * 1000 - dever_time << "\n";
Sleep(OutputDeleyTime * 1000 - dever_time);
}
END_WAIT_TIME_COUNTER END_WAIT_TIME_COUNTER
//std::lock_guard<std::mutex> locker(mutex); //std::lock_guard<std::mutex> locker(mutex);
...@@ -298,10 +309,10 @@ bool DeckLinkOutputDevice::getReferenceSignalMode(BMDDisplayMode* mode) ...@@ -298,10 +309,10 @@ bool DeckLinkOutputDevice::getReferenceSignalMode(BMDDisplayMode* mode)
//checkEndOfPreroll(); //checkEndOfPreroll();
} }
while (outputVideoFrameQueue.Size() > 30) /*while (outputVideoFrameQueue.Size() > 30)
{ {
outputVideoFrameQueue.Pop(outputImage); outputVideoFrameQueue.Pop(outputImage);
} }*/
} }
} }
......
...@@ -113,16 +113,19 @@ void DeckLinkOutputPage::customEvent(QEvent* event) ...@@ -113,16 +113,19 @@ void DeckLinkOutputPage::customEvent(QEvent* event)
void DeckLinkOutputPage::StartOutput() void DeckLinkOutputPage::StartOutput()
{ {
/*
if (!SelectedDevice) if (!SelectedDevice)
return; return;
BMDDisplayMode displayMode = bmdModeHD1080p50; BMDDisplayMode displayMode = bmdModeHD1080p25;
//displayMode = (BMDDisplayMode)VideoFormatCombo->currentData().value<unsigned int>(); //displayMode = (BMDDisplayMode)VideoFormatCombo->currentData().value<unsigned int>();
qDebug() << "==> " << displayMode << "\n";
BMDPixelFormat pixelFormat = bmdFormat10BitYUV; BMDPixelFormat pixelFormat = bmdFormat10BitYUV;
//pixelFormat = (BMDPixelFormat)VideoPixelFormatCombo->currentData().value<unsigned int>(); //pixelFormat = (BMDPixelFormat)VideoPixelFormatCombo->currentData().value<unsigned int>();
SelectedDevice->StartPlayback(displayMode, false, pixelFormat, false, PreviewView->GetDelegate()); SelectedDevice->StartPlayback(displayMode, false, pixelFormat, false, PreviewView->GetDelegate());
*/
} }
void DeckLinkOutputPage::AddDevice(ComPtr<IDeckLink>& deckLink, bool deviceIsActive) void DeckLinkOutputPage::AddDevice(ComPtr<IDeckLink>& deckLink, bool deviceIsActive)
...@@ -250,6 +253,8 @@ void DeckLinkOutputPage::RequestedDeviceGranted(ComPtr<IDeckLink>& device) ...@@ -250,6 +253,8 @@ void DeckLinkOutputPage::RequestedDeviceGranted(ComPtr<IDeckLink>& device)
connect(BindingInputPage->GetCapture(), &CaptureThread::PushFrame, Process.get(), &ProcessThread::AddFrame); connect(BindingInputPage->GetCapture(), &CaptureThread::PushFrame, Process.get(), &ProcessThread::AddFrame);
connect(Process.get(), &ProcessThread::PushFrame, SelectedDevice.Get(), &DeckLinkOutputDevice::AddFrame); connect(Process.get(), &ProcessThread::PushFrame, SelectedDevice.Get(), &DeckLinkOutputDevice::AddFrame);
connect(BindingInputPage, &DeckLinkInputPage::FormatChanged, this, &DeckLinkOutputPage::FormatChanged);
if(Process->isRunning()) if(Process->isRunning())
Process->exit(); Process->exit();
...@@ -263,6 +268,15 @@ void DeckLinkOutputPage::RequestedDeviceGranted(ComPtr<IDeckLink>& device) ...@@ -263,6 +268,15 @@ void DeckLinkOutputPage::RequestedDeviceGranted(ComPtr<IDeckLink>& device)
END_SLOT_TIME_COUNTER END_SLOT_TIME_COUNTER
} }
void DeckLinkOutputPage::FormatChanged(BMDDisplayMode displayMode)
{
BMDDisplayMode displayMode_ = displayMode;
BMDPixelFormat pixelFormat = bmdFormat10BitYUV;
SelectedDevice->StartPlayback(displayMode_, false, pixelFormat, false, PreviewView->GetDelegate());
}
void DeckLinkOutputPage::ObjectNameChanged(const QString& newName) void DeckLinkOutputPage::ObjectNameChanged(const QString& newName)
{ {
START_SLOT_TIME_COUNTER START_SLOT_TIME_COUNTER
......
...@@ -59,7 +59,7 @@ ULONG ScreenPreviewCallback::Release() ...@@ -59,7 +59,7 @@ ULONG ScreenPreviewCallback::Release()
HRESULT ScreenPreviewCallback::DrawFrame(IDeckLinkVideoFrame* theFrame) HRESULT ScreenPreviewCallback::DrawFrame(IDeckLinkVideoFrame* theFrame)
{ {
START_GL_TIME_COUNTER START_GL_TIME_COUNTER
//emit FrameArrived(ComPtr<IDeckLinkVideoFrame>(theFrame)); emit FrameArrived(ComPtr<IDeckLinkVideoFrame>(theFrame));
END_GL_TIME_COUNTER END_GL_TIME_COUNTER
return S_OK; return S_OK;
} }
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include "Utils/Image.h" #include "Utils/Image.h"
#include "DeckLinkAPI.h" #include "DeckLinkAPI.h"
int OutputDeleyTime = 5;
MomentaMedia::MomentaMedia(QWidget *parent) MomentaMedia::MomentaMedia(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
{ {
...@@ -32,6 +34,16 @@ MomentaMedia::MomentaMedia(QWidget *parent) ...@@ -32,6 +34,16 @@ MomentaMedia::MomentaMedia(QWidget *parent)
ProcessThreads[2] = std::make_shared<ProcessThread>(); ProcessThreads[2] = std::make_shared<ProcessThread>();
ProcessThreads[3] = std::make_shared<ProcessThread>(); ProcessThreads[3] = std::make_shared<ProcessThread>();
DeleyTimeEdit = ui.deleyTimeEdit;
QIntValidator* intValidator = new QIntValidator;
intValidator->setRange(0, 20);
DeleyTimeEdit->setValidator(intValidator);
connect(DeleyTimeEdit,&QLineEdit::textChanged,this,&MomentaMedia::DeleyTimeTextChanged);
ReadSettings();
QSize previewViewSize = ui.previewContainer->size(); QSize previewViewSize = ui.previewContainer->size();
PreviewLayout = new QGridLayout(ui.previewContainer); PreviewLayout = new QGridLayout(ui.previewContainer);
...@@ -138,48 +150,52 @@ void MomentaMedia::customEvent(QEvent* event) ...@@ -138,48 +150,52 @@ void MomentaMedia::customEvent(QEvent* event)
void MomentaMedia::closeEvent(QCloseEvent* event) void MomentaMedia::closeEvent(QCloseEvent* event)
{ {
for(auto& devicePage:InputDevicePages) //for(auto& devicePage:InputDevicePages)
{ //{
ComPtr<DeckLinkInputDevice> selectDevice = devicePage->GetSelectedDevice(); // ComPtr<DeckLinkInputDevice> selectDevice = devicePage->GetSelectedDevice();
if(selectDevice) // if(selectDevice)
{ // {
// Stop capture // // Stop capture
if (selectDevice->IsCapturing()) // if (selectDevice->IsCapturing())
selectDevice->StopCapture(); // selectDevice->StopCapture();
// Deregister profile callback // // Deregister profile callback
ComPtr<IDeckLinkProfileManager> profileManager(IID_IDeckLinkProfileManager, selectDevice->GetDeckLinkInstance()); // ComPtr<IDeckLinkProfileManager> profileManager(IID_IDeckLinkProfileManager, selectDevice->GetDeckLinkInstance());
if (profileManager) // if (profileManager)
profileManager->SetCallback(nullptr); // profileManager->SetCallback(nullptr);
} // }
} //}
for(auto& devicePage : OutputDevicePages) // for(auto& devicePage : OutputDevicePages)
{ // {
ComPtr<DeckLinkOutputDevice> selectDevice = devicePage->GetSelectedDevice(); // ComPtr<DeckLinkOutputDevice> selectDevice = devicePage->GetSelectedDevice();
if(selectDevice) // if(selectDevice)
{ // {
// Stop // // Stop
if(selectDevice->isPlaybackActive()) // if(selectDevice->isPlaybackActive())
{ // {
selectDevice->StopPlayback(); // selectDevice->StopPlayback();
} // }
// Deregister profile callback // // Deregister profile callback
ComPtr<IDeckLinkProfileManager> profileManager(IID_IDeckLinkProfileManager, selectDevice->GetDeckLinkInstance()); // ComPtr<IDeckLinkProfileManager> profileManager(IID_IDeckLinkProfileManager, selectDevice->GetDeckLinkInstance());
if (profileManager) // if (profileManager)
profileManager->SetCallback(nullptr); // profileManager->SetCallback(nullptr);
} // }
} // }
InputDevices.clear(); // InputDevices.clear();
OutputDevices.clear(); // OutputDevices.clear();
if (DeckLinkDiscovery) // if (DeckLinkDiscovery)
DeckLinkDiscovery->Disable(); // DeckLinkDiscovery->Disable();
// exit(0);
qint64 pid = QCoreApplication::applicationPid();
QString cmd = QString("TASKKILL /PID %1 /F").arg(pid);//Windows 系统下,杀死当前进程命令,不杀死其开启的子进程
WinExec(cmd.toLocal8Bit().data(), SW_HIDE);//SW_HIDE:控制运行cmd时,不弹出cmd运行窗口
exit(0);
} }
void MomentaMedia::AddDevice(ComPtr<IDeckLink>& deckLink) void MomentaMedia::AddDevice(ComPtr<IDeckLink>& deckLink)
...@@ -470,3 +486,23 @@ void MomentaMedia::TimecodeEnableChanged(bool enabled) ...@@ -470,3 +486,23 @@ void MomentaMedia::TimecodeEnableChanged(bool enabled)
} }
END_SLOT_TIME_COUNTER END_SLOT_TIME_COUNTER
} }
void MomentaMedia::DeleyTimeTextChanged(const QString& time)
{
START_SLOT_TIME_COUNTER
/*QString value = DeleyTimeEdit->text();
bool ok;*/
int deleyTime = time.toInt();
END_SLOT_TIME_COUNTER
}
void MomentaMedia::ReadSettings()
{
QString exe_dir = QCoreApplication::applicationDirPath();
QString ini_path = exe_dir + "/settings.ini";
QSettings settings(ini_path, QSettings::IniFormat);
settings.beginGroup("DELEYTIME");
OutputDeleyTime = settings.value("DELEY_TIME", "").toInt();
//qDebug() << "deleyTime=" << deleyTime << endl;
settings.endGroup();
}
\ No newline at end of file
#include "Threads/CaptureThread.h" #include "Threads/CaptureThread.h"
static int64_t GetCurrTimeMS()
{
LARGE_INTEGER nStartTime;
//LARGE_INTEGER nStopTime;
//LARGE_INTEGER nElapsed;
LARGE_INTEGER nFrequency;
::QueryPerformanceFrequency(&nFrequency);
::QueryPerformanceCounter(&nStartTime);
return nStartTime.QuadPart * 1000 / nFrequency.QuadPart;
//::QueryPerformanceCounter(&nStopTime);
//nElapsed.QuadPart = (nStopTime.QuadPart - nStartTime.QuadPart) * 1000000;
//nElapsed.QuadPart /= nFrequency.QuadPart;
}
int CaptureThread::s_count = 0; int CaptureThread::s_count = 0;
CaptureThread::CaptureThread() CaptureThread::CaptureThread()
: recvFrames(0), : recvFrames(0),
idx(s_count++),
recvStartTime(QDateTime::currentMSecsSinceEpoch()) recvStartTime(QDateTime::currentMSecsSinceEpoch())
//taskQueue(std::string("task")+ std::to_string(idx))
{ {
idx = s_count++; //idx = s_count++;
} }
CaptureThread::~CaptureThread() CaptureThread::~CaptureThread()
...@@ -16,6 +34,9 @@ CaptureThread::~CaptureThread() ...@@ -16,6 +34,9 @@ CaptureThread::~CaptureThread()
void CaptureThread::AddFrame(ComPtr<IDeckLinkVideoInputFrame> videoFrame) void CaptureThread::AddFrame(ComPtr<IDeckLinkVideoInputFrame> videoFrame)
{ {
int64_t st = QDateTime::currentMSecsSinceEpoch();
int64_t st2 = GetCurrTimeMS();
std::string tag = "CaptureThread::AddFrame::" + std::to_string(idx); std::string tag = "CaptureThread::AddFrame::" + std::to_string(idx);
const char* tags = tag.c_str(); const char* tags = tag.c_str();
//PRINT_CURR_TIME(tags); //PRINT_CURR_TIME(tags);
...@@ -41,10 +62,39 @@ void CaptureThread::AddFrame(ComPtr<IDeckLinkVideoInputFrame> videoFrame) ...@@ -41,10 +62,39 @@ void CaptureThread::AddFrame(ComPtr<IDeckLinkVideoInputFrame> videoFrame)
if (videoFrame->GetWidth() != 1920 || videoFrame->GetHeight() != 1080) if (videoFrame->GetWidth() != 1920 || videoFrame->GetHeight() != 1080)
return; return;
if (taskQueue.Size() >= 4) if (taskQueue.size() >= 4)
qDebug() << "CaptureThread::AddFrame::qsize::" << idx << "\t" << taskQueue.Size() << "\n"; qDebug() << "CaptureThread::AddFrame::qsize::" << idx << "\t" << taskQueue.size() << "\n";
tag = "CaptureThread::AddFrame::doing::" + std::to_string(idx);
tags = tag.c_str();
//PRINT_CURR_TIME(tags);
{
std::unique_lock<std::mutex> ulock(mutex);
tag = "CaptureThread::AddFrame::S0::" + std::to_string(idx);
tags = tag.c_str();
//PRINT_CURR_TIME(tags);
taskQueue.push(videoFrame);
tag = "CaptureThread::AddFrame::S1::" + std::to_string(idx);
tags = tag.c_str();
//PRINT_CURR_TIME(tags);
cv.notify_all();
}
tag = "CaptureThread::AddFrame::End::" + std::to_string(idx);
tags = tag.c_str();
//PRINT_CURR_TIME(tags);
int64_t elaspe = QDateTime::currentMSecsSinceEpoch() - st;
int64_t elaspe2 = GetCurrTimeMS() - st2;
if (elaspe >= 10)
qDebug() << "====> " << idx << "\t" << elaspe << " " << elaspe2 << "\n";
taskQueue.Push(videoFrame);
END_SLOT_TIME_COUNTER END_SLOT_TIME_COUNTER
} }
...@@ -56,7 +106,7 @@ void CaptureThread::run() ...@@ -56,7 +106,7 @@ void CaptureThread::run()
START_WAIT_TIME_COUNTER START_WAIT_TIME_COUNTER
ComPtr<IDeckLinkVideoInputFrame> videoFrame; ComPtr<IDeckLinkVideoInputFrame> videoFrame;
if(taskQueue.WaitFor(videoFrame)) /*if (taskQueue.WaitFor(videoFrame))
{ {
END_WAIT_TIME_COUNTER END_WAIT_TIME_COUNTER
...@@ -65,12 +115,33 @@ void CaptureThread::run() ...@@ -65,12 +115,33 @@ void CaptureThread::run()
std::shared_ptr<Image> image = std::make_shared<Image>(videoFrame); std::shared_ptr<Image> image = std::make_shared<Image>(videoFrame);
emit PushFrame(image); emit PushFrame(image);
} }
DEBUG_FUNCTION("taskQeueue Size: ", taskQueue.Size()) DEBUG_FUNCTION("taskQeueue Size: ", taskQueue.size())
}*/
{
std::unique_lock<std::mutex> ulock(mutex);
while (taskQueue.empty()) {
cv.wait(ulock);
}
videoFrame = taskQueue.front();
taskQueue.pop();
} }
while (taskQueue.Size() > 30) if (videoFrame.Get() != nullptr)
{
auto cur_time = QDateTime::currentMSecsSinceEpoch();
qDebug() << "input frame cur time:" << cur_time << "\n";
std::shared_ptr<Image> image = std::make_shared<Image>(videoFrame,cur_time);
emit PushFrame(image);
}
/*while (taskQueue.size() > 30)
{
//taskQueue.Pop(videoFrame);
{ {
taskQueue.Pop(videoFrame); std::unique_lock<std::mutex> ulock(mutex);
taskQueue.pop();
} }
}*/
} }
} }
\ No newline at end of file
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "libyuv.h" #include "libyuv.h"
int ProcessThread::s_count = 0; int ProcessThread::s_count = 0;
extern int OutputDeleyTime;
ProcessThread::ProcessThread() ProcessThread::ProcessThread()
: sendFrames(0), : sendFrames(0),
...@@ -50,6 +51,7 @@ void ProcessThread::ReadDatagrams() ...@@ -50,6 +51,7 @@ void ProcessThread::ReadDatagrams()
data.resize(udpSocket->pendingDatagramSize()); data.resize(udpSocket->pendingDatagramSize());
udpSocket->readDatagram(data.data(), data.size(), &inClientAddr, &inClientPort); udpSocket->readDatagram(data.data(), data.size(), &inClientAddr, &inClientPort);
//qDebug()<< "recv time:" << QDateTime::currentMSecsSinceEpoch() << "\t" << "recv udp data:" << idx << "\t" << data.data() << "\n";
} }
if(!data.isEmpty()) if(!data.isEmpty())
...@@ -79,7 +81,7 @@ void ProcessThread::run() ...@@ -79,7 +81,7 @@ void ProcessThread::run()
if(taskImageQueue.WaitFor(image)) if(taskImageQueue.WaitFor(image))
{ {
END_WAIT_TIME_COUNTER END_WAIT_TIME_COUNTER
//qDebug() << "ProcessThread image current time111:" << image->getInputFrameCurTimeStamp() << "\n";
if (taskROIQueue.WaitUntil(roi, 1)) if (taskROIQueue.WaitUntil(roi, 1))
{ {
lastReceiveMessage = roi; lastReceiveMessage = roi;
...@@ -122,8 +124,8 @@ void ProcessThread::run() ...@@ -122,8 +124,8 @@ void ProcessThread::run()
//PRINT_CURR_TIME(tags); //PRINT_CURR_TIME(tags);
if (taskImageQueue.Size() >= 4) //if (taskImageQueue.Size() >= 4)
qDebug() << "ProcessThread::run::qsize::" << idx << "\t" << taskImageQueue.Size() << "\n"; // qDebug() << "ProcessThread::run::qsize::" << idx << "\t" << taskImageQueue.Size() << "\n";
//qDebug() << "ROI- " << idx << " " << roi.X() << " " << roi.Y() << " " << roi.Width() << " " << roi.Height() << "\n"; //qDebug() << "ROI- " << idx << " " << roi.X() << " " << roi.Y() << " " << roi.Width() << " " << roi.Height() << "\n";
size_t size = roi.Width() * roi.Height() << 2; size_t size = roi.Width() * roi.Height() << 2;
...@@ -162,7 +164,7 @@ void ProcessThread::run() ...@@ -162,7 +164,7 @@ void ProcessThread::run()
tag = "ProcessThread::run::end::" + std::to_string(idx); tag = "ProcessThread::run::end::" + std::to_string(idx);
tags = tag.c_str(); tags = tag.c_str();
//PRINT_CURR_TIME(tags); //PRINT_CURR_TIME(tags);
//qDebug() << "ProcessThread image current time222:" << image->getInputFrameCurTimeStamp() << "\n";
emit PushFrame(image); emit PushFrame(image);
DEBUG_FUNCTION("taskImageQueue Size: ", taskImageQueue.Size()) DEBUG_FUNCTION("taskImageQueue Size: ", taskImageQueue.Size())
...@@ -177,7 +179,7 @@ void ProcessThread::run() ...@@ -177,7 +179,7 @@ void ProcessThread::run()
} }
} }
while(taskImageQueue.Size() > 30) while(taskImageQueue.Size() > 25 * OutputDeleyTime)
{ {
taskImageQueue.Pop(image); taskImageQueue.Pop(image);
} }
......
...@@ -37,6 +37,15 @@ Image::Image(ComPtr<IDeckLinkVideoInputFrame> videoFrame) ...@@ -37,6 +37,15 @@ Image::Image(ComPtr<IDeckLinkVideoInputFrame> videoFrame)
ConvertDeckLinkVideoFrame2Mat(inVideoFrame, mat); ConvertDeckLinkVideoFrame2Mat(inVideoFrame, mat);
} }
Image::Image(ComPtr<IDeckLinkVideoInputFrame> videoFrame, qint64 curtimestamp):inputFrameCurTimeStamp(curtimestamp)
{
if (videoFrame->GetWidth() != 1920 || videoFrame->GetHeight() != 1080)
{
return;
}
inVideoFrame = MakeComPtr<DeckLinkInputVideoFrame>(videoFrame.Get());
ConvertDeckLinkVideoFrame2Mat(inVideoFrame, mat);
}
Image::Image(const Image& other) Image::Image(const Image& other)
{ {
......
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