Skip to content

Commit

Permalink
Added RTSP
Browse files Browse the repository at this point in the history
  • Loading branch information
sackmotion committed Feb 26, 2014
1 parent 32f1e88 commit 22b946b
Show file tree
Hide file tree
Showing 8 changed files with 513 additions and 36 deletions.
2 changes: 1 addition & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ VIDEO_OBJ = @VIDEO@
OBJ = motion.o logger.o conf.o draw.o jpegutils.o vloopback_motion.o $(VIDEO_OBJ) \
netcam.o netcam_ftp.o netcam_jpeg.o netcam_wget.o track.o \
alg.o event.o picture.o rotate.o webhttpd.o \
stream.o md5.o @FFMPEG_OBJ@ @SDL_OBJ@
stream.o md5.o @FFMPEG_OBJ@ @SDL_OBJ@ @RTPS_OBJ@
SRC = $(OBJ:.o=.c)
DOC = CHANGELOG COPYING CREDITS INSTALL README motion_guide.html
EXAMPLES = *.conf motion.init-Debian motion.init-Fedora motion.init-FreeBSD.sh
Expand Down
3 changes: 3 additions & 0 deletions config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@
/* Define to 1 if you have av_avformat_alloc_context support */
#undef have_av_avformat_alloc_context

/* Define to 1 if you have av_get_media_type_string support */
#undef have_av_get_media_type_string

/* Define to 1 if you have av_register_protocol support */
#undef have_av_register_protocol

Expand Down
30 changes: 21 additions & 9 deletions configure
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for motion Git-aa2d317a553ea96300c56aac2f9f92af0014c925.
# Generated by GNU Autoconf 2.69 for motion trunkREVUNKNOWN.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
Expand Down Expand Up @@ -577,8 +577,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='motion'
PACKAGE_TARNAME='motion'
PACKAGE_VERSION='Git-aa2d317a553ea96300c56aac2f9f92af0014c925'
PACKAGE_STRING='motion Git-aa2d317a553ea96300c56aac2f9f92af0014c925'
PACKAGE_VERSION='trunkREVUNKNOWN'
PACKAGE_STRING='motion trunkREVUNKNOWN'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''

