meta-digi-dey: fix video sink in qt4 phonon patches

The FSL gstreamer-0.10 plugin has renamed the video sink from
'mfw_v4lsink' to 'imxv4l2sink' so the phonon patches need to be updated
accordingly.

https://jira.digi.com/browse/DEL-1850

Signed-off-by: Javier Viguera <javier.viguera@digi.com>
This commit is contained in:
Javier Viguera 2015-10-23 11:24:38 +02:00
parent 7bdd639621
commit 2b53d7ffe7
2 changed files with 510 additions and 0 deletions

View File

@ -0,0 +1,466 @@
From a902af35aac31927b66814475f4bf7340adf38ac Mon Sep 17 00:00:00 2001
From: Rogerio Pimentel <rogerio.pimentel@freescale.com>
Date: Tue, 24 Jul 2012 13:47:01 -0300
Subject: [PATCH] Add support for i.MX codecs to phonon
Add support for i.MX codecs to phonon
Signed-off-by: Daniele Dall'Acqua <daniele.d@freescale.com>
Signed-off-by: Rogerio Pimentel <rogerio.pimentel@freescale.com>
Signed-off-by: Javier Viguera <javier.viguera@digi.com>
---
src/3rdparty/phonon/gstreamer/abstractrenderer.h | 1 +
src/3rdparty/phonon/gstreamer/mediaobject.cpp | 4 +
src/3rdparty/phonon/gstreamer/videowidget.cpp | 60 +++-----
src/3rdparty/phonon/gstreamer/videowidget.h | 1 +
src/3rdparty/phonon/gstreamer/widgetrenderer.cpp | 169 ++++++++++++++---------
src/3rdparty/phonon/gstreamer/widgetrenderer.h | 17 +--
src/3rdparty/phonon/gstreamer/x11renderer.cpp | 25 +---
7 files changed, 144 insertions(+), 133 deletions(-)
diff --git a/src/3rdparty/phonon/gstreamer/abstractrenderer.h b/src/3rdparty/phonon/gstreamer/abstractrenderer.h
index 10a28227a5fb..fa0d87dcf20c 100644
--- a/src/3rdparty/phonon/gstreamer/abstractrenderer.h
+++ b/src/3rdparty/phonon/gstreamer/abstractrenderer.h
@@ -49,6 +49,7 @@ public:
virtual bool eventFilter(QEvent *) = 0;
virtual void handlePaint(QPaintEvent *) {}
virtual bool paintsOnWidget() { return true; } // Controls overlays
+ virtual void handleMove(QMoveEvent * event ) {};
protected:
VideoWidget *m_videoWidget;
diff --git a/src/3rdparty/phonon/gstreamer/mediaobject.cpp b/src/3rdparty/phonon/gstreamer/mediaobject.cpp
index 23a60c06e819..f806d64cd454 100644
--- a/src/3rdparty/phonon/gstreamer/mediaobject.cpp
+++ b/src/3rdparty/phonon/gstreamer/mediaobject.cpp
@@ -515,6 +515,9 @@ void MediaObject::createPipeline()
// reduce buffer overruns as these are not gracefully handled at the moment.
m_audioPipe = gst_element_factory_make("queue", NULL);
g_object_set(G_OBJECT(m_audioPipe), "max-size-time", MAX_QUEUE_TIME, (const char*)NULL);
+ g_object_set(G_OBJECT(m_audioPipe), "max-size-time", 0, (const char*)NULL);
+ g_object_set(G_OBJECT(m_audioPipe), "max-size-buffers", 0, (const char*)NULL);
+ g_object_set(G_OBJECT(m_audioPipe), "max-size-bytes", 0, (const char*)NULL);
gst_bin_add(GST_BIN(m_audioGraph), m_audioPipe);
GstPad *audiopad = gst_element_get_pad (m_audioPipe, "sink");
gst_element_add_pad (m_audioGraph, gst_ghost_pad_new ("sink", audiopad));
@@ -527,6 +530,7 @@ void MediaObject::createPipeline()
m_videoPipe = gst_element_factory_make("queue", NULL);
g_object_set(G_OBJECT(m_videoPipe), "max-size-time", MAX_QUEUE_TIME, (const char*)NULL);
+ g_object_set(G_OBJECT(m_videoPipe), "max-size-time", 33000, (const char*)NULL);
gst_bin_add(GST_BIN(m_videoGraph), m_videoPipe);
GstPad *videopad = gst_element_get_pad (m_videoPipe, "sink");
gst_element_add_pad (m_videoGraph, gst_ghost_pad_new ("sink", videopad));
diff --git a/src/3rdparty/phonon/gstreamer/videowidget.cpp b/src/3rdparty/phonon/gstreamer/videowidget.cpp
index a4c6f79eb9e2..3682d3f21d29 100644
--- a/src/3rdparty/phonon/gstreamer/videowidget.cpp
+++ b/src/3rdparty/phonon/gstreamer/videowidget.cpp
@@ -83,50 +83,16 @@ void VideoWidget::setupVideoBin()
Q_ASSERT(m_videoBin);
gst_object_ref (GST_OBJECT (m_videoBin)); //Take ownership
gst_object_sink (GST_OBJECT (m_videoBin));
-
- //The videoplug element is the final element before the pluggable videosink
- m_videoplug = gst_element_factory_make ("identity", NULL);
-
- //Colorspace ensures that the output of the stream matches the input format accepted by our video sink
- m_colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
-
- //Video scale is used to prepare the correct aspect ratio and scale.
- GstElement *videoScale = gst_element_factory_make ("videoscale", NULL);
-
- //We need a queue to support the tee from parent node
- GstElement *queue = gst_element_factory_make ("queue", NULL);
-
- if (queue && m_videoBin && videoScale && m_colorspace && videoSink && m_videoplug) {
- //Ensure that the bare essentials are prepared
- gst_bin_add_many (GST_BIN (m_videoBin), queue, m_colorspace, m_videoplug, videoScale, videoSink, (const char*)NULL);
- bool success = false;
- //Video balance controls color/sat/hue in the YUV colorspace
- m_videoBalance = gst_element_factory_make ("videobalance", NULL);
- if (m_videoBalance) {
- // For video balance to work we have to first ensure that the video is in YUV colorspace,
- // then hand it off to the videobalance filter before finally converting it back to RGB.
- // Hence we nede a videoFilter to convert the colorspace before and after videobalance
- GstElement *m_colorspace2 = gst_element_factory_make ("ffmpegcolorspace", NULL);
- gst_bin_add_many(GST_BIN(m_videoBin), m_videoBalance, m_colorspace2, (const char*)NULL);
- success = gst_element_link_many(queue, m_colorspace, m_videoBalance, m_colorspace2, videoScale, m_videoplug, videoSink, (const char*)NULL);
- } else {
- //If video balance is not available, just connect to sink directly
- success = gst_element_link_many(queue, m_colorspace, videoScale, m_videoplug, videoSink, (const char*)NULL);
- }
-
- if (success) {
- GstPad *videopad = gst_element_get_pad (queue, "sink");
- gst_element_add_pad (m_videoBin, gst_ghost_pad_new ("sink", videopad));
- gst_object_unref (videopad);
-#ifndef Q_WS_QPA
- QWidget *parentWidget = qobject_cast<QWidget*>(parent());
- if (parentWidget)
- parentWidget->winId(); // Due to some existing issues with alien in 4.4,
- // we must currently force the creation of a parent widget.
-#endif
- m_isValid = true; //initialization ok, accept input
- }
- }
+ gst_bin_add_many (GST_BIN (m_videoBin), videoSink, NULL);
+ GstPad *videopad = gst_element_get_pad (videoSink,"sink");
+ gst_element_add_pad (m_videoBin, gst_ghost_pad_new ("sink", videopad));
+ gst_object_unref (videopad);
+ QWidget *parentWidget = qobject_cast<QWidget*>(parent());
+
+ if (parentWidget)
+ parentWidget->winId(); // Due to some existing issues with alien in 4.4,
+ // we must currently force the creation of a parent widget.
+ m_isValid = true; //initialization ok, accept input
}
void VideoWidget::paintEvent(QPaintEvent *event)
@@ -135,6 +101,12 @@ void VideoWidget::paintEvent(QPaintEvent *event)
m_renderer->handlePaint(event);
}
+void VideoWidget::moveEvent(QMoveEvent * event )
+{
+ Q_ASSERT(m_renderer);
+ m_renderer->handleMove(event);
+}
+
void VideoWidget::setVisible(bool val) {
Q_ASSERT(m_renderer);
diff --git a/src/3rdparty/phonon/gstreamer/videowidget.h b/src/3rdparty/phonon/gstreamer/videowidget.h
index 8603f6ab07ac..38c7b1774336 100644
--- a/src/3rdparty/phonon/gstreamer/videowidget.h
+++ b/src/3rdparty/phonon/gstreamer/videowidget.h
@@ -65,6 +65,7 @@ public:
qreal saturation() const;
void setSaturation(qreal);
void setMovieSize(const QSize &size);
+ void moveEvent(QMoveEvent * event );
QSize sizeHint() const;
QRect scaleToAspect(QRect srcRect, int w, int h) const;
QRect calculateDrawFrameRect() const;
diff --git a/src/3rdparty/phonon/gstreamer/widgetrenderer.cpp b/src/3rdparty/phonon/gstreamer/widgetrenderer.cpp
index 423af9db5cd9..acf85ba60e02 100644
--- a/src/3rdparty/phonon/gstreamer/widgetrenderer.cpp
+++ b/src/3rdparty/phonon/gstreamer/widgetrenderer.cpp
@@ -15,7 +15,9 @@
along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <QMouseEvent>
#include <QtGui/QPainter>
+#include <QPaintEvent>
#include <gst/gst.h>
#include "common.h"
#include "message.h"
@@ -24,6 +26,18 @@
#include "widgetrenderer.h"
#include "qrgb.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <linux/mxcfb.h>
+
+#define MXCFB_GBL_ALPHA 255
+#define MXCFB_CLR_KEY 0x00000000 // ARGB8888
+
// support old OpenGL installations (1.2)
// assume that if TEXTURE0 isn't defined, none are
#ifndef GL_TEXTURE0
@@ -35,26 +49,6 @@
#ifndef QT_NO_PHONON_VIDEO
QT_BEGIN_NAMESPACE
-static void frameRendered()
-{
- static QString displayFps = qgetenv("PHONON_GST_FPS");
- if (displayFps.isEmpty())
- return;
-
- static int frames = 0;
- static QTime lastTime = QTime::currentTime();
- QTime time = QTime::currentTime();
-
- int delta = lastTime.msecsTo(time);
- if (delta > 2000) {
- printf("FPS: %f\n", 1000.0 * frames / qreal(delta));
- lastTime = time;
- frames = 0;
- }
-
- ++frames;
-}
-
namespace Phonon
{
namespace Gstreamer
@@ -62,17 +56,11 @@ namespace Gstreamer
WidgetRenderer::WidgetRenderer(VideoWidget *videoWidget)
: AbstractRenderer(videoWidget)
- , m_width(0)
- , m_height(0)
{
- videoWidget->backend()->logMessage("Creating QWidget renderer");
- if ((m_videoSink = GST_ELEMENT(g_object_new(get_type_RGB(), NULL)))) {
- gst_object_ref (GST_OBJECT (m_videoSink)); //Take ownership
+ if ((m_videoSink = gst_element_factory_make("imxv4l2sink", NULL)) && m_videoSink != NULL) {
+
+ gst_object_ref (GST_OBJECT (m_videoSink)); //Take ownership
gst_object_sink (GST_OBJECT (m_videoSink));
-
- QWidgetVideoSinkBase* sink = reinterpret_cast<QWidgetVideoSinkBase*>(m_videoSink);
- // Let the videosink know which widget to direct frame updates to
- sink->renderWidget = videoWidget;
}
// Clear the background with black by default
@@ -84,67 +72,124 @@ WidgetRenderer::WidgetRenderer(VideoWidget *videoWidget)
m_videoWidget->setAttribute(Qt::WA_PaintOnScreen, false);
}
-void WidgetRenderer::setNextFrame(const QByteArray &array, int w, int h)
+WidgetRenderer::~WidgetRenderer()
{
- if (m_videoWidget->root()->state() == Phonon::LoadingState)
- return;
-
- m_frame = QImage();
- {
- m_frame = QImage((uchar *)array.constData(), w, h, QImage::Format_RGB32);
- }
+ if (m_videoSink) {
+ gst_object_unref (GST_OBJECT (m_videoSink));
+ m_videoSink = 0;
+ }
+}
- m_array = array;
- m_width = w;
- m_height = h;
+void WidgetRenderer::setVideoSize(void)
+{
- m_videoWidget->update();
+ int adj_x;
+ int adj_y;
+
+ QSize wSize = m_videoWidget->size();
+ m_drawFrameRect = m_videoWidget->calculateDrawFrameRect();
+ framePos = m_videoWidget->mapToGlobal(QPoint(0,0));
+
+ //Center the video in the widget
+
+ adj_x = (wSize.width()/2) - (m_drawFrameRect.width()/2);
+ adj_y = (wSize.height()/2) - (m_drawFrameRect.height()/2);
+ g_object_set(G_OBJECT(m_videoSink), "axis-left",adj_x + framePos.x(),(const char*)NULL);
+ g_object_set(G_OBJECT(m_videoSink), "axis-top", adj_y + framePos.y(), (const char*)NULL);
+ g_object_set(G_OBJECT(m_videoSink), "disp-width", m_drawFrameRect.width(), (const char*)NULL);
+ g_object_set(G_OBJECT(m_videoSink), "disp-height", m_drawFrameRect.height(), (const char*)NULL);
+ g_object_set(G_OBJECT(m_videoSink), "setpara", 1, (const char*)NULL);
}
void WidgetRenderer::handleMediaNodeEvent(const MediaNodeEvent *event)
{
switch (event->type()) {
- case MediaNodeEvent::SourceChanged:
- {
- clearFrame();
- break;
- }
default:
break;
}
}
-void WidgetRenderer::clearFrame()
+void WidgetRenderer::handlePaint(QPaintEvent *event)
{
- m_frame = QImage();
- m_array = QByteArray();
- m_videoWidget->update();
+ Q_UNUSED(event);
+ QPainter painter(m_videoWidget);
+ painter.fillRect(m_videoWidget->rect(), m_videoWidget->palette().background());
}
-const QImage &WidgetRenderer::currentFrame() const
+int WidgetRenderer::setOverlay(void)
{
- return m_frame;
+ struct mxcfb_color_key color_key;
+ struct mxcfb_gbl_alpha alpha;
+ int fd_fb;
+
+ if ((fd_fb = open("/dev/fb0", O_RDWR, 0)) < 0)
+ {
+ printf("Unable to open %s\n", "/dev/fb0");
+ return -1;
+
+ }
+
+ alpha.alpha = MXCFB_GBL_ALPHA;
+ alpha.enable = 1;
+
+ if (ioctl(fd_fb, MXCFB_SET_GBL_ALPHA, &alpha) < 0) {
+ printf("Error in applying Alpha\n");
+ }
+
+ color_key.color_key = MXCFB_CLR_KEY & 0x00FFFFFF;
+ color_key.enable = 1;
+ if ( ioctl(fd_fb, MXCFB_SET_CLR_KEY, &color_key) < 0) {
+
+ printf("Error in applying Color Key\n");
+ return -1;
+ }
+
+ close (fd_fb);
+
+ return 0;
}
-void WidgetRenderer::handlePaint(QPaintEvent *event)
+void WidgetRenderer::handleMove( QMoveEvent * event)
{
- Q_UNUSED(event);
- QPainter painter(m_videoWidget);
- m_drawFrameRect = m_videoWidget->calculateDrawFrameRect();
- painter.drawImage(drawFrameRect(), currentFrame());
- frameRendered();
+ Q_UNUSED(event);
+
+ if (framePos != m_videoWidget->mapToGlobal(QPoint(0,0)))
+ setVideoSize();
}
bool WidgetRenderer::eventFilter(QEvent * event)
{
- if (event->type() == QEvent::User) {
- NewFrameEvent *frameEvent= static_cast <NewFrameEvent *>(event);
- setNextFrame(frameEvent->frame, frameEvent->width, frameEvent->height);
- return true;
+ if (event->type() == QEvent::Show) {
+
+ setOverlay();
+ return true;
+
+ } else if (event->type() == QEvent::Resize) {
+
+ setVideoSize();
+ return true;
}
+ if (framePos != m_videoWidget->mapToGlobal(QPoint(0,0)))
+ setVideoSize();
return false;
}
+void WidgetRenderer::aspectRatioChanged(Phonon::VideoWidget::AspectRatio)
+{
+ setVideoSize();
+}
+
+void WidgetRenderer::scaleModeChanged(Phonon::VideoWidget::ScaleMode)
+{
+ setVideoSize();
+}
+
+void WidgetRenderer::movieSizeChanged(const QSize &movieSize)
+{
+ Q_UNUSED(movieSize);
+ setVideoSize();
+}
+
}
} //namespace Phonon::Gstreamer
diff --git a/src/3rdparty/phonon/gstreamer/widgetrenderer.h b/src/3rdparty/phonon/gstreamer/widgetrenderer.h
index 03ee9c065a98..6de1a03e5c01 100644
--- a/src/3rdparty/phonon/gstreamer/widgetrenderer.h
+++ b/src/3rdparty/phonon/gstreamer/widgetrenderer.h
@@ -40,20 +40,21 @@ class WidgetRenderer : public AbstractRenderer
{
public:
WidgetRenderer(VideoWidget *videoWidget);
+ ~WidgetRenderer(void);
bool eventFilter(QEvent * event);
void handlePaint(QPaintEvent *paintEvent);
void handleMediaNodeEvent(const MediaNodeEvent *event);
- const QImage& currentFrame() const;
QRect drawFrameRect() const { return m_drawFrameRect; }
- void setNextFrame(const QByteArray &array, int width, int height);
- bool frameIsSet() { return !m_array.isNull(); }
- void clearFrame();
+ void aspectRatioChanged(Phonon::VideoWidget::AspectRatio aspectRatio);
+ void scaleModeChanged(Phonon::VideoWidget::ScaleMode scaleMode);
+ void movieSizeChanged(const QSize &movieSize);
+ void setVideoSize(void);
+ int setOverlay(void);
+ void handleMove(QMoveEvent* event);
private:
- mutable QImage m_frame;
- QByteArray m_array;
- int m_width;
- int m_height;
+ void paintEvent ( QPaintEvent * event );
QRect m_drawFrameRect;
+ QPoint framePos;
};
}
diff --git a/src/3rdparty/phonon/gstreamer/x11renderer.cpp b/src/3rdparty/phonon/gstreamer/x11renderer.cpp
index 968f3a8fd7af..0d8cc095d001 100644
--- a/src/3rdparty/phonon/gstreamer/x11renderer.cpp
+++ b/src/3rdparty/phonon/gstreamer/x11renderer.cpp
@@ -31,6 +31,8 @@
#include "mediaobject.h"
#include "message.h"
+#define FSL_GSTREAMER 1
+
QT_BEGIN_NAMESPACE
namespace Phonon
@@ -78,31 +80,16 @@ X11Renderer::~X11Renderer()
{
m_renderWidget->setAttribute(Qt::WA_PaintOnScreen, false);
m_renderWidget->setAttribute(Qt::WA_NoSystemBackground, false);
+ if (m_videoSink) {
+ gst_object_unref (GST_OBJECT (m_videoSink));
+ }
delete m_renderWidget;
}
GstElement* X11Renderer::createVideoSink()
{
- GstElement *videoSink = gst_element_factory_make ("xvimagesink", NULL);
- if (videoSink) {
- // Check if the xv sink is usable
- if (gst_element_set_state(videoSink, GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS) {
- gst_object_unref(GST_OBJECT(videoSink));
- videoSink = 0;
- } else {
- // Note that this should not really be necessary as these are
- // default values, though under certain conditions values are retained
- // even between application instances. (reproducible on 0.10.16/Gutsy)
- g_object_set(G_OBJECT(videoSink), "brightness", 0, (const char*)NULL);
- g_object_set(G_OBJECT(videoSink), "contrast", 0, (const char*)NULL);
- g_object_set(G_OBJECT(videoSink), "hue", 0, (const char*)NULL);
- g_object_set(G_OBJECT(videoSink), "saturation", 0, (const char*)NULL);
- }
- }
-
- if (!videoSink)
- videoSink = gst_element_factory_make ("ximagesink", NULL);
+ GstElement *videoSink = gst_element_factory_make ("imxv4l2sink", NULL);
gst_object_ref (GST_OBJECT (videoSink)); //Take ownership
gst_object_sink (GST_OBJECT (videoSink));

View File

@ -0,0 +1,44 @@
From cce5cbf14765e1f6072fd497b15472b4967189c0 Mon Sep 17 00:00:00 2001
From: Eric Nelson <eric.nelson@boundarydevices.com>
Date: Fri, 16 Aug 2013 11:42:23 -0700
Subject: [PATCH] i.MX video renderer: Allow v4l device from environment
The i.MX6 supports multiple IPUs and multiple V4L2 output
devices for each.
Devices are numbered starting with /dev/video16 and defined
for each configured display. In general, /dev/video16 will
correspond to the RGB (background) layer for /dev/fb0.
If a display is the first on an IPU, an additional V4L2
output will be defined that corresponds to the normally
YUV overlay (foreground) layer.
This patch allows association of the proper device for
a particular session for use in multi-headed applications.
The default is /dev/video17:
export v4lsinkdev=/dev/video17
Signed-off-by: Eric Nelson <eric.nelson@boundarydevices.com>
Signed-off-by: Javier Viguera <javier.viguera@digi.com>
---
src/3rdparty/phonon/gstreamer/widgetrenderer.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/3rdparty/phonon/gstreamer/widgetrenderer.cpp b/src/3rdparty/phonon/gstreamer/widgetrenderer.cpp
index acf85ba60e02..fa59dddc3e09 100644
--- a/src/3rdparty/phonon/gstreamer/widgetrenderer.cpp
+++ b/src/3rdparty/phonon/gstreamer/widgetrenderer.cpp
@@ -58,9 +58,12 @@ WidgetRenderer::WidgetRenderer(VideoWidget *videoWidget)
: AbstractRenderer(videoWidget)
{
if ((m_videoSink = gst_element_factory_make("imxv4l2sink", NULL)) && m_videoSink != NULL) {
-
+ char *videodev;
gst_object_ref (GST_OBJECT (m_videoSink)); //Take ownership
gst_object_sink (GST_OBJECT (m_videoSink));
+ videodev=getenv("v4lsinkdev");
+ if (videodev)
+ g_object_set (G_OBJECT (m_videoSink), "device", videodev, NULL);
}
// Clear the background with black by default