ledset优化丢包问题
This commit is contained in:
parent
caf3ef0add
commit
b6e2a745f4
|
@ -11,6 +11,7 @@
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -74,7 +75,7 @@ QByteArray getNetDev(QWidget *parent) {
|
||||||
auto dlg = new BaseDlg(parent);
|
auto dlg = new BaseDlg(parent);
|
||||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
dlg->setWindowTitle("选择网卡");
|
dlg->setWindowTitle("选择网卡");
|
||||||
dlg->resize(1200, 300);
|
dlg->resize(900, 300);
|
||||||
|
|
||||||
auto vBox = new QVBoxLayout(dlg->center);
|
auto vBox = new QVBoxLayout(dlg->center);
|
||||||
vBox->setContentsMargins(0,0,0,0);
|
vBox->setContentsMargins(0,0,0,0);
|
||||||
|
@ -125,12 +126,12 @@ VideoWin *VideoWin::newIns(QWidget *parent) {
|
||||||
auto name = getNetDev(parent);
|
auto name = getNetDev(parent);
|
||||||
if(name.isEmpty()) return 0;
|
if(name.isEmpty()) return 0;
|
||||||
char errbuf[PCAP_ERRBUF_SIZE]{'\0'};
|
char errbuf[PCAP_ERRBUF_SIZE]{'\0'};
|
||||||
auto pcapRe = pcap_open(name.data(), 65535, PCAP_OPENFLAG_PROMISCUOUS | PCAP_OPENFLAG_MAX_RESPONSIVENESS, 15, 0, errbuf);
|
auto pcapRe = pcap_open_live(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS, 50, errbuf);
|
||||||
if(pcapRe == 0) {
|
if(pcapRe == 0) {
|
||||||
QMessageBox::critical(parent, "Error", QString("打开网卡失败")+errbuf);
|
QMessageBox::critical(parent, "Error", QString("打开网卡失败")+errbuf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
auto pcapSend = pcap_open(name.data(), 65535, 0, 15, 0, errbuf);
|
auto pcapSend = pcap_open_live(name.data(), 65536, 0, 50, errbuf);
|
||||||
if(pcapSend == 0) {
|
if(pcapSend == 0) {
|
||||||
QMessageBox::critical(parent, "Error", QString("打开网卡失败")+errbuf);
|
QMessageBox::critical(parent, "Error", QString("打开网卡失败")+errbuf);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -153,14 +154,14 @@ VideoWin::VideoWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWi
|
||||||
|
|
||||||
fdWidth = new QSpinBox;
|
fdWidth = new QSpinBox;
|
||||||
fdWidth->setRange(1, 9999);
|
fdWidth->setRange(1, 9999);
|
||||||
fdWidth->setValue(320);
|
fdWidth->setValue(640);
|
||||||
hBox->addWidget(fdWidth);
|
hBox->addWidget(fdWidth);
|
||||||
|
|
||||||
hBox->addWidget(new QLabel("x"));
|
hBox->addWidget(new QLabel("x"));
|
||||||
|
|
||||||
fdHeight = new QSpinBox;
|
fdHeight = new QSpinBox;
|
||||||
fdHeight->setRange(1, 9999);
|
fdHeight->setRange(1, 9999);
|
||||||
fdHeight->setValue(180);
|
fdHeight->setValue(360);
|
||||||
hBox->addWidget(fdHeight);
|
hBox->addWidget(fdHeight);
|
||||||
|
|
||||||
hBox->addSpacing(20);
|
hBox->addSpacing(20);
|
||||||
|
@ -193,19 +194,32 @@ VideoWin::VideoWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWi
|
||||||
hBox = new HBox(vBox);
|
hBox = new HBox(vBox);
|
||||||
|
|
||||||
hBox->addWidget(new QLabel("接收:"));
|
hBox->addWidget(new QLabel("接收:"));
|
||||||
|
hBox->addSpacing(20);
|
||||||
|
hBox->addWidget(new QLabel("丢包次数: "));
|
||||||
|
hBox->addWidget(fdLostTimes = new QLabel);
|
||||||
|
fdLostTimes->setMinimumWidth(40);
|
||||||
|
hBox->addWidget(new QLabel("丢包数: "));
|
||||||
|
hBox->addWidget(fdLostPkts = new QLabel);
|
||||||
|
fdLostPkts->setMinimumWidth(40);
|
||||||
hBox->addStretch();
|
hBox->addStretch();
|
||||||
|
|
||||||
auto fdReceive = new QLabel;
|
auto fdCanvas = new Canvas;
|
||||||
vBox->addWidget(fdReceive, 1);
|
vBox->addWidget(fdCanvas, 1);
|
||||||
|
|
||||||
thdRece = new VideoRecThread(pcapRece);
|
thdRece = new VideoRecThread(pcapRece);
|
||||||
connect(thdRece, &QThread::finished, this, [this] {
|
connect(thdRece, &QThread::finished, this, [this] {
|
||||||
thdRece = 0;
|
thdRece = 0;
|
||||||
});
|
});
|
||||||
connect(thdRece, &VideoRecThread::onMsg, fdReceive, [fdReceive](QImage img) {
|
connect(thdRece, &VideoRecThread::onMsg, fdCanvas, [this, fdCanvas](QImage img, int lostTimes, int lostPkts) {
|
||||||
fdReceive->setPixmap(QPixmap::fromImage(img));
|
fdCanvas->img = img;
|
||||||
|
fdCanvas->update();
|
||||||
|
if(lostPkts==0) return;
|
||||||
|
this->lostTimes += lostTimes;
|
||||||
|
this->lostPkts += lostPkts;
|
||||||
|
fdLostTimes->setText(QString::number(this->lostTimes));
|
||||||
|
fdLostPkts->setText(QString::number(this->lostPkts));
|
||||||
});
|
});
|
||||||
thdRece->start();
|
thdRece->start(QThread::TimeCriticalPriority);
|
||||||
|
|
||||||
sendThd = new VideoSendThread(pcapSend);
|
sendThd = new VideoSendThread(pcapSend);
|
||||||
connect(sendThd, &QThread::finished, this, [this] {
|
connect(sendThd, &QThread::finished, this, [this] {
|
||||||
|
@ -247,6 +261,7 @@ VideoSendThread::VideoSendThread(pcap_t *pcap) : pcap(pcap) {
|
||||||
#define MAX_ONCE 1482
|
#define MAX_ONCE 1482
|
||||||
void VideoSendThread::run() {
|
void VideoSendThread::run() {
|
||||||
QImage img;
|
QImage img;
|
||||||
|
quint32 idx = 0;
|
||||||
while(status!=2) {
|
while(status!=2) {
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mtx);
|
std::lock_guard<std::mutex> lock(mtx);
|
||||||
|
@ -284,7 +299,8 @@ void VideoSendThread::run() {
|
||||||
} else once = lineLen;
|
} else once = lineLen;
|
||||||
auto bytesPerLine = img.bytesPerLine();
|
auto bytesPerLine = img.bytesPerLine();
|
||||||
auto bits = img.constBits();
|
auto bits = img.constBits();
|
||||||
for(uint i=0; i<img.height(); i++) for(uint j=0; j<lineLen; j+=once) {
|
idx = 0;
|
||||||
|
for(int i=0; i<img.height(); i++) for(int j=0; j<lineLen; j+=once) {
|
||||||
int dataLen = lineLen - j;
|
int dataLen = lineLen - j;
|
||||||
if(dataLen > once) dataLen = once;
|
if(dataLen > once) dataLen = once;
|
||||||
dataLen += 4;
|
dataLen += 4;
|
||||||
|
@ -297,7 +313,8 @@ void VideoSendThread::run() {
|
||||||
bytes.append(2, 0); //应答填充项
|
bytes.append(2, 0); //应答填充项
|
||||||
crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2);
|
crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2);
|
||||||
bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
|
bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
|
||||||
bytes.append(i>>24).append(i>>16).append(i>>8).append(i);
|
bytes.append(idx>>24).append(idx>>16).append(idx>>8).append(idx);
|
||||||
|
idx++;
|
||||||
bytes.append((const char*)bits + i * bytesPerLine + j, dataLen - 4);
|
bytes.append((const char*)bits + i * bytesPerLine + j, dataLen - 4);
|
||||||
crc32 = crc32_calc((uint8_t*)bytes.data()+bytes.length()-dataLen, dataLen);
|
crc32 = crc32_calc((uint8_t*)bytes.data()+bytes.length()-dataLen, dataLen);
|
||||||
bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
|
bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
|
||||||
|
@ -321,9 +338,9 @@ void VideoSendThread::run() {
|
||||||
onErr(QString("添加结束失败: ")+pcap_geterr(pcap));
|
onErr(QString("添加结束失败: ")+pcap_geterr(pcap));
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
int res;
|
u_int res;
|
||||||
if((res = pcap_sendqueue_transmit(pcap, queue, 0)) < queue->len) {
|
if((res = pcap_sendqueue_transmit(pcap, queue, 0)) < queue->len) {
|
||||||
onErr(QString::asprintf("发送包出错: %s. 仅发了 %d bytes", pcap_geterr(pcap), res));
|
onErr(QString::asprintf("发送包出错: %s. 仅发了 %d / %d bytes", pcap_geterr(pcap), res, queue->len));
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,6 +349,27 @@ void VideoSendThread::run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Callback function invoked by libpcap for every incoming packet */
|
||||||
|
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) {
|
||||||
|
struct tm ltime;
|
||||||
|
char timestr[16];
|
||||||
|
time_t local_tv_sec;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unused variables
|
||||||
|
*/
|
||||||
|
(VOID)(param);
|
||||||
|
(VOID)(pkt_data);
|
||||||
|
|
||||||
|
/* convert the timestamp to readable format */
|
||||||
|
local_tv_sec = header->ts.tv_sec;
|
||||||
|
localtime_s(<ime, &local_tv_sec);
|
||||||
|
strftime( timestr, sizeof timestr, "%H:%M:%S", <ime);
|
||||||
|
|
||||||
|
printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
VideoRecThread::VideoRecThread(pcap_t *pcap) : pcap(pcap) {
|
VideoRecThread::VideoRecThread(pcap_t *pcap) : pcap(pcap) {
|
||||||
connect(this, &QThread::finished, this, &QThread::deleteLater);
|
connect(this, &QThread::finished, this, &QThread::deleteLater);
|
||||||
}
|
}
|
||||||
|
@ -340,21 +378,41 @@ void VideoRecThread::run() {
|
||||||
const u_char *data;
|
const u_char *data;
|
||||||
QImage img;
|
QImage img;
|
||||||
int res;
|
int res;
|
||||||
|
int lastIdx = -1;
|
||||||
|
int lostTimes{0}, lostPkts{0};
|
||||||
while((res = pcap_next_ex(pcap, &header, &data)) >= 0) {
|
while((res = pcap_next_ex(pcap, &header, &data)) >= 0) {
|
||||||
if(status==2) return;
|
if(status==2) return;
|
||||||
if(status==1 || res == 0) continue; //超时
|
if(status==1 || res == 0) continue; //超时
|
||||||
if(header->caplen<24) continue;
|
if(header->caplen<24) continue;
|
||||||
if(data[0]!=0x55 || data[1]!=0x55) continue;
|
if(data[0]!=0x55 || data[1]!=0x55) continue;
|
||||||
if(data[2]==0x9a && data[3]==0x3d) {
|
if(data[2]==0x9a && data[3]==0x3d) {
|
||||||
if(data[17]==0xBB) img = QImage(((int)data[24] << 8) + data[25], ((int)data[26] << 8) + data[27], QImage::Format_RGB888);
|
if(data[17]==0xBB) {
|
||||||
else if(data[17]==0xCC) emit onMsg(img);
|
img = QImage(((int)data[24] << 8) + data[25], ((int)data[26] << 8) + data[27], QImage::Format_RGB888);
|
||||||
|
lastIdx = -1;
|
||||||
|
lostTimes = 0;
|
||||||
|
lostPkts = 0;
|
||||||
|
} else if(data[17]==0xCC) emit onMsg(img, lostTimes, lostPkts);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(data[2]!=0x1 || data[3]!=0x33) continue;
|
if(data[2]!=0x1 || data[3]!=0x33) continue;
|
||||||
int len = ((int)data[4] << 8) + data[5];
|
int len = ((int)data[4] << 8) + data[5];
|
||||||
int row = ((int)data[14] << 8) + data[15];
|
int row = ((int)data[14] << 8) + data[15];
|
||||||
int col = ((int)data[16] << 8) + data[17];
|
int col = ((int)data[16] << 8) + data[17];
|
||||||
|
quint32 idx = ((quint32)data[24] << 24) + ((quint32)data[25] << 16) + ((quint32)data[26] << 8) + data[27];
|
||||||
|
//auto epoch = chrono::duration_cast<chrono::microseconds>(chrono::steady_clock::now().time_since_epoch()).count();
|
||||||
memcpy(img.bits()+row*img.bytesPerLine()+col, &data[28], len-4);
|
memcpy(img.bits()+row*img.bytesPerLine()+col, &data[28], len-4);
|
||||||
|
int diff = idx - lastIdx - 1;
|
||||||
|
lastIdx = idx;
|
||||||
|
if(diff > 0) {
|
||||||
|
//qDebug()<<"丢包"<<diff;
|
||||||
|
lostTimes++;
|
||||||
|
lostPkts += diff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
emit onErr(pcap_geterr(pcap));
|
emit onErr(pcap_geterr(pcap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Canvas::paintEvent(QPaintEvent *event) {
|
||||||
|
QPainter painter(this);
|
||||||
|
painter.drawImage(0, 0, img);
|
||||||
|
}
|
||||||
|
|
|
@ -44,10 +44,17 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void run();
|
void run();
|
||||||
signals:
|
signals:
|
||||||
void onMsg(QImage);
|
void onMsg(QImage, int, int);
|
||||||
void onErr(char *);
|
void onErr(char *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Canvas : public QWidget {
|
||||||
|
public:
|
||||||
|
QImage img;
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *event);
|
||||||
|
};
|
||||||
|
|
||||||
class VideoWin : public BaseWin {
|
class VideoWin : public BaseWin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -65,9 +72,10 @@ public:
|
||||||
int timerId{0};
|
int timerId{0};
|
||||||
QSpinBox *fdWidth, *fdHeight;
|
QSpinBox *fdWidth, *fdHeight;
|
||||||
QRadioButton *fdEnd;
|
QRadioButton *fdEnd;
|
||||||
QLabel *fdInfo;
|
QLabel *fdInfo, *fdLostTimes, *fdLostPkts;
|
||||||
QString info;
|
QString info;
|
||||||
qint64 last_epoch{0};
|
qint64 last_epoch{0};
|
||||||
|
int lostTimes{0}, lostPkts{0};
|
||||||
protected:
|
protected:
|
||||||
void timerEvent(QTimerEvent *event) override;
|
void timerEvent(QTimerEvent *event) override;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user