fix: 修复推流地址切换不生效问题

video_old
cbwu 4 months ago
parent 5ff339f86a
commit 434323ec8d

@ -14,7 +14,7 @@ QMAKE_PROJECT_DEPTH = 0
# QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\" # QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\"
#程序版本 #程序版本
VERSION = 1.0.2.2 VERSION = 1.0.2.3
#程序版本 #程序版本
QMAKE_TARGET_COMPANY = "HTSDFP" QMAKE_TARGET_COMPANY = "HTSDFP"

@ -516,6 +516,7 @@ void GDDCdlg::startPushURL() {
ffmpegvideoDlg *videoDlg = ui->WgtffmpegVideo; ffmpegvideoDlg *videoDlg = ui->WgtffmpegVideo;
videoDlg->setStreamIP(m_DlgGDDCSet->m_playURL1); videoDlg->setStreamIP(m_DlgGDDCSet->m_playURL1);
videoDlg->setPushStreamIP(m_DlgGDDCSet->m_pushURL); videoDlg->setPushStreamIP(m_DlgGDDCSet->m_pushURL);
qDebug() << "DLG:" << m_DlgGDDCSet->m_pushURL;
videoDlg->setPushStream(true); videoDlg->setPushStream(true);
m_DlgGDDCSet->setPushStreamText("停止推送"); m_DlgGDDCSet->setPushStreamText("停止推送");

@ -85,10 +85,10 @@ bool Cffmpeg_decode::open_input_file() {
// av_dict_set(&avdic, "listen_timeout", "200000", 0); // av_dict_set(&avdic, "listen_timeout", "200000", 0);
// 在尝试连接到一个流或网络资源时,等待的最长时间。如果在这个时间内无法建立连接,就会返回超时错误 // 在尝试连接到一个流或网络资源时,等待的最长时间。如果在这个时间内无法建立连接,就会返回超时错误
av_dict_set(&avdic, "stimeout", "5000000", 0); // 设置超时5秒 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, "tune", "zerolatency", 0); // 实时编码
av_dict_set(&avdic, "preset", "ultrafast", 0); // faster 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打开空流时间过长问题 // 设置最大重试时间为1s,解决avformat_open_input打开空流时间过长问题
av_dict_set(&avdic, "max_interleave_delta", "1000000", 0); 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->lowres = decoder->max_lowres;
decoderCtx->flags2 |= AV_CODEC_FLAG2_FAST; decoderCtx->flags2 |= AV_CODEC_FLAG2_FAST;
decoderCtx->thread_count = 8;
// 打开解码器 // 打开解码器
if (avcodec_open2(decoderCtx, decoder, NULL) < 0) { if (avcodec_open2(decoderCtx, decoder, NULL) < 0) {
printf("Cannot open codec.\n"); printf("Cannot open codec.\n");
@ -325,9 +326,9 @@ void Cffmpeg_decode::run() {
double elapsed_system_time = av_gettime() - first_frame_system_time; double elapsed_system_time = av_gettime() - first_frame_system_time;
// 计算需要等待的时间(us) // 计算需要等待的时间(us)
double wait_time = elapsed_pts_time - elapsed_system_time; double wait_time = elapsed_pts_time - elapsed_system_time;
qDebug() << "pull stream sleep time:" // qDebug() << "pull stream sleep time:"
<< QString::number(wait_time / 1000.0); // << QString::number(wait_time / 1000.0);
if (wait_time > 0 && bPushStreamFlag) { if (wait_time > 0 && bPushStreamFlag) { //
av_usleep(wait_time); // 延时以同步 PTS av_usleep(wait_time); // 延时以同步 PTS
// sleepMsec(wait_time); // sleepMsec(wait_time);
} }

@ -25,6 +25,7 @@ int FFmpegPushStream::openNetworkStream(AVFormatContext *inputFormatCtx) {
qDebug() << "Could not create output context."; qDebug() << "Could not create output context.";
return -1; return -1;
} }
// 复制流信息 // 复制流信息
for (unsigned int i = 0; i < inputFormatCtx->nb_streams; ++i) { for (unsigned int i = 0; i < inputFormatCtx->nb_streams; ++i) {
// AVStream *stream = inputFormatCtx->streams[i]; // AVStream *stream = inputFormatCtx->streams[i];
@ -47,6 +48,24 @@ int FFmpegPushStream::openNetworkStream(AVFormatContext *inputFormatCtx) {
// outputStream->codecpar = inputStream->codecpar; // outputStream->codecpar = inputStream->codecpar;
outputStream->codecpar->codec_tag = 0; outputStream->codecpar->codec_tag = 0;
// outputStream->time_base.num = 1; // 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; break;
} }
} }
@ -66,6 +85,7 @@ int FFmpegPushStream::openNetworkStream(AVFormatContext *inputFormatCtx) {
qDebug() << "Error occurred when write_header into output file.\n"; qDebug() << "Error occurred when write_header into output file.\n";
return -1; return -1;
} }
// sendSPS_PPS(inputFormatCtx, outputFormatCtx);
mInitStatus = true; mInitStatus = true;
this->inputFormatCtx = inputFormatCtx; this->inputFormatCtx = inputFormatCtx;
// startTime = av_gettime_relative(); // 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 * @brief
* @param pkt: * @param pkt:
@ -149,7 +227,7 @@ int FFmpegPushStream::pushStream(AVPacket *pkt, int frm_cnt, int64_t startTime,
// qDebug() << "****************PushStream sleep time:" // qDebug() << "****************PushStream sleep time:"
// << QString::number(delay / 1000); // << QString::number(delay / 1000);
av_usleep(delay); av_usleep(delay);
// sleepMsec(delay); // sleepMsec(40);
} else { } else {
// av_packet_unref(pkt); // av_packet_unref(pkt);
// return 1; // 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); int ret = av_interleaved_write_frame(outputFormatCtx, pkt);
if (ret < 0) { if (ret < 0) {
if (ret == -10053) { if (ret == -10053) {
qDebug() << "网络不稳定"; // qDebug() << "网络不稳定";
} }
// if (ret == AVERROR(EPIPE) || ret == AVERROR(ECONNRESET)) { // if (ret == AVERROR(EPIPE) || ret == AVERROR(ECONNRESET)) {
// qDebug() << "网络不稳定1"; // qDebug() << "网络不稳定1";

@ -34,6 +34,8 @@ public slots:
private: private:
int reconnect(int ret); int reconnect(int ret);
int sendSPS_PPS(AVFormatContext *input_format_context,
AVFormatContext *output_format_context);
}; };
#endif // FFMPEGPUSHSTREAM_H #endif // FFMPEGPUSHSTREAM_H

@ -146,8 +146,8 @@ void ffmpegvideoDlg::setPushStream(bool bPush) {
// 创建推流任务对象 // 创建推流任务对象
if (ffmpegPushStream == nullptr) { if (ffmpegPushStream == nullptr) {
ffmpegPushStream = new FFmpegPushStream; ffmpegPushStream = new FFmpegPushStream;
ffmpegPushStream->setRemoteIP(m_pushStreamIP); // 设置推流地址
} }
ffmpegPushStream->setRemoteIP(m_pushStreamIP); // 设置推流地址
// 推流线程开启 // 推流线程开启
if (pushStreamThread == nullptr) { if (pushStreamThread == nullptr) {
pushStreamThread = new QThread; pushStreamThread = new QThread;

@ -2,7 +2,7 @@
global::global() {} global::global() {}
QString g_SoftwareVersion = "版本号V1.0.2.2_20241111"; QString g_SoftwareVersion = "版本号V1.0.2.3_20241114";
QColor g_themeColor(51, 51, 51); QColor g_themeColor(51, 51, 51);
QString g_PushBtnStyle = /**正常情况下样式**/ QString g_PushBtnStyle = /**正常情况下样式**/

@ -370,4 +370,5 @@ void MainWindow::initUAVIDMap() {
for (int i = 8; i < 13; ++i) { for (int i = 8; i < 13; ++i) {
g_mapAppName[i] = "jsyj"; g_mapAppName[i] = "jsyj";
} }
g_mapAppName[99] = "testyj";
} }

Loading…
Cancel
Save