c++qt4gstreamerqtgstreamer

Retrieving video size using QtGStreamer returns ZERO


I'm playing with QtGStreamer 0.10.0 and I'm trying to retrieve the video size but it's returning ZERO for height and width values.

However, I am able to play the video with no problems on a QImage.

QGst::init();        

pipeline = QGst::Pipeline::create();
filesrc = QGst::ElementFactory::make("filesrc");
filesrc->setProperty("location", "sample.avi");
pipeline->add(filesrc);

decodebin = QGst::ElementFactory::make("decodebin2").dynamicCast<QGst::Bin>();
pipeline->add(decodebin);
QGlib::connect(decodebin, "pad-added", this, &MyMultimedia::onNewDecodedPad);
QGlib::connect(decodebin, "pad-removed", this, &MyMultimedia::onRemoveDecodedPad);
filesrc->link(decodebin);

// more code ...

The code above shows the begining of the pipeline setup. By connecting my method MyMultimedia::onNewDecodedPad on the signal "pad-added" I have access to the data of the video. At least that's what I think.

void MyMultimedia::onNewDecodedPad(QGst::PadPtr pad)
{  
    QGst::CapsPtr caps = pad->caps();
    QGst::StructurePtr structure = caps->internalStructure(0);
    if (structure->name().contains("video/x-raw"))
    {
        // Trying to print width and height using a couple of different ways,
        // but all of them returns 0 for width/height.

        qDebug() << "#1 Size: " << structure->value("width").get<int>() << "x" << structure->value("height").get<int>();

        qDebug() << "#2 Size: " << structure->value("width").toInt() << "x" << structure->value("height").toInt();

        qDebug() << "#3 Size: " << structure.data()->value("width").get<int>() << "x" << structure.data()->value("height").get<int>();

        // numberOfFields also returns 0, which is very wierd.
        qDebug() << "numberOfFields:" << structure->numberOfFields(); 

    }

    // some other code
}

I wonder what I might be doing wrong. Any tips? I was unable to find a relevant example on the web using this API.


Solution

  • Solved it. At onNewDecodedPad() you still don't have access to information about the video frames.

    The class MyMultimedia inherits from QGst::Utils::ApplicationSink, so I had to implement a method named QGst::FlowReturn MyMultimedia::newBuffer() that is called by QtGstreamer whenever a new frame is ready.

    In other words, use this method to copy the frame of the video to a QImage. What I didn't know is that pullBuffer() returns a QGst::BufferPtr, which has a QGst::CapsPtr. It's an internal structure from this var that holds the information I was looking for:

    QGst::FlowReturn MyMultimedia::newBuffer()
    {
        QGst::BufferPtr buf_ptr = pullBuffer();        
        QGst::CapsPtr caps_ptr = buf_ptr->caps();
        QGst::StructurePtr struct_ptr = caps_ptr->internalStructure(0);
    
        qDebug() << struct_ptr->value("width").get<int>() << 
                    "x" << 
                    struct_ptr->value("height").get<int>();
    
        // ...
    }