After much trawling through the forums, I found a way to record the video stream at the receiving end using gst-launch-1.0 in such a way that it can be converted to a playable format later on without re-encoding and the resulting loss of quality. Eventually, replacing gst-launch-1.0 with a dedicated gstreamer application would allow a valid video file to be recorded straight from the stream without the current post processing. This flight also included a test of the external amplified antenna for the Ultimate GPS Breakout board. The results were disappointing, not attaining sufficient accuracy for the desired application. The flight was cut short due to a combination of high, turbulent wind and dumb thumbs, but was long enough to get meaningful results. You need to watch the video at 720p for a meaningful comparison. Please bear in mind that the video has been re-encoded at least once, possibly three times between the Pi and your browser. https://www.youtube.com/watch?v=eCazn-JbR_0
The amplified GPS antenna comes with 5 metres of cable and a heavy magnet. I shortened the cable and removed the magnet, but the parts were still unwieldy when strapped to the top of the plane. Hardware wise this was the only addition to the previous test.
I had already generated and swapped ssh keys between the Pi and the laptop to remove the need to enter a password when connecting. While I’ve been testing different GPS setups , I’ve started gpsd using a small shell script
#!/bin/bash echo Starting gpsd sudo gpsd /dev/ttyAMA0 -n -F /var/run/gpsd.sock
I want to use the current time and date for the video and gpx file names. As the Pi does not have a real time clock, I set the time from GPS using a script based on one I found at http://blog.petrilopia.net
#!/bin/bash sudo date -s '01/01/2014 00:01' sleep 1 GPSDATE=`gpspipe -w | head -10 | grep TPV | sed -r 's/.*"time":"([^"]*)".*/\1/' | head -1` echo $GPSDATE sudo date -s "$GPSDATE"
Next I run cgps to check the GPS accuracy. Once it stops improving I exit cgps and run the third script to start gps logging and record the video stream. The video is recorded as the raw h264 stream with a Tx (Transmitter) suffix.
#!/bin/sh cat $0 # Duration in milliseconds. Use 0(Zero) for continuous DURATION=1800000 WIDTH=1280 HEIGHT=720 FRAMERATE=25 BITRATE=2500000 NOW=`date +%Y%m%d%H%M%S` FILENAME=$NOW-Tx.h264 gpxlogger -i 2 -f $NOW.gpx & IP=$(ip -o addr show wlan0 | sed -n 's/.*inet \([0-9.]*\)\/.. .*/\1/p') PORT=5000 /opt/vc/bin/raspivid -t $DURATION -w $WIDTH -h $HEIGHT -fps $FRAMERATE -b $BITRATE -n -o - | tee $FILENAME | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=$IP port=$PORT
Finally, back on the laptop, in a new terminal window, I run a script to capture and display the video stream. The h264 file is multiplexed (muxed) into an mpeg transport stream (ts) container with a Rx (Receiver) suffix.
#!/bin/bash # Read the Settings file source ./settings.conf # Set file name from current time NOW=`date +%Y%m%d%H%M%S` FILENAME=$NOW-Rx.ts # Read the stream. gst-launch-1.0 -v tcpclientsrc host=$IP port=$PORT ! \ gdpdepay ! rtph264depay ! \ h264parse config-interval=96 ! \ tee name=t ! queue ! \ video/x-h264, framerate=25/1 ! avdec_h264 ! videoconvert ! autovideosink sync=false t. ! \ queue ! mpegtsmux ! filesink location=$FILENAME # Try to copy the file from SD card to Hard Disk if [ ! -d $TARGETDIR ]; then sudo mount /dev/sdb4 /mnt fi cp $FILE $TARGETDIR/$FILENAME
Here is a sample settings.conf
#!/bin/bash export IP=192.168.42.1 export PORT=5000 export FRAMERATE=25 export TARGETDIR=/mnt/home/user
When I arrived at the field the wind felt to be blowing at a constant 10 mph. In the short time it took to get everything ready it had started gusting much harder. Having driven to the field and got everything setup I was determined to fly so opened the throttle and gave it a good chuck. My first realisation was that the wind was stronger than anything I had flown in before. In order to get the aircraft to track up the field and not be blown out the back, I had to point it 20 to 30 degrees past the desired direction of flight. Also, as the aircraft got further up the field and closer to the trees, the turbulence made it harder to control. Eventually, it got bucked around to the point I lost orientation, dumb thumbed the rudder flipping it upside down and I wasn’t able to recover it before it hit the ground. When I checked later, the met office were quoting 26 mph gusts.
The previous months rain had softened the ground enough that the aircraft nose was stuck in three or four inches with no apparent damage. The rubber bands had separated, releasing the wings. Any electronics that weren’t screwed down were scattered around the crash site and given a liberal coating of mud. Everything was dismantled and cleaned in fresh water, then left to dry. When I did reconnect everything, it all worked. The only problem was that camera now has a green tint. I suspect that that the mud has abraded the lens coating, either on impact or during cleaning. As they are cheap I bought a new one.
I was worried that the crash would have lost or corrupted the on-board video recording. As it turned out, only the last few seconds of the flight were lost, as you can see in the video. After collecting the scattered components, I found the X terminal on the laptop reporting that the SD card had become read only. It was still receiving and recording a video stream, although this was mostly a totally brown frame which turned to a greeny orange when I removed most of the mud.
I’ll cover the GPS first as it’s going to be short. The results using the larger amplified antenna were better, but still not good enough. There seems to be either a lag or an offset in the computation. The two images below show the problem. For the next flight I’m going to use the CRIUS CN-06 V2 U-blox GPS module.
The video recorded on the Pi (Tx) was copied to a Windows PC using WinSCP. Then I used MP4BoxGUI to mux it into a MP4 file. I have not had any problems using the generated file. With the video recorded on the laptop (Rx) as a transport stream, the first task was to convert it into an mp4. The following script takes the file name as an argument and creates two new videos. This need to be run on a machine using Gstreamer version 1.2 (Check using gst-launch-1.0 –version).
#!/bin/bash echo . echo Remux echo . gst-launch-1.0 -v filesrc location=$1 ! tsdemux ! h264parse ! video/x-h264,framerate=25/1 ! mp4mux ! filesink location=$1.remux.mp4 echo . echo Re-encode echo . gst-launch-1.0 -v filesrc location=$1 ! tsdemux ! h264parse ! video/x-h264,framerate=25/1 ! avdec_h264 ! videoconvert ! x264enc bitrate=2500 ! mp4mux ! filesink location=$1.reenc.mp4
The first gstreamer pipeline (Remux), simply extracts the h264 video from the transport stream container and them multiplexes it into an mp4 container. The h264 stream is unchanged, so there is no loss of video quality. To make this file viewable on Windows required a couple of extra steps. With the file copied on to the Windows PC I used MP4BoxGUI to demux and extract the h264 stream (again) and then to Mux it back into an MP4 file. This new file was playable in Windows media Player. The second gstreamer pipeline (Re-encode), re-encodes the video as a new h264 file and multiplexes it into an mp4 container. While re-encoding has to reduce the picture quality, it is not obvious without close inspection. I use the re-encoded video in Sony Movie Studio 11.0, which had trouble reading the first remuxed file. I also had to manually set the frame rate in Sony Movie Studio 11 to 25 fps as by default it was using 29.97 fps making it impossible to sync the Tx and Rx videos together.
The video posted on Youtube shows the Tx and Rx videos side by side. They are fully synced and without a gap between I don’t think you can spot a join or see any difference in video quality. Although a bit of a faff, for now I have a working pipeline to record usable video on the ground. As for the GPS, the search goes on.