QGst::BinPtr GstExporter::createDecoder(const int i) { qDebug() << "createDecoder start, i: " << i; char* decArray = nameWithIndex("decoder", i); QGst::BinPtr decoderBin; try { decoderBin = QGst::Bin::create(decArray); QGst::ElementPtr parser = QGst::ElementFactory::make("h264parse"); QGst::ElementPtr decoder; if (usesOmx) { decoder = QGst::ElementFactory::make("omxh264dec"); } else { decoder = QGst::ElementFactory::make("avdec_h264"); } decoderBin->add(parser, decoder); parser->link(decoder); QGst::PadPtr parserSinkPad = parser->getStaticPad("sink"); QGst::PadPtr decoderSrcPad = decoder->getStaticPad("src"); // Add Ghostpads for abstraction decoderBin->addPad(QGst::GhostPad::create(parserSinkPad, "sink")); decoderBin->addPad(QGst::GhostPad::create(decoderSrcPad, "src")); } catch (const QGlib::Error& error) { qCritical() << "Failed to create a decoder:" << error; return QGst::BinPtr(); } return decoderBin; }
void GstExporter::callbackNewPad(const QGst::ElementPtr& sender, const QGst::PadPtr& pad) { QString padName = pad->name(); qDebug() << "new pad created: " << padName; QString demuxerName = sender->name(); QRegExp rx("(\\d+)"); rx.indexIn(demuxerName); quint16 i = rx.cap(1).toInt(); QString decoderQString = "decoder" + QString::number(i); QByteArray decoderBa = decoderQString.toLocal8Bit(); char* decoderName = decoderBa.data(); QGst::ElementPtr decoder = m_pipeline->getElementByName(decoderName); pad->link(decoder->getStaticPad("sink")); }
QGst::BinPtr GstExporter::createFileSrcBin(const QString path, const int i) { qDebug() << "creating filesrc bin, path: " << path << " i: " << i; QGst::BinPtr videoBin; QDir current = QDir::current(); current.cd("recordings"); const QString fullPath = current.absoluteFilePath(path); try { char* srcname = nameWithIndex("file", i); QGst::ElementPtr src = QGst::ElementFactory::make("filesrc", srcname); src->setProperty("location", fullPath); char* demuxName = nameWithIndex("demux", i); QGst::ElementPtr demuxer = QGst::ElementFactory::make("qtdemux", demuxName); QGst::BinPtr decoder = createDecoder(i); QGst::ElementPtr scale = QGst::ElementFactory::make("videoscale"); QGst::ElementPtr capsfilter = createCapsFilter(elementWidthPx, elementHeightPx); char* binname = nameWithIndex("filebin", i); videoBin = QGst::Bin::create(binname); videoBin->add(src, demuxer, decoder, capsfilter, scale); src->link(demuxer); videoBin->linkMany(decoder, scale, capsfilter); qDebug() << "filesrc bin: Added and linked all elements"; QGst::PadPtr filterPadSrc = capsfilter->getStaticPad("src"); videoBin->addPad(QGst::GhostPad::create(filterPadSrc, "src")); qDebug() << "filesrc bin: Added Ghostpad to the bin"; QGlib::connect(demuxer, "pad-added", this, &GstExporter::callbackNewPad, QGlib::PassSender); } catch (const QGlib::Error& error) { qCritical() << "Failed to create a filesource:" << error; return QGst::BinPtr(); } return videoBin; }
QGst::BinPtr GstExporter::createVideoMixer() { qDebug() << "createVideoMixer start"; QGst::BinPtr videoMixerBin = QGst::Bin::create(); try { QGst::ElementPtr videoMixer = QGst::ElementFactory::make("videomixer", "mix"); videoMixer->setProperty("background", (int) 1); //black background videoMixerBin->add(videoMixer); int count = 0; // go through every element in the grid for (int i = 0; i < rec_->grid.height; ++i) { for (int j = 0; j < rec_->grid.width; ++j) { VideoFile* current = &rec_->grid.grid[i][j]; if (current->id != 0) { qDebug() << "Working on video[" << i << "][" << j << "] with id: " << current->id; QGst::PadPtr pad = videoMixer->getRequestPad("sink_%u"); pad->setProperty("ypos", i * elementHeightPx); pad->setProperty("xpos", j * elementWidthPx); qDebug() << "Pad created with xpos: " << pad->property("xpos") << ", ypos: " << pad->property("ypos"); QGst::BinPtr filesrc = createFileSrcBin(current->filepath, count); videoMixerBin->add(filesrc); QGst::PadPtr sourcepad = filesrc->getStaticPad("src"); sourcepad->link(pad); ++count; } } } QGst::PadPtr mixSrcPad = videoMixer->getStaticPad("src"); videoMixerBin->addPad(QGst::GhostPad::create(mixSrcPad, "src")); } catch (const QGlib::Error& error) { qDebug() << "Failed to create a videomixer:" << error; return QGst::BinPtr(); } return videoMixerBin; }
QGst::BinPtr GstRecorder::createVideoSrcBin() { QGst::BinPtr videoBin; try { videoBin = QGst::Bin::create(); QGst::ElementPtr src = QGst::ElementFactory::make("v4l2src"); src->setProperty("device", devicepath); qDebug() << "GstRecorder: v4l2src with device: " << devicepath; QGst::ElementPtr encoder; QGst::ElementPtr capsfilter = createCapsFilter(videoWitdhPx, videoHeightPx, framerate); //QGst::ElementPtr parse = QGst::ElementFactory::make("h264parse"); //QGst::ElementPtr queue = QGst::ElementFactory::make("queue"); if (usesOmx) { encoder = QGst::ElementFactory::make("omxh264enc"); } else { encoder = QGst::ElementFactory::make("x264enc"); qDebug() << "GstRecoder: created x264enc"; } videoBin->add(src, capsfilter, encoder); videoBin->linkMany(src, capsfilter, encoder); qDebug() << "GstRecorder: createVideoSrcBin: added and linked the elements"; QGst::PadPtr encoderSrcPad = encoder->getStaticPad("src"); videoBin->addPad(QGst::GhostPad::create(encoderSrcPad, "src")); } catch (const QGlib::Error &error) { qDebug() << "Failed to create video source bin:" << error; return QGst::BinPtr(); } return videoBin; }
void VideoSinkController::initFromStreamingThread(const QGst::PadPtr & srcPad, const QGst::PipelinePtr & pipeline) { m_bin = QGst::Bin::create(); m_tee = QGst::ElementFactory::make("tee"); QGst::ElementPtr fakesink = QGst::ElementFactory::make("fakesink"); fakesink->setProperty("sync", false); fakesink->setProperty("async", false); fakesink->setProperty("silent", true); fakesink->setProperty("enable-last-sample", false); m_bin->add(m_tee, fakesink); m_tee->getRequestPad("src_%u")->link(fakesink->getStaticPad("sink")); QGst::PadPtr binSinkPad = QGst::GhostPad::create(m_tee->getStaticPad("sink"), "sink"); m_bin->addPad(binSinkPad); pipeline->add(m_bin); m_bin->syncStateWithParent(); srcPad->link(binSinkPad); }