Commit f9433419 by wangguotao

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

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