wang-bin / QtAV

A cross-platform multimedia framework based on Qt and FFmpeg. 基于Qt和FFmpeg的跨平台高性能音视频播放框架. Recommand to use new sdk https://github.com/wang-bin/mdk-sdk
http://qtav.org
3.94k stars 1.5k forks source link

多个 AVPlayer + OpenGLWidgetRenderer 时,结束一个另外的也会被结束掉 ... #876

Open nulijiabei opened 7 years ago

nulijiabei commented 7 years ago

多个 AVPlayer 添加到 this->scene()->addWidget(z->m_renderer->widget());

多个 AVPlayer + OpenGLWidgetRenderer 时,结束一个另外的也会被结束掉 ...

    VideoRenderer* renderer = z->m_avplayer->renderer();
    if (renderer->widget()) {
        renderer->widget()->close(); //TODO: rename
        if (!renderer->widget()->testAttribute(Qt::WA_DeleteOnClose) && !renderer->widget()->parent())
            delete renderer;
    }
--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/44981241-avplayer-openglwidgetrenderer?utm_campaign=plugin&utm_content=tracker%2F307703&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F307703&utm_medium=issues&utm_source=github).
wang-bin commented 7 years ago

需要delete么?

nulijiabei commented 7 years ago

@wang-bin 需要 ... scene 同一个层需要使用不同的 QWidget ,AVPlayer 只是其中之一 ...

不过上下文都是 AVPlayer 则不 Delete ... 如果不是则需要 Delete ... 不释放一般 20分钟 就 Crash 了

nulijiabei commented 7 years ago

@wang-bin 看看有什么办法,只释放当前的 AVPlayer ... 而不是所有 ...

如果把每个 AVPlayer 都保存下来 ... 通过各种标记来实现反复使用 ... 下下策有点 ...

wang-bin commented 7 years ago

delete renderer前不用removeWidget之类的操作?

nulijiabei commented 7 years ago

@wang-bin 当然会 this->scene()->removeItem ...

// 播放

if (!m_zs.contains(_m_index))
{
    QSharedPointer<Z> z(new Z());
    z->m_id = _m_id;
    z->m_index = _m_index;
    z->m_format = "vplus";
    z->m_content = _m_content;
    z->m_rectf = _m_rectf;
    // OpenGLWidgetRenderer
    z->m_renderer = new OpenGLWidgetRenderer;
    z->m_renderer->setFixedSize(QSize(z->m_rectf.width(), z->m_rectf.height()));
    z->m_renderer->move(z->m_rectf.x(), z->m_rectf.y());
    // AVPlayer
    z->m_avplayer = new QtAV::AVPlayer;
    z->m_avplayer->setRepeat(-1); // 循环播放 ...
    QStringList dec;
    dec << Runtime::m_configure.m_default_decoder.toLatin1().constData();
    // dec << "FFmpeg" << "CUDA" << "DXVA" << "D3D11" << "VAAPI";
    z->m_avplayer->setVideoDecoderPriority(dec);
    z->m_avplayer->setRenderer(z->m_renderer);
    // z->m_avplayer->audio()->setMute(true);
    z->m_avplayer->play(z->m_content);
    // QGraphicsProxyWidget
    z->m_proxy_widget = this->scene()->addWidget(z->m_renderer->widget());
    // 设置 QGraphicsProxyWidget 前后关系 ...
    z->m_proxy_widget->setZValue(-(z->m_index));
    // 保存 ... Z
    this->insert(z);
} else { // 任何格式切换窗口部件时, 先停止再创建
    QSharedPointer<Z> z = m_zs[_m_index];
    // 判断一下将要切换的类型与原类型是否相等 ...
    if (z->m_format == "vplus") // 视频 -> 视频
    {
        // 相关参数 ...
        z->m_id = _m_id;
        z->m_index = _m_index;
        z->m_format = "vplus";
        z->m_content = _m_content;
        z->m_rectf = _m_rectf;
        // OpenGLWidgetRenderer
        z->m_renderer->setFixedSize(QSize(z->m_rectf.width(), z->m_rectf.height()));
        z->m_renderer->move(z->m_rectf.x(), z->m_rectf.y());
        // AVPlayer
        z->m_avplayer->play(z->m_content);
    } else {
        // 先停止对象 ...
        this->stop(_m_index);
        // 创建对象
        this->playVideoPlus(_m_index, _m_start, _m_id, _m_content, _m_rectf);
    }
}

// 停止

    this->scene()->removeItem(z->m_proxy_widget);
    // --------------------------------------------------------------------------
    VideoRenderer* renderer = z->m_avplayer->renderer();
    if (renderer->widget()) {
        renderer->widget()->close(); //TODO: rename
        if (!renderer->widget()->testAttribute(Qt::WA_DeleteOnClose) && !renderer->widget()->parent())
            delete renderer;
    }
    // --------------------------------------------------------------------------
    delete z->m_avplayer;
    z->m_avplayer = nullptr;
nulijiabei commented 7 years ago

@wang-bin 没能理解您的想法?您是说移除 this->scene()->removeItem 后不要 delete renderer ?

nulijiabei commented 7 years ago

createDIB: CreateDIBSection failed.

nulijiabei commented 7 years ago

搞不定啊 ... 多个 QtAV::AVPlayer 如果不 renderer->widget()->close(); 一会儿就 createDIB: CreateDIBSection failed. 如果 close(); 只要一 close(); 另外一个 QtAV::AVPlayer 的 renderer 就不显示了 ...

wang-bin commented 7 years ago

你试试不用graphicsview

nulijiabei commented 7 years ago

@wang-bin 不用 graphicsview 貌似没事 ...