Commit f9433419 by wangguotao

解决延迟不准问题 解决ndi输出卡顿问题

parent c3dcb986
...@@ -87,6 +87,7 @@ private: ...@@ -87,6 +87,7 @@ private:
int Index; int Index;
bool PrevInputSignalAbsent; bool PrevInputSignalAbsent;
bool HasVideo = false;
int m_fps; int m_fps;
uint64_t m_lastRecvTS = 0; uint64_t m_lastRecvTS = 0;
......
...@@ -62,7 +62,8 @@ private: ...@@ -62,7 +62,8 @@ private:
std::shared_ptr<AudioConvert> AudioCvtPtr; std::shared_ptr<AudioConvert> AudioCvtPtr;
std::thread audio_thread; std::thread audio_thread;
qint32 deleyTime_; qint32 deleyTime_{0};
qint32 queue_max_size{0};
int64_t current_v_sleep_ms = 0; int64_t current_v_sleep_ms = 0;
int64_t current_a_sleep_ms = 0; int64_t current_a_sleep_ms = 0;
}; };
\ No newline at end of file
...@@ -260,4 +260,11 @@ private: ...@@ -260,4 +260,11 @@ private:
std::shared_ptr<VideoScale> video_scale_ptr; std::shared_ptr<VideoScale> video_scale_ptr;
int last_scale_w = 0; int last_scale_w = 0;
int last_scale_h = 0; int last_scale_h = 0;
uint8_t* buff1 = NULL;
qint32 buff1_size = 0;
uint8_t* buff2 = NULL;
qint32 buff2_size = 0;
uint8_t* buff3 = NULL;
qint32 buff3_size = 0;
}; };
\ No newline at end of file
...@@ -105,6 +105,7 @@ HRESULT DeckLinkInputDevice::VideoInputFrameArrived(IDeckLinkVideoInputFrame* vi ...@@ -105,6 +105,7 @@ HRESULT DeckLinkInputDevice::VideoInputFrameArrived(IDeckLinkVideoInputFrame* vi
{ {
auto cur_time = QDateTime::currentMSecsSinceEpoch(); auto cur_time = QDateTime::currentMSecsSinceEpoch();
Capture->AddFrame(frame, cur_time); Capture->AddFrame(frame, cur_time);
if (!HasVideo) HasVideo = true;
/*std::string path = "d:\\1080\\yuv\\" + std::to_string(cur_time); /*std::string path = "d:\\1080\\yuv\\" + std::to_string(cur_time);
FILE* fp = fopen(path.c_str(), "wb"); FILE* fp = fopen(path.c_str(), "wb");
auto h = videoFrame->GetHeight(); auto h = videoFrame->GetHeight();
...@@ -130,7 +131,7 @@ HRESULT DeckLinkInputDevice::VideoInputFrameArrived(IDeckLinkVideoInputFrame* vi ...@@ -130,7 +131,7 @@ HRESULT DeckLinkInputDevice::VideoInputFrameArrived(IDeckLinkVideoInputFrame* vi
m_lastRecvTS = currTime; m_lastRecvTS = currTime;
}*/ }*/
} }
if(audioPacket) if(audioPacket && HasVideo)
{ {
//qDebug() << "DeckLinkInputDevice get audio packet--------------" << "\n"; //qDebug() << "DeckLinkInputDevice get audio packet--------------" << "\n";
auto cur_time = QDateTime::currentMSecsSinceEpoch(); auto cur_time = QDateTime::currentMSecsSinceEpoch();
......
...@@ -356,7 +356,7 @@ void DeckLinkInputPage::ObjectNameChanged(const QString& newName) ...@@ -356,7 +356,7 @@ void DeckLinkInputPage::ObjectNameChanged(const QString& newName)
NDIOutput = std::make_unique<NDIOutputThread>(NDINameLabel->text(), 1920, 1080); NDIOutput = std::make_unique<NDIOutputThread>(NDINameLabel->text(), 1920, 1080);
connect(Capture.get(), SIGNAL(PushFrame(std::shared_ptr<Image>)), NDIOutput.get(), SLOT(AddFrame(std::shared_ptr<Image>))); connect(Capture.get(), SIGNAL(PushFrame(std::shared_ptr<Image>)), NDIOutput.get(), SLOT(AddFrame(std::shared_ptr<Image>)), Qt::DirectConnection);
END_SLOT_TIME_COUNTER END_SLOT_TIME_COUNTER
} }
......
...@@ -35,7 +35,8 @@ DeckLinkOutputDevice::DeckLinkOutputDevice(ComPtr<IDeckLink>& decklink, int vide ...@@ -35,7 +35,8 @@ DeckLinkOutputDevice::DeckLinkOutputDevice(ComPtr<IDeckLink>& decklink, int vide
if (!deckLinkOutput) if (!deckLinkOutput)
throw std::runtime_error("DeckLink device does not have an output interface."); throw std::runtime_error("DeckLink device does not have an output interface.");
//current_sleep_ms = OutputDeleyTime * 1000; //current_sleep_ms = OutputDeleyTime * 1000;
queue_max_size = (output_deley_ms / 1000 + 3) * 50; //queue_max_size = (output_deley_ms / 1000 + 3) * 50;
queue_max_size = (output_deley_ms + 3000) * 50 / 1000;
//InitResource(); //InitResource();
} }
...@@ -650,7 +651,8 @@ void DeckLinkOutputDevice::AddAudioFrame(std::shared_ptr<AudioPacket> audio_pack ...@@ -650,7 +651,8 @@ void DeckLinkOutputDevice::AddAudioFrame(std::shared_ptr<AudioPacket> audio_pack
if (outputAudioFrameQueue.Size() > queue_max_size) if (outputAudioFrameQueue.Size() > queue_max_size)
{ {
qDebug() << "index:" << Index << ",outputAudioFrameQueue will reset,and size:" << outputAudioFrameQueue.Size() <<"\n"; qDebug() << "index:" << Index << ",outputAudioFrameQueue will reset,and size:" << outputAudioFrameQueue.Size() <<"\n";
outputAudioFrameQueue.Reset(); //outputAudioFrameQueue.Reset();
outputAudioFrameQueue.Pop();
} }
if (audio_packet) if (audio_packet)
{ {
...@@ -696,5 +698,6 @@ void DeckLinkOutputDevice::InitResource() ...@@ -696,5 +698,6 @@ void DeckLinkOutputDevice::InitResource()
void DeckLinkOutputDevice::SetDeleyTime(qint32& deleyTime) void DeckLinkOutputDevice::SetDeleyTime(qint32& deleyTime)
{ {
output_deley_ms = deleyTime; output_deley_ms = deleyTime;
queue_max_size = (output_deley_ms / 1000 + 3) * 50; //queue_max_size = (output_deley_ms / 1000 + 3) * 50;
queue_max_size = (output_deley_ms + 3000) * 50 / 1000;
} }
...@@ -288,8 +288,8 @@ void DeckLinkOutputPage::RequestedDeviceGranted(ComPtr<IDeckLink>& device) ...@@ -288,8 +288,8 @@ void DeckLinkOutputPage::RequestedDeviceGranted(ComPtr<IDeckLink>& device)
// TODO: Connect // TODO: Connect
connect(BindingInputPage->GetCapture(), &CaptureThread::PushFrame, Process.get(), &ProcessThread::AddFrame); connect(BindingInputPage->GetCapture(), &CaptureThread::PushFrame, Process.get(), &ProcessThread::AddFrame);
connect(Process.get(), &ProcessThread::PushFrame, NDIOutput.get(), &NDIOutputThread::AddFrame); connect(Process.get(), &ProcessThread::PushFrame, NDIOutput.get(), &NDIOutputThread::AddFrame, Qt::DirectConnection);
connect(Process.get(), &ProcessThread::PushFrame, SelectedDevice.Get(), &DeckLinkOutputDevice::AddFrame); connect(Process.get(), &ProcessThread::PushFrame, SelectedDevice.Get(), &DeckLinkOutputDevice::AddFrame, Qt::DirectConnection);
connect(BindingInputPage->GetSelectedDevice().Get(), &DeckLinkInputDevice::PushAudioFrame, SelectedDevice.Get(), &DeckLinkOutputDevice::AddAudioFrame); connect(BindingInputPage->GetSelectedDevice().Get(), &DeckLinkInputDevice::PushAudioFrame, SelectedDevice.Get(), &DeckLinkOutputDevice::AddAudioFrame);
connect(BindingInputPage->GetSelectedDevice().Get(), &DeckLinkInputDevice::PushAudioFrame, NDIOutput.get(), &NDIOutputThread::AddAudioFrame); connect(BindingInputPage->GetSelectedDevice().Get(), &DeckLinkInputDevice::PushAudioFrame, NDIOutput.get(), &NDIOutputThread::AddAudioFrame);
......
...@@ -32,7 +32,7 @@ bool HaveBlackDataFlag = true; ...@@ -32,7 +32,7 @@ bool HaveBlackDataFlag = true;
int main_ver = 2; int main_ver = 2;
int mid_ver = 0; int mid_ver = 0;
int small_ver = 5; int small_ver = 7;
bool scale_enable = true; bool scale_enable = true;
std::atomic_bool bk_flag = false; std::atomic_bool bk_flag = false;
......
...@@ -13,6 +13,7 @@ extern int FrameRate; ...@@ -13,6 +13,7 @@ extern int FrameRate;
#define SAMPLE 9600 #define SAMPLE 9600
#define SAMPLERATE 48000 #define SAMPLERATE 48000
#define QUEUEMAXSIZE 500
NDIOutputThread::NDIOutputThread(const QString& Name, int w, int h, qint32 deleyTime) : NDISenderName(Name), width(w), height(h), deleyTime_(deleyTime), isSending(false), Instance(nullptr), cropFlag(false), AudioCvtPtr(nullptr) NDIOutputThread::NDIOutputThread(const QString& Name, int w, int h, qint32 deleyTime) : NDISenderName(Name), width(w), height(h), deleyTime_(deleyTime), isSending(false), Instance(nullptr), cropFlag(false), AudioCvtPtr(nullptr)
{ {
...@@ -20,6 +21,8 @@ NDIOutputThread::NDIOutputThread(const QString& Name, int w, int h, qint32 deley ...@@ -20,6 +21,8 @@ NDIOutputThread::NDIOutputThread(const QString& Name, int w, int h, qint32 deley
if (index >= 0) if (index >= 0)
{ {
cropFlag = true; cropFlag = true;
//queue_max_size = (deleyTime_ / 1000 + 3) * 50;
queue_max_size = (deleyTime_ + 3000) * 50 / 1000;
} }
} }
...@@ -53,6 +56,7 @@ void NDIOutputThread::SetNDIImageSize(int w, int h) ...@@ -53,6 +56,7 @@ void NDIOutputThread::SetNDIImageSize(int w, int h)
void NDIOutputThread::SetDeleyTime(qint32& deleyTime) void NDIOutputThread::SetDeleyTime(qint32& deleyTime)
{ {
deleyTime_ = deleyTime; deleyTime_ = deleyTime;
queue_max_size = (deleyTime_ + 3000) * 50 / 1000;
} }
bool NDIOutputThread::Init() bool NDIOutputThread::Init()
...@@ -172,7 +176,6 @@ void NDIOutputThread::run() ...@@ -172,7 +176,6 @@ void NDIOutputThread::run()
{ {
current_v_sleep_ms = deleyTime_ - dever_time; current_v_sleep_ms = deleyTime_ - dever_time;
std::this_thread::sleep_for(std::chrono::milliseconds(current_v_sleep_ms)); std::this_thread::sleep_for(std::chrono::milliseconds(current_v_sleep_ms));
} }
} }
else frame->Fill(Frame.p_data, Frame.xres * Frame.yres * 4); else frame->Fill(Frame.p_data, Frame.xres * Frame.yres * 4);
...@@ -204,6 +207,27 @@ void NDIOutputThread::AddFrame(std::shared_ptr<Image> frame) ...@@ -204,6 +207,27 @@ void NDIOutputThread::AddFrame(std::shared_ptr<Image> frame)
{ {
taskQueue.Push(frame); taskQueue.Push(frame);
}*/ }*/
if (cropFlag)
{
if (taskQueue.Size() > queue_max_size)
{
qDebug() << "ndi send VideoQueue size than maxsize ,queue size:" << taskQueue.Size() << "\n";
//taskQueue.Reset();
taskQueue.Pop();
}
}
else
{
if (taskQueue.Size() > QUEUEMAXSIZE)
{
qDebug() << "ndi send VideoQueue size than maxsize ,queue size:" << taskQueue.Size() << "\n";
//taskQueue.Reset();
taskQueue.Pop();
}
}
taskQueue.Push(frame); taskQueue.Push(frame);
END_SLOT_TIME_COUNTER END_SLOT_TIME_COUNTER
......
...@@ -34,6 +34,9 @@ ProcessThread::ProcessThread() ...@@ -34,6 +34,9 @@ ProcessThread::ProcessThread()
ProcessThread::~ProcessThread() ProcessThread::~ProcessThread()
{ {
if (buff1) delete[] buff1;
if (buff2) delete[] buff2;
if (buff3) delete[] buff3;
udpSocket->close(); udpSocket->close();
udpSocket->deleteLater(); udpSocket->deleteLater();
} }
...@@ -187,7 +190,7 @@ void ProcessThread::cutRunFront() ...@@ -187,7 +190,7 @@ void ProcessThread::cutRunFront()
auto itor = cutRuleMap.find(sequence); auto itor = cutRuleMap.find(sequence);
if (itor != cutRuleMap.end()) if (itor != cutRuleMap.end())
{ {
qDebug() << "idx:" << idx << "find rule,sequence: " << sequence << "\n"; //qDebug() << "idx:" << idx << "find rule,sequence: " << sequence << "\n";
lastReceiveMessage = itor->second; lastReceiveMessage = itor->second;
WorkCutImage(image, lastReceiveMessage); WorkCutImage(image, lastReceiveMessage);
taskImageQueue.Pop(); taskImageQueue.Pop();
...@@ -490,44 +493,6 @@ void ProcessThread::run() ...@@ -490,44 +493,6 @@ void ProcessThread::run()
void ProcessThread::WorkCutImage(std::shared_ptr<Image>& pImage, RoiMessage& roi) void ProcessThread::WorkCutImage(std::shared_ptr<Image>& pImage, RoiMessage& roi)
{ {
//roi = lastReceiveMessage;
//START_TIME_COUNTER_BASE(OpenCV)
/*cv::Rect cvroi(roi.X(), roi.Y(), roi.Width(), roi.Height());
cv::Mat mat = image->GetMat().clone();
cv::UMat umat4Image(mat.rows, mat.cols, CV_8UC3);
cv::UMat umat4RotatedImage(810, 1080, CV_8UC3);
cv::cvtColor(mat, umat4Image, cv::COLOR_BGRA2BGR);
cv::UMat umat4ClippedImage = umat4Image(cvroi);
cv::rotate(umat4ClippedImage, umat4RotatedImage, cv::ROTATE_90_CLOCKWISE);
cv::UMat umat4ResizedImage;
cv::resize(umat4RotatedImage, umat4ResizedImage, cv::Size(1440, 1080));
cv::UMat umat4FinalImage = cv::UMat::zeros(cv::Size(1920, 1080), CV_8UC3);
umat4ResizedImage.copyTo(umat4FinalImage(cv::Rect(240, 0, 1440, 1080)));
cv::Mat finalmat;
cv::cvtColor(umat4FinalImage, finalmat, cv::COLOR_BGR2BGRA);
image->SetMat(finalmat);*/
/*std::string tag = "ProcessThread::run::start::" + std::to_string(idx);
const char* tags = tag.c_str();*/
//PRINT_CURR_TIME(tags);
//if (taskImageQueue.Size() >= 4)
// qDebug() << "ProcessThread::run::qsize::" << idx << "\t" << taskImageQueue.Size() << "\n";
//qDebug() << "ROI- " << idx << " " << roi.X() << " " << roi.Y() << " " << roi.Width() << " " << roi.Height() << "\n";
int x = 0, y = 0; int x = 0, y = 0;
int center_x = roi.CenterX(); int center_x = roi.CenterX();
...@@ -536,19 +501,22 @@ void ProcessThread::WorkCutImage(std::shared_ptr<Image>& pImage, RoiMessage& roi ...@@ -536,19 +501,22 @@ void ProcessThread::WorkCutImage(std::shared_ptr<Image>& pImage, RoiMessage& roi
else if ((center_x - half) < 0) x = 0; else if ((center_x - half) < 0) x = 0;
else x = center_x - half; else x = center_x - half;
#if USE_1080P #if USE_1080P
//qDebug() << "wgt------------idx:" << idx << ",cut image of timestamp : " << pImage->getInputFrameCurTimeStamp() << ", cur image of x : " << roi.X() << "\n"; size_t size = roi.Width() * roi.Height() << 2;
/*if (!aspec_num) aspec_num = AspecNum; if (!buff1)
if (!aspec_den) aspec_den = AspecDen;
while ((aspec_den != AspecDen) || (aspec_num != AspecNum))
{ {
aspec_num = AspecNum; buff1 = new uint8_t[size];
aspec_den = AspecDen; buff1_size = size;
std::this_thread::sleep_for(std::chrono::milliseconds(1));
} }
int correct_w = roi.Height() * aspec_den / aspec_num;*/ else
{
size_t size = roi.Width() * roi.Height() << 2; if (size != buff1_size)
uint8_t* buff1 = new uint8_t[size]; {
delete buff1;
buff1 = new uint8_t[size];
buff1_size = size;
}
}
//uint8_t* buff1 = new uint8_t[size];
libyuv::ConvertToARGB(pImage->GetBytes(), (1920 * 1080 << 2), buff1, (roi.Height() << 2), libyuv::ConvertToARGB(pImage->GetBytes(), (1920 * 1080 << 2), buff1, (roi.Height() << 2),
x, y, 1920, 1080, roi.Width(), roi.Height(), x, y, 1920, 1080, roi.Width(), roi.Height(),
libyuv::kRotate90, libyuv::FOURCC_ARGB); libyuv::kRotate90, libyuv::FOURCC_ARGB);
...@@ -564,9 +532,15 @@ void ProcessThread::WorkCutImage(std::shared_ptr<Image>& pImage, RoiMessage& roi ...@@ -564,9 +532,15 @@ void ProcessThread::WorkCutImage(std::shared_ptr<Image>& pImage, RoiMessage& roi
//int scale_mode = map_scale_mode[key]; //int scale_mode = map_scale_mode[key];
int scale_mode = libyuv::kFilterNone; int scale_mode = libyuv::kFilterNone;
int dstw = 1920, dsth = 1080, scalew = 0, scaleh = 1080; int dstw = 1920, dsth = 1080, scalew = 0, scaleh = 1080;
uint8_t* buff2 = NULL; //uint8_t* buff2 = NULL;
uint8_t* buff3 = new uint8_t[dstw * dsth << 2]; size = dstw * dsth << 2;
memset(buff3, 0, (dstw * dsth << 2)); if (!buff3)
{
this->buff3_size = size;
buff3 = new uint8_t[buff3_size];
}
//uint8_t* buff3 = new uint8_t[dstw * dsth << 2];
memset(buff3, 0, size);
if (bk_flag && bk_mat.data) if (bk_flag && bk_mat.data)
{ {
...@@ -613,13 +587,22 @@ void ProcessThread::WorkCutImage(std::shared_ptr<Image>& pImage, RoiMessage& roi ...@@ -613,13 +587,22 @@ void ProcessThread::WorkCutImage(std::shared_ptr<Image>& pImage, RoiMessage& roi
} }
} }
#else #else
buff2 = new uint8_t[scalew * scaleh << 2]; size = scalew * scaleh << 2;
/*cv::Mat kernel = (cv::Mat_<float>(3, 3) << if (!buff2)
0, -1, 0, {
-1, 5, -1, buff2 = new uint8_t[size];
0, -1, 0); buff2_size = size;
cv::Mat bgra1 = cv::Mat(roi.Width(), roi.Height(), CV_8UC4, buff1); }
filter2D(bgra1, bgra1, -1, kernel);*/ else
{
if (size != buff2_size)
{
delete buff2;
buff2 = new uint8_t[size];
buff2_size = size;
}
}
libyuv::ARGBScale(buff1, (roi.Height() << 2), roi.Height(), roi.Width(), libyuv::ARGBScale(buff1, (roi.Height() << 2), roi.Height(), roi.Width(),
buff2, scalew << 2, scalew, scaleh, libyuv::FilterMode(scale_mode)); buff2, scalew << 2, scalew, scaleh, libyuv::FilterMode(scale_mode));
...@@ -670,9 +653,9 @@ void ProcessThread::WorkCutImage(std::shared_ptr<Image>& pImage, RoiMessage& roi ...@@ -670,9 +653,9 @@ void ProcessThread::WorkCutImage(std::shared_ptr<Image>& pImage, RoiMessage& roi
pImage->SetMat(bgra); pImage->SetMat(bgra);
if(buff1) delete[] buff1; /*if(buff1) delete[] buff1;
if(buff2) delete[] buff2; if(buff2) delete[] buff2;
if(buff3) delete[] buff3; if(buff3) delete[] buff3;*/
emit PushFrame(pImage); emit PushFrame(pImage);
last_scale_h = scaleh; last_scale_h = scaleh;
last_scale_w = scalew; last_scale_w = scalew;
......
...@@ -4,9 +4,9 @@ FRAME_RATE=50 ...@@ -4,9 +4,9 @@ FRAME_RATE=50
PRVW_FLAG=0 PRVW_FLAG=0
OUTPUT_PLAY_MODE=0 OUTPUT_PLAY_MODE=0
BLACK_BOTTOM_HEIGHT=0 BLACK_BOTTOM_HEIGHT=0
AUDIO_CHANNEL=8 AUDIO_CHANNEL=2
ASPEC_DEN=9 ASPEC_DEN=3
ASPEC_NUM=16 ASPEC_NUM=4
SCALE_MODE=0 SCALE_MODE=0
SCALE_MODE_1=3 SCALE_MODE_1=3
SCALE_MODE_2=0 SCALE_MODE_2=0
...@@ -22,6 +22,6 @@ NDI_DELEY_TIME_2=5000 ...@@ -22,6 +22,6 @@ NDI_DELEY_TIME_2=5000
NDI_DELEY_TIME_3=5000 NDI_DELEY_TIME_3=5000
NDI_DELEY_TIME_4=5000 NDI_DELEY_TIME_4=5000
BLACK_BOTTOM_HEIGHT_1=300 BLACK_BOTTOM_HEIGHT_1=300
BLACK_BOTTOM_HEIGHT_2=10 BLACK_BOTTOM_HEIGHT_2=300
BLACK_BOTTOM_HEIGHT_3=500 BLACK_BOTTOM_HEIGHT_3=500
BLACK_BOTTOM_HEIGHT_4=300 BLACK_BOTTOM_HEIGHT_4=300
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