Qt5分离视频小部件

时间:2017-02-27 22:34:20

标签: c++11 qt5

我正在尝试找到一种方法来创建视频小部件并将其分成两部分,以便处理立体视频:

  • 第一个会播放视频的一部分;
  • 第二个会播放视频的另一部分。

我目前不知道从哪里开始。我正在搜索qt多媒体模块,但我不知道如何实现这种行为。

有没有人有想法?

我还想构建两个视频小部件并将它们分成两个线程,但它们必须完美同步。我们的想法是将视频剪切为两个ffmpeg,并将每个视频影响到一个视频小部件。但是我认为实现这一点并不容易(每个帧都必须同步)。

感谢您的回答。

1 个答案:

答案 0 :(得分:1)

如果您的立体视频数据是以某种需要在编解码器/容器格式上解码的特殊格式编码的,我认为Qt中的QMultiMedia内容对于这种用例来说太基本了,因为它不允许调整为“ “多流传输容器的流”。

但是,如果您在“普通”视频流中每帧编码交替扫描线,交替帧或甚至“并排”或“上下”图像,那么您只需要do在解码时截取帧并将帧分成两个 QImages 并显示它们。

这绝对可行!

但是,根据您的视频源甚至平台,您可能需要选择不同的方法。例如,如果您使用QCamera作为视频来源,则可以使用 QVideoProbe QViewFinder 方法。有趣的是,这些方法在不同平台上的可用性各不相同,所以一定要先弄明白。

如果您使用 QMediaPlayer 解码视频, QVideoProbe 可能就是您的选择。

有关如何使用不同方法抓取帧的介绍,请查看有关该主题的official documentation的一些示例。

以下是使用QVideoProbe方法的简短示例:

videoProbe = new QVideoProbe(this);
// Here, myVideoSource is a camera or other media object compatible with QVideoProbe 
if (videoProbe->setSource(myVideoSource)) {
    // Probing succeeded, videoProbe->isValid() should be true.
    connect(videoProbe, SIGNAL(videoFrameProbed(QVideoFrame)),
            this, SLOT(processIndividualFrame(QVideoFrame)));
}

// Cameras need to be started. Do whatever your video source requires to start here
myVideoSource->start();

// [...]

// This is the slot where the magic happens (separating each single frame from video into two `QImage`s and posting the result to two `QLabel`s for example):

void processIndividualFrame(QVideoFrame &frame){
    QVideoFrame cloneFrame(frame);
    cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
    const QImage image(cloneFrame.bits(),
                           cloneFrame.width(),
                           cloneFrame.height(),
QVideoFrame::imageFormatFromPixelFormat(cloneFrame.pixelFormat()));
    cloneFrame.unmap();
    QSize sz = image.size();
    const int w = sz.width();
    const int h2 = sz.height() / 2;
    // Assumes "over-and-under" placement of stereo data for simplicity.
    // If you instead need access to individual scanlines, please have a look at [this][2].
    QImage leftImage = image.copy(0, 0,   w, h2);
    QImage rightImage = image.copy(0, h2, w, h2);
    // Assumes you have a UI set up with labels named as below, and with sizing / layout set up correctly
    ui->myLeftEyeLabel.setPixmap(QPixmap::fromImage(leftImage));
    ui->myRightEyeLabel.setPixmap(QPixmap::fromImage(leftImage));
    // Should play back rather smooth since they are effectively updated simultaneously
}

我希望这很有用。

大胖警告:只有部分代码已经过测试甚至编译过!