valbok / QtAVPlayer

Free and open-source Qt Media Player library based on FFmpeg, for Linux, Windows, macOS, iOS and Android.
MIT License
282 stars 54 forks source link

Consume QAVFrame with QGraphicsVideoItem #482

Closed kimvnhung closed 3 months ago

kimvnhung commented 3 months ago

I tried widget_video sample and run successfully. But while I try to use QGraphicsVideoItem to show video inside a QGraphicsView, the app crashed.

This is the debug mode last point before crashing 1 QAVVideoFrame::formatName qavvideoframe.cpp 140 0x7ff7b1429978 2 VideoBuffer_D3D11::handle qavhwdevice_d3d11.cpp 325 0x7ff7b14c9fc2 3 QAVVideoFrame::handle qavvideoframe.cpp 123 0x7ff7b142990e 4 PlanarVideoBuffer::mapTextures qavvideoframe.cpp 312 0x7ff7b142f527

This is how I use QGraphicsVideoItem to show video

GraphicsVideoItem *item = new GraphicsVideoItem();
QGraphicsScene *sence = new QGraphicsScene(this);
QGraphicsView *view = new QGraphicsView(sence);

sence->addItem(item);

setLayout(new QGridLayout(this));
layout()->addWidget(view);
player->addVideoOutput(item);
player->setSource("rtsp://admin:abcd1234@116.97.240.172:554/Streaming/Channels/101/", {
                                                                                                 {"rtsp_transport","tcp"},
                                                                                                 {"preset","ultrafast"},
                                                                                                 });
QPushButton *playBtn = new QPushButton("Play");
connect(playBtn, &QPushButton::clicked, [this]
        {
    player->play();
});
layout()->addWidget(playBtn);
valbok commented 3 months ago

Thanks for the report.

Does it mean that frame() returns nullptr there?

Could you test https://github.com/valbok/QtAVPlayer/blob/master/src/QtAVPlayer/qavhwdevice_d3d11.cpp#L324

if (!frame().frame())
    return {};
kimvnhung commented 3 months ago

I tried your test but frame() is not nullptr, The problem occurred on this line: return QLatin1String(av_pix_fmt_desc_get(QAVVideoFrame::format())->name); And I saw that QAVVideoFrame::format() return -1 at that.

I tried 2 simillar samples with QVideoWidget and QGraphicsVideoItem, It both contains a videoSink. The sample with QVideoWidget worked fine, But the sample with QGraphicsVideoItem crashed on the line above after call to play()

valbok commented 3 months ago

could you qDebug() << frame().frame()->format; ?

Is it -1?

kimvnhung commented 3 months ago

Yes, It prints -1, but with the QVideoWidget, It prints 172. I think It has some difference between QVideoSink in QVideoWidget and in QGraphicsVideoItem. But I'm not sure

Note: I used the same rtsp link with both case

valbok commented 3 months ago

Forgot to ask, static_cast<bool>(frame()) should be false there?

Meant that the frame is invalid and should be skipped

kimvnhung commented 3 months ago

Sorry, I dont know where is the "static_cast(frame())" you mentioned I'm using Qt 6.6.2 which has a defined for handling

valbok commented 3 months ago

meant to check like if (!frame()) qDebug() <<"empty frame";

kimvnhung commented 3 months ago

It's empty frame...

image

log image

valbok commented 3 months ago

so could you please just skip it?

if (!frame())
    return {};

And check if some correct video frames will be sent? Also could you provide std output? Maybe it could not find a codec...

kimvnhung commented 3 months ago

Oh, ok, It works fine now with QGraphicsVideoItem. Thanks for your support

kimvnhung commented 3 months ago

483