ledset优化丢包问题
This commit is contained in:
parent
caf3ef0add
commit
b6e2a745f4
|
@ -11,6 +11,7 @@
|
|||
#include <QDesktopWidget>
|
||||
#include <QScreen>
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -74,7 +75,7 @@ QByteArray getNetDev(QWidget *parent) {
|
|||
auto dlg = new BaseDlg(parent);
|
||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dlg->setWindowTitle("选择网卡");
|
||||
dlg->resize(1200, 300);
|
||||
dlg->resize(900, 300);
|
||||
|
||||
auto vBox = new QVBoxLayout(dlg->center);
|
||||
vBox->setContentsMargins(0,0,0,0);
|
||||
|
@ -125,12 +126,12 @@ VideoWin *VideoWin::newIns(QWidget *parent) {
|
|||
auto name = getNetDev(parent);
|
||||
if(name.isEmpty()) return 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) {
|
||||
QMessageBox::critical(parent, "Error", QString("打开网卡失败")+errbuf);
|
||||
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) {
|
||||
QMessageBox::critical(parent, "Error", QString("打开网卡失败")+errbuf);
|
||||
return 0;
|
||||
|
@ -153,14 +154,14 @@ VideoWin::VideoWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWi
|
|||
|
||||
fdWidth = new QSpinBox;
|
||||
fdWidth->setRange(1, 9999);
|
||||
fdWidth->setValue(320);
|
||||
fdWidth->setValue(640);
|
||||
hBox->addWidget(fdWidth);
|
||||
|
||||
hBox->addWidget(new QLabel("x"));
|
||||
|
||||
fdHeight = new QSpinBox;
|
||||
fdHeight->setRange(1, 9999);
|
||||
fdHeight->setValue(180);
|
||||
fdHeight->setValue(360);
|
||||
hBox->addWidget(fdHeight);
|
||||
|
||||
hBox->addSpacing(20);
|
||||
|
@ -193,19 +194,32 @@ VideoWin::VideoWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWi
|
|||
hBox = new HBox(vBox);
|
||||
|
||||
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();
|
||||
|
||||
auto fdReceive = new QLabel;
|
||||
vBox->addWidget(fdReceive, 1);
|
||||
auto fdCanvas = new Canvas;
|
||||
vBox->addWidget(fdCanvas, 1);
|
||||
|
||||
thdRece = new VideoRecThread(pcapRece);
|
||||
connect(thdRece, &QThread::finished, this, [this] {
|
||||
thdRece = 0;
|
||||
});
|
||||
connect(thdRece, &VideoRecThread::onMsg, fdReceive, [fdReceive](QImage img) {
|
||||
fdReceive->setPixmap(QPixmap::fromImage(img));
|
||||
connect(thdRece, &VideoRecThread::onMsg, fdCanvas, [this, fdCanvas](QImage img, int lostTimes, int lostPkts) {
|
||||
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);
|
||||
connect(sendThd, &QThread::finished, this, [this] {
|
||||
|
@ -247,6 +261,7 @@ VideoSendThread::VideoSendThread(pcap_t *pcap) : pcap(pcap) {
|
|||
#define MAX_ONCE 1482
|
||||
void VideoSendThread::run() {
|
||||
QImage img;
|
||||
quint32 idx = 0;
|
||||
while(status!=2) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
|
@ -284,7 +299,8 @@ void VideoSendThread::run() {
|
|||
} else once = lineLen;
|
||||
auto bytesPerLine = img.bytesPerLine();
|
||||
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;
|
||||
if(dataLen > once) dataLen = once;
|
||||
dataLen += 4;
|
||||
|
@ -297,7 +313,8 @@ void VideoSendThread::run() {
|
|||
bytes.append(2, 0); //应答填充项
|
||||
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(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);
|
||||
crc32 = crc32_calc((uint8_t*)bytes.data()+bytes.length()-dataLen, dataLen);
|
||||
bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
|
||||
|
@ -321,9 +338,9 @@ void VideoSendThread::run() {
|
|||
onErr(QString("添加结束失败: ")+pcap_geterr(pcap));
|
||||
goto end;
|
||||
}
|
||||
int res;
|
||||
u_int res;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
connect(this, &QThread::finished, this, &QThread::deleteLater);
|
||||
}
|
||||
|
@ -340,21 +378,41 @@ void VideoRecThread::run() {
|
|||
const u_char *data;
|
||||
QImage img;
|
||||
int res;
|
||||
int lastIdx = -1;
|
||||
int lostTimes{0}, lostPkts{0};
|
||||
while((res = pcap_next_ex(pcap, &header, &data)) >= 0) {
|
||||
if(status==2) return;
|
||||
if(status==1 || res == 0) continue; //超时
|
||||
if(header->caplen<24) continue;
|
||||
if(data[0]!=0x55 || data[1]!=0x55) continue;
|
||||
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);
|
||||
else if(data[17]==0xCC) emit onMsg(img);
|
||||
if(data[17]==0xBB) {
|
||||
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;
|
||||
}
|
||||
if(data[2]!=0x1 || data[3]!=0x33) continue;
|
||||
int len = ((int)data[4] << 8) + data[5];
|
||||
int row = ((int)data[14] << 8) + data[15];
|
||||
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);
|
||||
int diff = idx - lastIdx - 1;
|
||||
lastIdx = idx;
|
||||
if(diff > 0) {
|
||||
//qDebug()<<"丢包"<<diff;
|
||||
lostTimes++;
|
||||
lostPkts += diff;
|
||||
}
|
||||
}
|
||||
emit onErr(pcap_geterr(pcap));
|
||||
}
|
||||
|
||||
void Canvas::paintEvent(QPaintEvent *event) {
|
||||
QPainter painter(this);
|
||||
painter.drawImage(0, 0, img);
|
||||
}
|
||||
|
|
|
@ -44,10 +44,17 @@ public:
|
|||
protected:
|
||||
void run();
|
||||
signals:
|
||||
void onMsg(QImage);
|
||||
void onMsg(QImage, int, int);
|
||||
void onErr(char *);
|
||||
};
|
||||
|
||||
class Canvas : public QWidget {
|
||||
public:
|
||||
QImage img;
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
};
|
||||
|
||||
class VideoWin : public BaseWin {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -65,9 +72,10 @@ public:
|
|||
int timerId{0};
|
||||
QSpinBox *fdWidth, *fdHeight;
|
||||
QRadioButton *fdEnd;
|
||||
QLabel *fdInfo;
|
||||
QLabel *fdInfo, *fdLostTimes, *fdLostPkts;
|
||||
QString info;
|
||||
qint64 last_epoch{0};
|
||||
int lostTimes{0}, lostPkts{0};
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *event) override;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user