Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
proview
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Esteban Blanc
proview
Commits
f7c7a5c3
Commit
f7c7a5c3
authored
Sep 21, 2015
by
Claes Sjofors
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Xtt camera, connection down detection with reconnect added
parent
105bc30d
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
179 additions
and
26 deletions
+179
-26
src/wbl/pwrb/src/pwrb_c_xttcamera.wb_load
src/wbl/pwrb/src/pwrb_c_xttcamera.wb_load
+20
-0
xtt/lib/xtt/gtk/xtt_stream_gtk.cpp
xtt/lib/xtt/gtk/xtt_stream_gtk.cpp
+128
-26
xtt/lib/xtt/gtk/xtt_stream_gtk.h
xtt/lib/xtt/gtk/xtt_stream_gtk.h
+5
-0
xtt/lib/xtt/src/xtt_stream.cpp
xtt/lib/xtt/src/xtt_stream.cpp
+24
-0
xtt/lib/xtt/src/xtt_stream.h
xtt/lib/xtt/src/xtt_stream.h
+2
-0
No files found.
src/wbl/pwrb/src/pwrb_c_xttcamera.wb_load
View file @
f7c7a5c3
...
...
@@ -188,11 +188,31 @@ SObject pwrb:Class
Attr Flags |= PWR_MASK_DEVHIDEVALUE
EndBody
EndObject
!/**
! Connection timeout.
!*/
Object ConnectionTimeout $Attribute 17
Body SysBody
Attr TypeRef = "pwrs:Type-$Float32"
EndBody
EndObject
!/**
! Reconnect time.
! If the connection is down, a reconnect will be made
! cyclically with this interval.
!*/
Object ReconnectTime $Attribute 18
Body SysBody
Attr TypeRef = "pwrs:Type-$Float32"
EndBody
EndObject
EndObject
Object Template XttCamera
Body RtBody
Attr Width = 800
Attr Height = 600
Attr ConnectionTimeout = 10
Attr ReconnectTime = 5
EndBody
EndObject
EndObject
...
...
xtt/lib/xtt/gtk/xtt_stream_gtk.cpp
View file @
f7c7a5c3
...
...
@@ -93,15 +93,43 @@ static GstBusSyncReply bus_sync_handler (GstBus * bus, GstMessage * message,
void
XttStreamGtk
::
realize_cb
(
GtkWidget
*
widget
,
void
*
data
)
{
XttStreamGtk
*
strm
=
(
XttStreamGtk
*
)
data
;
GdkWindow
*
window
=
gtk_widget_get_window
(
strm
->
video_form
);
guintptr
window_handle
;
if
(
!
gdk_window_ensure_native
(
window
))
g_error
(
"Couldn't create native window needed for GstXOverlay!"
);
GstElement
*
videosink
;
g_object_get
(
strm
->
playbin2
,
"video-sink"
,
&
videosink
,
NULL
);
GdkWindow
*
window
=
gtk_widget_get_window
(
strm
->
video_form
);
// if (!gdk_window_ensure_native (window))
// g_error ("Couldn't create native window needed for GstXOverlay!");
window_handle
=
GDK_WINDOW_XID
(
window
);
gst_x_overlay_set_xwindow_id
(
GST_X_OVERLAY
(
strm
->
playbin2
),
window_handle
);
gst_x_overlay_set_xwindow_id
(
GST_X_OVERLAY
(
videosink
),
window_handle
);
}
void
XttStreamGtk
::
source_setup_cb
(
GstElement
*
playbin2
,
GstElement
*
src
,
gpointer
data
)
{
XttStreamGtk
*
strm
=
(
XttStreamGtk
*
)
data
;
// Set timeout for connection
GstElement
*
source
;
guint
tmo
=
(
int
)
(
strm
->
connection_timeout
+
0.5
);
g_object_get
(
strm
->
playbin2
,
"source"
,
&
source
,
NULL
);
g_object_set
(
source
,
"timeout"
,
tmo
,
NULL
);
// If the connections has been down, overlay has to be set again
GstElement
*
videosink
;
guintptr
window_handle
;
g_object_get
(
strm
->
playbin2
,
"video-sink"
,
&
videosink
,
NULL
);
if
(
videosink
)
{
GdkWindow
*
window
=
gtk_widget_get_window
(
strm
->
video_form
);
window_handle
=
GDK_WINDOW_XID
(
window
);
gst_x_overlay_set_xwindow_id
(
GST_X_OVERLAY
(
videosink
),
window_handle
);
}
}
/* This function is called when the PLAY button is clicked */
...
...
@@ -148,18 +176,7 @@ gboolean XttStreamGtk::expose_cb( GtkWidget *widget, GdkEventExpose *event, void
XttStreamGtk
*
strm
=
(
XttStreamGtk
*
)
data
;
if
(
strm
->
state
<
GST_STATE_PAUSED
)
{
GtkAllocation
allocation
;
GdkWindow
*
window
=
gtk_widget_get_window
(
widget
);
cairo_t
*
cr
;
/* Cairo is a 2D graphics library which we use here to clean the video window.
* It is used by GStreamer for other reasons, so it will always be available to us. */
gtk_widget_get_allocation
(
widget
,
&
allocation
);
cr
=
gdk_cairo_create
(
window
);
cairo_set_source_rgb
(
cr
,
0
,
0
,
0
);
cairo_rectangle
(
cr
,
0
,
0
,
allocation
.
width
,
allocation
.
height
);
cairo_fill
(
cr
);
cairo_destroy
(
cr
);
strm
->
erase_window
();
}
return
FALSE
;
...
...
@@ -213,6 +230,22 @@ void XttStreamGtk::refresh_ui( XttStreamGtk *strm)
}
void
XttStreamGtk
::
erase_window
()
{
GtkAllocation
allocation
;
GdkWindow
*
window
=
gtk_widget_get_window
(
video_form
);
cairo_t
*
cr
;
/* Cairo is a 2D graphics library which we use here to clean the video window.
* It is used by GStreamer for other reasons, so it will always be available to us. */
gtk_widget_get_allocation
(
video_form
,
&
allocation
);
cr
=
gdk_cairo_create
(
window
);
cairo_set_source_rgb
(
cr
,
0
,
0
,
0
);
cairo_rectangle
(
cr
,
0
,
0
,
allocation
.
width
,
allocation
.
height
);
cairo_fill
(
cr
);
cairo_destroy
(
cr
);
}
void
XttStreamGtk
::
refresh
(
void
*
data
)
{
XttStreamGtk
*
strm
=
(
XttStreamGtk
*
)
data
;
...
...
@@ -222,6 +255,52 @@ void XttStreamGtk::refresh( void *data)
strm
->
timerid
->
add
(
strm
->
scan_time
,
strm
->
refresh
,
data
);
}
void
XttStreamGtk
::
reconnect
(
void
*
data
)
{
XttStreamGtk
*
strm
=
(
XttStreamGtk
*
)
data
;
GstState
state
,
async
;
GstStateChangeReturn
ch
=
gst_element_get_state
(
strm
->
playbin2
,
&
state
,
&
async
,
0
);
printf
(
"Try to reconnect %d %d %d
\n
"
,
state
,
async
,
ch
);
if
(
state
==
GST_STATE_PLAYING
)
return
;
printf
(
"Adding reconnect
\n
"
);
strm
->
reconnect_timerid
->
remove
();
strm
->
reconnect_timerid
->
add
(
int
(
strm
->
reconnect_time
*
1000
),
reconnect
,
strm
);
if
(
strm
->
no_uri
)
{
printf
(
"Reconnect no URI
\n
"
);
strm
->
no_uri
=
0
;
pwr_tURL
luri
;
char
*
s
;
if
(
strm
->
options
&
strm_mOptions_HttpBasicAuthentication
)
{
if
(
strcmp
(
strm
->
user
,
""
)
!=
0
&&
strcmp
(
strm
->
password
,
""
)
!=
0
&&
(
s
=
strstr
(
strm
->
uri
,
"://"
)))
{
unsigned
long
int
offs
=
s
-
(
char
*
)
strm
->
uri
+
3
;
strncpy
(
luri
,
strm
->
uri
,
offs
);
luri
[
offs
]
=
0
;
strcat
(
luri
,
strm
->
user
);
strcat
(
luri
,
":"
);
strcat
(
luri
,
strm
->
password
);
strcat
(
luri
,
"@"
);
strcat
(
luri
,
&
strm
->
uri
[
offs
]);
}
else
strcpy
(
luri
,
strm
->
uri
);
}
else
if
(
strm
->
options
&
strm_mOptions_CgiParameterAuthentication
)
snprintf
(
luri
,
sizeof
(
luri
),
"%s?user=%s&pwd=%s"
,
strm
->
uri
,
strm
->
user
,
strm
->
password
);
else
strcpy
(
luri
,
strm
->
uri
);
g_object_set
(
strm
->
playbin2
,
"uri"
,
luri
,
NULL
);
}
else
gst_element_set_state
(
strm
->
playbin2
,
GST_STATE_PLAYING
);
}
/* This function is called when new metadata is discovered in the stream */
void
XttStreamGtk
::
tags_cb
(
GstElement
*
playbin2
,
gint
stream
,
void
*
data
)
{
...
...
@@ -244,16 +323,28 @@ void XttStreamGtk::error_cb( GstBus *bus, GstMessage *msg, void *data)
GError
*
err
;
gchar
*
debug_info
;
printf
(
"Message %d
\n
"
,
GST_MESSAGE_TYPE
(
data
));
printf
(
"Message %d
\n
"
,
GST_MESSAGE_TYPE
(
msg
));
/* Print error details on the screen */
gst_message_parse_error
(
msg
,
&
err
,
&
debug_info
);
printf
(
"Error received from element %s: %s
\n
"
,
GST_OBJECT_NAME
(
msg
->
src
),
err
->
message
);
printf
(
"Debugging information: %s
\n
"
,
debug_info
?
debug_info
:
"none"
);
if
(
strcmp
(
err
->
message
,
"No URI set"
)
==
0
)
strm
->
no_uri
=
1
;
g_clear_error
(
&
err
);
g_free
(
debug_info
);
/* Set the pipeline to READY (which stops playback) */
gst_element_set_state
(
strm
->
playbin2
,
GST_STATE_READY
);
// Erase window
strm
->
erase_window
();
// Try to reconnect
strm
->
reconnect_timerid
->
remove
();
strm
->
reconnect_timerid
->
add
(
int
(
strm
->
reconnect_time
*
1000
),
reconnect
,
strm
);
break
;
}
case
GST_MESSAGE_BUFFERING
:
{
...
...
@@ -597,7 +688,7 @@ XttStreamGtk::XttStreamGtk( GtkWidget *st_parent_wid, void *st_parent_ctx, const
int
width
,
int
height
,
int
x
,
int
y
,
double
scan_time
,
unsigned
int
st_options
,
int
st_embedded
,
pwr_tAttrRef
*
st_arp
,
pwr_tStatus
*
sts
)
:
XttStream
(
st_parent_ctx
,
name
,
st_uri
,
width
,
height
,
x
,
y
,
scan_time
,
st_options
,
st_embedded
,
st_arp
),
scroll_cnt
(
0
),
ptz_box_displayed
(
0
),
is_live
(
0
),
buftime
(
pwr_cNTime
),
parent_wid
(
st_parent_wid
),
ptz_box
(
0
)
scroll_cnt
(
0
),
ptz_box_displayed
(
0
),
is_live
(
0
),
buftime
(
pwr_cNTime
),
parent_wid
(
st_parent_wid
),
ptz_box
(
0
)
,
reconnect_timerid
(
0
),
no_uri
(
0
)
{
GstStateChangeReturn
ret
;
GstBus
*
bus
;
...
...
@@ -657,6 +748,8 @@ XttStreamGtk::XttStreamGtk( GtkWidget *st_parent_wid, void *st_parent_ctx, const
g_signal_connect
(
G_OBJECT
(
playbin2
),
"audio-tags-changed"
,(
GCallback
)
tags_cb
,
this
);
g_signal_connect
(
G_OBJECT
(
playbin2
),
"text-tags-changed"
,(
GCallback
)
tags_cb
,
this
);
g_signal_connect
(
G_OBJECT
(
playbin2
),
"source-setup"
,(
GCallback
)
source_setup_cb
,
this
);
if
(
!
embedded
)
{
toplevel
=
gtk_window_new
(
GTK_WINDOW_TOPLEVEL
);
g_signal_connect
(
G_OBJECT
(
toplevel
),
"delete-event"
,
G_CALLBACK
(
delete_event_cb
),
this
);
...
...
@@ -670,6 +763,9 @@ XttStreamGtk::XttStreamGtk( GtkWidget *st_parent_wid, void *st_parent_ctx, const
else
toplevel
=
parent_wid
;
GstElement
*
x_overlay
=
gst_element_factory_make
(
"xvimagesink"
,
"videosink"
);
g_object_set
(
G_OBJECT
(
playbin2
),
"video-sink"
,
x_overlay
,
NULL
);
video_form
=
gtk_drawing_area_new
();
gtk_widget_set_double_buffered
(
video_form
,
FALSE
);
g_signal_connect
(
video_form
,
"realize"
,
G_CALLBACK
(
realize_cb
),
this
);
...
...
@@ -682,6 +778,7 @@ XttStreamGtk::XttStreamGtk( GtkWidget *st_parent_wid, void *st_parent_ctx, const
gtk_widget_add_events
(
video_form
,
GDK_BUTTON_PRESS_MASK
|
GDK_BUTTON_RELEASE_MASK
|
GDK_SCROLL_MASK
);
// GtkWidget *controls;
GtkWidget
*
hbox
=
gtk_hbox_new
(
FALSE
,
0
);
if
(
options
&
strm_mOptions_VideoControlPanel
)
{
...
...
@@ -1000,8 +1097,8 @@ XttStreamGtk::XttStreamGtk( GtkWidget *st_parent_wid, void *st_parent_ctx, const
gtk_container_add
(
GTK_CONTAINER
(
toplevel
),
main_box
);
gtk_window_set_default_size
(
GTK_WINDOW
(
toplevel
),
width
,
height
);
gtk_widget_show_all
(
toplevel
);
gtk_widget_show_all
(
toplevel
);
if
(
ptz_box
)
g_object_set
(
ptz_box
,
"visible"
,
FALSE
,
NULL
);
if
(
!
(
options
&
strm_mOptions_CameraControlPanel
))
...
...
@@ -1050,6 +1147,7 @@ XttStreamGtk::XttStreamGtk( GtkWidget *st_parent_wid, void *st_parent_ctx, const
wow
=
new
CoWowGtk
(
toplevel
);
timerid
=
wow
->
timer_new
();
scroll_timerid
=
wow
->
timer_new
();
reconnect_timerid
=
wow
->
timer_new
();
timerid
->
add
(
scan_time
,
refresh
,
this
);
*
sts
=
XNAV__SUCCESS
;
...
...
@@ -1057,8 +1155,12 @@ XttStreamGtk::XttStreamGtk( GtkWidget *st_parent_wid, void *st_parent_ctx, const
XttStreamGtk
::~
XttStreamGtk
()
{
timerid
->
remove
();
scroll_timerid
->
remove
();
if
(
timerid
)
timerid
->
remove
();
if
(
scroll_timerid
)
scroll_timerid
->
remove
();
if
(
reconnect_timerid
)
reconnect_timerid
->
remove
();
gst_element_set_state
(
playbin2
,
GST_STATE_NULL
);
gst_object_unref
(
playbin2
);
...
...
xtt/lib/xtt/gtk/xtt_stream_gtk.h
View file @
f7c7a5c3
...
...
@@ -81,6 +81,8 @@ class XttStreamGtk : public XttStream {
GtkWidget
*
tools
;
void
*
overlay
;
CoWowTimer
*
reconnect_timerid
;
int
no_uri
;
static
int
gst_initialized
;
...
...
@@ -94,6 +96,7 @@ class XttStreamGtk : public XttStream {
void
setup
();
void
*
get_widget
()
{
return
main_box
;}
void
create_popup_menu
(
int
x
,
int
y
);
void
erase_window
();
static
void
scroll_cb
(
void
*
data
);
static
void
refresh
(
void
*
data
);
...
...
@@ -114,7 +117,9 @@ class XttStreamGtk : public XttStream {
static
void
state_changed_cb
(
GstBus
*
bus
,
GstMessage
*
msg
,
void
*
data
);
static
void
application_cb
(
GstBus
*
bus
,
GstMessage
*
msg
,
void
*
data
);
static
void
resize_cb
(
GtkWidget
*
w
,
GtkAllocation
*
allocation
,
gpointer
data
);
static
void
source_setup_cb
(
GstElement
*
playbin2
,
GstElement
*
src
,
gpointer
data
);
static
gboolean
mousebutton_cb
(
GtkWidget
*
widget
,
GdkEvent
*
event
,
void
*
data
);
static
void
reconnect
(
void
*
data
);
static
void
menu_position_func
(
GtkMenu
*
menu
,
gint
*
x
,
gint
*
y
,
gboolean
*
push_in
,
gpointer
data
);
static
void
activate_zoomreset
(
GtkWidget
*
w
,
gpointer
data
);
...
...
xtt/lib/xtt/src/xtt_stream.cpp
View file @
f7c7a5c3
...
...
@@ -117,6 +117,30 @@ XttStream::XttStream( void *st_parent_ctx, const char *name, const char *st_uri,
if
(
EVEN
(
sts
))
strcpy
(
user
,
""
);
pwr_tFloat32
tmo
;
sts
=
gdh_ArefANameToAref
(
&
aref
,
"ConnectionTimeout"
,
&
aaref
);
if
(
ODD
(
sts
))
sts
=
gdh_GetObjectInfoAttrref
(
&
aaref
,
&
tmo
,
sizeof
(
tmo
));
if
(
ODD
(
sts
))
{
connection_timeout
=
tmo
;
if
(
connection_timeout
<
1
)
connection_timeout
=
10
;
}
else
connection_timeout
=
10
;
pwr_tFloat32
time
;
sts
=
gdh_ArefANameToAref
(
&
aref
,
"ReconnectTime"
,
&
aaref
);
if
(
ODD
(
sts
))
sts
=
gdh_GetObjectInfoAttrref
(
&
aaref
,
&
time
,
sizeof
(
time
));
if
(
ODD
(
sts
))
{
reconnect_time
=
time
;
if
(
connection_timeout
<
1
)
reconnect_time
=
5
;
}
else
reconnect_time
=
5
;
if
(
strcmp
(
user
,
""
)
!=
0
&&
strcmp
(
password
,
""
)
!=
0
)
{
// sprintf( &uri[strlen(uri)], "?user=%s&pwd=%s", user, password);
}
...
...
xtt/lib/xtt/src/xtt_stream.h
View file @
f7c7a5c3
...
...
@@ -118,6 +118,8 @@ class XttStream {
XttCameraControl
*
camera_control
;
pwr_tEnum
control_protocol
;
pwr_tAttrRef
aref
;
float
connection_timeout
;
float
reconnect_time
;
XttStream
(
void
*
st_parent_ctx
,
const
char
*
name
,
const
char
*
st_uri
,
int
st_width
,
int
st_height
,
int
x
,
int
y
,
...
...
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