GStreamer RTSP with RPi


0. 개요


 RTSP(real-time streaming protocol)란 실시간으로 음성이나 동화를 송수신하기 위한 통신

규약입니다. 오직 전송을 위한 프로토콜이므로 저장공간을 낭비하지 않으면서 고화질 영상을

빠르게 전송할 수 있는 장점이 있습니다. 단, 스트리밍을 지원하는 동영상 플레이어에서만 시

청이 가능하며, 스마트폰 어플 개발에서는 안드로이드가 기본적으로 RTSP를 지원합

니다. VLC를 통해서도 RTSP 스트리밍이 가능합니다만 지연 시간이 길다는 단점이 있습니다.

그러나 GStreamer를 이용하면 고해상도의 영상도 아주 빠른 속도로 스트리밍이 가능합니다.

본 강좌는 SSH에서의 명령어를 통한 방법입니다. 또한 USB 웹캠이 아닌 라즈베리파이

카메라 모듈을 기반으로 합니다.


1. GStreamer RTSP


앞서 GStreamer RTSP 서버 프로그램이 필요합니다. wget을 통해 압축파일을 저장하고 이를

풀어주도록 하겠습니다. 만약 링크로 받을 수 없다면 첨부파일을 통해 저장하신 후 ~/ 위치에 

저장해주십시오.



AERY@AFTERMATH.KR:~$ wget http://gstreamer.freedesktop.org/src/gst-rtsp/gst-rtsp-0.10.8.tar.bz2

--2013-08-17 19:15:29-- http://gstreamer.freedesktop.org/src/gst-rtsp/gst-rtsp-0.10.8.tar.bz2Resolving gstreamer.freedesktop.org (gstreamer.freedesktop.org)... 131.252.210.176Connecting to gstreamer.freedesktop.org (gstreamer.freedesktop.org)|131.252.210.176|:80... 

connected.HTTP request sent, awaiting response... 200 OKLength: 567670 (554K) [application/x-bzip2]Saving to: `gst-rtsp-0.10.8.tar.bz2'100%[================================>] 567,670 313K/s in 1.8s

2013-08-17 19:15:32 (313 KB/s) - `gst-rtsp-0.10.8.tar.bz2' saved [567670/567670]

AERY@AFTERMATH.KR:~$ bzip2 -d gst-rtsp-0.10.8.tar.bz2

AERY@AFTERMATH.KR:~$ tar xvf gst-rtsp-0.10.8.tar

AERY@AFTERMATH.KR:~$ cd gst-rtsp-0.10.8/

AERY@AFTERMATH.KR:~/gst-rtsp-0.10.8$


2. GStreamer-0.10 패키지 설치


서버 프로그램이 준비되었다면 라이브러리를 설치하도록 합니다. 명심하실 것은 본 서버는

GStreamer0.10 버전에서 작동합니다. GStreamer1.0 버전이 미리 설치되어있으시더라도 아래

명령어를 통하여 기본적인 필수 라이브러리를 설치합니다.



AERY@AFTERMATH.KR:~/gst-rtsp-0.10.8$ sudo apt-get install libglib2.0-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev gstreamer-tools gstreamer0.10-plugins-base gstreamer0.10-plugins-good gstreamer0.10-plugins-bad gstreamer0.10-plugins-ugly


3. GStreamer RTSP 설치


패키지 설치가 끝나셨으면 본격적으로 컴파일을 시작합니다.


AERY@AFTERMATH.KR:~/gst-rtsp-0.10.8$ ./configure

checking for a BSD-compatible install... /usr/bin/install -c

checking whether build environment is sane... yes

checking for a thread-safe mkdir -p... /bin/mkdir -p

checking for gawk... no

checking for mawk... mawk

checking whether make sets $(MAKE)... yes

checking nano version... 0 (release)

checking whether to enable maintainer-specific portions of Makefiles... no

checking build system type... armv6l-unknown-linux-gnueabi

checking host system type... armv6l-unknown-linux-gnueabi

checking for style of include used by make... GNU

checking for gcc... gcc

checking whether the C compiler works... yes

checking for C compiler default output file name... a.out

checking for suffix of executables... 

checking whether we are cross compiling... no

checking for suffix of object files... o

checking whether we are using the GNU C compiler... yes

checking whether gcc accepts -g... yes

checking for gcc option to accept ISO C89... none needed

checking dependency style of gcc... gcc3

checking for a sed that does not truncate output... /bin/sed

checking for grep that handles long lines and -e... /bin/grep

checking for egrep... /bin/grep -E

checking for fgrep... /bin/grep -F

checking for ld used by gcc... /usr/bin/ld

checking if the linker (/usr/bin/ld) is GNU ld... yes

checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B

checking the name lister (/usr/bin/nm -B) interface... BSD nm

checking whether ln -s works... yes

