標籤:
mjpg-streamer網路攝影機遠程傳輸UVC
1 下載原始碼
mjpg-streamer的原始碼地址 https://github.com/codewithpassion/mjpg-streamer
嵌入式 mini2440版 https://github.com/vfonov/mjpg-streamer
2 編譯
mjpg-streamermake
執行
export LD_LIBRARY_PATH="$(pwd)"
./mjpg_streamer -i "./input_uvc.so -y" -o "./output_ http.so -w ./www"
電腦端 用Firefox瀏覽器 輸入
http://192.168.1.17:8080/?
action=stream
當中 192.168.1.17依據實際情況輸入
2原始碼分析
從main開始 位於Mjpg_streamer.c
getopt_long_only:解析輸入的參數global.in.init = dlsym(global.in.handle, "input_init"); // 讓 global.in.init = input_init dlsym 取動態對象地址
input_init (input_uvc.c )-->if (init_videoIn(videoIn, dev, width, height, fps, format, 1) < 0) init_videoIn(V4l2uvc.c (plugins\input_uvc) init_v4l2
global.in.run = dlsym(global.in.handle, "input_run");
input_run(input_uvc.c )
-->pthread_create(&cam, 0, cam_thread, NULL);
void *cam_thread( void *arg )
uvcGrab(videoIn)
if (videoIn->formatIn == V4L2_PIX_FMT_YUYV)
pglobal->size = compress_yuyv_to_jpeg(videoIn, pglobal->buf, videoIn->framesizeIn, gquality);
else
{
pglobal->size = memcpy_picture(pglobal->buf, videoIn->tmpbuffer, videoIn->buf.bytesused);
}
global.out[i].init = dlsym(global.out[i].handle, "output_init"); output_init( output_http.c)
servers[param->id].id = param->id; servers[param->id].pglobal = param->global; servers[param->id].conf.port = port; servers[param->id].conf.credentials = credentials; servers[param->id].conf.www_folder = www_folder; servers[param->id].conf.nocommands = nocommands;
global.out[i].stop = dlsym(global.out[i].handle, "output_stop");
output_stop
pthread_cancel(servers[id].threadID);
global.out[i].run = dlsym(global.out[i].handle, "output_run");
output_run(output_http.c) pthread_create(&(servers[id].threadID), NULL, server_thread, &(servers[id])); // 建立一個線程 server_thread pthread_detach(servers[id].threadID); // 等待線程結束,以便回收
server_thread (Httpd.c\plugins\output_http) -> client_thread if ( strstr(buffer, "GET /?action=snapshot") != NULL )
{
req.type = A_SNAPSHOT;
}
else if ( strstr(buffer, "GET /?action=stream") != NULL )
{
req.type = A_STREAM;
}
else if ( strstr(buffer, "GET /?action=command") != NULL )
{
req.type = A_COMMAND; }
switch ( req.type ){
case A_SNAPSHOT:
DBG("Request for snapshot\n");
send_snapshot(lcfd.fd);
break;
case A_STREAM:
DBG("Request for stream\n");
send_stream(lcfd.fd);
break;
}
mjpg-streamer網路攝影機遠程傳輸UVC