Package: kamoso Version: 2.0.2-2+b1 Severity: wishlist Dear Maintainer,
We would like to transition to qt-gstreamer 1.x and Kamoso is one of the users of that package. I've produced a patch that makes the qt4 version of kamoso compatible with qt- gstreamer. I believe upstream is working on a qt5 version. I haven't forwarded this patch upstream, however I'll point some of the KDE developers to it to see if we should. Diane. -- System Information: Debian Release: 8.0 APT prefers stable-updates APT policy: (500, 'stable-updates'), (500, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 'experimental') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 3.16.0-4-amd64 (SMP w/4 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages kamoso depends on: ii gstreamer0.10-plugins-good 0.10.31-3+nmu4+b1 ii gstreamer0.10-x 0.10.36-2 ii kde-runtime 4:4.14.2-2 ii libc6 2.19-18 ii libgcc1 1:4.9.2-10 ii libkdecore5 4:4.14.2-5 ii libkdeui5 4:4.14.2-5 ii libkfile4 4:4.14.2-5 ii libkio5 4:4.14.2-5 ii libkipi11 4:4.13.3-1 ii libnepomuk4 4:4.14.2-5 ii libphonon4 4:4.8.0-5 ii libqt4-dbus 4:4.8.6+git64-g5dc8b2b+dfsg-3 ii libqtcore4 4:4.8.6+git64-g5dc8b2b+dfsg-3 ii libqtglib-2.0-0 1.2.0-2 ii libqtgstreamer-0.10-0 0.10.2-2.1 ii libqtgstreamerui-0.10-0 0.10.2-2.1 ii libqtgui4 4:4.8.6+git64-g5dc8b2b+dfsg-3 ii libsolid4 4:4.14.2-5 ii libstdc++6 4.9.2-10 ii phonon 4:4.8.0-5 Versions of packages kamoso recommends: ii kipi-plugins 4:4.4.0-1.1 kamoso suggests no packages. -- no debconf information
diff --git a/cmake/FindGStreamer.cmake b/cmake/FindGStreamer.cmake index a1b6e33..b5634bb 100644 --- a/cmake/FindGStreamer.cmake +++ b/cmake/FindGStreamer.cmake @@ -15,40 +15,38 @@ # TODO: Other versions --> GSTREAMER_X_Y_FOUND (Example: GSTREAMER_0_8_FOUND and GSTREAMER_0_10_FOUND etc) -IF (GSTREAMER_INCLUDE_DIR AND GSTREAMER_LIBRARIES AND GSTREAMER_BASE_LIBRARY AND GSTREAMER_INTERFACE_LIBRARY) +IF (GSTREAMER_INCLUDE_DIR AND GSTREAMER_LIBRARIES AND GSTREAMER_BASE_LIBRARY) # in cache already SET(GStreamer_FIND_QUIETLY TRUE) -ELSE (GSTREAMER_INCLUDE_DIR AND GSTREAMER_LIBRARIES AND GSTREAMER_BASE_LIBRARY AND GSTREAMER_INTERFACE_LIBRARY) +ELSE (GSTREAMER_INCLUDE_DIR AND GSTREAMER_LIBRARIES AND GSTREAMER_BASE_LIBRARY) SET(GStreamer_FIND_QUIETLY FALSE) -ENDIF (GSTREAMER_INCLUDE_DIR AND GSTREAMER_LIBRARIES AND GSTREAMER_BASE_LIBRARY AND GSTREAMER_INTERFACE_LIBRARY) +ENDIF (GSTREAMER_INCLUDE_DIR AND GSTREAMER_LIBRARIES AND GSTREAMER_BASE_LIBRARY) +SET(GSTREAMER_API_VERSION 1.0) IF (NOT WIN32) FIND_PACKAGE(PkgConfig REQUIRED) # use pkg-config to get the directories and then use these values # in the FIND_PATH() and FIND_LIBRARY() calls # don't make this check required - otherwise you can't use macro_optional_find_package on this one - PKG_CHECK_MODULES(PKG_GSTREAMER gstreamer-0.10) + PKG_CHECK_MODULES(PKG_GSTREAMER gstreamer-${GSTREAMER_API_VERSION}) SET(GSTREAMER_VERSION ${PKG_GSTREAMER_VERSION}) SET(GSTREAMER_DEFINITIONS ${PKG_GSTREAMER_CFLAGS}) ENDIF (NOT WIN32) +message(STATUS "Found GStreamer package: ${PKG_GSTREAMER_VERSION}") + FIND_PATH(GSTREAMER_INCLUDE_DIR gst/gst.h PATHS ${PKG_GSTREAMER_INCLUDE_DIRS} - PATH_SUFFIXES gstreamer-0.10 - ) - -FIND_LIBRARY(GSTREAMER_LIBRARIES NAMES gstreamer-0.10 - PATHS - ${PKG_GSTREAMER_LIBRARY_DIRS} + PATH_SUFFIXES gstreamer-${GSTREAMER_API_VERSION} ) -FIND_LIBRARY(GSTREAMER_BASE_LIBRARY NAMES gstbase-0.10 +FIND_LIBRARY(GSTREAMER_LIBRARIES NAMES gstreamer-${GSTREAMER_API_VERSION} PATHS ${PKG_GSTREAMER_LIBRARY_DIRS} ) -FIND_LIBRARY(GSTREAMER_INTERFACE_LIBRARY NAMES gstinterfaces-0.10 +FIND_LIBRARY(GSTREAMER_BASE_LIBRARY NAMES gstbase-${GSTREAMER_API_VERSION} PATHS ${PKG_GSTREAMER_LIBRARY_DIRS} ) @@ -63,12 +61,7 @@ ELSE (GSTREAMER_LIBRARIES) MESSAGE(STATUS "GStreamer: WARNING: library not found") ENDIF (GSTREAMER_LIBRARIES) -IF (GSTREAMER_INTERFACE_LIBRARY) -ELSE (GSTREAMER_INTERFACE_LIBRARY) - MESSAGE(STATUS "GStreamer: WARNING: interface library not found") -ENDIF (GSTREAMER_INTERFACE_LIBRARY) - INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(GStreamer DEFAULT_MSG GSTREAMER_LIBRARIES GSTREAMER_INCLUDE_DIR GSTREAMER_BASE_LIBRARY GSTREAMER_INTERFACE_LIBRARY) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GStreamer DEFAULT_MSG GSTREAMER_LIBRARIES GSTREAMER_INCLUDE_DIR GSTREAMER_BASE_LIBRARY) -MARK_AS_ADVANCED(GSTREAMER_INCLUDE_DIR GSTREAMER_LIBRARIES GSTREAMER_BASE_LIBRARY GSTREAMER_INTERFACE_LIBRARY) +MARK_AS_ADVANCED(GSTREAMER_INCLUDE_DIR GSTREAMER_LIBRARIES GSTREAMER_BASE_LIBRARY ) diff --git a/src/webcamwidget.cpp b/src/webcamwidget.cpp index 62b7831..dc886ef 100644 --- a/src/webcamwidget.cpp +++ b/src/webcamwidget.cpp @@ -46,6 +46,7 @@ #include <QGst/Element> #include <QGst/Parse> #include <QGst/Buffer> +#include <QGst/Memory> #include <QGst/Pad> #include <QGst/Fourcc> #include <QGst/ElementFactory> @@ -55,7 +56,7 @@ #include <QGst/Structure> #include <QGst/Clock> #include <QGst/Init> -#include <QGst/XOverlay> +#include <QGst/VideoOverlay> #include <QGst/Message> #include <gst/gst.h> #include <gst/video/video.h> @@ -130,8 +131,8 @@ void WebcamWidget::playFile(const Device &device) QByteArray pipe = basicPipe(); //Set the right colorspace to convert to QImage - pipe += " ! ffmpegcolorspace ! " - GST_VIDEO_CAPS_xRGB_HOST_ENDIAN + pipe += " ! videoconvert ! " + GST_VIDEO_CAPS_MAKE("RGB") " ! fakesink name=fakesink"; kDebug() << "================ PIPELINE ================"; @@ -157,7 +158,7 @@ void WebcamWidget::playFile(const Device &device) setVideoSettings(); kDebug() << "================ Capabilities ================"; - kDebug() << d->m_pipeline->getElementByName("v4l2src")->getStaticPad("src")->caps()->toString(); + //kDebug() << d->m_pipeline->getElementByName("v4l2src")->getStaticPad("src")->caps()->toString(); d->m_pipeline->setState(QGst::StatePlaying); } @@ -179,72 +180,87 @@ bool WebcamWidget::takePhoto(const KUrl &dest) } kDebug() << dest; d->destination = dest; + if (!d->m_bin) { + return false; + } d->m_bin->getElementByName("fakesink")->setProperty("signal-handoffs", true); QGlib::connect(d->m_bin->getElementByName("fakesink"), "handoff", this, &WebcamWidget::photoGstCallback); return true; } //This code has been borrowed from the Qt Multimedia project. -void WebcamWidget::photoGstCallback(QGst::BufferPtr buffer, QGst::PadPtr) +void WebcamWidget::photoGstCallback(QGst::BufferPtr buffer, QGst::PadPtr pad) { kDebug(); QImage img; - QGst::CapsPtr caps = buffer->caps(); + QGst::CapsPtr caps = pad->currentCaps(); const QGst::StructurePtr structure = caps->internalStructure(0); int width, height; width = structure.data()->value("width").get<int>(); height = structure.data()->value("height").get<int>(); + QString format; + format = structure.data()->value("format").get<QString>(); kDebug() << "We've got a caps in here"; kDebug() << "Size: " << width << "x" << height; kDebug() << "Name: " << structure.data()->name(); + kDebug() << "Format: " << format; - if (qstrcmp(structure.data()->name().toLatin1(), "video/x-raw-yuv") == 0) { + if (format == "YUV") { QGst::Fourcc fourcc = structure->value("format").get<QGst::Fourcc>(); kDebug() << "fourcc: " << fourcc.value.as_integer; if (fourcc.value.as_integer == QGst::Fourcc("I420").value.as_integer) { + QGst::MapInfo memory_info; img = QImage(width/2, height/2, QImage::Format_RGB32); - const uchar *data = (const uchar *)buffer->data(); + if (buffer->map(memory_info, QGst::MapRead)) { + const uchar *data = (const uchar *)memory_info.data(); - for (int y=0; y<height; y+=2) { - const uchar *yLine = data + y*width; - const uchar *uLine = data + width*height + y*width/4; - const uchar *vLine = data + width*height*5/4 + y*width/4; + for (int y=0; y<height; y+=2) { + const uchar *yLine = data + y*width; + const uchar *uLine = data + width*height + y*width/4; + const uchar *vLine = data + width*height*5/4 + y*width/4; - for (int x=0; x<width; x+=2) { - const qreal Y = 1.164*(yLine[x]-16); - const int U = uLine[x/2]-128; - const int V = vLine[x/2]-128; + for (int x=0; x<width; x+=2) { + const qreal Y = 1.164*(yLine[x]-16); + const int U = uLine[x/2]-128; + const int V = vLine[x/2]-128; - int b = qBound(0, int(Y + 2.018*U), 255); - int g = qBound(0, int(Y - 0.813*V - 0.391*U), 255); - int r = qBound(0, int(Y + 1.596*V), 255); + int b = qBound(0, int(Y + 2.018*U), 255); + int g = qBound(0, int(Y - 0.813*V - 0.391*U), 255); + int r = qBound(0, int(Y + 1.596*V), 255); - img.setPixel(x/2,y/2,qRgb(r,g,b)); + img.setPixel(x/2,y/2,qRgb(r,g,b)); + } } + buffer->unmap(memory_info); } } else { kDebug() << "Not I420"; } - } else if (qstrcmp(structure.data()->name().toLatin1(), "video/x-raw-rgb") == 0) { - kDebug() << "RGB name"; + } else if (format == "RGB") { QImage::Format format = QImage::Format_Invalid; int bpp = structure.data()->value("bpp").get<int>(); + // need a better solution. + bpp = 24; if (bpp == 24) format = QImage::Format_RGB888; else if (bpp == 32) format = QImage::Format_RGB32; if (format != QImage::Format_Invalid) { - img = QImage((const uchar *)buffer->data(), - width, - height, - format); - img.bits(); //detach + QGst::MapInfo memory_info; + if (buffer->map(memory_info, QGst::MapRead)) { + img = QImage((const uchar *)memory_info.data(), + width, + height, + format); + img.bits(); //detach + buffer->unmap(memory_info); + } } } @@ -285,7 +301,7 @@ void WebcamWidget::recordVideo(bool sound) //Get the audio from alsa " ! mux. autoaudiosrc " //Sound type and quality - " ! audio/x-raw-int,rate=48000,channels=2,depth=16 " + " ! audio/x-raw,rate=48000,channels=2,depth=16 " //Encode sound as vorbis " ! queue ! audioconvert ! queue " " ! vorbisenc " @@ -368,11 +384,11 @@ QByteArray WebcamWidget::basicPipe() //Accepted capabilities pipe += - " ! ffmpegcolorspace" - " ! video/x-raw-yuv, width=640, height=480, framerate=15/1;" - " video/x-raw-yuv, width=640, height=480, framerate=24/1;" - " video/x-raw-yuv, width=640, height=480, framerate=30/1;" - " video/x-raw-yuv, width=352, height=288, framerate=15/1" + " ! videoconvert" + " ! video/x-raw, width=640, height=480, framerate=15/1;" + " video/x-raw, width=640, height=480, framerate=24/1;" + " video/x-raw, width=640, height=480, framerate=30/1;" + " video/x-raw, width=352, height=288, framerate=15/1" //Basic plug-in for video controls " ! gamma name=gamma" @@ -424,7 +440,7 @@ void WebcamWidget::activeAspectRatio() { QGst::BinPtr sink = d->m_bin->getElementByName("videosink").staticCast<QGst::Bin>(); - QGlib::RefPointer<QGst::XOverlay> over = sink->getElementByInterface<QGst::XOverlay>(); + QGlib::RefPointer<QGst::VideoOverlay> over = sink->getElementByInterface<QGst::VideoOverlay>(); if (over->findProperty("force-aspect-ratio")) { kDebug() << "Setting aspect ratio";