checking the maximum length of command line arguments... 1572864

checking whether the shell understands some XSI constructs... yes

checking whether the shell understands "+="... yes

checking for /usr/bin/ld option to reload object files... -r

checking for objdump... objdump

checking how to recognize dependent libraries... pass_all

checking for ar... ar

checking for strip... strip

checking for ranlib... ranlib

checking command to parse /usr/bin/nm -B output from gcc object... ok

checking how to run the C preprocessor... gcc -E

checking for ANSI C header files... yes

checking for sys/types.h... yes

checking for sys/stat.h... yes

checking for stdlib.h... yes

checking for string.h... yes

checking for memory.h... yes

checking for strings.h... yes

checking for inttypes.h... yes

checking for stdint.h... yes

checking for unistd.h... yes

checking for dlfcn.h... yes

checking for objdir... .libs

checking if gcc supports -fno-rtti -fno-exceptions... no

checking for gcc option to produce PIC... -fPIC -DPIC

checking if gcc PIC flag -fPIC -DPIC works... yes

checking if gcc static flag -static works... yes

checking if gcc supports -c -o file.o... yeschecking if gcc supports -c -o file.o... (cached) yes

checking whether the gcc linker (/usr/bin/ld) supports shared libraries... yes

checking whether -lc should be explicitly linked in... no

checking dynamic linker characteristics... GNU/Linux ld.so

checking how to hardcode library paths into programs... immediate

checking whether stripping libraries is possible... yes

checking if libtool supports shared libraries... yes

checking whether to build shared libraries... yes

checking whether to build static libraries... yes

checking whether NLS is requested... yes

checking for msgfmt... /usr/bin/msgfmt

checking for gmsgfmt... /usr/bin/msgfmt

checking for xgettext... /usr/bin/xgettext

checking for msgmerge... /usr/bin/msgmerge

checking for ld used by GCC... /usr/bin/ld

checking if the linker (/usr/bin/ld) is GNU ld... yes

checking for shared library run path origin... done

checking for CFPreferencesCopyAppValue... no

checking for CFLocaleCopyCurrent... no

checking for GNU gettext in libc... yes

checking whether to use NLS... yes

checking where the gettext function comes from... libc

checking for pkg-config... /usr/bin/pkg-config

checking pkg-config is at least version 0.9.0... yes

checking for VALGRIND... no

no

configure: Using Gst-RTSP source release as package name

configure: Using Unknown package origin as package origin

configure: Using GST_PKG_CONFIG_PATH = $(top_builddir)/pkgconfig

checking for gcc... (cached) gcc

checking whether we are using the GNU C compiler... (cached) yes

checking whether gcc accepts -g... (cached) yes

checking for gcc option to accept ISO C89... (cached) none needed

checking dependency style of gcc... (cached) gcc3

checking whether gcc and cc understand -c and -o together... yes

checking for valgrind... no

checking for gobject-introspection... no

checking whether to build gtk-doc documentation... no

checking for gtkdoc-check... no

checking for python... /usr/bin/python

checking for python version... 2.7

checking for python platform... linux2

checking for python script directory... ${prefix}/lib/python2.7/dist-packages

checking for python extension module directory... ${exec_prefix}/lib/python2.7/dist-packages

checking for python >= 2.3... okay

checking for headers required to compile python extensions... not found

checking for PYGOBJECT... no

checking for PYGST... no

checking for GLIB... yes

checking for GST... yes

configure: using GStreamer tools in /usr/bin

configure: using GStreamer plug-ins in /usr/lib/arm-linux-gnueabihf/gstreamer-0.10

configure: Using GStreamer Core Plugins in /usr/lib/arm-linux-gnueabihf/gstreamer-0.10

checking for GST_BASE... yes

checking for GST_PLUGINS_BASE... yes

configure: using GStreamer Base Plugins in /usr/lib/arm-linux-gnueabihf/gstreamer-0.10

configure: Using GStreamer Base Plugins in /usr/lib/arm-linux-gnueabihf/gstreamer-0.10

checking for GST_CHECK... yes

checking for check named check_pic - version >= 0.9.2... no

*** Could not run check test program, checking why...

*** The test program failed to compile or link. See the file config.log for

*** the exact error that occured.

checking for check named check - version >= 0.9.2... no

*** Could not run check test program, checking why...

*** The test program failed to compile or link. See the file config.log for

*** the exact error that occured.

configure: Using /usr/local/lib/gstreamer-0.10 as the plugin install location

checking to see if compiler understands -Wall... yes

checking to see if compiler understands -Wdeclaration-after-statement... yes

checking to see if compiler understands -Wvla... yes

checking to see if compiler understands -Wpointer-arith... yes

configure: set WARNING_CFLAGS to -Wall -Wdeclaration-after-statement -Wvla -Wpointer-arith

configure: set ERROR_CFLAGS to configure: Using autoaudiosink as default audio sink