Expand Down Expand Up @@ -625,6 +625,7 @@ BIN_PATH
EGREP
GREP
CPP
RTPS_OBJ
FFMPEG_OBJ
SDL_OBJ
VIDEO
Expand Down Expand Up @@ -1244,7 +1245,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures motion Git-aa2d317a553ea96300c56aac2f9f92af0014c925 to adapt to many kinds of systems.
\`configure' configures motion trunkREVUNKNOWN to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
Expand Down Expand Up @@ -1305,7 +1306,7 @@ fi

if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of motion Git-aa2d317a553ea96300c56aac2f9f92af0014c925:";;
short | recursive ) echo "Configuration of motion trunkREVUNKNOWN:";;
esac
cat <<\_ACEOF
Expand Down Expand Up @@ -1453,7 +1454,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
motion configure Git-aa2d317a553ea96300c56aac2f9f92af0014c925
motion configure trunkREVUNKNOWN
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
Expand Down Expand Up @@ -2055,7 +2056,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by motion $as_me Git-aa2d317a553ea96300c56aac2f9f92af0014c925, which was
It was created by motion $as_me trunkREVUNKNOWN, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
Expand Down Expand Up @@ -4451,6 +4452,9 @@ $as_echo "not found" >&6; }
FFMPEG_OBJ="ffmpeg.o"


RTPS_OBJ="netcam_rtsp.o"


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking file_protocol is defined in ffmpeg ?" >&5
$as_echo_n "checking file_protocol is defined in ffmpeg ?... " >&6; }
saved_CFLAGS=$CFLAGS
Expand Down Expand Up @@ -6063,6 +6067,14 @@ $as_echo "#define have_av_register_protocol 1" >>confdefs.h

fi

ac_fn_c_check_func "$LINENO" "av_get_media_type_string" "ac_cv_func_av_get_media_type_string"
if test "x$ac_cv_func_av_get_media_type_string" = xyes; then :

$as_echo "#define have_av_get_media_type_string 1" >>confdefs.h

fi
0


#
# Add the right exec path for rc scripts
Expand Down Expand Up @@ -6593,7 +6605,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by motion $as_me Git-aa2d317a553ea96300c56aac2f9f92af0014c925, which was
This file was extended by motion $as_me trunkREVUNKNOWN, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
Expand Down Expand Up @@ -6655,7 +6667,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
motion config.status Git-aa2d317a553ea96300c56aac2f9f92af0014c925
motion config.status trunkREVUNKNOWN
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
Expand Down
5 changes: 5 additions & 0 deletions configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,9 @@ if test "${FFMPEG_OK}" = "found"; then
FFMPEG_OBJ="ffmpeg.o"
AC_SUBST(FFMPEG_OBJ)

RTPS_OBJ="netcam_rtsp.o"
AC_SUBST(RTPS_OBJ)

AC_MSG_CHECKING([file_protocol is defined in ffmpeg ?])
saved_CFLAGS=$CFLAGS
saved_LIBS=$LIBS
Expand Down Expand Up @@ -1218,6 +1221,8 @@ AC_CHECK_FUNC(avformat_alloc_context, AC_DEFINE([have_avformat_alloc_context],1,
AC_CHECK_FUNC(av_avformat_alloc_context, AC_DEFINE([have_av_avformat_alloc_context],1,[Define to 1 if you have av_avformat_alloc_context support]))
AC_CHECK_FUNC(av_register_protocol2, AC_DEFINE([have_av_register_protocol2],1,[Define to 1 if you have av_register_protocol2 support]))
AC_CHECK_FUNC(av_register_protocol, AC_DEFINE([have_av_register_protocol],1,[Define to 1 if you have av_register_protocol support]))
AC_CHECK_FUNC(av_get_media_type_string, AC_DEFINE([have_av_get_media_type_string],1,[Define to 1 if you have av_get_media_type_string support]))0


#
# Add the right exec path for rc scripts
Expand Down
151 changes: 125 additions & 26 deletions netcam.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
#include <sys/socket.h>

#include "netcam_ftp.h"
#ifdef have_av_get_media_type_string
#include "netcam_rtsp.h"
#endif

#define CONNECT_TIMEOUT 10 /* Timeout on remote connection attempt */
#define READ_TIMEOUT 5 /* Default timeout on recv requests */
Expand Down Expand Up @@ -146,8 +149,13 @@ static void netcam_url_parse(struct url_t *parse_url, const char *text_url)
{
char *s;
int i;
#ifdef have_av_get_media_type_string
const char *re = "(http|ftp|mjpg|rtsp)://(((.*):(.*))@)?"
"([^/:]|[-.a-z0-9]+)(:([0-9]+))?($|(/[^:]*))";
#else
const char *re = "(http|ftp|mjpg)://(((.*):(.*))@)?"
"([^/:]|[-.a-z0-9]+)(:([0-9]+))?($|(/[^:]*))";
#endif
regex_t pattbuf;
regmatch_t matches[10];

Expand Down Expand Up @@ -203,6 +211,10 @@ static void netcam_url_parse(struct url_t *parse_url, const char *text_url)
parse_url->port = 80;
else if (!strcmp(parse_url->service, "ftp"))
parse_url->port = 21;
#ifdef have_av_get_media_type_string
else if (!strcmp(parse_url->service, "rtsp") && parse_url->port == 0)
parse_url->port = 554;
#endif
}

regfree(&pattbuf);
Expand Down Expand Up @@ -2401,6 +2413,71 @@ static int netcam_setup_ftp(netcam_context_ptr netcam, struct url_t *url)
return 0;
}

#ifdef have_av_get_media_type_string
static int netcam_setup_rtsp(netcam_context_ptr netcam, struct url_t *url)
{
struct context *cnt = netcam->cnt;
const char *ptr;

netcam->caps.streaming = NCS_RTSP;
netcam->rtsp = rtsp_new_context();

if (netcam->rtsp == NULL) {
MOTION_LOG(ERR, TYPE_NETCAM, NO_ERRNO, "%s: unable to create rtsp context");
return -1;
}

/*
* Allocate space for a working string to contain the path.
* The extra 5 is for "://", ":" and string terminator.
*/

// force port to a sane value
if (netcam->connect_port > 65536) {
netcam->connect_port = 65536;
} else if (netcam->connect_port < 0) {
netcam->connect_port = 0;
}

ptr = mymalloc(strlen(url->service) + strlen(netcam->connect_host)
+ 5 + strlen(url->path) + 5);
sprintf((char *)ptr, "%s://%s:%d%s", url->service,
netcam->connect_host, netcam->connect_port, url->path);

netcam->rtsp->path = (char *)ptr;

if (cnt->conf.netcam_userpass != NULL) {
ptr = cnt->conf.netcam_userpass;
} else {
ptr = url->userpass; /* Don't set this one NULL, gets freed. */
}

if (ptr != NULL) {
char *cptr;

if ((cptr = strchr(ptr, ':')) == NULL) {
netcam->rtsp->user = mystrdup(ptr);
} else {
netcam->rtsp->user = mymalloc((cptr - ptr));
memcpy(netcam->rtsp->user, ptr,(cptr - ptr));
netcam->rtsp->pass = mystrdup(cptr + 1);
}
}

netcam_url_free(url);

/*
* The RTSP context should be all ready to attempt a connection with
* the server, so we try ....
*/
rtsp_connect(netcam);

netcam->get_image = netcam_read_rtsp_image;

return 0;
}
#endif

/**
* netcam_recv
*
Expand Down Expand Up @@ -2631,6 +2708,11 @@ int netcam_next(struct context *cnt, unsigned char *image)
pthread_mutex_unlock(&netcam->mutex);
}

if (netcam->caps.streaming == NCS_RTSP) {
memcpy(image, netcam->latest->ptr, netcam->latest->used);
return 0;
}

/*
* If an error occurs in the JPEG decompression which follows this,
* jpeglib will return to the code within this 'if'. Basically, our
Expand Down Expand Up @@ -2808,6 +2890,13 @@ int netcam_start(struct context *cnt)

strcpy(url.service, "http"); /* Put back a real URL service. */
retval = netcam_setup_mjpg(netcam, &url);
#ifdef have_av_get_media_type_string
} else if ((url.service) && (!strcmp(url.service, "rtsp"))) {
MOTION_LOG(INF, TYPE_NETCAM, NO_ERRNO, "%s: now calling"
" netcam_setup_rtsp()");

retval = netcam_setup_rtsp(netcam, &url);
#endif
} else {
MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: Invalid netcam service '%s' - "
"must be http, ftp, mjpg or file.", url.service);
Expand All @@ -2831,36 +2920,46 @@ int netcam_start(struct context *cnt)
return -1;
}

/*
* If an error occurs in the JPEG decompression which follows this,
* jpeglib will return to the code within this 'if'. If such an error
* occurs during startup, we will just abandon this attempt.
*/
if (setjmp(netcam->setjmp_buffer)) {
MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: libjpeg decompression failure "
"on first frame - giving up!");
return -1;
}
#ifdef have_av_get_media_type_string
if (netcam->caps.streaming != NCS_RTSP) {
#endif
/*
* If an error occurs in the JPEG decompression which follows this,
* jpeglib will return to the code within this 'if'. If such an error
* occurs during startup, we will just abandon this attempt.
*/
if (setjmp(netcam->setjmp_buffer)) {
MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: libjpeg decompression failure "
"on first frame - giving up!");
return -1;
}

netcam->netcam_tolerant_check = cnt->conf.netcam_tolerant_check;
netcam->JFIF_marker = 0;
netcam_get_dimensions(netcam);
netcam->netcam_tolerant_check = cnt->conf.netcam_tolerant_check;
netcam->JFIF_marker = 0;
netcam_get_dimensions(netcam);

/*
* Motion currently requires that image height and width is a
* multiple of 16. So we check for this.
*/
if (netcam->width % 8) {
MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: netcam image width (%d)"
" is not modulo 8", netcam->width);
return -3;
}
/*
* Motion currently requires that image height and width is a
* multiple of 16. So we check for this.
*/
if (netcam->width % 8) {
MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: netcam image width (%d)"
" is not modulo 8", netcam->width);
return -3;
}

if (netcam->height % 8) {
MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: netcam image height (%d)"
" is not modulo 8", netcam->height);
return -3;
if (netcam->height % 8) {
MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: netcam image height (%d)"
" is not modulo 8", netcam->height);
return -3;
}
#ifdef have_av_get_media_type_string
} else {
// not jpeg, get the dimensions
netcam->width = netcam->rtsp->codec_context->width;
netcam->height = netcam->rtsp->codec_context->height;
}
#endif

/* Fill in camera details into context structure. */
cnt->imgs.width = netcam->width;
Expand Down
4 changes: 4 additions & 0 deletions netcam.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ typedef struct file_context {
#define NCS_UNSUPPORTED 0 /* streaming is not supported */
#define NCS_MULTIPART 1 /* streaming is done via multipart */
#define NCS_BLOCK 2 /* streaming is done via MJPG-block */
#define NCS_RTSP 3 /* streaming is done via RTSP */

/*
* struct netcam_context contains all the structures and other data
Expand Down Expand Up @@ -199,6 +200,9 @@ typedef struct netcam_context {
struct file_context *file; /* this structure contains the
context for FILE connection */

struct rtsp_context *rtsp; /* this structure contains the
context for RTSP connection */

int (*get_image)(netcam_context_ptr);
/* Function to fetch the image from
the netcam. It is initialised in
Expand Down
Loading

0 comments on commit 22b946b

Please sign in to comment.