diff --git a/PayloadAPP.pro b/PayloadAPP.pro index b898e74..cd6288f 100644 --- a/PayloadAPP.pro +++ b/PayloadAPP.pro @@ -14,7 +14,7 @@ QMAKE_PROJECT_DEPTH = 0 # QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\" #程序版本 -VERSION = 1.0.0.1014 +VERSION = 1.0.2.1 #程序版本 QMAKE_TARGET_COMPANY = "HTSDFP" diff --git a/Src/GDDC/gddcSet.cpp b/Src/GDDC/gddcSet.cpp index baa9473..08f73ae 100644 --- a/Src/GDDC/gddcSet.cpp +++ b/Src/GDDC/gddcSet.cpp @@ -50,7 +50,8 @@ void GDDCSet::initParam() { ui->comboBox_streamSource->addItem("载荷端"); ui->comboBox_streamSource->setCurrentIndex(0); - ui->lineEdit_pushURL->setText(QStringLiteral("-1")); + ui->comboBox_pushURL->addItem(QStringLiteral("-1")); + ui->comboBox_pushURL->addItem(QStringLiteral("-1")); ui->radioButton_NetCtrlUDP->setChecked(true); ui->radioButton_NetCtrlTCP->setChecked(false); @@ -222,7 +223,7 @@ void GDDCSet::saveDataToLocalIni() { // inBuf, // strSysIniName); - m_pushURL = ui->lineEdit_pushURL->text(); + m_pushURL = ui->comboBox_pushURL->currentText(); ba = m_pushURL.toLocal8Bit(); inBuf = ba.data(); ::WritePrivateProfileStringA("光电吊舱-推流", "推流URL", inBuf, @@ -295,7 +296,10 @@ void GDDCSet::on_uavIDSpinBox_valueChanged(int arg1) { if ("地面端" == streamSource) { QString pushURL = generatePushURL(uavID, QString::fromStdString(iter->second)); - ui->lineEdit_pushURL->setText(pushURL); + QString pushURL2 = + generatePushURL2(uavID, QString::fromStdString(iter->second)); + ui->comboBox_pushURL->setItemText(0, pushURL); + ui->comboBox_pushURL->setItemText(1, pushURL2); } else { QString pullURL = generatePullURL(uavID, QString::fromStdString(iter->second)); diff --git a/Src/GDDC/gddcSet.ui b/Src/GDDC/gddcSet.ui index 90c0ca6..06b2d4e 100644 --- a/Src/GDDC/gddcSet.ui +++ b/Src/GDDC/gddcSet.ui @@ -174,19 +174,6 @@ 推流地址: - - - - 80 - 100 - 421 - 23 - - - - true - - @@ -255,6 +242,16 @@ + + + + 80 + 100 + 421 + 23 + + + diff --git a/Src/ModelCamera/modelcameradlg.ui b/Src/ModelCamera/modelcameradlg.ui index b7dba3d..88dde32 100644 --- a/Src/ModelCamera/modelcameradlg.ui +++ b/Src/ModelCamera/modelcameradlg.ui @@ -23,7 +23,7 @@ - QFrame::Shape::NoFrame + QFrame::NoFrame @@ -44,7 +44,7 @@ - Qt::Orientation::Horizontal + Qt::Horizontal @@ -67,7 +67,7 @@ 4 - 4 + 12 4 @@ -192,7 +192,7 @@ - Qt::Orientation::Vertical + Qt::Vertical @@ -221,7 +221,7 @@ 4 - 4 + 12 4 @@ -400,7 +400,7 @@ - QAbstractSpinBox::ButtonSymbols::NoButtons + QAbstractSpinBox::NoButtons 1 @@ -412,7 +412,7 @@ 25.000000000000000 - QAbstractSpinBox::StepType::DefaultStepType + QAbstractSpinBox::DefaultStepType @@ -434,7 +434,7 @@ 4 - 4 + 12 4 @@ -620,7 +620,7 @@ 4 - 4 + 12 4 @@ -631,7 +631,7 @@ - QLayout::SizeConstraint::SetDefaultConstraint + QLayout::SetDefaultConstraint 5 @@ -941,7 +941,7 @@ ISO: - Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false @@ -1276,7 +1276,7 @@ - Qt::Orientation::Horizontal + Qt::Horizontal @@ -1304,7 +1304,7 @@ } - QFrame::Shape::Box + QFrame::Box diff --git a/Src/Video/cffmpeg_decode.cpp b/Src/Video/cffmpeg_decode.cpp index 484bc70..fcef312 100644 --- a/Src/Video/cffmpeg_decode.cpp +++ b/Src/Video/cffmpeg_decode.cpp @@ -83,10 +83,11 @@ bool Cffmpeg_decode::open_input_file() { av_dict_set(&avdic, "buffer_size", "4096000", 0); // 设置超时断开连接时间,单位微秒//listen_timeout // av_dict_set(&avdic, "listen_timeout", "200000", 0); + // 在尝试连接到一个流或网络资源时,等待的最长时间。如果在这个时间内无法建立连接,就会返回超时错误 av_dict_set(&avdic, "stimeout", "5000000", 0); // 设置超时5秒 - // av_dict_set(&avdic, "max_delay", "300000", 0); // 设置最大时延300ms + av_dict_set(&avdic, "max_delay", "300000", 0); // 设置最大时延300ms av_dict_set(&avdic, "tune", "zerolatency", 0); // 实时编码 - av_dict_set(&avdic, "preset", "faster", 0); // ultrafast + av_dict_set(&avdic, "preset", "ultrafast", 0); // faster av_dict_set(&avdic, "threads", "auto", 0); // 自动开启线程数 // 设置最大重试时间为1s,解决avformat_open_input打开空流时间过长问题 av_dict_set(&avdic, "max_interleave_delta", "1000000", 0); @@ -94,9 +95,10 @@ bool Cffmpeg_decode::open_input_file() { // av_dict_set(&avdic, "reconnect", "1", 0); // 开启自动重连 // av_dict_set(&avdic, "reconnect_streamed", "1", 0); // 对于流媒体自动重连 av_dict_set(&avdic, "reconnect_delay_max", "5", - 0); // 最大重连延时 5 秒f'f'f'f'f'f'f'f'f'f'f + 0); // 最大重连延时 5 秒 // av_dict_set(&avdic, "rtsp_flags", "prefer_tcp", 0); // 保持TCP连接 - // av_dict_set(&avdic, "timeout", "500000", 0); // 超时时间设置为500ms + // av_dict_set(&avdic, "timeout", "8000000", + // 0); // 超时时间(包括连接和数据传输的时间)设置为5s // av_dict_set(&avdic, "probesize", "50000000", 0); // 增加探针大小,1MB // av_dict_set(&avdic, "analyzeduration", "5000000", 0); // // av_dict_set(&avdic, "keepalive", "1", 0); @@ -323,10 +325,11 @@ void Cffmpeg_decode::run() { double elapsed_system_time = av_gettime() - first_frame_system_time; // 计算需要等待的时间(us) double wait_time = elapsed_pts_time - elapsed_system_time; - // qDebug() << "pull stream sleep time:" - // << QString::number(wait_time / 1000.0); - if (wait_time > 0) { - // av_usleep(wait_time); // 延时以同步 PTS + qDebug() << "pull stream sleep time:" + << QString::number(wait_time / 1000.0); + if (wait_time > 0 && bPushStreamFlag) { + av_usleep(wait_time); // 延时以同步 PTS + // sleepMsec(wait_time); } // 更新 previous_pts_time 为当前帧的 PTS previous_pts_time = pts_time; diff --git a/Src/Video/cffmpeg_decode.h b/Src/Video/cffmpeg_decode.h index 6391a2b..caf3b91 100644 --- a/Src/Video/cffmpeg_decode.h +++ b/Src/Video/cffmpeg_decode.h @@ -2,6 +2,7 @@ #define CFFMPEG_DECODE_H #include "ffmpeginclude.h" +#include "global.h" #include #include #include diff --git a/Src/Video/ffmpegpushstream.cpp b/Src/Video/ffmpegpushstream.cpp index 6d08075..f750042 100644 --- a/Src/Video/ffmpegpushstream.cpp +++ b/Src/Video/ffmpegpushstream.cpp @@ -144,10 +144,15 @@ int FFmpegPushStream::pushStream(AVPacket *pkt, int frm_cnt, int64_t startTime, int64_t streamTime = pts_time - firstDts; // 计算帧的相对时间 auto now_time = av_gettime() - startTime; // 获取差值 int64_t delay = streamTime - now_time; - if (delay > 0) { - qDebug() << "****************PushStream sleep time:" - << QString::number(delay / 1000); + delay = delay < MAXDELAY ? delay : MAXDELAY; + if (delay >= 0) { + // qDebug() << "****************PushStream sleep time:" + // << QString::number(delay / 1000); av_usleep(delay); + // sleepMsec(delay); + } else { + // av_packet_unref(pkt); + // return 1; } // 计算延时后,重新指定时间戳 @@ -175,9 +180,9 @@ int FFmpegPushStream::pushStream(AVPacket *pkt, int frm_cnt, int64_t startTime, pkt->stream_index = 0; int ret = av_interleaved_write_frame(outputFormatCtx, pkt); if (ret < 0) { - // if (ret == -10053) { - // qDebug() << "网络不稳定"; - // } + if (ret == -10053) { + qDebug() << "网络不稳定"; + } // if (ret == AVERROR(EPIPE) || ret == AVERROR(ECONNRESET)) { // qDebug() << "网络不稳定1"; // } diff --git a/Src/Video/ffmpegpushstream.h b/Src/Video/ffmpegpushstream.h index b06610b..0326e9e 100644 --- a/Src/Video/ffmpegpushstream.h +++ b/Src/Video/ffmpegpushstream.h @@ -2,6 +2,7 @@ #define FFMPEGPUSHSTREAM_H #include "ffmpeginclude.h" +#include "global.h" #include #include @@ -24,6 +25,7 @@ private: bool mInitStatus = false; int64_t startTime; int MAXCONNECT = 12; + int MAXDELAY = 40000; // 最大休眠时间40ms public slots: int pushStream(AVPacket *pkt, int frm_cnt, int64_t startTime, int64_t firstDts); diff --git a/Src/Video/ffmpegvideodlg.h b/Src/Video/ffmpegvideodlg.h index 60c22a2..ffcf880 100644 --- a/Src/Video/ffmpegvideodlg.h +++ b/Src/Video/ffmpegvideodlg.h @@ -4,6 +4,7 @@ #include "cffmpeg_decode.h" #include "ffmpeginclude.h" #include "ffmpegpushstream.h" +#include "global.h" #include #include #include diff --git a/global.cpp b/global.cpp index 01fad35..196ab29 100644 --- a/global.cpp +++ b/global.cpp @@ -2,7 +2,7 @@ global::global() {} -QString g_SoftwareVersion = "版本号:V1.0.2.1024"; +QString g_SoftwareVersion = "版本号:V1.0.2.1_20241106"; QColor g_themeColor(51, 51, 51); QString g_PushBtnStyle = /**正常情况下样式**/ @@ -240,3 +240,38 @@ QString generatePullURL(int uavID, QString appName, QString uavName, } return rtmpUrl; } + +/** + * @brief 非阻塞延时 + * @param msec 延时毫秒 + */ +void sleepMsec(int msec) { + if (msec <= 0) + return; + QEventLoop loop; // 定义一个新的事件循环 + QTimer::singleShot( + msec, &loop, SLOT(quit())); // 创建单次定时器,槽函数为事件循环的退出函数 + loop.exec(); // 事件循环开始执行,程序会卡在这里,直到定时时间到,本循环被退出 +} + +/** + * @brief 生成公司推流平台地址 + * @param uavID:飞控ID + * @param appName: + * @param uavName:飞机型号,默认981cs + * @return + */ +QString generatePushURL2(int uavID, QString appName, QString uavName, + int clientID, QString pushDomain) { + QString rtmpUrl = ""; + QString clientName = ""; + if (0 == clientID) { + clientName = "gcs"; // 地面端 + } else { + clientName = "uav"; // 载荷端 + } + QString streamName = + uavName + "_" + QString::number(uavID) + "_" + clientName; + rtmpUrl = "rtmp://" + pushDomain + "/" + appName + "/" + streamName; + return rtmpUrl; +} diff --git a/global.h b/global.h index 0c60843..3c92f37 100644 --- a/global.h +++ b/global.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include extern QString g_SoftwareVersion; // 软件版本号 @@ -48,6 +50,19 @@ extern QString generatePushURL(int uavID, QString appName = "nmyj", long expireTime = 6 * 3600, QString pushKey = "ZRjGVcPYGhKib0rdgH"); +/** + * @brief 生成公司推流平台地址 + * @param uavID:飞控ID + * @param clientID: 客户端ID,0为地面端,1为载荷端。 + * @param appName: + * @param uavName:飞机型号,默认981cs + * @param pushDomain: 推流地址 + * @return + */ +extern QString generatePushURL2(int uavID, QString appName = "nmyj", + QString uavName = "981cs", int clientID = 0, + QString pushDomain = "182.92.130.23"); + /** * @brief 生成拉流地址 * @param uavID: 飞控ID @@ -60,13 +75,19 @@ extern QString generatePushURL(int uavID, QString appName = "nmyj", * @return 返回拉流地址 */ extern QString generatePullURL(int uavID, QString appName = "nmyj", - QString uavName = "981cs", int clientID = 1, + QString uavName = "981cs", int clientID = 0, QString pullDomain = "play.uavideo.cn", long expireTime = 6 * 3600, QString pullKey = "HDaMVkLnIcr0mGhV8d"); extern std::map g_mapAppName; +/** + * @brief 非阻塞延时 + * @param msec 延时毫秒 + */ +void sleepMsec(int msec); + class global { public: global();