configure: Using alsasrc as default audio source

configure: Using autovideosink as default video sink

configure: Using v4l2src as default video source

configure: Using goom as default visualizer

configure: creating ./config.status

config.status: creating Makefile

config.status: creating gst-rtsp.spec

config.status: creating common/Makefile

config.status: creating common/m4/Makefile

config.status: creating gst/Makefile

config.status: creating gst/rtsp-server/Makefile

config.status: creating examples/Makefile

config.status: creating tests/Makefile

config.status: creating bindings/Makefile

config.status: creating bindings/python/Makefile

config.status: creating bindings/python/codegen/Makefile

config.status: creating bindings/vala/Makefile

config.status: creating pkgconfig/Makefile

config.status: creating pkgconfig/gst-rtsp-server.pc

config.status: creating pkgconfig/gst-rtsp-server-uninstalled.pc

config.status: creating docs/Makefile

config.status: creating docs/version.entities

config.status: creating docs/libs/Makefile

config.status: creating config.h

config.status: config.h is unchanged

config.status: executing depfiles commands

config.status: executing libtool commands

config.status: executing po-directories commands


Configuration 

Version : 0.10.8 

Source code location : . 

Prefix : /usr/local 

Compiler : gcc 

Vala bindings : yes 

Python bindings: : no


Gst-rtsp-server configured. Type 'make' to build.


AERY@AFTERMATH.KR:~/gst-rtsp-0.10.8$

위와 같이 나왔다면 패키지 설치에 성공하신 겁니다. 마지막으로 make를 해줍니다.
(sudo make install은 하지 않습니다.)

AERY@AFTERMATH.KR:~/gst-rtsp-0.10.8$ make


4. 스트리밍


실행 순서는 다음과 같습니다. raspivid를 통해 카메라 모듈을 실행하고 gst-launch에서 인코

딩 및 영상 전송을 준비합니다. 여기까지는 GStreamer를 통해 영상을 스트리밍이 가능한 상태

입니다. 여기서 앞서 준비한 GStreamer RTSP를 이용합니다. 스트리밍에 사용할 실행 파일은

~/gst-rtsp-0.10.8/examples/test-launch 입니다.

단, gst-lauch 인자값에 포트 번호와 스트리밍의 포트는 별개입니다. 실제로 RTSP 규격은 554

번 또는 8554번 포트를 사용하며, 본 서버 프로그램은 8554번 포트를 사용합니다.



AERY@AFTERMATH.KR:~/gst-rtsp-0.10.8$ cd examples

AERY@AFTERMATH.KR:~/gst-rtsp-0.10.8/examples$ raspivid -t 0 -h 720 -w 1280 -fps 25 -b 2000000 -vf -hf -n -o - | gst-launch -v fdsrc ! h264parse ! gdppay ! tcpserversink host=127.0.0.1 port=5000 | ./test-launch "( tcpclientsrc host=127.0.0.1 port=5000 ! gdpdepay ! avdec_h264 ! rtph264pay name=pay0 pt=96 )"


별 다른 반응없이 카메라 모듈에 불이 들어왔다면 영상을 열어보도록 하겠습니다.
저는 다음팟플레이어를 사용하겠습니다.




Ctrl + U 를 눌러 '주소 열기'를 실행합니다.
주소형식은 RTSP://아이피:8554/test 입니다.




잠시동안의 로딩이 끝나고 영상이 스트리밍됩니다.




아두이노 듀에와 알피노가 보이네요. 
지연 시간은 약 0.4초 내외로 아주 빠릅니다.
스크린샷은 강좌를 위해 일부로 사이즈를 줄인 것이며, 실제로는 720p 입니다.

[테스트 영상]





다음은 스마트폰에서의 테스트입니다.
저는 널리 사용되는 MX 플레이어를 사용했습니다.

메뉴키를 눌러 '네트워크 스트림'을 열어 주소를 입력합니다.




스마트폰의 경우 PC와는 달리 로딩이 조금 더 지연될 수 있습니다.




5. Android Development Tools 에서의 RTSP


iOS의 경우에는 RTSP를 지원하지 않기 때문에 직접 라이브러리를 개발하셔야 사용이 가능합

니다. (RTSP를 지원하는 iOS 어플이 있긴 합니다. iOS는 HTTP 형식의 스트리밍을 지원합니다.)

그러나 안드로이드에서는 기본적으로 RTSP를 지원하므로 간편하게 개발이 가능합니다.

본 강좌는 라즈베리 파이 강좌이기 때문에 안드로이드 개발에 대한 내용은 생략하겠습니다.

(android.media.MediaPlayer 등에서 주소값을 rtsp:// 로 적으면 알아서 다해줍니다.)



[참고사이트]


o http://www.raspberrypi.org/phpBB3/viewtopic.php?f=43&t=49278