Beispiel #1
0
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 UriHandlerTest::makeTest()
{
    QVERIFY(QGst::UriHandler::protocolIsSupported(QGst::UriSrc, "file"));

    QGst::ElementPtr e = QGst::UriHandler::makeFromUri(QGst::UriSrc, QUrl::fromLocalFile("/bin/sh"));
    QVERIFY(!e.isNull());

    QGst::UriHandlerPtr u = e.dynamicCast<QGst::UriHandler>();
    QVERIFY(!u.isNull());
    QCOMPARE(u->uri(), QUrl::fromLocalFile("/bin/sh"));
}
Beispiel #3
0
void RefPointerTest::cppWrappersTest()
{
    QGst::ElementPtr e = QGst::ElementFactory::make("playbin");
    QVERIFY(!e.isNull());

    {
        QGst::PipelinePtr pipeline = e.dynamicCast<QGst::Pipeline>();
        QVERIFY(!pipeline.isNull());
        //the C++ wrappers must be the same
        QCOMPARE(static_cast<QGlib::RefCountedObject*>(pipeline.operator->()),
                 static_cast<QGlib::RefCountedObject*>(e.operator->()));
    }

    {
        QGst::ChildProxyPtr proxy = e.dynamicCast<QGst::ChildProxy>();
        QVERIFY(!proxy.isNull());
        //the C++ wrappers must be the same
        QCOMPARE(static_cast<QGlib::RefCountedObject*>(proxy.operator->()),
                 static_cast<QGlib::RefCountedObject*>(e.operator->()));
    }

    { //new wrap() should give the same C++ instance
        GstElement *gobj = e;
        QGst::ElementPtr e2 = QGst::ElementPtr::wrap(gobj);
        QCOMPARE(static_cast<QGlib::RefCountedObject*>(e2.operator->()),
                 static_cast<QGlib::RefCountedObject*>(e.operator->()));
    }

    {
        QGst::StreamVolumePtr sv = e.dynamicCast<QGst::StreamVolume>();
        QVERIFY(!sv.isNull());
        //now the C++ wrapper must not be the same, since Pipeline does not inherit StreamVolume
        QVERIFY(static_cast<QGlib::RefCountedObject*>(sv.operator->())
                != static_cast<QGlib::RefCountedObject*>(e.operator->()));
    }

    {
        QGst::MessagePtr msg = QGst::ApplicationMessage::create(e);
        QGst::MessagePtr msg2 = msg;
        QCOMPARE(static_cast<QGlib::RefCountedObject*>(msg.operator->()),
                 static_cast<QGlib::RefCountedObject*>(msg2.operator->()));
        QVERIFY(msg2 == msg);

        QGst::MessagePtr msg3 = QGst::MessagePtr::wrap(msg2);
        QVERIFY(static_cast<QGlib::RefCountedObject*>(msg3.operator->())
                != static_cast<QGlib::RefCountedObject*>(msg2.operator->()));
        QVERIFY(msg3 == msg2);
    }
}
Beispiel #4
0
const QString GstRecorder::recordLocally() {
  QGst::BinPtr videoSrcBin = createVideoSrcBin();
  //QGst::BinPtr audioSrcBin = createAudioSrcBin();
  //QGst::ElementPtr mux = QGst::ElementFactory::make("mp4mux");

  QGst::BinPtr mux = createVideoMuxBin();
  QGst::ElementPtr sink = QGst::ElementFactory::make("filesink");

  QString currentTime =
      QDateTime::currentDateTime().toString("yyyy_MM_dd_hh_mm_ss");

  const QString filename = QDir::current().absoluteFilePath(
      currentTime + "-device-" + QString::number(deviceNumber) + ".mp4");
  qDebug() << "GstRecorder: writing to:" << filename;
  sink->setProperty("location", filename);

  if (!videoSrcBin || !sink) {
    qDebug() << "Error. One or more elements could not be created.";
    return "";
  }
  if (m_pipeline) {
    qDebug() << "Another Recording was not started. Already one in progress";
    return "";
  }

  m_pipeline = QGst::Pipeline::create();
  //m_pipeline->add(videoSrcBin, audioSrcBin, mux, sink);

  m_pipeline->add(videoSrcBin, mux, sink);

  //QGst::PadPtr videoPad = mux->getRequestPad("video_%u");
  //QGst::PadPtr audioPad = mux->getRequestPad("audio_%u");

  //videoSrcBin->getStaticPad("src")->link(videoPad);
  //audioSrcBin->getStaticPad("src")->link(audioPad);

  videoSrcBin->link(mux);
  mux->link(sink);

  m_pipeline->bus()->addSignalWatch();
  QGlib::connect(m_pipeline->bus(), "message", this,
                 &GstRecorder::onBusMessage);

  m_pipeline->setState(QGst::StatePlaying);

  return filename;
}
QGst::BinPtr QtGStreamerCaptureBackend::createAudioSrcBin()
{
    QGst::BinPtr audioBin;

    try {
        audioBin = QGst::Bin::fromDescription("autoaudiosrc name=\"audiosrc\" ! audioconvert ! "
                                              "audioresample ! audiorate ! vorbisenc name=enc quality=0.6 ! queue");
    } catch (const QGlib::Error &error) {
        qCritical() << "Failed to create audio source bin:" << error;
        return QGst::BinPtr();
    }
    QGst::ElementPtr src = audioBin->getElementByName("audiosrc");
    //autoaudiosrc creates the actual source in the READY state

    src->setState(QGst::StateReady);
    return audioBin;
}
Beispiel #6
0
void App::startListen(QGst::PipelinePtr pipe, int port) {
    QGst::ElementPtr rtcpudpsink = QGst::ElementFactory::make("udpsrc");
    rtcpudpsink->setProperty("host", "127.0.0.1"); // TODO settings
    rtcpudpsink->setProperty("port", port);        // source
//    rtcpudpsink->setProperty("sync", false);
//    rtcpudpsink->setProperty("async", false);
    rtcpudpsink->setProperty("caps", QGst::Caps::fromString("application/x-rtp,media=(string)audio, clock-rate=(int)8000, encoding-name=(string)SPEEX,payload=(int)110"));
    pipe->add(rtcpudpsink);


    QGst::ElementPtr bin;

    try {
        bin = QGst::Bin::fromDescription(
            "rtpspeexdepay ! speexdec ! audioconvert"
        );
    } catch (const QGlib::Error & error) {
        qCritical() << error;
        qFatal("One ore more required elements are missing. Aborting...");
    }
    pipe->add(bin);
    rtcpudpsink->link(bin);

    volumeIn = QGst::ElementFactory::make("volume"); // TODO settings
    pipe->add(volumeIn);
    bin->link(volumeIn);


    QGst::ElementPtr audioSynk = QGst::ElementFactory::make("autoaudiosink");
    pipe->add(audioSynk);
    volumeIn->link(audioSynk);
}
Beispiel #7
0
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"));
}
Beispiel #8
0
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;
}
Beispiel #9
0
QGst::BinPtr GstRecorder::createAudioSrcBin() {
  QGst::BinPtr audioBin;
  qDebug() << "creating Audio Source bin.";

  try {
    audioBin = QGst::Bin::fromDescription(
        "autoaudiosrc name=\"audiosrc\" ! audioconvert ! "
        "audioresample ! audiorate ! speexenc ! queue");
  } catch (const QGlib::Error &error) {
    qCritical() << "Failed to create audioSrcBin: " << error;
    return QGst::BinPtr();
  }

  QGst::ElementPtr src = audioBin->getElementByName("audiosrc");
  //autoaudiosrc creates the actual source in the READY state
  src->setState(QGst::StateReady);

  return audioBin;
}
Beispiel #10
0
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;
}
Beispiel #11
0
QGst::ElementPtr GstExporter::createCapsFilter(const quint16 width,
                                               const quint16 height) {
  qDebug() << "creating capsfilter with width: " << width
           << ", height: " << height;
  QGst::ElementPtr capsfilter;
  try {
    capsfilter = QGst::ElementFactory::make("capsfilter");

    const QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw");
    caps->setValue("width", (int)width);
    caps->setValue("height", (int)height);

    capsfilter->setProperty("caps", caps);

  } catch (const QGlib::Error& error) {
    qCritical() << "Failed to create capsfilter: " << error;
    return QGst::ElementPtr();
  }

  return capsfilter;
}
Beispiel #12
0
void RefPointerTest::equalityTest()
{
    QGst::BinPtr bin = QGst::Bin::create();
    QGst::ElementPtr element = bin;
    QVERIFY(element == bin);
    QVERIFY(bin == element);
    QVERIFY(bin == bin);

    GstElement *e = element;
    QVERIFY(e == element);
    QVERIFY(element == e);
    QVERIFY(bin == e);
    QVERIFY(e == bin);

    e++;
    QVERIFY(e != element);
    QVERIFY(element != e);
    QVERIFY(bin != e);
    QVERIFY(e != bin);

    e = NULL;
    QVERIFY(e != element);
    QVERIFY(element != e);
    QVERIFY(bin != e);
    QVERIFY(e != bin);

    element.clear();
    QVERIFY(element != bin);
    QVERIFY(bin != element);
    QVERIFY(e == element);
    QVERIFY(element == e);

    bin.clear();
    QVERIFY(element == bin);
    QVERIFY(bin == element);
    QVERIFY(bin == bin);
    QVERIFY(bin == e);
    QVERIFY(e == bin);
}
Beispiel #13
0
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;
}
Beispiel #14
0
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);
}
Beispiel #15
0
QString GstExporter::exportVideo() {
  qDebug() << "Starting Videoexport...";
  QGst::BinPtr mixer = createVideoMixer();
  QGst::BinPtr encoder = createEncoder();
  QGst::ElementPtr scale = QGst::ElementFactory::make("videoscale");
  QGst::ElementPtr sink = QGst::ElementFactory::make("filesink");
  QGst::ElementPtr capsfilter = createCapsFilter(exportWidthPx, exportHeightPx);
  QString recordingTime = rec_->datetime.toString("yyyy_MM_dd_hh_mm_ss");
  qDebug() << "Loaded recodring, recording time: " << rec_->datetime;

  QDir current = QDir::current();
  current.mkdir("exports");
  current.cd("exports");

  QString filename =
      current.absoluteFilePath("export-" + recordingTime + ".mp4");

  sink->setProperty("location", filename);

  m_pipeline = QGst::Pipeline::create();
  m_pipeline->add(mixer, capsfilter, encoder, scale, sink);
  m_pipeline->linkMany(mixer, capsfilter, scale, encoder, sink);
  qDebug() << "GstExporter: pipeline: Added and linked all elements";

  m_pipeline->bus()->addSignalWatch();
  QGlib::connect(m_pipeline->bus(), "message", this,
                 &GstExporter::onBusMessage);
  qDebug() << "exportVideo(): Starting pipeline";
  m_pipeline->setState(QGst::StatePlaying);

  timer = new QTimer(this);
  connect(timer, &QTimer::timeout, this, &GstExporter::progressPercent);
  timer->start(1000);

  return current.relativeFilePath(filename);
}
void QtGStreamerCaptureBackend::startCapture(const QString &filePath)
{
    // clear pipeline if still existing
    if (m_pipeline) {
        qCWarning(LIBSOUND_LOG) << "removing forgotten pipeline";
        //send an end-of-stream event to flush metadata and cause an EosMessage to be delivered
        m_pipeline->sendEvent(QGst::EosEvent::create());
    }

    QGst::BinPtr audioSrcBin = createAudioSrcBin();
    QGst::ElementPtr mux = QGst::ElementFactory::make("oggmux");
    QGst::ElementPtr sink = QGst::ElementFactory::make("filesink");

    if (!audioSrcBin || !mux || !sink) {
        qCritical() << "One or more elements could not be created. "
                 << "Verify that you have all the necessary element plugins installed.";
        return;
    }

    // set output path
    sink->setProperty("location", filePath);

    m_pipeline = QGst::Pipeline::create();
    m_pipeline->add(audioSrcBin, mux, sink);

    //link elements
    QGst::PadPtr audioPad = mux->getRequestPad("audio_%u");
    audioSrcBin->getStaticPad("src")->link(audioPad);

    mux->link(sink);

    //connect the bus
    m_pipeline->bus()->addSignalWatch();
    QGlib::connect(m_pipeline->bus(), "message", this, &QtGStreamerCaptureBackend::onBusMessage);
    m_pipeline->setState(QGst::StatePlaying);
}
Beispiel #17
0
void GstRecorder::createRtpSink(quint16 port, QString address) {
  QGst::BinPtr videoSrcBin = createVideoSrcBin();
  QGst::ElementPtr rtpbin = QGst::ElementFactory::make("rtpbin");
  QGst::ElementPtr h264pay = QGst::ElementFactory::make("rtph264pay");

  if (!videoSrcBin || !rtpbin) {
    qDebug() << "Error. One or more elements could not be created.";
    return;
  }

  m_pipeline = QGst::Pipeline::create();
  m_pipeline->add(videoSrcBin, h264pay);
  videoSrcBin->link(h264pay);

  m_pipeline->add(rtpbin);
  // send_rtp_sink_0 is needed as a parameter for rtpbin for the configuration
  h264pay->link(rtpbin, "send_rtp_sink_0");

  QGst::ElementPtr RtpUdpSink = QGst::ElementFactory::make("udpsink");
  RtpUdpSink->setProperty("port", (int)port);
  RtpUdpSink->setProperty("host", address);
  if (!RtpUdpSink) {
    qFatal("Failed to create udpsink. Aborting...");
  }
  m_pipeline->add(RtpUdpSink);
  rtpbin->link("send_rtp_src_0", RtpUdpSink);

  QGst::ElementPtr RtcpUdpSink = QGst::ElementFactory::make("udpsink");
  RtcpUdpSink->setProperty("port", port + 1);
  RtcpUdpSink->setProperty("host", address);
  RtcpUdpSink->setProperty("sync", false);  // needed for real-time
  RtcpUdpSink->setProperty("async", false);
  m_pipeline->add(RtcpUdpSink);
  rtpbin->link("send_rtcp_src_0", RtcpUdpSink);

  QGst::ElementPtr RtcpUdpSrc = QGst::ElementFactory::make("udpsrc");
  RtcpUdpSrc->setProperty("port", port + 2);
  m_pipeline->add(RtcpUdpSrc);
  RtcpUdpSrc->link(rtpbin, "recv_rtcp_sink_0");

  // watch the bus
  m_pipeline->bus()->addSignalWatch();
  QGlib::connect(m_pipeline->bus(), "message", this,
                 &GstRecorder::onBusMessage);

  qDebug() << "Streaming to RTP";

  m_pipeline->setState(QGst::StatePlaying);
}
Beispiel #18
0
void App::startVoice() {
    rtpbin = QGst::ElementFactory::make("gstrtpbin");
    if (!rtpbin) {
        qFatal("Failed to create gstrtpbin");
    }
    qDebug() << "initn create";

    m_pipelineOut->add(rtpbin);

    //audio content
    //sending side
    QGst::ElementPtr audiosrc;

    try {
        audiosrc = QGst::Bin::fromDescription(
//            "alsasrc device=plughw:0 ! queue ! audioconvert ! audiorate ! audio/x-raw-int,rate=8000 "
//            "! speexenc ! rtpspeexpay"
//        );
            "audiotestsrc ! queue ! audioconvert ! audiorate ! audio/x-raw-int,rate=8000 ! audioconvert"
        );
//        audiosrc = QGst::Bin::fromDescription(
//             "audiotestsrc ! audioconvert ! level ! audioconvert ! twolame  ! rtpmpapay"
//        );
    } catch (const QGlib::Error & error) {
        qCritical() << error;
        qFatal("One ore more required elements are missing. Aborting...");
    }
    m_pipelineOut->add(audiosrc);

    volumeOut = QGst::ElementFactory::make("volume");
    m_pipelineOut->add(volumeOut); // TODO settings

    audiosrc->link(volumeOut);

    QGst::ElementPtr decoder;
    try {
        decoder = QGst::Bin::fromDescription(
            "speexenc vad=false ! rtpspeexpay"
        );
    } catch (const QGlib::Error & error) {
        qCritical() << error;
        qFatal("One ore more required elements are missing. Aborting...");
    }
    m_pipelineOut->add(decoder);
    volumeOut->link(decoder);



    decoder->link(rtpbin, "send_rtp_sink_1");

    rtpudpsink =  QGst::ElementFactory::make("udpsink");
    if (!rtpudpsink) {
        qFatal("Failed to create udpsink. Aborting...");
    }


    rtpudpsink->setProperty("host", "127.0.0.1"); // desttination 192.168.0.102
    rtpudpsink->setProperty("port", 5000);        // port
    m_pipelineOut->add(rtpudpsink);
    rtpbin->link("send_rtp_src_1", rtpudpsink);

}