Skip to content

Streaming video from android using ffmpeg

rngadam edited this page Apr 26, 2011 · 8 revisions

The Haipad uses a ov7670 sensor from which we want to capture video and stream to elsewhere.

The low-level interface to the ov7670 is Linux video4linux2:

http://v4l2spec.bytesex.org/spec-single/v4l2.html

drivers/media/video/tcccam/ov7690_vga.c
drivers/media/video/tcccam/ov7690_vga.h

...exposes a sensor_init_fnc that is called by:

drivers/media/video/tcccam/sensor_if.c:sensor_if_init(struct v4l2_pix_format *pix)

...where it has:

    /* Make the default capture format QVGA YUV422 */
    pix->width = sensor_sizes[VGA].width;
    pix->height = sensor_sizes[VGA].height;
    pix->pixelformat = V4L2_PIX_FMT_YUYV;

dmesg outputs the following

<4>ov7670 sensor_open
<4>CLK :: MCLK = 24, SCLK = 80.
<4>tccxxx_cif_buffer_set enter req_buf===4
<4>data->scaler_x===640
<4>data->scaler_y===480
<4>ov7670 sensor_close

...which in turns calls this rather ridiculous function that does nothing!

/* initialize Sensor after module was reset. */
int sensor_init_module(enum image_size isize, enum pixel_format pfmt,unsigned long xclk)
{
        return 0;
}

...on other hand, it does have this:

/* Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type.  This
 * ioctl is used to negotiate the image capture size and pixel format
 * without actually making it take effect.
 */
static int sensor_try_format(struct v4l2_pix_format *pix)

Some additional user functions declared in drivers/media/video/tcccam/tcc_cam.h: #define VIDIOC_USER_CIF_OVERLAY _IOWR ('V', BASE_VIDIOC_PRIVATE, cif_SuperImpose) #define VIDIOC_USER_JPEG_CAPTURE _IOWR ('V', BASE_VIDIOC_PRIVATE+1, int) #define VIDIOC_USER_GET_CAPTURE_INFO _IOWR ('V', BASE_VIDIOC_PRIVATE+2, TCCXXX_JPEG_ENC_DATA) #define VIDIOC_USER_PROC_AUTOFOCUS _IOWR ('V', BASE_VIDIOC_PRIVATE+3, int

these are handled by camera_core.c:camera_core_do_ioctl

install Code Sourcery and Cygwin, use the following to build:

export CYGPATH=cygpath # [[https://support.codesourcery.com/GNUToolchain/kbentry46]]

Running example from v4linux2 http://v4l2spec.bytesex.org/spec/capture-example.html

export CC=/cygdrive/c/sourcery/bin/arm-none-linux-gnueabi-gcc
$CC v4l2_example.c -static -o v4l2_example;adb push v4l2_example /data/ffmpeg
chmod 777 v4l2_example; ./v4l2_example -d /dev/video0 -m

Checkout and configure ffmpeg

git clone git://git.videolan.org/ffmpeg.git ffmpeg
cd ffmpeg
./configure --arch=arm --cross-prefix=/cygdrive/c/sourcery/bin/arm-none-linux-gnueabi- --extra-ldflags=-static --target -os=linux  --enable-cross-compile
make -j4

on device:

mkdir /data/ffmpeg

push:

adb push ffserver /data/ffmpeg

set permissions

chmod 777 /data/ffmpeg/ffserver

We want to stream using http://www.ffmpeg.org/ffmpeg.html

equivalent settings should be:

    fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width       = 640; fmt.fmt.pix.height      = 480;

-s vga

    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
    //fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
    fmt.fmt.pix.field       = V4L2_FIELD_NONE;
	fmt.fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
	fmt.fmt.pix.bytesperline = fmt.fmt.pix.width*2;
	fmt.fmt.pix.sizeimage = fmt.fmt.pix.bytesperline*fmt.fmt.pix.height;
	fmt.fmt.pix.priv = 0;


cd /data/ffmpeg
./ffmpeg -f video4linux2 -i /dev/video0 -f avi -vcodec mjmpeg tvffmpeg.avi
./ffmpeg -f video4linux2 -s 640x480 -i /dev/video0 webcam.mpg
./ffmpeg -f video4linux -s 640x480 -i /dev/video0 webcam.mpg
./ffmpeg -f video4linux2 -r 30 -s 640x480 -i /dev/video0 webcam.mpg
./ffmpeg  -f video4linux2  -r 30 -s 640x480 -i /dev/video0 -f mp4 -y webcam.mp4
./ffmpeg -pix_fmt yuv422p16be -f video4linux2 -s 320x240 -r 30 -i /dev/video0 -f mp4 webcam.mp4

Clone this wiki locally