Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
32292bab
Commit
32292bab
authored
Aug 30, 2016
by
Gus Grubba
Committed by
GitHub
Aug 30, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3991 from dogmaphobic/rtspVideo
RTSP Video, Android x86 and other fixes.
parents
32cfa15c
49e012ae
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
743 additions
and
524 deletions
+743
-524
QGCCommon.pri
QGCCommon.pri
+12
-6
qgroundcontrol.pro
qgroundcontrol.pro
+9
-0
qgroundcontrol.qrc
qgroundcontrol.qrc
+2
-0
FlightDisplayView.qml
src/FlightDisplay/FlightDisplayView.qml
+4
-21
FlightDisplayViewDummy.qml
src/FlightDisplay/FlightDisplayViewDummy.qml
+15
-0
FlightDisplayViewUVC.qml
src/FlightDisplay/FlightDisplayViewUVC.qml
+35
-0
FlightDisplayViewVideo.qml
src/FlightDisplay/FlightDisplayViewVideo.qml
+0
-1
VideoManager.cc
src/FlightDisplay/VideoManager.cc
+105
-39
VideoManager.h
src/FlightDisplay/VideoManager.h
+21
-1
QGCVideoBackground.qml
src/FlightMap/QGCVideoBackground.qml
+0
-15
VideoReceiver.cc
src/VideoStreaming/VideoReceiver.cc
+47
-8
VideoStreaming.pri
src/VideoStreaming/VideoStreaming.pri
+6
-2
VideoSurface.cc
src/VideoStreaming/VideoSurface.cc
+4
-2
VideoSurface.h
src/VideoStreaming/VideoSurface.h
+3
-2
gstqtvideosinkplugin.cpp
src/VideoStreaming/gstqtvideosink/gstqtvideosinkplugin.cpp
+2
-2
GeneralSettings.qml
src/ui/preferences/GeneralSettings.qml
+478
-425
No files found.
QGCCommon.pri
View file @
32292bab
...
...
@@ -30,12 +30,18 @@ linux {
CONFIG += LinuxBuild
DEFINES += __STDC_LIMIT_MACROS __rasp_pi2__
} else : android-g++ {
message("Android build")
CONFIG += AndroidBuild MobileBuild
DEFINES += __android__
DEFINES += __STDC_LIMIT_MACROS
DEFINES += QGC_ENABLE_BLUETOOTH
target.path = $$DESTDIR
equals(ANDROID_TARGET_ARCH, x86) {
CONFIG += Androidx86Build
DEFINES += __androidx86__
message("Android x86 build")
} else {
message("Android Arm build")
}
} else {
error("Unsuported Linux toolchain, only GCC 32- or 64-bit is supported")
}
...
...
@@ -54,11 +60,11 @@ linux {
DEFINES += __macos__
CONFIG += x86_64
CONFIG -= x86
equals(QT_MAJOR_VERSION, 5) | greaterThan(QT_MINOR_VERSION, 5) {
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
} else {
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
}
equals(QT_MAJOR_VERSION, 5) | greaterThan(QT_MINOR_VERSION, 5) {
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
} else {
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
}
QMAKE_MAC_SDK = macosx10.11
QMAKE_CXXFLAGS += -fvisibility=hidden
} else {
...
...
qgroundcontrol.pro
View file @
32292bab
...
...
@@ -46,6 +46,15 @@ contains (DEFINES, QGC_DISABLE_BLUETOOTH) {
DEFINES
+=
QGC_ENABLE_BLUETOOTH
}
#
USB
Camera
and
UVC
Video
Sources
contains
(
DEFINES
,
QGC_DISABLE_UVC
)
{
message
(
"Skipping support for UVC devices (manual override from command line)"
)
DEFINES
-=
QGC_DISABLE_UVC
}
else
:
exists
(
user_config
.
pri
)
:
infile
(
user_config
.
pri
,
DEFINES
,
QGC_DISABLE_UVC
)
{
message
(
"Skipping support for UVC devices (manual override from user_config.pri)"
)
DEFINES
-=
QGC_DISABLE_UVC
}
LinuxBuild
{
CONFIG
+=
link_pkgconfig
}
...
...
qgroundcontrol.qrc
View file @
32292bab
...
...
@@ -15,6 +15,8 @@
<file alias="LogDownload.qml">src/ViewWidgets/LogDownload.qml</file>
<file alias="FirmwareUpgrade.qml">src/VehicleSetup/FirmwareUpgrade.qml</file>
<file alias="FlightDisplayView.qml">src/FlightDisplay/FlightDisplayView.qml</file>
<file alias="FlightDisplayViewUVC.qml">src/FlightDisplay/FlightDisplayViewUVC.qml</file>
<file alias="FlightDisplayViewDummy.qml">src/FlightDisplay/FlightDisplayViewDummy.qml</file>
<file alias="PX4FlightModes.qml">src/AutoPilotPlugins/PX4/PX4FlightModes.qml</file>
<file alias="PX4AdvancedFlightModes.qml">src/AutoPilotPlugins/PX4/PX4AdvancedFlightModes.qml</file>
<file alias="PX4SimpleFlightModes.qml">src/AutoPilotPlugins/PX4/PX4SimpleFlightModes.qml</file>
...
...
src/FlightDisplay/FlightDisplayView.qml
View file @
32292bab
...
...
@@ -184,34 +184,17 @@ QGCView {
}
}
]
//--
UDP
Video Streaming
//-- Video Streaming
FlightDisplayViewVideo
{
anchors.fill
:
parent
visible
:
QGroundControl
.
videoManager
.
isGStreamer
}
//-- UVC Video (USB Camera or Video Device)
Rectangle
{
id
:
noVideo
Loader
{
id
:
cameraLoader
anchors.fill
:
parent
color
:
Qt
.
rgba
(
0
,
0
,
0
,
0.75
)
visible
:
!
QGroundControl
.
videoManager
.
isGStreamer
Camera
{
id
:
camera
deviceId
:
QGroundControl
.
videoManager
.
videoSourceID
captureMode
:
Camera
.
CaptureViewfinder
}
VideoOutput
{
id
:
viewFinder
source
:
camera
anchors.fill
:
parent
visible
:
!
QGroundControl
.
videoManager
.
isGStreamer
}
onVisibleChanged
:
{
if
(
visible
)
camera
.
start
()
else
camera
.
stop
()
}
source
:
QGroundControl
.
videoManager
.
uvcEnabled
?
"
qrc:/qml/FlightDisplayViewUVC.qml
"
:
"
qrc:/qml/FlightDisplayViewDummy.qml
"
}
}
...
...
src/FlightDisplay/FlightDisplayViewDummy.qml
0 → 100644
View file @
32292bab
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
import
QtQuick
2.5
Rectangle
{
anchors.fill
:
parent
color
:
Qt
.
rgba
(
0
,
0
,
0
,
0.75
)
}
src/FlightDisplay/FlightDisplayViewUVC.qml
0 → 100644
View file @
32292bab
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
import
QtQuick
2.5
import
QtMultimedia
5.5
import
QGroundControl
1.0
Rectangle
{
anchors.fill
:
parent
color
:
Qt
.
rgba
(
0
,
0
,
0
,
0.75
)
Camera
{
id
:
camera
deviceId
:
QGroundControl
.
videoManager
.
videoSourceID
captureMode
:
Camera
.
CaptureViewfinder
}
VideoOutput
{
source
:
camera
anchors.fill
:
parent
fillMode
:
VideoOutput
.
PreserveAspectCrop
visible
:
!
QGroundControl
.
videoManager
.
isGStreamer
}
onVisibleChanged
:
{
if
(
visible
)
camera
.
start
()
else
camera
.
stop
()
}
}
src/FlightDisplay/FlightDisplayViewVideo.qml
View file @
32292bab
...
...
@@ -41,7 +41,6 @@ Item {
display
:
QGroundControl
.
videoManager
.
videoSurface
receiver
:
QGroundControl
.
videoManager
.
videoReceiver
visible
:
QGroundControl
.
videoManager
.
videoRunning
runVideo
:
true
/* TODO: Come up with a way to make this an option
QGCAttitudeHUD {
id: attitudeHUD
...
...
src/FlightDisplay/VideoManager.cc
View file @
32292bab
...
...
@@ -19,51 +19,36 @@
#include "VideoManager.h"
static
const
char
*
kVideoSourceKey
=
"VideoSource"
;
static
const
char
*
kGStreamerSource
=
"UDP Video Stream"
;
static
const
char
*
kVideoUDPPortKey
=
"VideoUDPPort"
;
static
const
char
*
kVideoRTSPUrlKey
=
"VideoRTSPUrl"
;
static
const
char
*
kUDPStream
=
"UDP Video Stream"
;
#if defined(QGC_GST_STREAMING)
static
const
char
*
kRTSPStream
=
"RTSP Video Stream"
;
#endif
static
const
char
*
kNoVideo
=
"No Video Available"
;
QGC_LOGGING_CATEGORY
(
VideoManagerLog
,
"VideoManagerLog"
)
//-----------------------------------------------------------------------------
VideoManager
::
VideoManager
(
QGCApplication
*
app
)
:
QGCTool
(
app
)
,
_videoSurface
(
NULL
)
,
_videoReceiver
(
NULL
)
,
_videoRunning
(
false
)
,
_udpPort
(
5600
)
//-- Defalut Port 5600 == Solo UDP Port
,
_init
(
false
)
{
/*
* This is the receiving end of an UDP RTP stream. The sender can be setup with this command:
*
* gst-launch-1.0 uvch264src initial-bitrate=1000000 average-bitrate=1000000 iframe-period=1000 name=src auto-start=true src.vidsrc ! \
* video/x-h264,width=1280,height=720,framerate=24/1 ! h264parse ! rtph264pay ! udpsink host=192.168.1.9 port=5600
*
* Where the main parameters are:
*
* uvch264src: Your h264 video source (the example above uses a Logitech C920 on an Raspberry PI 2+ or Odroid C1
* host=192.168.1.9 This is the IP address of QGC. You can use Avahi/Zeroconf to find QGC using the "_qgroundcontrol._udp" service.
*
* Advanced settings (you should probably read the gstreamer documentation before changing these):
*
* initial-bitrate=1000000 average-bitrate=1000000
* The bit rate to use. The greater, the better quality at the cost of higher bandwidth.
*
* width=1280,height=720,framerate=24/1
* The video resolution and frame rate. This depends on the camera used.
*
* iframe-period=1000
* Interval between iFrames. The greater the interval the lesser bandwidth at the cost of a longer time to recover from lost packets.
*
* Do not change anything else unless you know what you are doing. Any other change will require a matching change on the receiving end.
*
*/
_videoSurface
=
new
VideoSurface
;
_videoReceiver
=
new
VideoReceiver
(
this
);
_videoReceiver
->
setUri
(
QLatin1Literal
(
"udp://0.0.0.0:5600"
));
// Port 5600=Solo UDP port, if you change it, you will break Solo video support
//-- Get saved settings
QSettings
settings
;
setVideoSource
(
settings
.
value
(
kVideoSourceKey
,
kUDPStream
).
toString
());
setUdpPort
(
settings
.
value
(
kVideoUDPPortKey
,
5600
).
toUInt
());
setRtspURL
(
settings
.
value
(
kVideoRTSPUrlKey
,
"rtsp://192.168.42.1:554/live"
).
toString
());
//-- Example RTSP URL
_init
=
true
;
#if defined(QGC_GST_STREAMING)
_
videoReceiver
->
setVideoSink
(
_videoSurface
->
videoSink
()
);
_
updateVideo
(
);
connect
(
&
_frameTimer
,
&
QTimer
::
timeout
,
this
,
&
VideoManager
::
_updateTimer
);
_frameTimer
.
start
(
1000
);
#endif
//-- Get saved video source
QSettings
settings
;
setVideoSource
(
settings
.
value
(
kVideoSourceKey
,
kGStreamerSource
).
toString
());
}
//-----------------------------------------------------------------------------
...
...
@@ -96,20 +81,32 @@ bool
VideoManager
::
isGStreamer
()
{
#if defined(QGC_GST_STREAMING)
return
_videoSource
==
k
GStreamerSource
;
return
_videoSource
==
k
UDPStream
||
_videoSource
==
kRTSPStream
;
#else
return
false
;
#endif
}
//-----------------------------------------------------------------------------
#ifndef QGC_DISABLE_UVC
bool
VideoManager
::
uvcEnabled
()
{
return
QCameraInfo
::
availableCameras
().
count
()
>
0
;
}
#endif
//-----------------------------------------------------------------------------
void
VideoManager
::
setVideoSource
(
QString
vSource
)
{
if
(
vSource
==
kNoVideo
)
return
;
_videoSource
=
vSource
;
QSettings
settings
;
settings
.
setValue
(
kVideoSourceKey
,
vSource
);
emit
videoSourceChanged
();
#ifndef QGC_DISABLE_UVC
QList
<
QCameraInfo
>
cameras
=
QCameraInfo
::
availableCameras
();
foreach
(
const
QCameraInfo
&
cameraInfo
,
cameras
)
{
if
(
cameraInfo
.
description
()
==
vSource
)
{
...
...
@@ -119,8 +116,51 @@ VideoManager::setVideoSource(QString vSource)
break
;
}
}
#endif
emit
isGStreamerChanged
();
qCDebug
(
VideoManagerLog
)
<<
"New Video Source:"
<<
vSource
;
/*
* Not working. Requires restart for now. (Undef KRTSP/kUDP above when enabling this)
if(isGStreamer())
_updateVideo();
*/
if
(
_videoReceiver
)
{
if
(
isGStreamer
())
{
_videoReceiver
->
start
();
}
else
{
_videoReceiver
->
stop
();
}
}
}
//-----------------------------------------------------------------------------
void
VideoManager
::
setUdpPort
(
quint16
port
)
{
_udpPort
=
port
;
QSettings
settings
;
settings
.
setValue
(
kVideoUDPPortKey
,
port
);
emit
udpPortChanged
();
/*
* Not working. Requires restart for now. (Undef KRTSP/kUDP above when enabling this)
if(_videoSource == kUDPStream)
_updateVideo();
*/
}
//-----------------------------------------------------------------------------
void
VideoManager
::
setRtspURL
(
QString
url
)
{
_rtspURL
=
url
;
QSettings
settings
;
settings
.
setValue
(
kVideoRTSPUrlKey
,
url
);
emit
rtspURLChanged
();
/*
* Not working. Requires restart for now. (Undef KRTSP/kUDP above when enabling this)
if(_videoSource == kRTSPStream)
_updateVideo();
*/
}
//-----------------------------------------------------------------------------
...
...
@@ -129,20 +169,25 @@ VideoManager::videoSourceList()
{
_videoSourceList
.
clear
();
#if defined(QGC_GST_STREAMING)
_videoSourceList
.
append
(
kGStreamerSource
);
_videoSourceList
.
append
(
kUDPStream
);
_videoSourceList
.
append
(
kRTSPStream
);
#endif
#ifndef QGC_DISABLE_UVC
QList
<
QCameraInfo
>
cameras
=
QCameraInfo
::
availableCameras
();
foreach
(
const
QCameraInfo
&
cameraInfo
,
cameras
)
{
qCDebug
(
VideoManagerLog
)
<<
"UVC Video source ID:"
<<
cameraInfo
.
deviceName
()
<<
" Name:"
<<
cameraInfo
.
description
();
_videoSourceList
.
append
(
cameraInfo
.
description
());
}
#endif
if
(
_videoSourceList
.
count
()
==
0
)
_videoSourceList
.
append
(
kNoVideo
);
return
_videoSourceList
;
}
//-----------------------------------------------------------------------------
#if defined(QGC_GST_STREAMING)
void
VideoManager
::
_updateTimer
(
void
)
void
VideoManager
::
_updateTimer
()
{
#if defined(QGC_GST_STREAMING)
if
(
_videoRunning
)
{
time_t
elapsed
=
0
;
...
...
@@ -150,7 +195,7 @@ void VideoManager::_updateTimer(void)
{
elapsed
=
time
(
0
)
-
_videoSurface
->
lastFrame
();
}
if
(
elapsed
>
2
)
if
(
elapsed
>
2
&&
_videoSurface
)
{
_videoRunning
=
false
;
_videoSurface
->
setLastFrame
(
0
);
...
...
@@ -167,5 +212,26 @@ void VideoManager::_updateTimer(void)
}
}
}
}
#endif
}
//-----------------------------------------------------------------------------
void
VideoManager
::
_updateVideo
()
{
if
(
_init
)
{
if
(
_videoReceiver
)
delete
_videoReceiver
;
if
(
_videoSurface
)
delete
_videoSurface
;
_videoSurface
=
new
VideoSurface
;
_videoReceiver
=
new
VideoReceiver
(
this
);
#if defined(QGC_GST_STREAMING)
_videoReceiver
->
setVideoSink
(
_videoSurface
->
videoSink
());
if
(
_videoSource
==
kUDPStream
)
_videoReceiver
->
setUri
(
QStringLiteral
(
"udp://0.0.0.0:%1"
).
arg
(
_udpPort
));
else
_videoReceiver
->
setUri
(
_rtspURL
);
#endif
_videoReceiver
->
start
();
}
}
src/FlightDisplay/VideoManager.h
View file @
32292bab
...
...
@@ -35,6 +35,9 @@ public:
Q_PROPERTY
(
QString
videoSource
READ
videoSource
WRITE
setVideoSource
NOTIFY
videoSourceChanged
)
Q_PROPERTY
(
QStringList
videoSourceList
READ
videoSourceList
NOTIFY
videoSourceListChanged
)
Q_PROPERTY
(
bool
videoRunning
READ
videoRunning
NOTIFY
videoRunningChanged
)
Q_PROPERTY
(
quint16
udpPort
READ
udpPort
WRITE
setUdpPort
NOTIFY
udpPortChanged
)
Q_PROPERTY
(
QString
rtspURL
READ
rtspURL
WRITE
setRtspURL
NOTIFY
rtspURLChanged
)
Q_PROPERTY
(
bool
uvcEnabled
READ
uvcEnabled
CONSTANT
)
Q_PROPERTY
(
VideoSurface
*
videoSurface
MEMBER
_videoSurface
CONSTANT
)
Q_PROPERTY
(
VideoReceiver
*
videoReceiver
MEMBER
_videoReceiver
CONSTANT
)
...
...
@@ -44,7 +47,18 @@ public:
QString
videoSourceID
()
{
return
_videoSourceID
;
}
QString
videoSource
()
{
return
_videoSource
;
}
QStringList
videoSourceList
();
quint16
udpPort
()
{
return
_udpPort
;
}
QString
rtspURL
()
{
return
_rtspURL
;
}
#if defined(QGC_DISABLE_UVC)
bool
uvcEnabled
()
{
return
false
;
}
#else
bool
uvcEnabled
();
#endif
void
setVideoSource
(
QString
vSource
);
void
setUdpPort
(
quint16
port
);
void
setRtspURL
(
QString
url
);
// Override from QGCTool
void
setToolbox
(
QGCToolbox
*
toolbox
);
...
...
@@ -56,9 +70,12 @@ signals:
void
videoSourceListChanged
();
void
isGStreamerChanged
();
void
videoSourceIDChanged
();
void
udpPortChanged
();
void
rtspURLChanged
();
private:
void
_updateTimer
(
void
);
void
_updateTimer
();
void
_updateVideo
();
private:
VideoSurface
*
_videoSurface
;
...
...
@@ -70,6 +87,9 @@ private:
QString
_videoSource
;
QString
_videoSourceID
;
QStringList
_videoSourceList
;
quint16
_udpPort
;
QString
_rtspURL
;
bool
_init
;
};
#endif
src/FlightMap/QGCVideoBackground.qml
View file @
32292bab
...
...
@@ -22,20 +22,5 @@ VideoItem {
id
:
videoBackground
property
var
display
property
var
receiver
property
var
runVideo
:
false
surface
:
display
onRunVideoChanged
:
{
if
(
videoBackground
.
receiver
&&
videoBackground
.
display
)
{
if
(
videoBackground
.
runVideo
)
{
videoBackground
.
receiver
.
start
();
}
else
{
videoBackground
.
receiver
.
stop
();
}
}
}
Component.onCompleted
:
{
if
(
videoBackground
.
runVideo
&&
videoBackground
.
receiver
)
{
videoBackground
.
receiver
.
start
();
}
}
}
src/VideoStreaming/VideoReceiver.cc
View file @
32292bab
...
...
@@ -49,6 +49,23 @@ void VideoReceiver::setVideoSink(GstElement* sink)
}
#endif
#if defined(QGC_GST_STREAMING)
static
void
newPadCB
(
GstElement
*
element
,
GstPad
*
pad
,
gpointer
data
)
{
gchar
*
name
;
name
=
gst_pad_get_name
(
pad
);
g_print
(
"A new pad %s was created
\n
"
,
name
);
GstCaps
*
p_caps
=
gst_pad_get_pad_template_caps
(
pad
);
gchar
*
description
=
gst_caps_to_string
(
p_caps
);
qDebug
()
<<
p_caps
<<
", "
<<
description
;
g_free
(
description
);
GstElement
*
p_rtph264depay
=
GST_ELEMENT
(
data
);
if
(
gst_element_link_pads
(
element
,
name
,
p_rtph264depay
,
"sink"
)
==
false
)
qCritical
()
<<
"newPadCB : failed to link elements
\n
"
;
g_free
(
name
);
}
#endif
void
VideoReceiver
::
start
()
{
#if defined(QGC_GST_STREAMING)
...
...
@@ -56,7 +73,6 @@ void VideoReceiver::start()
qCritical
()
<<
"VideoReceiver::start() failed because URI is not specified"
;
return
;
}
if
(
_videoSink
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed because video sink is not set"
;
return
;
...
...
@@ -72,29 +88,44 @@ void VideoReceiver::start()
GstElement
*
parser
=
NULL
;
GstElement
*
decoder
=
NULL
;
bool
isUdp
=
_uri
.
contains
(
"udp://"
);
do
{
if
((
_pipeline
=
gst_pipeline_new
(
"receiver"
))
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with gst_pipeline_new()"
;
break
;
}
if
((
dataSource
=
gst_element_factory_make
(
"udpsrc"
,
"udp-source"
))
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with gst_element_factory_make('udpsrc')"
;
break
;
if
(
isUdp
)
{
dataSource
=
gst_element_factory_make
(
"udpsrc"
,
"udp-source"
);
}
else
{
dataSource
=
gst_element_factory_make
(
"rtspsrc"
,
"rtsp-source"
);
}
if
(
(
caps
=
gst_caps_from_string
(
"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264"
))
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with
gst_caps_from_string
()"
;
if
(
!
dataSource
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with
data source for gst_element_factory_make
()"
;
break
;
}
g_object_set
(
G_OBJECT
(
dataSource
),
"uri"
,
qPrintable
(
_uri
),
"caps"
,
caps
,
NULL
);
if
(
isUdp
)
{
if
((
caps
=
gst_caps_from_string
(
"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264"
))
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with gst_caps_from_string()"
;
break
;
}
g_object_set
(
G_OBJECT
(
dataSource
),
"uri"
,
qPrintable
(
_uri
),
"caps"
,
caps
,
NULL
);
}
else
{
g_object_set
(
G_OBJECT
(
dataSource
),
"location"
,
qPrintable
(
_uri
),
"latency"
,
0
,
NULL
);
}
if
((
demux
=
gst_element_factory_make
(
"rtph264depay"
,
"rtp-h264-depacketizer"
))
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with gst_element_factory_make('rtph264depay')"
;
break
;
}
if
(
!
isUdp
)
{
g_signal_connect
(
dataSource
,
"pad-added"
,
G_CALLBACK
(
newPadCB
),
demux
);
}
if
((
parser
=
gst_element_factory_make
(
"h264parse"
,
"h264-parser"
))
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with gst_element_factory_make('h264parse')"
;
break
;
...
...
@@ -107,7 +138,15 @@ void VideoReceiver::start()
gst_bin_add_many
(
GST_BIN
(
_pipeline
),
dataSource
,
demux
,
parser
,
decoder
,
_videoSink
,
NULL
);
if
(
gst_element_link_many
(
dataSource
,
demux
,
parser
,
decoder
,
_videoSink
,
NULL
)
!=
(
gboolean
)
TRUE
)
{
gboolean
res
=
FALSE
;
if
(
isUdp
)
{
res
=
gst_element_link_many
(
dataSource
,
demux
,
parser
,
decoder
,
_videoSink
,
NULL
);
}
else
{
res
=
gst_element_link_many
(
demux
,
parser
,
decoder
,
_videoSink
,
NULL
);
}
if
(
!
res
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with gst_element_link_many()"
;
break
;
}
...
...
src/VideoStreaming/VideoStreaming.pri
View file @
32292bab
...
...
@@ -73,8 +73,12 @@ LinuxBuild {
QMAKE_POST_LINK += $$escape_expand(\\n) xcopy \"$$GST_ROOT_WIN\\lib\\gstreamer-1.0\\validate\\*.dll\" \"$$DESTDIR_WIN\\gstreamer-plugins\\validate\\\" /Y $$escape_expand(\\n)
}
} else:AndroidBuild {
#- gstreamer assumed to be installed in $$PWD/../../android/gstreamer-1.0-android-armv7-1.5.2
GST_ROOT = $$PWD/../../gstreamer-1.0-android-armv7-1.5.2
#- gstreamer assumed to be installed in $$PWD/../../android/gstreamer-1.0-android-armv7-1.5.2 (or x86)
Androidx86Build {
GST_ROOT = $$PWD/../../gstreamer-1.0-android-x86-1.5.2
} else {
GST_ROOT = $$PWD/../../gstreamer-1.0-android-armv7-1.5.2
}
exists($$GST_ROOT) {
QMAKE_CXXFLAGS += -pthread
CONFIG += VideoEnabled
...
...
src/VideoStreaming/VideoSurface.cc
View file @
32292bab
...
...
@@ -27,6 +27,7 @@ VideoSurface::VideoSurface(QObject *parent)
#if defined(QGC_GST_STREAMING)
,
_data
(
new
VideoSurfacePrivate
)
,
_lastFrame
(
0
)
,
_refed
(
false
)
#endif
{
}
...
...
@@ -34,7 +35,7 @@ VideoSurface::VideoSurface(QObject *parent)
VideoSurface
::~
VideoSurface
()
{
#if defined(QGC_GST_STREAMING)
if
(
_data
->
videoSink
!=
NULL
)
{
if
(
!
_refed
&&
_data
->
videoSink
!=
NULL
)
{
gst_element_set_state
(
_data
->
videoSink
,
GST_STATE_NULL
);
}
delete
_data
;
...
...
@@ -42,7 +43,7 @@ VideoSurface::~VideoSurface()
}
#if defined(QGC_GST_STREAMING)
GstElement
*
VideoSurface
::
videoSink
()
const
GstElement
*
VideoSurface
::
videoSink
()
{
if
(
_data
->
videoSink
==
NULL
)
{
if
((
_data
->
videoSink
=
gst_element_factory_make
(
"qtquick2videosink"
,
NULL
))
==
NULL
)
{
...
...
@@ -50,6 +51,7 @@ GstElement* VideoSurface::videoSink() const
return
NULL
;
}
g_signal_connect
(
_data
->
videoSink
,
"update"
,
G_CALLBACK
(
onUpdateThunk
),
(
void
*
)
this
);
_refed
=
true
;
}
return
_data
->
videoSink
;
}
...
...
src/VideoStreaming/VideoSurface.h
View file @
32292bab
...
...
@@ -40,7 +40,7 @@ public:
* is called. The surface will always keep a reference to this element.
*/
#if defined(QGC_GST_STREAMING)
GstElement
*
videoSink
()
const
;
GstElement
*
videoSink
();
time_t
lastFrame
()
{
return
_lastFrame
;
}
void
setLastFrame
(
time_t
t
)
{
_lastFrame
=
t
;
}
#endif
...
...
@@ -55,7 +55,8 @@ private:
friend
class
VideoItem
;
#if defined(QGC_GST_STREAMING)
VideoSurfacePrivate
*
const
_data
;
time_t
_lastFrame
;
time_t
_lastFrame
;
bool
_refed
;
#endif
};
...
...
src/VideoStreaming/gstqtvideosink/gstqtvideosinkplugin.cpp
View file @
32292bab
...
...
@@ -27,7 +27,7 @@
#include "gstqwidgetvideosink.h"
#define PACKAGE "mini-qt-gstreamer"
#define PACKAGE_NAME "QgcQtGStreamer"
#define PACKAGE_NAME "QgcQtGStreamer"
#define PACKAGE_ORIGIN "http://gstreamer.freedesktop.org/"
#define PACKAGE_VERSION "1.2.0"
...
...
@@ -44,7 +44,7 @@ static gboolean plugin_init(GstPlugin *plugin)
G_STRINGIFY
(
QGC_VIDEOSINK_PLUGIN
),
0
,
"Debug category for GstQtVideoSink"
);
if
(
!
gst_element_register
(
plugin
,
G_STRINGIFY
(
QGC_VIDEOSINK_PLUGIN
),
if
(
!
gst_element_register
(
plugin
,
G_STRINGIFY
(
QGC_VIDEOSINK_PLUGIN
),
GST_RANK_NONE
,
GST_TYPE_QT_VIDEO_SINK
))
{
GST_ERROR
(
"Failed to register "
G_STRINGIFY
(
QGC_VIDEOSINK_PLUGIN
));
return
FALSE
;
...
...
src/ui/preferences/GeneralSettings.qml
View file @
32292bab
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment