增加网络监测延迟显示;增加rtsp流本地保存功能(进行中)

pull/11/head
caoyuhui 6 months ago
parent e14b81431c
commit aba562c473

@ -19,6 +19,10 @@ void deviceStateDlg::initWindow() {
setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint); setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
hide(); hide();
m_greyIcon.addFile(":/res/lamp/grey.png");
m_greenIcon.addFile(":/res/lamp/green.png");
m_redIcon.addFile(":/res/lamp/red.png");
QString stateButtonStyle = QString stateButtonStyle =
/*正常情况下样式*/ /*正常情况下样式*/
"QPushButton{" "QPushButton{"
@ -36,14 +40,16 @@ void deviceStateDlg::initWindow() {
ui->pushButton_state_adHocNetwork->setStyleSheet(stateButtonStyle); ui->pushButton_state_adHocNetwork->setStyleSheet(stateButtonStyle);
ui->pushButton_state_rescue->setStyleSheet(stateButtonStyle); ui->pushButton_state_rescue->setStyleSheet(stateButtonStyle);
//"image: url(:/res/lamp/grey.png)-23px 0px no-repeat;" //"image: url(:/res/lamp/grey.png)-23px 0px no-repeat;"
QIcon greyIcon(":/res/lamp/grey.png");
ui->pushButton_state_GDDC->setIcon(greyIcon);
ui->pushButton_state_LLink->setIcon(greyIcon); ui->pushButton_state_GDDC->setIcon(m_greyIcon);
ui->pushButton_state_3DCamra->setIcon(greyIcon); ui->pushButton_state_LLink->setIcon(m_greyIcon);
ui->pushButton_state_KuSatelliteComm->setIcon(greyIcon); ui->pushButton_state_3DCamra->setIcon(m_greyIcon);
ui->pushButton_state_PDT->setIcon(greyIcon); ui->pushButton_state_KuSatelliteComm->setIcon(m_greyIcon);
ui->pushButton_state_adHocNetwork->setIcon(greyIcon); ui->pushButton_state_PDT->setIcon(m_greyIcon);
ui->pushButton_state_rescue->setIcon(greyIcon); ui->pushButton_state_adHocNetwork->setIcon(m_greyIcon);
ui->pushButton_state_rescue->setIcon(m_greyIcon);
ui->pushButton_state_GDDC->setIconSize(QSize(35, 35)); ui->pushButton_state_GDDC->setIconSize(QSize(35, 35));
ui->pushButton_state_LLink->setIconSize(QSize(35, 35)); ui->pushButton_state_LLink->setIconSize(QSize(35, 35));
ui->pushButton_state_3DCamra->setIconSize(QSize(35, 35)); ui->pushButton_state_3DCamra->setIconSize(QSize(35, 35));
@ -52,6 +58,14 @@ void deviceStateDlg::initWindow() {
ui->pushButton_state_adHocNetwork->setIconSize(QSize(35, 35)); ui->pushButton_state_adHocNetwork->setIconSize(QSize(35, 35));
ui->pushButton_state_rescue->setIconSize(QSize(35, 35)); ui->pushButton_state_rescue->setIconSize(QSize(35, 35));
ui->pushButton_state_GDDC->setToolTip("未知");
ui->pushButton_state_LLink->setToolTip("未知");
ui->pushButton_state_3DCamra->setToolTip("未知");
ui->pushButton_state_KuSatelliteComm->setToolTip("未知");
ui->pushButton_state_PDT->setToolTip("未知");
ui->pushButton_state_adHocNetwork->setToolTip("未知");
ui->pushButton_state_rescue->setToolTip("未知");
ui->lineEdit_1_GDDC->setText("--"); ui->lineEdit_1_GDDC->setText("--");
ui->lineEdit_2_GDDC->setText("--"); ui->lineEdit_2_GDDC->setText("--");
ui->lineEdit_3_GDDC->setText("--"); ui->lineEdit_3_GDDC->setText("--");
@ -91,45 +105,48 @@ void deviceStateDlg::initParam() {
} }
// 接收线程结果 // 接收线程结果
void deviceStateDlg::receiveResult(int id, QString result) { void deviceStateDlg::receiveResult(int id, QString result,QString delay) {
// qDebug() << result; // qDebug() << result;
switch (id) { switch (id) {
case 0: case 0:
if (result == "在线") { if (result == "在线") {
ui->pushButton_state_GDDC->setIcon(QIcon(":/res/lamp/green.png")); ui->pushButton_state_GDDC->setIcon(m_greenIcon);
} else { } else {
ui->pushButton_state_GDDC->setIcon(QIcon(":/res/lamp/red.png")); ui->pushButton_state_GDDC->setIcon(m_redIcon);
} }
ui->pushButton_state_GDDC->setToolTip(delay);
break; break;
case 1: case 1:
if (result == "在线") { if (result == "在线") {
ui->pushButton_state_LLink->setIcon(QIcon(":/res/lamp/green.png")); ui->pushButton_state_LLink->setIcon(m_greenIcon);
} else { } else {
ui->pushButton_state_LLink->setIcon(QIcon(":/res/lamp/red.png")); ui->pushButton_state_LLink->setIcon(m_redIcon);
} }
ui->pushButton_state_LLink->setToolTip(delay);
break; break;
case 2: case 2:
if (result == "在线") { if (result == "在线") {
ui->pushButton_state_adHocNetwork->setIcon(QIcon(":/res/lamp/green.png")); ui->pushButton_state_adHocNetwork->setIcon(m_greenIcon);
} else { } else {
ui->pushButton_state_adHocNetwork->setIcon(QIcon(":/res/lamp/red.png")); ui->pushButton_state_adHocNetwork->setIcon(m_redIcon);
} }
ui->pushButton_state_adHocNetwork->setToolTip(delay);
break; break;
case 3: case 3:
if (result == "在线") { if (result == "在线") {
ui->pushButton_state_KuSatelliteComm->setIcon( ui->pushButton_state_KuSatelliteComm->setIcon(m_greenIcon);
QIcon(":/res/lamp/green.png"));
} else { } else {
ui->pushButton_state_KuSatelliteComm->setIcon( ui->pushButton_state_KuSatelliteComm->setIcon(m_redIcon);
QIcon(":/res/lamp/red.png"));
} }
ui->pushButton_state_KuSatelliteComm->setToolTip(delay);
break; break;
case 4: case 4:
if (result == "在线") { if (result == "在线") {
ui->pushButton_state_3DCamra->setIcon(QIcon(":/res/lamp/green.png")); ui->pushButton_state_3DCamra->setIcon(m_greenIcon);
} else { } else {
ui->pushButton_state_3DCamra->setIcon(QIcon(":/res/lamp/red.png")); ui->pushButton_state_3DCamra->setIcon(m_redIcon);
} }
ui->pushButton_state_3DCamra->setToolTip(delay);
break; break;
default: default:
break; break;
@ -219,8 +236,8 @@ void deviceStateDlg::startNetDetn() {
m_workerThread[i] = new QThread(); m_workerThread[i] = new QThread();
m_networkDetection[i]->moveToThread(m_workerThread[i]); m_networkDetection[i]->moveToThread(m_workerThread[i]);
m_workerThread[i]->start(); m_workerThread[i]->start();
connect(m_networkDetection[i], SIGNAL(resultReady(int, QString)), this, connect(m_networkDetection[i], SIGNAL(resultReady(int, QString, QString)), this,
SLOT(receiveResult(int, QString))); // 接收线程运行结果 SLOT(receiveResult(int, QString, QString))); // 接收线程运行结果
switch (i) { switch (i) {
case 0: case 0:
connect(this, &deviceStateDlg::startThread0, m_networkDetection[i], connect(this, &deviceStateDlg::startThread0, m_networkDetection[i],

@ -44,7 +44,7 @@ private slots:
void on_pushButton_homePage_KuSatelliteComm_clicked(); void on_pushButton_homePage_KuSatelliteComm_clicked();
void receiveResult(int, QString); // 接收线程结果 void receiveResult(int, QString, QString); // 接收线程结果
private: private:
Ui::deviceStateDlg *ui; Ui::deviceStateDlg *ui;
@ -55,7 +55,7 @@ public:
// 3ku卫通 // 3ku卫通
// 4三维相机 // 4三维相机
QStringList cmdlist[deviceNum]; QStringList cmdlist[deviceNum];
QIcon m_greyIcon,m_greenIcon,m_redIcon;
networkDetection *m_networkDetection[deviceNum]; networkDetection *m_networkDetection[deviceNum];
QThread *m_workerThread[deviceNum]; QThread *m_workerThread[deviceNum];
QTimer *m_timer; QTimer *m_timer;

@ -15,15 +15,16 @@ void networkDetection::dowork(int id, QStringList cmdlist) {
while (flagRun) { while (flagRun) {
m_process->start("cmd", m_cmd); m_process->start("cmd", m_cmd);
m_process->waitForFinished(); // 等待指令执行完毕 m_process->waitForFinished(); // 等待指令执行完毕
result = m_process->readAll(); // 获取指令执行结果 result = QString::fromLocal8Bit(m_process->readAll()); // 获取指令执行结果
// qDebug() << result; // qDebug() << result;
if (result.contains(QString("TTL="))) // 若包含TTL=字符串则认为网络在线 if (result.contains(QString("TTL="))) // 若包含TTL=字符串则认为网络在线
{ {
// qDebug() << "在线"; // qDebug() << "在线";
emit resultReady(m_id, "在线"); QString delay = selectTTL(result);
emit resultReady(m_id, "在线",delay);
} else { } else {
// qDebug() << "离线"; // qDebug() << "离线";
emit resultReady(m_id, "离线"); emit resultReady(m_id, "离线","通信异常");
} }
// if (CmdListChanged) { // if (CmdListChanged) {
// CmdListChanged = false; // CmdListChanged = false;
@ -40,3 +41,10 @@ void networkDetection::DyChangeCmdList(QStringList changeCmdList) {
m_cmd = changeCmdList; m_cmd = changeCmdList;
CmdListChanged = true; CmdListChanged = true;
} }
//查找延迟
QString networkDetection::selectTTL(QString str) {
str = str.remove(0,str.indexOf("平均 = ")+5);
str = str.left(str.indexOf("ms")+2);
return "通信正常\n"+str;
}

@ -17,7 +17,7 @@ public slots:
void dowork(int, QStringList); void dowork(int, QStringList);
void stop(); void stop();
signals: signals:
void resultReady(int, QString); void resultReady(int, QString, QString);
public: public:
void DyChangeCmdList(QStringList); void DyChangeCmdList(QStringList);
@ -30,6 +30,7 @@ public:
bool flagRun; // 运行标志 bool flagRun; // 运行标志
bool CmdListChanged; // 指令列表改变标志 bool CmdListChanged; // 指令列表改变标志
QProcess *m_process; // 执行CMD QProcess *m_process; // 执行CMD
QString selectTTL(QString str);//查找延迟
}; };
#endif // NETWORKDETECTION_H #endif // NETWORKDETECTION_H

@ -1,6 +1,6 @@
SOURCES += \ SOURCES += \
$$PWD/cffmpeg_decode.cpp \ $$PWD/cffmpeg_decode.cpp \
$$PWD/ffmpegvideodlg.cpp \ $$PWD/ffmpegvideodlg.cpp
HEADERS += \ HEADERS += \
$$PWD/cffmpeg_decode.h \ $$PWD/cffmpeg_decode.h \

@ -1,25 +1,36 @@
#include "cffmpeg_decode.h" #include "cffmpeg_decode.h"
// Cffmpeg_decode::Cffmpeg_decode() { // Cffmpeg_decode::Cffmpeg_decode() {
Cffmpeg_decode::Cffmpeg_decode(QObject *parent) : QObject(parent) { Cffmpeg_decode::Cffmpeg_decode(QObject *parent) : QObject(parent) {
fmtCtx = avformat_alloc_context(); inputFormatCtx = avformat_alloc_context();
pkt = av_packet_alloc(); outputFormatCtx = avformat_alloc_context();
inputPacket = av_packet_alloc();
outputPacket = av_packet_alloc();
yuvFrame = av_frame_alloc(); yuvFrame = av_frame_alloc();
rgbFrame = av_frame_alloc(); rgbFrame = av_frame_alloc();
avformat_network_init();
} }
Cffmpeg_decode::~Cffmpeg_decode() { Cffmpeg_decode::~Cffmpeg_decode() {
if (!pkt) if (!inputPacket)
av_packet_free(&pkt); av_packet_free(&inputPacket);
if (!outputPacket)
av_packet_free(&outputPacket);
if (!yuvFrame) if (!yuvFrame)
av_frame_free(&yuvFrame); av_frame_free(&yuvFrame);
if (!rgbFrame) if (!rgbFrame)
av_frame_free(&rgbFrame); av_frame_free(&rgbFrame);
if (!videoCodecCtx) if (!encoderCtx)
avcodec_free_context(&videoCodecCtx); avcodec_free_context(&encoderCtx);
if (!videoCodecCtx) if (!encoderCtx)
avcodec_close(videoCodecCtx); avcodec_close(encoderCtx);
if (!fmtCtx) if (!decoderCtx)
avformat_close_input(&fmtCtx); avcodec_free_context(&decoderCtx);
if (!decoderCtx)
avcodec_close(decoderCtx);
if (!inputFormatCtx)
avformat_close_input(&inputFormatCtx);
if (!outputFormatCtx)
avformat_close_input(&outputFormatCtx);
} }
void Cffmpeg_decode::setUrl(QString url) { _url = url; } void Cffmpeg_decode::setUrl(QString url) { _url = url; }
@ -28,76 +39,196 @@ bool Cffmpeg_decode::open_input_file() {
if (_url.isEmpty()) if (_url.isEmpty())
return 0; return 0;
//========================解码============================
AVDictionary *avdic = NULL; AVDictionary *avdic = NULL;
// 设置缓存大小1080p可将值调大 // 设置缓存大小1080p可将值调大
av_dict_set(&avdic, "buffer_size", "2048000", 0); av_dict_set(&avdic, "buffer_size", "2048000", 0);
// 以udp方式打开如果以tcp方式打开将udp替换为tcp // 以udp方式打开如果以tcp方式打开将udp替换为tcp
av_dict_set(&avdic, "rtsp_transport", "udp", 0); av_dict_set(&avdic, "rtsp_transport", "udp", 0);
// 设置超时断开连接时间,单位微秒//listen_timeout // 设置超时断开连接时间,单位微秒//listen_timeout
av_dict_set(&avdic, "listen_timeout", "200000", 0); //av_dict_set(&avdic, "listen_timeout", "200000", 0);
// av_dict_set(&avdic, "stimeout", "200000", 0); av_dict_set(&avdic, "stimeout", "200000", 0);
av_dict_set(&avdic, "max_delay", "3", 0); // 设置最大时延 av_dict_set(&avdic, "max_delay", "3", 0); // 设置最大时延
av_dict_set(&avdic, "tune", "zerolatency", 0); av_dict_set(&avdic, "tune", "zerolatency", 0);
av_dict_set(&avdic, "preset", "ultrafast", 0); av_dict_set(&avdic, "preset", "ultrafast", 0);
fmtCtx->flags |= AVFMT_FLAG_NONBLOCK;
if (avformat_open_input(&fmtCtx, _url.toUtf8().data(), NULL, &avdic) < 0) { inputFormatCtx->flags |= AVFMT_FLAG_NONBLOCK;
// 打开输入流
if (avformat_open_input(&inputFormatCtx, _url.toUtf8().data(), NULL, &avdic) <0) {
printf("Cannot open input file.\n"); printf("Cannot open input file.\n");
return 0; return 0;
} }
// 查找流信息
if (avformat_find_stream_info(fmtCtx, NULL) < 0) { if (avformat_find_stream_info(inputFormatCtx, NULL) < 0) {
printf("Cannot find any stream in file.\n"); printf("Cannot find any stream in file.\n");
return 0; return 0;
} }
// 从输入流中找到第一个视频流
int streamCnt = fmtCtx->nb_streams; for (int i = 0; i < inputFormatCtx->nb_streams; i++) {
for (int i = 0; i < streamCnt; i++) { if (inputFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
if (fmtCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStreamIndex = i; videoStreamIndex = i;
continue; continue;
} }
} }
if (videoStreamIndex == -1) { if (videoStreamIndex == -1) {
printf("Cannot find video stream in file.\n"); printf("Cannot find video stream in file.\n");
return 0; return 0;
} }
AVCodecParameters *videoCodecPara = // 获取视频流的解码器参数
fmtCtx->streams[videoStreamIndex]->codecpar; videoCodecPara = inputFormatCtx->streams[videoStreamIndex]->codecpar;
if (!(videoCodec = avcodec_find_decoder(videoCodecPara->codec_id))) { decoder = avcodec_find_decoder(videoCodecPara->codec_id);
if (!decoder) {
printf("Cannot find valid decode codec.\n"); printf("Cannot find valid decode codec.\n");
return 0; return 0;
} }
// 为解码器上下文分配空间
if (!(videoCodecCtx = avcodec_alloc_context3(videoCodec))) { decoderCtx = avcodec_alloc_context3(decoder);
if (!decoderCtx) {
printf("Cannot find valid decode codec context.\n"); printf("Cannot find valid decode codec context.\n");
return 0; return 0;
} }
// 初始化解码器上下文
if (avcodec_parameters_to_context(videoCodecCtx, videoCodecPara) < 0) { if (avcodec_parameters_to_context(decoderCtx, videoCodecPara) < 0) {
printf("Cannot initialize parameters.\n"); printf("Cannot initialize parameters.\n");
return 0; return 0;
} }
if (avcodec_open2(videoCodecCtx, videoCodec, NULL) < 0) { // 打开解码器
if (avcodec_open2(decoderCtx, decoder, NULL) < 0) {
printf("Cannot open codec.\n"); printf("Cannot open codec.\n");
return 0; return 0;
} }
img_ctx = sws_getContext(videoCodecCtx->width, videoCodecCtx->height,
videoCodecCtx->pix_fmt, videoCodecCtx->width,
videoCodecCtx->height, AV_PIX_FMT_RGB32, SWS_BICUBIC,
NULL, NULL, NULL);
numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB32, videoCodecCtx->width, //===============================编码================================
videoCodecCtx->height, 1); // 1、输出文件设置
if (avformat_alloc_output_context2(&outputFormatCtx, NULL, NULL, "output_video.mp4") < 0) {
qDebug() << "Could not create output context.\n";
return 0;
}
// 从输入流中找到第一个视频流
for (int i = 0; i < inputFormatCtx->nb_streams; i++) {
if (inputFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStreamIndexOut = i;
continue;
}
}
if (videoStreamIndexOut == -1) {
printf("Cannot find video stream in file.\n");
return 0;
}
// 获取视频流的解码器参数
videoCodecPara2 = inputFormatCtx->streams[videoStreamIndexOut]->codecpar;
// 3、创建输出视频流
outStream = avformat_new_stream(outputFormatCtx, NULL);
if (!outStream) {
qDebug() << "Failed allocating output stream.\n";
return 0;
}
//4、查找编码器
encoder = avcodec_find_encoder(videoCodecPara2->codec_id);
if(!encoder){
return 0;
}
//5、分配解码器上下文
encoderCtx = avcodec_alloc_context3(encoder);
if (!encoderCtx) {
return 0;
}
//初始化视频AVCodecContext
encoderCtx->height = videoCodecPara2->height;
encoderCtx->width = videoCodecPara2->width;
videoCodecPara2->framerate = av_guess_frame_rate(inputFormatCtx,inputFormatCtx->streams[videoStreamIndexOut],NULL);
//视频流的时间基是1 / 帧率
encoderCtx->time_base = av_inv_q(inputFormatCtx->streams[videoStreamIndexOut]->codecpar->framerate);
encoderCtx->sample_aspect_ratio = inputFormatCtx->streams[videoStreamIndexOut]->codecpar->sample_aspect_ratio;
if (encoder->pix_fmts)
{
encoderCtx->pix_fmt = encoder->pix_fmts[0];
}
encoderCtx->codec_type = AVMEDIA_TYPE_VIDEO;
encoderCtx->codec_id = AV_CODEC_ID_H264;
encoderCtx->bit_rate = 2000000;
encoderCtx->time_base.num = 1;
encoderCtx->time_base.den = 20;
//全局头
if (outputFormatCtx->oformat->flags & AVFMT_GLOBALHEADER)
{
encoderCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
// //设置选项
// AVDictionary *param = 0;
// //H.264
// if(videoCodecPara->codec_id == AV_CODEC_ID_H264) {
// av_dict_set(&param, "preset", "slow", 0);
// av_dict_set(&param, "tune", "zerolatency", 0);
// av_dict_set(&param, "profile", "main", 0);
// }
// //H.265
// if(videoCodecPara->codec_id == AV_CODEC_ID_H265){
// av_dict_set(&param, "preset", "ultrafast", 0);
// av_dict_set(&param, "tune", "zero-latency", 0);
// }
//6、打开编码器
if (avcodec_open2(encoderCtx, encoder, NULL) < 0) {
qDebug() << "Error occurred when opening encoder.\n";
//return 0;
}
avcodec_parameters_from_context(outputFormatCtx->streams[0]->codecpar, encoderCtx);
//avcodec_parameters_to_context(encoderCtx,outStream->codecpar);
// 打开输出文件
if (!(outputFormatCtx->oformat->flags & AVFMT_NOFILE)) {
if (avio_open(&outputFormatCtx->pb,
outputFormatCtx->url /* "output_video.mp4"*/,
AVIO_FLAG_WRITE) < 0) {
printf("Could not open output file.\n");
return 0;
}
}
//写入输出文件的头信息
if (avformat_write_header(outputFormatCtx, NULL) < 0) {
qDebug() << "Error occurred when opening output file.\n";
//return 0;
}
//格式化输出输出文件信息
av_dump_format(outputFormatCtx,0,outputFormatCtx->url,1);
// 初始化图像转换器
swsCtx = sws_getContext(decoderCtx->width, //
decoderCtx->height, //
decoderCtx->pix_fmt, //
decoderCtx->width, //
decoderCtx->height, //
AV_PIX_FMT_RGB32, //
SWS_BICUBIC, NULL, NULL, NULL);
numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB32, //
decoderCtx->width, //
decoderCtx->height, //
1);
out_buffer = (unsigned char *)av_malloc(numBytes * sizeof(unsigned char)); out_buffer = (unsigned char *)av_malloc(numBytes * sizeof(unsigned char));
int res = av_image_fill_arrays(rgbFrame->data, rgbFrame->linesize, out_buffer, int res = av_image_fill_arrays(rgbFrame->data, //
AV_PIX_FMT_RGB32, videoCodecCtx->width, rgbFrame->linesize, //
videoCodecCtx->height, 1); out_buffer, //
AV_PIX_FMT_RGB32, //
decoderCtx->width, //
decoderCtx->height, 1);
if (res < 0) { if (res < 0) {
qDebug() << "Fill arrays failed."; qDebug() << "Fill arrays failed.\n";
return 0; return 0;
} }
@ -113,52 +244,83 @@ void Cffmpeg_decode::run() {
return; return;
} }
while (av_read_frame(fmtCtx, pkt) >= 0) { // 读取数据包
if (pkt->stream_index == videoStreamIndex) { while (av_read_frame(inputFormatCtx, inputPacket) >= 0) {
if (avcodec_send_packet(videoCodecCtx, pkt) >= 0) { if (IsstopPlay) {
qDebug() << "video play stop";
break;
}
if (inputPacket->stream_index == videoStreamIndex) {
// 解码数据包
if (avcodec_send_packet(decoderCtx, inputPacket) >= 0) {
int ret; int ret;
while ((ret = avcodec_receive_frame(videoCodecCtx, yuvFrame)) >= 0) { while ((ret = avcodec_receive_frame(decoderCtx, yuvFrame)) >= 0) {
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
return; return;
else if (ret < 0) { } else if (ret < 0) {
fprintf(stderr, "Error during decoding\n"); fprintf(stderr, "Error during decoding\n");
exit(1); exit(1);
} }
sws_scale(img_ctx, yuvFrame->data, yuvFrame->linesize, 0, sws_scale(swsCtx, //
videoCodecCtx->height, rgbFrame->data, rgbFrame->linesize); yuvFrame->data, //
yuvFrame->linesize, //
0, //
decoderCtx->height, //
rgbFrame->data, //
rgbFrame->linesize);
QImage img(out_buffer, videoCodecCtx->width, videoCodecCtx->height, QImage img(out_buffer, //
decoderCtx->width, //
decoderCtx->height, //
QImage::Format_RGB32); QImage::Format_RGB32);
emit sendQImage(img); emit sendQImage(img);
// int m_timeframe= ((double)videoCodecCtx->framerate.den /
// videoCodecCtx->framerate.num)*1000;
QThread::msleep(28); QThread::msleep(28);
//将解码后的帧写入输出文件
if (av_write_frame(outputFormatCtx, inputPacket) < 0) {
//qDebug() << "Error muxing packet.\n";
break;
} }
} }
av_packet_unref(pkt);
} }
if (IsstopPlay) { av_packet_unref(inputPacket);
break;
} }
//花屏
// if (av_read_frame(inputFormatCtx, inputPacket) < 0) {
// break; // 达到文件末尾
// }
} }
qDebug() << "All video play done";
} }
// 退出 // 退出
void Cffmpeg_decode::stop() { void Cffmpeg_decode::stop() {
// 写入输出文件的尾信息
// av_write_trailer(outputFormatCtx);
IsstopPlay = true; IsstopPlay = true;
if (!pkt) if (!inputPacket)
av_packet_free(&pkt); av_packet_free(&inputPacket);
if (!outputPacket)
av_packet_free(&outputPacket);
if (!yuvFrame) if (!yuvFrame)
av_frame_free(&yuvFrame); av_frame_free(&yuvFrame);
if (!rgbFrame) if (!rgbFrame)
av_frame_free(&rgbFrame); av_frame_free(&rgbFrame);
if (!videoCodecCtx) if (!encoderCtx)
avcodec_free_context(&videoCodecCtx); avcodec_free_context(&encoderCtx);
if (!videoCodecCtx) if (!encoderCtx)
avcodec_close(videoCodecCtx); avcodec_close(encoderCtx);
if (!fmtCtx) if (!decoderCtx)
avformat_close_input(&fmtCtx); avcodec_free_context(&decoderCtx);
if (!decoderCtx)
avcodec_close(decoderCtx);
if (!inputFormatCtx)
avformat_close_input(&inputFormatCtx);
if (!outputFormatCtx)
avformat_close_input(&outputFormatCtx);
} }

@ -46,18 +46,33 @@ signals:
void sendConnectFail(int); void sendConnectFail(int);
private: private:
AVFormatContext *fmtCtx = NULL; AVFormatContext *inputFormatCtx = NULL; //
const AVCodec *videoCodec = NULL; AVFormatContext *outputFormatCtx = NULL; //
AVCodecContext *videoCodecCtx = NULL;
AVPacket *pkt = NULL; AVCodecContext *decoderCtx = NULL; //
AVCodecContext *encoderCtx = NULL;//
const AVCodec *decoder = NULL; // 解码器
const AVCodec *encoder = NULL; //
AVPacket *inputPacket = NULL; //
AVPacket *outputPacket = NULL; //
AVFrame *yuvFrame = NULL; AVFrame *yuvFrame = NULL;
AVFrame *rgbFrame = NULL; AVFrame *rgbFrame = NULL;
struct SwsContext *img_ctx = NULL; struct SwsContext *swsCtx = NULL;
AVCodecParameters *videoCodecPara = nullptr;
AVCodecParameters *videoCodecPara2 = nullptr;
AVStream *outStream;
unsigned char *out_buffer = nullptr; unsigned char *out_buffer = nullptr;
int videoStreamIndex = -1; int videoStreamIndex = -1;
int videoStreamIndexOut = -1;
int numBytes = -1; int numBytes = -1;
QString _url; QString _url;

@ -36,7 +36,6 @@ MainWindow::MainWindow(QWidget *parent)
} }
QString appDir = QCoreApplication::applicationDirPath() + "/app"; QString appDir = QCoreApplication::applicationDirPath() + "/app";
qDebug() << "Open file fail " << appDir; qDebug() << "Open file fail " << appDir;
} }

Loading…
Cancel
Save