dv4l に解像度指定できる機能を追加してみた


dv4l は DV カメラの入力を v4l に変換してくれる Linux 向けのソフトです。
これを使用することで ustream でのストリーミングに DV カメラを使用できるようになります。
ただ、DV カメラからの入力である 640x480 のうち、DV カメラの中心部分 320x240 しか ustream に映らないという状態になる問題があります。(画面の周辺部分が切り取られてしまって見えなくなっているイメージ)
今回 dv4l の dv4lstart に、解像度を指定すれば縮小してくれる機能を追加しました。


ダウンロードはこちらから。
http://drop.io/dv4l_ForceResizeAdded


dv4l-1.0-ForceResizeAdded.tar.gz を展開してから

$ ./configure
$ make
$ sudo make install
$ dv4lstart --width 320 --height 240 epiphany

とかやると「--width 320 --height 240」で設定したサイズに画像が縮小された状態の入力が epiphany (ブラウザ)に渡ります。この2つのオプションが今回追加したものになります。




ustream で画面の中心しか映らずこんな感じだったのが


こんな感じになります。(DV カメラの位置は変えてません)




関係ないけど、epiphany は軽いので ustream するときだけブラウザとしてこれを使用してます。
あと、dv4l のコードはインデントがタブとスペースごちゃ混ぜだったので、今回のファイルではそれもスペースに書き直してしまってます。
タブスペース以外の diff は以下になります。

diff -uNrp dv4l-1.0_org_cleaned/interdv4l.c dv4l-1.0-ForceResizeAdded/interdv4l.c
--- dv4l-1.0_org_cleaned/interdv4l.c	2008-11-27 01:41:01.000000000 +0900
+++ dv4l-1.0-ForceResizeAdded/interdv4l.c	2008-11-28 02:04:22.000000000 +0900
@@ -89,6 +89,8 @@ typedef struct {
 } vid_context_t;
 
 static vid_context_t vctx = { 0 };
+static int vid_resize_width = 0;
+static int vid_resize_height = 0;
 
 static int is_videodev(const char *name);
 
@@ -391,6 +393,17 @@ char *getenv(const char *name)
 
         dv4l_env = getenv("DV4L_RGBONLY");
         vctx.vrgbonly = (dv4l_env != NULL);
+
+        dv4l_env = getenv("DV4L_WIDTH");
+        if(dv4l_env != NULL){
+            vid_resize_width = atoi(dv4l_env);
+        }
+
+        dv4l_env = getenv("DV4L_HEIGHT");
+        if(dv4l_env != NULL){
+            vid_resize_height = atoi(dv4l_env);
+        }
+
     }
 
     if(strcmp(name, "LD_PRELOAD") == 0) {
@@ -726,8 +739,16 @@ debug("#1 dv4l open libdv_init\n"); \
         vctx.vcap.maxheight = 0; \
 log("#2 dv4l open vfd %d fake_fd %d\n", vctx.vfd, fake_fd); \
         get_camsize(&vctx); \
-        vctx.vwin.width = vctx.vcap.maxwidth; \
-        vctx.vwin.height = vctx.vcap.maxheight; \
+        if(vid_resize_width > 0 && vid_resize_width < vctx.vcap.maxwidth) { \
+            vctx.vwin.width = vid_resize_width; \
+        } else { \
+            vctx.vwin.width = vctx.vcap.maxwidth; \
+        } \
+        if(vid_resize_height > 0 && vid_resize_height < vctx.vcap.maxheight) { \
+            vctx.vwin.height = vid_resize_height; \
+        } else { \
+            vctx.vwin.height = vctx.vcap.maxheight; \
+        } \
 debug("#3 dv4l open\n"); \
         iec61883_dv_set_buffers(iec61883_dv_fb_get_dv(vctx.viec), 1000); \
         if(iec61883_dv_fb_start(vctx.viec, 63) < 0) { \
diff -uNrp dv4l-1.0_org_cleaned/mkdv4lstart dv4l-1.0-ForceResizeAdded/mkdv4lstart
--- dv4l-1.0_org_cleaned/mkdv4lstart	2008-11-27 01:41:01.000000000 +0900
+++ dv4l-1.0-ForceResizeAdded/mkdv4lstart	2008-11-21 22:17:38.000000000 +0900
@@ -11,6 +11,12 @@ usage () {
     echo
     echo "Version " $2
     echo
+    echo "    -wd, --width"
+    echo "        Set width(pix) which you want to scale to."
+    echo
+    echo "    -ht, --height"
+    echo "        Set height(pix) which you want to scale to."
+    echo
     echo "    -c, --color-correction"
     echo "        Set this option if red objects look blue."
     echo
@@ -45,6 +51,16 @@ do
         DV4L_RGBONLY=1
         export DV4L_RGBONLY
         ;;
+    -wd | --width)
+        shift
+        DV4L_WIDTH=\$1
+        export DV4L_WIDTH
+        ;;
+    -ht | --height)
+        shift
+        DV4L_HEIGHT=\$1
+        export DV4L_HEIGHT
+        ;;
     -v | --verbose)
         shift
         DV4L_VERBOSE=\$1
diff -uNrp dv4l-1.0_org_cleaned/palettes.c dv4l-1.0-ForceResizeAdded/palettes.c
--- dv4l-1.0_org_cleaned/palettes.c	2008-11-27 01:41:01.000000000 +0900
+++ dv4l-1.0-ForceResizeAdded/palettes.c	2008-11-21 22:17:38.000000000 +0900
@@ -17,6 +17,7 @@
  * Author: Wolfgang Beck <bewo at users.berlios.de> 2007
  */
 
+#include <sys/time.h>
 #include <linux/videodev.h>
 
 /*