Captura de jpegs de una secuencia h264 con gstreamer en una Raspberry Pi
raspberry-pi openmax (1)
Tengo uno de los nuevos complementos de cámara para una Raspberry Pi. Todavía no tiene soporte para video4linux, pero viene con un pequeño programa que arroja una secuencia 1080p h264. He verificado que esto funciona y lo tengo empujando el video a stdout con:
raspivid -n -t 1000000 -vf -b 2000000 -fps 25 -o -
Me gustaría procesar esta secuencia de manera que termine con una instantánea del video tomada una vez por segundo.
Como es 1080p, necesitaré usar el soporte de hardware de rpi para la codificación H264. Creo que gstreamer es la única aplicación que lo admite, por lo que las soluciones que usen ffmpeg o avconv no funcionarán. Utilicé el script de compilación en http://www.trans-omni.co.uk/pi/GStreamer-1.0/build_gstreamer para hacer gstreamer y el complemento para la codificación de hardware H264 y parece funcionar:
root@raspberrypi:~/streamtest# GST_OMX_CONFIG_DIR=/etc/gst gst-inspect-1.0 | grep 264
...
omx: omxh264enc: OpenMAX H.264 Video Encoder
omx: omxh264dec: OpenMAX H.264 Video Decoder
Así que tengo que construir un canal de lanzamiento de gst que toma video en stdin y escupe un jpeg nuevo una vez por segundo. Sé que puedo usar el receptor ''multifilesink'' de gstreamer para hacer esto, así que he creado el siguiente script breve para ejecutarlo:
root@raspberrypi:~/streamtest# cat test.sh
#!/bin/bash
export GST_OMX_CONFIG_DIR=/etc/gst
raspivid -n -t 1000000 -vf -b 2000000 -fps 25 -o - | /
gst-launch-1.0 fdsrc fd=0 ! decodebin ! videorate ! video/x-raw,framerate=1/1 ! jpegenc ! multifilesink location=img_%03d.jpeg
El problema es que no funciona: gstreamer simplemente se sienta para siempre en el estado de pre-entrenamiento y nunca escupe mis jpegs preciosos.
root@raspberrypi:~/streamtest# ./test.sh
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
[waits forever]
En caso de que sea útil, la salida con el conjunto de indicadores de -v de gstreamer está en http://pastebin.com/q4WySu4L.
¿Alguien puede explicar lo que estoy haciendo mal?
Finalmente encontramos una solución a esto. Mi gstreamer pipeline estaba en lo cierto, pero dos problemas combinados para dejar de funcionar:
- raspivid no agrega marcas de tiempo a los marcos h264 que produce
- las versiones recientes de gstreamer tienen un error que lo detienen al manejar marcos sin marca
Ejecuta una versión 1.0 de gstreamer (asegúrate de construir desde cero y elimina todos los rastros de intentos anteriores) y el problema desaparece.
Ver http://gstreamer-devel.966125.n4.nabble.com/Capturing-jpegs-from-an-h264-stream-tt4660254.html para el hilo de la lista de correo.