2

I'm trying to find the camera module device of an IP camera (running Linux), without much success.

My main objective is to find the camera stream, so I can attach an RTSP server.

Update 26/02/2019

Found libs related to OpenMAX (OMX). I've been trying to cross compile GStreamer with gst-omx to see what I can do with this, but still without success.

Someone familiarized with OMX that doesn't mind giving some pointers?

$ find / -iname "*omx*"
/lib/libOMX_VSRC.so
/lib/libOMX_AVQE_A.so
/lib/libOMX_BELA.so
/lib/libOMX_IJPE_ENC_HW.so
/lib/libOMX_VMFE.so
/lib/libOMX_VSPL.so
/lib/libOMX_IJPE.so
/lib/libOMX_VVHE.so
/lib/libOMX_ASPL.so
/lib/libOMX_IJPE_MEM_MGR.so
/lib/libOMX_ALSA.so
/lib/libOMX_IJPE_ENC_SW.so
/lib/libOMX_ACODEC.so

What I've tried

1. Looking for video devices in /dev

$ ls /dev | grep -i video
$

Nothing... Full ls /dev here.

2. List devices using ffmpeg

$ ffmpeg -devices
ffmpeg version 3.2-static http://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 5.4.1 (Debian 5.4.1-3) 20161019
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-5 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libass --enable-libebur128 --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-librtmp --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg
  libavutil      55. 34.100 / 55. 34.100
  libavcodec     57. 64.100 / 57. 64.100
  libavformat    57. 56.100 / 57. 56.100
  libavdevice    57.  1.100 / 57.  1.100
  libavfilter     6. 65.100 /  6. 65.100
  libswscale      4.  2.100 /  4.  2.100
  libswresample   2.  3.100 /  2.  3.100
  libpostproc    54.  1.100 / 54.  1.100
Devices:
 D. = Demuxing supported
 .E = Muxing supported
 --
 D  dv1394          DV1394 A/V grab
 DE fbdev           Linux framebuffer
 D  lavfi           Libavfilter virtual input device
 DE oss             OSS (Open Sound System) playback
  E v4l2            Video4Linux2 output device
 D  video4linux2,v4l2 Video4Linux2 device grab
 D  x11grab         X11 screen capture, using XCB

Some interesting results here, nothing pointing me to a device on the filesystem or anything.

Just referring to these devices by name inside ffmpeg throws an obvious Cannot open video device, since these names aren't actual devices.

3. Tried v4l2-utils

$ v4l2-ctl --list-devices
Failed to open /dev/video0: No such file or directory
$ v4l2-sysfs-path
Alsa playback device(s): hw:0,0

4. Tried searching the whole filesystem for something

Only found what I guess are proprietary solutions.

$ ls /run | grep video
video_mainstream
video_rawstream
video_substream

$ ls -la /run/video_mainstream/
total 0
drwx------    2 root     root            60 Feb 23 17:03 .
drwxr-xr-x   14 root     root           360 Jan  1  1970 ..
srwxrwxrwx    1 root     root             0 Jan  1  1970 control

Don't know what this empty control file is.

$ ls /mnt/data/bin/
agent_client                  log2tf.sh                     miio_client                   miio_nas_syncer               miio_sdcard                   network_governor.sh           wifi_start.sh
factory                       log_diag.sh                   miio_client_helper_nomqtt.sh  miio_ota                      miio_send_line                play_audio_test
fetch_av                      miio_agent                    miio_devicekit                miio_qrcode                   miio_stream                   post-ota.sh
ipc_client                    miio_alarm                    miio_md                       miio_record                   mortoxc                       pre-ota.sh
log2mi.sh                     miio_algo                     miio_nas                      miio_recv_line                mortoxd                       shbf_client

A lot of proprietary scripts and binaries. I've analyzed some with an elf tool and hex editors (fetch_av, miio_stream, miio_record) but didn't find anything useful.

P.S: Camera is the Xiaomi mjsxj02cm (SoC msc313e, camera sensor SC2235), which uses a linux based firmware.

  • Look through dmesg after boot and see if you can find something. If probably won't be exposed as a linux device, but as something proprietary used by modules like fetch_av, so probably tour best bet is to reverse engineer the API. – dirkt Feb 23 at 17:54
  • @dirkt Thank you! Any tips on how to reverse engineer this? I've already analyzed some binaries using Cutter, but that would mean making sense of all the assembly... Don't get me wrong, if I ultimately have to analyze assembly so be it, but maybe there's an easier way? For example capturing directly on the MIPI CSI interface? (If that makes sense...). Also took a look at dmesg, found a couple of lines mentioning ISP and CSI, but nothing that helps (full dmesg) – Telmo Marques Feb 23 at 19:07
2

Very partial answer, based on dmesg and the msc313e datasheet:

The camera module itself is controlled via I2C, it transfers image data via DVP/MIPI, and there are several hardware image encoders, color processing blocks etc.

From

MSYS: DMEM request: [S1:VENCDMP1]:0x00069AE0
MSYS: DMEM request: [S1:VENCDMP0]:0x00069AE0
MSYS: DMEM request: [S1:VENCDMOUT]:0x0000A100
MSYS: DMEM request: [S0:VENCDMP1]:0x0007F800
MSYS: DMEM request: [S0:VENCDMP0]:0x0007F800
MSYS: DMEM request: [S0:VENCDMOUT]:0x0000A800

I would guess that VENC means "video encoder". There's also a lot of DMA stuff, an "RTMPQ" (queue) etc.

So my guess is that the workflow is based on hardware and DMA transfers. The CPU just sets up those transfers, and lets the hardware blocks do their thing.

You didn't say how this thing is connected up, but if it acts as an USB camera device, one option is that the USB driver has a dedicated memory area as destination of the encoded image produced by the other hardware blocks, and it will just read out the image and transfer it via USB.

This will be difficult to get into and modify in any way, but it least you could inspect the memory areas with known address via /dev/mem and compare them to what you receive as image.

  • 1
    Thank you, I was able to make progress based on this ideia! Wrote a script that went through all the DMEM requests and dumped them from /dev/mem. One of the files is actually a JPEG (0x22CC0000), but it's a snap that only changes every 30 seconds or so. I analyzed all the files using binwalk and file, but this is the only identifiable one. I've uploaded everything here if you don't mind taking a look! – Telmo Marques Feb 24 at 15:38
  • They are likely switching buffers/channels from time to time. As I said, this will be hard to get into. May I ask what you ultimately want to do with the data? Another angle of approach may be to look through the web interface (often there is one), which might offer a way to stream the data over the web, which usually will invoke some program to do the actual streaming. You could try to use this program for your own purposes, which may or may not be enough to do what you want. – dirkt Feb 24 at 17:15
  • My ultimate goal is to attach an RTSP server to the camera stream, because these cameras don't offer that functionality. Some other Xiaomi cameras have already been hacked in this manner (example, another example) but these are different SoC. I was trying to get to the original camera stream to avoid re-encoding a stream, but since I've hit a roadblock I might as well try that... – Telmo Marques Feb 24 at 20:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.