Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

在mac book pro上视频的实际显示大小是width/height的2分之1 #8

Open
JavinYang opened this issue Nov 12, 2020 · 6 comments

Comments

@JavinYang
Copy link

JavinYang commented Nov 12, 2020

在mac book pro上视频的实际显示大小是width/height的2分之1。为什么?和分辨的PPI有关吗?怎么解决?

@JavinYang
Copy link
Author

JavinYang commented Nov 12, 2020

// 我在这里*2 绘制尺寸才正常

void AVideoWidget::paint(QPainter *painter)
{
    if (!m_render)
        return;

    painter->beginNativePainting();

    if (!m_render->isInitialized())
        // 我在这里*2 绘制尺寸才正常
        m_render->initialize(width()*2, height()*2);

    {
    std::lock_guard<std::mutex> lock(m_mutex);
    m_render->setFrameInfo(m_rotation, m_mirrored);
    if (m_frame)
        m_render->renderFrame(*m_frame);
    }

    painter->endNativePainting();
}

设备像素比(devicePixelRatio): 设备像素比 = 设备像素 / 设备独立像素。(在Retina屏的iphone上,DPR为2,1个css像素相当于2个物理像素)

我是试图调用 qDebug() << painter->device()->devicePixelRatioF(); 不过打印是1 很奇怪按理说视网膜屏应该是2,我的就是retina屏。

https://doc.qt.io/qt-5/qpaintdevice.html#devicePixelRatioF

我发现

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QApplication app(argc, argv);
    app.setOrganizationName("Agora");
    app.setOrganizationDomain("agora.io");

    qmlRegisterType<AVideoWidget>("AVideoWidget", 1, 0, "AVideoWidget");

    MainWindow w;
    // 通过这样获取devicePixelRatioF就是2
    qDebug() << w.devicePixelRatioF(); 
    w.show();
    return app.exec();
}

但是通过AVideoWidget的paint

void AVideoWidget::paint(QPainter *painter)
{
    if (!m_render)
        return;

    painter->beginNativePainting();
    // 这个结果是1
    qDebug() << painter->device()->devicePixelRatioF();

    if (!m_render->isInitialized())
        m_render->initialize(width()*2, height()*2);

    {
    std::lock_guard<std::mutex> lock(m_mutex);
    m_render->setFrameInfo(m_rotation, m_mirrored);
    if (m_frame)
        m_render->renderFrame(*m_frame);
    }

    painter->endNativePainting();
}

AVideoWidget继承了QQuickPaintedItem看来QQuickPaintedItem出现了什么问题。

最终的解决方法是

void AVideoWidget::handleWindowChanged(QQuickWindow *win)
{
    if (win)
    {
        // 修改这里 这样devicePixelRatio的值是正确的 视网膜屏为2
        m_devicePixelRatio = win->devicePixelRatio();
        connect(win, SIGNAL(sceneGraphInvalidated()), this, SLOT(cleanup()), Qt::DirectConnection);
    }
}

void AVideoWidget::paint(QPainter *painter)
{
    if (!m_render)
        return;

    painter->beginNativePainting();

    if (!m_render->isInitialized())
        // 修改这里
        m_render->initialize(width()*m_devicePixelRatio, height()*m_devicePixelRatio);

    {
    std::lock_guard<std::mutex> lock(m_mutex);
    m_render->setFrameInfo(m_rotation, m_mirrored);
    if (m_frame)
        m_render->renderFrame(*m_frame);
    }

    painter->endNativePainting();
}

avideowidget.h

#ifndef AVIDEOCANVAS_H
#define AVIDEOCANVAS_H

#include <QQuickPaintedItem>
#include <mutex>
#include <memory>

namespace agora { namespace media {
    class IVideoFrame;
}}

class VideoRendererOpenGL;

class AVideoWidget : public QQuickPaintedItem
{
	Q_OBJECT
public:
    AVideoWidget(QQuickItem *parent = 0);
    ~AVideoWidget();
    int setViewProperties(int zOrder, float left, float top, float right, float bottom);
    int deliverFrame(const agora::media::IVideoFrame& videoFrame, int rotation, bool mirrored);
    virtual void paint(QPainter *painter) Q_DECL_OVERRIDE;
protected:
    virtual void geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry) Q_DECL_OVERRIDE;
signals:
    void frameDelivered();
    void widgetInvalidated();
    void viewSizeChanged(int width, int height);

public slots:
    void renderFrame();
    void handleWindowChanged(QQuickWindow *win);
    void cleanup();
private:
    std::unique_ptr<VideoRendererOpenGL> m_render;
    std::mutex m_mutex;
    //usage of m_frame should be guarded by m_mutex
    agora::media::IVideoFrame* m_frame;
    int m_rotation;
    bool m_mirrored;
    qreal m_devicePixelRatio; // 修改这里
};

#endif // AVIDEOCANVAS_H

@plutoless
Copy link
Contributor

您用的native sdk版本是?

@JavinYang
Copy link
Author

您用的本地sdk版本是?

macOS v3.1.2

@plutoless
Copy link
Contributor

@JavinYang ioquake/ioq3#422
您可以参考这里调整下plist配置或者修改opengl,这应该是catalina后引入的问题

@JavinYang
Copy link
Author

JavinYang commented Dec 4, 2020

在我的mac book pro上全屏显示相当烫手 小窗口还行

@plutoless
Copy link
Contributor

@JavinYang 您可以试试我们的非Qt版本是否有类似的情况,或者这边可以简单做个profiling看下性能消耗在哪块吗?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants