Qt多解码线程连接到多个显示小部件,性能低下

时间:2017-09-06 01:15:52

标签: c++ multithreading qt signals-slots

这是我的代码。在Processor类中,它会生成Frame个对象以显示相应的QGLCanvas对象。当有5 ProcessorQGLCanvas对时,程序运行顺畅。但是当对数大于6时,GUI不具有响应性,并且在调整窗口小部件窗口大小时内存消耗不稳定。

可能是内存消耗问题是paintEvent类中的绘制函数QGLCanvas不足以处理发出的Frame

但是为什么GUI的响应性会降低(是因为未处理的emit imageReady(frame);)?每个QGLCanvas对象中的槽函数是以并行方式处理的,这是正确的吗?如果是这种情况,为什么添加更多Processor + QGLCanvas会降低GUI的响应能力?

任何人都可以提供一些有关如何改进此解码的实用建议。显示逻辑?

对于解码图像,它是1920x1080 RGB彩色图像。我的机器是i7-4980和8GB内存+ GT750M显卡。当程序运行时,cpu消耗,gpu消耗和内存消耗都不满。

class Processor: public QObject
{
    Q_OBJECT

public:
    ConcurrentQueue<std::shared_ptr<std::string>> image_queue_;
    QGLCanvas* widget_;
    Worker* decoder_;
    QThread* decoderThread_;
    static void CALLBACK DecCBFun();
    void DecodeThread();
    void Start();
    void SetWidget(QGLCanvas* widget);

signals:
    void imageReady(std::shared_ptr<Frame> frame);
    void operate();
    void imageString(std::shared_ptr<std::string> data);
};

Processor::Processor()
{

    decoderThread_ = new QThread();
    decoder_ = nullptr;
    widget_ = nullptr;

    decoder_ = new Worker(camera_id_, this);
    decoder_->moveToThread(decoderThread_);
    QObject::connect(decoderThread_, &QThread::finished, decoder_, &QObject::deleteLater);
    QObject::connect(this, &Processor::operate, decoder_, &Worker::Process);
    decoderThread_->start();
}

void Processor::Start()
{
    if(started_ == false)
        emit operate();
}

void Processor::DecodeThread()
{
    while(true)
    {
        std::shared_ptr<std::string> tmp_str;
        image_queue_.pop(tmp_str);

        if(tmp_str->size() == 4 && *(tmp_str) == "stop")
        {
            stop_ = true;
            break;
        }
        QImage tmp_img((unsigned char*)tmp_str->c_str(), 1920, 1080, QImage::Format_RGB888);

        {

            // should add bbox display method
            std::shared_ptr<Frame> frame = std::make_shared<Frame>();
            frame->image = tmp_img;
            emit imageReady(frame);
        }


    }
}


void Processor::SetWidget(QGLCanvas* widget)
{
    widget_ = widget;
    QObject::connect(this, SIGNAL(imageReady(std::shared_ptr<Frame>)), widget_, SLOT(ShowImage(std::shared_ptr<Frame>)));
}


class Worker : public QObject
{
    Q_OBJECT

public:
    Worker(Processor* processor) : {processor_ = std::shared_ptr<Processor>(processor);}
    void Stop(){emit finished();}
    ~Worker(){}

private:
    std::shared_ptr<Processor> processor_;

public slots:
    void Process();

signals:
    void finished();
};

void Worker::Process()
{
    processor_->DecodeThread();
}


class QGLCanvas : public QOpenGLWidget
{
    Q_OBJECT
public:
    QGLCanvas(QWidget* parent = NULL);

    void paintEvent(QPaintEvent* event);
private:

    std::shared_ptr<Frame> frame_;

public slots:
    void ShowImage(std::shared_ptr<Frame> frame);
};

void QGLCanvas::ShowImage(std::shared_ptr<Frame> frame)
{
    frame_ = frame;
    repaint();
}

void QGLCanvas::paintEvent(QPaintEvent* event)
{
    p.setRenderHint(QPainter::SmoothPixmapTransform, 1);
    p.drawImage(this->rect(), frame_->image);
}


// other part
std::unordered_map<int, std::shared_ptr<Processor>> processors_;
// funtion to load processors_...
std::vector<QGLCanvas* > display_widgets_(processors_.size());
int counter = 0;
for(auto& it:processors_)
{
    it.second->SetWidget(display_widgets_[counter]);
    it.second->Start();
    counter++;
}

0 个答案:

没有答案