QT Release 下生成日志log以及release下支持调试

数组 越界经常的表现是Debug,不会报错,Release就会崩溃,为了保存qDebug信息,以下方法可以解决这个问题,就很棒!!!

首先 .pro文件添加  DEFINES += QT_MESSAGELOGCONTEXT

#include "dialog.h"
#include <QApplication>
#include <QMutex>
#include <QFile>
#include <QDateTime>
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    // 加锁
    static QMutex mutex;
    mutex.lock();

    QByteArray localMsg = msg.toLocal8Bit();

    QString strMsg("");
    switch(type)
    {
    case QtDebugMsg:
        strMsg = QString("Debug:");
        break;
    case QtWarningMsg:
        strMsg = QString("Warning:");
        break;
    case QtCriticalMsg:
        strMsg = QString("Critical:");
        break;
    case QtFatalMsg:
        strMsg = QString("Fatal:");
        break;
    }

    // 设置输出信息格式
    QString strDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd");
    QString strMessage = QString("Message:%1 File:%2  Line:%3  Function:%4  DateTime:%5")
            .arg(localMsg.constData()).arg(context.file).arg(context.line).arg(context.function).arg(strDateTime);

    // 输出信息至文件中(读写、追加形式)
    QFile file("log.txt");
    file.open(QIODevice::ReadWrite | QIODevice::Append);
    QTextStream stream(&file);
    stream << strMessage << "\r\n";
    file.flush();
    file.close();

    // 解锁
    mutex.unlock();
}



int main(int argc, char *argv[])
{

    // 安装消息处理程序
    qInstallMessageHandler(myMessageOutput);

    QApplication a(argc, argv);
    Dialog w;

    qDebug()<< "main begin";
    w.setWindowFlags(w.windowFlags()&~Qt::WindowContextHelpButtonHint);//隐藏帮助按钮
    w.setWindowTitle("Talk");
    w.show();
    return a.exec();
}

 在你的pro文件中只需要添加下面两行:注意这会导致执行文件变大

#QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
#QMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
你好,下面是一个基于 Qt 和 OpenCV 的 RTMP 推流示例: 首先,需要安装 ffmpeg 和 librtmp 库,这里以 Ubuntu 为例,使用以下命令进行安装: ``` sudo apt-get install libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavdevice-dev libavfilter-dev libavresample-dev librtmp-dev ``` 然后,在 Qt 工程中添加以下头文件: ```cpp #include <opencv2/opencv.hpp> #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavutil/avutil.h> #include <libswscale/swscale.h> #include <libavdevice/avdevice.h> #include <libavfilter/avfilter.h> #include <libavresample/avresample.h> #include <librtmp/rtmp.h> ``` 接着,定义 RTMP 推流的相关参数: ```cpp #define RTMP_URL "rtmp://xxxxx" // RTMP 服务器地址 #define WIDTH 640 // 视频宽度 #define HEIGHT 480 // 视频高度 #define FPS 25 // 视频帧率 #define BITRATE 500000 // 视频比特率 ``` 然后,初始化 ffmpeg 和 librtmp: ```cpp av_register_all(); avformat_network_init(); avdevice_register_all(); avcodec_register_all(); avfilter_register_all(); av_log_set_level(AV_LOG_INFO); ``` 接着,打开摄像头并设置参数: ```cpp cv::VideoCapture cap(0); cap.set(CV_CAP_PROP_FRAME_WIDTH, WIDTH); cap.set(CV_CAP_PROP_FRAME_HEIGHT, HEIGHT); cap.set(CV_CAP_PROP_FPS, FPS); ``` 然后,创建 RTMP 推流句柄并连接 RTMP 服务器: ```cpp RTMP *rtmp = RTMP_Alloc(); RTMP_Init(rtmp); RTMP_SetupURL(rtmp, RTMP_URL); RTMP_EnableWrite(rtmp); if (!RTMP_Connect(rtmp, NULL) || !RTMP_ConnectStream(rtmp, 0)) { qDebug() << "RTMP connect error"; return -1; } ``` 接着,创建 AVFrame 和 AVPacket 并初始化: ```cpp AVFrame *frame = av_frame_alloc(); AVPacket *packet = av_packet_alloc(); memset(packet, 0, sizeof(AVPacket)); ``` 然后,设置帧参数: ```cpp frame->width = WIDTH; frame->height = HEIGHT; frame->format = AV_PIX_FMT_BGR24; av_frame_get_buffer(frame, 0); ``` 接着,开始推流: ```cpp while (true) { cap >> frame; if (frame.empty()) { break; } frame->pts = static_cast<int64_t>(av_gettime() / 1000.0 / 1000.0 * FPS); AVCodecContext *codec_context = rtmp->streams[0]->codec; codec_context->codec_tag = 0; codec_context->codec_id = AV_CODEC_ID_H264; codec_context->bit_rate = BITRATE; codec_context->width = WIDTH; codec_context->height = HEIGHT; codec_context->time_base.num = 1; codec_context->time_base.den = FPS; codec_context->gop_size = FPS * 2; codec_context->pix_fmt = AV_PIX_FMT_YUV420P; codec_context->max_b_frames = 0; codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; AVCodec *codec = avcodec_find_encoder(codec_context->codec_id); if (!codec) { qDebug() << "Codec not found"; return -1; } if (avcodec_open2(codec_context, codec, NULL) < 0) { qDebug() << "Could not open codec"; return -1; } AVPixelFormat pixel_format = static_cast<AVPixelFormat>(frame->format); int width = frame->width; int height = frame->height; AVFrame *frame_yuv = av_frame_alloc(); frame_yuv->format = AV_PIX_FMT_YUV420P; frame_yuv->width = width; frame_yuv->height = height; av_frame_get_buffer(frame_yuv, 0); SwsContext *sws_context = sws_getContext(width, height, pixel_format, width, height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); sws_scale(sws_context, frame->data, frame->linesize, 0, height, frame_yuv->data, frame_yuv->linesize); avcodec_send_frame(codec_context, frame_yuv); av_frame_unref(frame_yuv); int ret = avcodec_receive_packet(codec_context, packet); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { continue; } else if (ret < 0) { qDebug() << "Error during encoding"; return -1; } packet->stream_index = rtmp->streams[0]->id; RTMP_SendPacket(rtmp, packet, 1); av_packet_unref(packet); avcodec_free_context(&codec_context); } ``` 最后,关闭推流句柄和摄像头: ```cpp RTMP_Close(rtmp); RTMP_Free(rtmp); cap.release(); ``` 完整的 Qt 工程代码如下所示: ```cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include <opencv2/opencv.hpp> #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavutil/avutil.h> #include <libswscale/swscale.h> #include <libavdevice/avdevice.h> #include <libavfilter/avfilter.h> #include <libavresample/avresample.h> #include <librtmp/rtmp.h> #define RTMP_URL "rtmp://xxxxx" // RTMP 服务器地址 #define WIDTH 640 // 视频宽度 #define HEIGHT 480 // 视频高度 #define FPS 25 // 视频帧率 #define BITRATE 500000 // 视频比特率 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); av_register_all(); avformat_network_init(); avdevice_register_all(); avcodec_register_all(); avfilter_register_all(); av_log_set_level(AV_LOG_INFO); cv::VideoCapture cap(0); cap.set(CV_CAP_PROP_FRAME_WIDTH, WIDTH); cap.set(CV_CAP_PROP_FRAME_HEIGHT, HEIGHT); cap.set(CV_CAP_PROP_FPS, FPS); RTMP *rtmp = RTMP_Alloc(); RTMP_Init(rtmp); RTMP_SetupURL(rtmp, RTMP_URL); RTMP_EnableWrite(rtmp); if (!RTMP_Connect(rtmp, NULL) || !RTMP_ConnectStream(rtmp, 0)) { qDebug() << "RTMP connect error"; return; } AVFrame *frame = av_frame_alloc(); AVPacket *packet = av_packet_alloc(); memset(packet, 0, sizeof(AVPacket)); frame->width = WIDTH; frame->height = HEIGHT; frame->format = AV_PIX_FMT_BGR24; av_frame_get_buffer(frame, 0); while (true) { cap >> frame; if (frame.empty()) { break; } frame->pts = static_cast<int64_t>(av_gettime() / 1000.0 / 1000.0 * FPS); AVCodecContext *codec_context = rtmp->streams[0]->codec; codec_context->codec_tag = 0; codec_context->codec_id = AV_CODEC_ID_H264; codec_context->bit_rate = BITRATE; codec_context->width = WIDTH; codec_context->height = HEIGHT; codec_context->time_base.num = 1; codec_context->time_base.den = FPS; codec_context->gop_size = FPS * 2; codec_context->pix_fmt = AV_PIX_FMT_YUV420P; codec_context->max_b_frames = 0; codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; AVCodec *codec = avcodec_find_encoder(codec_context->codec_id); if (!codec) { qDebug() << "Codec not found"; return; } if (avcodec_open2(codec_context, codec, NULL) < 0) { qDebug() << "Could not open codec"; return; } AVPixelFormat pixel_format = static_cast<AVPixelFormat>(frame->format); int width = frame->width; int height = frame->height; AVFrame *frame_yuv = av_frame_alloc(); frame_yuv->format = AV_PIX_FMT_YUV420P; frame_yuv->width = width; frame_yuv->height = height; av_frame_get_buffer(frame_yuv, 0); SwsContext *sws_context = sws_getContext(width, height, pixel_format, width, height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); sws_scale(sws_context, frame->data, frame->linesize, 0, height, frame_yuv->data, frame_yuv->linesize); avcodec_send_frame(codec_context, frame_yuv); av_frame_unref(frame_yuv); int ret = avcodec_receive_packet(codec_context, packet); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { continue; } else if (ret < 0) { qDebug() << "Error during encoding"; return; } packet->stream_index = rtmp->streams[0]->id; RTMP_SendPacket(rtmp, packet, 1); av_packet_unref(packet); avcodec_free_context(&codec_context); } RTMP_Close(rtmp); RTMP_Free(rtmp); cap.release(); av_frame_free(&frame); av_packet_free(&packet); } MainWindow::~MainWindow() { delete ui; } ``` 请注意:这个例程只是一个简单的示例,还需要进行错误处理、内存管理等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老赵的博客

叮咚,你的赏钱已到账,嘿嘿嘿

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值