diff --git a/PayloadAPP.pro b/PayloadAPP.pro index 225f98a..65a0fd4 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.2.2 +VERSION = 1.0.2.3 #程序版本 QMAKE_TARGET_COMPANY = "HTSDFP" diff --git a/Src/GDDC/gddcdlg.cpp b/Src/GDDC/gddcdlg.cpp index 2ac1ee3..0f6a960 100644 --- a/Src/GDDC/gddcdlg.cpp +++ b/Src/GDDC/gddcdlg.cpp @@ -516,6 +516,7 @@ void GDDCdlg::startPushURL() { ffmpegvideoDlg *videoDlg = ui->WgtffmpegVideo; videoDlg->setStreamIP(m_DlgGDDCSet->m_playURL1); videoDlg->setPushStreamIP(m_DlgGDDCSet->m_pushURL); + qDebug() << "DLG:" << m_DlgGDDCSet->m_pushURL; videoDlg->setPushStream(true); m_DlgGDDCSet->setPushStreamText("停止推送"); diff --git a/Src/Video/cffmpeg_decode.cpp b/Src/Video/cffmpeg_decode.cpp index fcef312..340a31a 100644 --- a/Src/Video/cffmpeg_decode.cpp +++ b/Src/Video/cffmpeg_decode.cpp @@ -85,10 +85,10 @@ bool Cffmpeg_decode::open_input_file() { // 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", "ultrafast", 0); // faster - av_dict_set(&avdic, "threads", "auto", 0); // 自动开启线程数 + // av_dict_set(&avdic, "threads", "auto", 0); // 自动开启线程数 // 设置最大重试时间为1s,解决avformat_open_input打开空流时间过长问题 av_dict_set(&avdic, "max_interleave_delta", "1000000", 0); @@ -154,6 +154,7 @@ bool Cffmpeg_decode::open_input_file() { // 设置加速解码 decoderCtx->lowres = decoder->max_lowres; decoderCtx->flags2 |= AV_CODEC_FLAG2_FAST; + decoderCtx->thread_count = 8; // 打开解码器 if (avcodec_open2(decoderCtx, decoder, NULL) < 0) { printf("Cannot open codec.\n"); @@ -325,10 +326,10 @@ 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 && bPushStreamFlag) { - 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 diff --git a/Src/Video/ffmpegpushstream.cpp b/Src/Video/ffmpegpushstream.cpp index f750042..8b99584 100644 --- a/Src/Video/ffmpegpushstream.cpp +++ b/Src/Video/ffmpegpushstream.cpp @@ -25,6 +25,7 @@ int FFmpegPushStream::openNetworkStream(AVFormatContext *inputFormatCtx) { qDebug() << "Could not create output context."; return -1; } + // 复制流信息 for (unsigned int i = 0; i < inputFormatCtx->nb_streams; ++i) { // AVStream *stream = inputFormatCtx->streams[i]; @@ -47,6 +48,24 @@ int FFmpegPushStream::openNetworkStream(AVFormatContext *inputFormatCtx) { // outputStream->codecpar = inputStream->codecpar; outputStream->codecpar->codec_tag = 0; // outputStream->time_base.num = 1; + + // if (outputFormatCtx->oformat->flags & AVFMT_GLOBALHEADER) + // c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; + + // if (outputFormatCtx->oformat->flags & AVFMT_GLOBALHEADER) { + // outputFormatCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; + // if (inputStream->codecpar->extradata_size > 0) { + // int extra_size = (uint64_t)inputStream->codecpar->extradata_size + + // AV_INPUT_BUFFER_PADDING_SIZE; + // outputStream->codecpar->extradata = (uint8_t + // *)av_malloc(extra_size); memcpy(outputStream->codecpar->extradata, + // inputStream->codecpar->extradata, + // inputStream->codecpar->extradata_size); + // outputStream->codecpar->extradata_size = + // inputStream->codecpar->extradata_size; + // } + // } + break; } } @@ -66,6 +85,7 @@ int FFmpegPushStream::openNetworkStream(AVFormatContext *inputFormatCtx) { qDebug() << "Error occurred when write_header into output file.\n"; return -1; } + // sendSPS_PPS(inputFormatCtx, outputFormatCtx); mInitStatus = true; this->inputFormatCtx = inputFormatCtx; // startTime = av_gettime_relative(); @@ -96,6 +116,64 @@ int FFmpegPushStream::reconnect(int ret) { } } +int FFmpegPushStream::sendSPS_PPS(AVFormatContext *input_format_context, + AVFormatContext *output_format_context) { + for (unsigned int i = 0; i < input_format_context->nb_streams; i++) { + AVStream *in_stream = input_format_context->streams[i]; + + if (in_stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + AVStream *out_stream = output_format_context->streams[0]; + // Send SPS and PPS for video + AVCodecContext *codec_context = avcodec_alloc_context3(nullptr); + if (!codec_context) { + qDebug() << "Could not allocate video codec context."; + return -1; + } + + if (avcodec_parameters_to_context(codec_context, in_stream->codecpar) < + 0) { + qDebug() << "Failed to copy codec parameters to context."; + return -1; + } + + AVPacket sps_pps_packet; + av_init_packet(&sps_pps_packet); + sps_pps_packet.data = nullptr; + sps_pps_packet.size = 0; + + if (avcodec_send_frame(codec_context, nullptr) < 0) { + qDebug() << "Failed to send a frame for SPS/PPS extraction."; + return -1; + } + + while (avcodec_receive_packet(codec_context, &sps_pps_packet) == 0) { + if (sps_pps_packet.pts == AV_NOPTS_VALUE) { + sps_pps_packet.pts = + av_rescale_q_rnd(sps_pps_packet.dts, codec_context->time_base, + out_stream->time_base, AV_ROUND_NEAR_INF); + } + sps_pps_packet.dts = + av_rescale_q_rnd(sps_pps_packet.dts, codec_context->time_base, + out_stream->time_base, AV_ROUND_NEAR_INF); + sps_pps_packet.duration = + av_rescale_q(sps_pps_packet.duration, codec_context->time_base, + out_stream->time_base); + sps_pps_packet.pos = -1; + sps_pps_packet.stream_index = out_stream->index; + + if (av_interleaved_write_frame(output_format_context, &sps_pps_packet) < + 0) { + qDebug() << "Error sending SPS/PPS packet."; + return -1; + } + av_packet_unref(&sps_pps_packet); + } + + avcodec_free_context(&codec_context); + } + } +} + /** * @brief 推流 * @param pkt: 未解码帧 @@ -149,7 +227,7 @@ int FFmpegPushStream::pushStream(AVPacket *pkt, int frm_cnt, int64_t startTime, // qDebug() << "****************PushStream sleep time:" // << QString::number(delay / 1000); av_usleep(delay); - // sleepMsec(delay); + // sleepMsec(40); } else { // av_packet_unref(pkt); // return 1; @@ -181,7 +259,7 @@ int FFmpegPushStream::pushStream(AVPacket *pkt, int frm_cnt, int64_t startTime, int ret = av_interleaved_write_frame(outputFormatCtx, pkt); if (ret < 0) { if (ret == -10053) { - qDebug() << "网络不稳定"; + // qDebug() << "网络不稳定"; } // if (ret == AVERROR(EPIPE) || ret == AVERROR(ECONNRESET)) { // qDebug() << "网络不稳定1"; diff --git a/Src/Video/ffmpegpushstream.h b/Src/Video/ffmpegpushstream.h index 0326e9e..9351c91 100644 --- a/Src/Video/ffmpegpushstream.h +++ b/Src/Video/ffmpegpushstream.h @@ -34,6 +34,8 @@ public slots: private: int reconnect(int ret); + int sendSPS_PPS(AVFormatContext *input_format_context, + AVFormatContext *output_format_context); }; #endif // FFMPEGPUSHSTREAM_H diff --git a/Src/Video/ffmpegvideodlg.cpp b/Src/Video/ffmpegvideodlg.cpp index f12c2ad..e8b579f 100644 --- a/Src/Video/ffmpegvideodlg.cpp +++ b/Src/Video/ffmpegvideodlg.cpp @@ -146,8 +146,8 @@ void ffmpegvideoDlg::setPushStream(bool bPush) { // 创建推流任务对象 if (ffmpegPushStream == nullptr) { ffmpegPushStream = new FFmpegPushStream; - ffmpegPushStream->setRemoteIP(m_pushStreamIP); // 设置推流地址 } + ffmpegPushStream->setRemoteIP(m_pushStreamIP); // 设置推流地址 // 推流线程开启 if (pushStreamThread == nullptr) { pushStreamThread = new QThread; diff --git a/global.cpp b/global.cpp index 7b5f66b..8c952b5 100644 --- a/global.cpp +++ b/global.cpp @@ -2,7 +2,7 @@ global::global() {} -QString g_SoftwareVersion = "版本号:V1.0.2.2_20241111"; +QString g_SoftwareVersion = "版本号:V1.0.2.3_20241114"; QColor g_themeColor(51, 51, 51); QString g_PushBtnStyle = /**正常情况下样式**/ diff --git a/mainwindow.cpp b/mainwindow.cpp index 5fd039a..9896f54 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -370,4 +370,5 @@ void MainWindow::initUAVIDMap() { for (int i = 8; i < 13; ++i) { g_mapAppName[i] = "jsyj"; } + g_mapAppName[99] = "testyj"; }