METEOR(4) | FreeBSD Kernel Interfaces Manual | METEOR(4) |
名称
meteor — ビデオキャプチャドライバインタフェース解説
meteor ドライバは、ビデオキャプチャインタフェースを定義しています。 meteor ドライバは、もはや開発ツリーに存在しませんが、他のデバイスがこのインタフェースをサポートするので、インタフェース部分をここで文書化しています。meteor キャプチャモード
meteor キャプチャドライバには、キャプチャ操作の 3 つのモードがあります。- 従来の read(2) インタフェース。
このモードは、使用するのに最も簡単で最も遅いです。このモードは、少ないプログラミングコストで一つのフィールドをキャプチャするのに最適です。
このモードでは、ユーザは、デバイスをオープンし、キャプチャモードとサイズ ( METEORSETGEO ioctl(2) 呼び出しを参照) を設定し、データをバッファにロードするために read(2) システムコールを使用します。
meteor_read.c は、400x300 RGB24 を目視可能な PPM ファイルに読み込みます。
#include <sys/fcntl.h> #include <machine/ioctl_meteor.h> extern int errno; #define ROWS 300 #define COLS 400 #define SIZE (ROWS * COLS * 4) main() { struct meteor_geomet geo; char buf[SIZE],b[4],header[16],*p; int i,o,c; if ((i = open("/dev/meteor0", O_RDONLY)) < 0) { printf("open failed: %d\n", errno); exit(1); } /* キャプチャタイプとサイズをセットアップします */ geo.rows = ROWS; geo.columns = COLS; geo.frames = 1; geo.oformat = METEOR_GEO_RGB24 ; if (ioctl(i, METEORSETGEO, &geo) < 0) { printf("ioctl failed: %d\n", errno); exit(1); } c = METEOR_FMT_NTSC; if (ioctl(i, METEORSFMT, &c) < 0) { printf("ioctl failed: %d\n", errno); exit(1); } c = METEOR_INPUT_DEV0; if (ioctl(i, METEORSINPUT, &c) < 0) { printf("ioctl failed: %d\n", errno); exit(1); } if ((c=read(i, &buf[0], SIZE)) < SIZE) { printf("read failed %d %d %d\n", c, i, errno); close(i); exit(1); } close(i); if ((o = open("rgb24.ppm", O_WRONLY | O_CREAT, 0644)) < 0) { printf("ppm open failed: %d\n", errno); exit(1); } /* PPM ヘッダを作成してファイルに保存 */ strcpy(&header[0], "P6 400 300 255 "); header[2] = header[6] = header[10] = header[14] = '\n'; write (o, &header[0], 15); /* save the RGB data to PPM file */ for (p = &buf[0]; p < &buf[SIZE]; ) { b[2] = *p++; /* 青 */ b[1] = *p++; /* 緑 */ b[0] = *p++; /* 赤 */ *p++; /* NULL バイト */ write(o,&b[0], 3); /* それほど効率的でない */ } close(o); exit(0); }
- メモリマップしたシングルキャプチャ、または非同期連続キャプチャ。
シングルキャプチャモードは、 nv のような会議ツールのために設計されています。これらのツールは、イメージキャプチャの開始を制御するために必要とされ、また 1 秒にいくつかのフレームを必要とします。連続キャプチャモードは、自由実行データを必要とするアプリケーションのために設計されています。
このモードでは、ユーザは、デバイスをオープンし、キャプチャモードとサイズを設定し ( METEORSETGEO ioctl(2) を参照)、フレームバッファメモリをユーザプロセス空間にマップ mmap(2) し、データをメモリマップしたバッファにロードするためにシングルキャプチャか連続キャプチャ ( METEORCAPTUR ioctl(2) を参照) のいずれかが呼び出されます。
METEORCAPTUR ioctl(2) 呼び出しで説明されるように、シングルフレームキャプチャ ioctl(2) は、キャプチャが完了するまでブロックされますが、連続キャプチャは、すぐに返ります。
meteor_mmap_single_continuous.c
#include <sys/types.h> #include <sys/mman.h> #include <sys/fcntl.h> #include <machine/ioctl_meteor.h> extern int errno; #define ROWS 480 #define COLS 640 #define SIZE (ROWS * COLS * 2) main() { struct meteor_geomet geo; char buf[SIZE]; char *mmbuf; int i,c; if ((i = open("/dev/meteor0", O_RDONLY)) < 0) { printf("open failed\n"); exit(1); } geo.rows = ROWS; geo.columns = COLS; geo.frames = 1; geo.oformat = METEOR_GEO_RGB16 ; if (ioctl(i, METEORSETGEO, &geo) < 0) { printf("ioctl failed: %d\n", errno); exit(1); } c = METEOR_FMT_NTSC; if (ioctl(i, METEORSFMT, &c) < 0) { printf("ioctl failed: %d\n", errno); exit(1); } c = METEOR_INPUT_DEV0; if (ioctl(i, METEORSINPUT, &c) < 0) { printf("ioctl failed: %d\n", errno); exit(1); } mmbuf=(char *)mmap((caddr_t)0, SIZE, PROT_READ, MAP_SHARED, i, (off_t)0); #ifdef SINGLE_MODE /* シングルフレームキャプチャ */ c = METEOR_CAP_SINGLE ; ioctl(i, METEORCAPTUR, &c); /* フレームを待つ */ /* mmbuf 中のフレームバッファ配列データを直接アクセスする */ #else /* 連続フレームキャプチャ */ c = METEOR_CAP_CONTINOUS ; ioctl(i, METEORCAPTUR, &c); /* 直ちに返る */ /* mmbuf 中のフレームバッファ配列データを直接アクセスする */ c = METEOR_CAP_STOP_CONT ; ioctl(i, METEORCAPTUR, &c); /* クローズすればキャプチャ も停止 */ #endif close(i); exit(0); }
- メモリマップした、マルチフレームリングバッファ同期キャプチャ。
この連続キャプチャモードは、最大 32 個のフレームを処理するアプリケーションと同期します。これは、シングルと連続キャプチャモードの両方の利点があります。
カーネルは、アプリケーションで定義されたシグナルを起こすことによって、新しいデータのアプリケーションに通知します。また、ドライバは、カーネルによって書き込まれたフレームとアプリケーションによって読み込まれたフレームとの通信を許可するアプリケーションで構造体を共有します。
共有された構造体は、利用者のデータの後に最初のページを開始します。構造体のアドレスは、次の計算で見つけることができます:
(number_rows * number_columns * pixel_depth + 4095) & 0xfffff000
または
((number_rows * number_columns * pixel_depth + 4095)/4096) * 4096
共有された構造体は、タイプ struct meteor_mem です。 2 つの最も重要なフィールドは、 active と num_active_buf と呼ばれます。 active は、カーネルによって書き込まれたフレームのビットマップです。 num_active_bufs は、 active フィールドでマークされたフレームのカウント (数) です。フレームがドライバによって読み込まれるとき、 num_active_bufs カウント (数) は、テストされ、このカウントがアクティブなフレームの数の閾値 ( meteor_mem の hiwat 変数の値) より下であるなら、バッファ中のフレーム番号を表すビットは、 active 変数に格納され、 num_active_bufs が増加され、次に、カーネルは、ユーザアプリケーションを起動するために指定されたシグナルを起こします。ユーザアプリケーションの責任は、シグナルが得られたとき、最も低いアクティブなフレームを決定するために active ビットマップをチェックし、アプリケーションが望んでいるようにデータを使用して、そのフレームのビットマップエントリをクリアして、 num_active_bufs を減少させます。アクティブなフレーム ( hiwat) の数が閾値を超えたなら、カーネルからの新しいフレームまたはシグナルは、 num_active_bufs が lowat 以下になるまで発生しません。
ドライバは、ラウンドロビン方法でフレームをロードします。それは、ユーザが同じ順序でそれらを削除すると期待しています。ドライバは、フレームが既にアクティブであるかどうかチェックしません。
また、 frame_size とバッファ中のフレームの数は、 meteor_mem 構造体に提供されますが、アプリケーションでこれらのフィールドを変更してもドライバの操作は、変更されません。
このモードでのプログラミングでは、ユーザは、デバイスをオープンし、ジオメトリを設定し、データを共通制御構造体にマップ mmap(2) し、次に、連続キャプチャ捕獲モードを開始します。特別なシグナルキャッチャは、それらがカーネルで読み込まれるときフレームを処理するために必要です。
ジオメトリ ( METEORSETGEO ioctl(2) 呼び出しを参照) を指定するとき、フレームの数が 1 以上に設定されることは、重要です。
skeleton_capture_n.c
#include <sys/types.h> #include <sys/mman.h> #include <sys/fcntl.h> #include <sys/signal.h> #include <machine/ioctl_meteor.h> int video; /* シグナルハンドラでキャプチャを停止したいなら、 グローバルで作成 */ caddr_t data_frames; struct meteor_mem *common_mem; extern int errno; #define FRAME_MAX void usr2_catcher() { #ifdef SIGNAL_STOP struct meteor_capframe capframe; /* ioctl に必要 */ #endif char *frame; /* フレームを見つける */ frame = (char *) (data_frames + sig_cnt * common_mem->frame_size) ; /* ここでフレーム追加処理 */ /* フレームを非アクティブにする */ common_mem->active &= ~(1 << (sig_cnt % 16)); common_mem->num_active_bufs--; /* 次の割り込みで次のフレームを処理 */ sig_cnt = ((sig_cnt+1) % FRAME_MAX); #ifdef SIGNAL_STOP if (some_condition_requiring_stopping) { capframe.command=METEOR_CAP_STOP_FRAMES; if (ioctl(i, METEORCAPFRM, &capframe) < 0) { printf("METEORCAPFRM failed %d\n", errno); exit(1); } } #endif } main() { struct meteor_geomet geo; int height, width, depth, frames, size; struct meteor_capframe capframe; if ((i = open("/dev/meteor0", O_RDONLY)) < 0) { printf("open failed\n"); exit(1); } printf("test %d %d\n", errno, i); height = geo.rows = 120; width= geo.columns = 320; frames = geo.frames = FRAME_MAX; depth = 2; /* RGB のピクセル毎に 2 バイト */ geo.oformat = METEOR_GEO_RGB16; if (ioctl(i, METEORSETGEO, &geo) < 0) { printf("METEORSETGEO failed %d\n", errno); exit(1); } c = METEOR_FMT_NTSC; if (ioctl(i, METEORSFMT, &c) < 0) { printf("ioctl failed: %d\n", errno); exit(1); } c = METEOR_INPUT_DEV0; if (ioctl(i, METEORSINPUT, &c) < 0) { printf("ioctl failed: %d\n", errno); exit(1); } size = ((width*height*depth*frames+4095)/4096)*4096; /* meteor_mem のデータの後に 1 ページ追加 */ data_frames = mmap((caddr_t)0, size + 4096, PROT_READ | PROT_WRITE, MAP_SHARED, i, (off_t)0); if (data_frames == (caddr_t) MAP_FAILED) return (0); /* common_mem は次のデータのページに位置付けられる */ common_mem = (struct meteor_mem *) (y + size); signal(SIGUSR2, usr2_catcher); /* 新しいフレームメッセージ を捕獲 */ capframe.command=METEOR_CAP_N_FRAMES; capframe.signal=SIGUSR2; capframe.lowat=12; /* hiwat 未満でなければ ならない */ capframe.hiwat=14; /* FRAME_MAX 未満で なければならない */ /* 同期キャプチャを開始 */ if (ioctl(i, METEORCAPFRM, &capframe) < 0) { printf("METEORCAPFRM failed %d\n", errno); exit(1); } /* これはバックグラウンドの作業領域, または sleep できる */ /* キャプチャを停止する */ capframe.command=METEOR_CAP_STOP_FRAMES; if (ioctl(i, METEORCAPFRM, &capframe) < 0) { printf("METEORCAPFRM failed %d\n", errno); exit(1); } }
meteor IOCTL 呼び出しとパラメータ
meteor キャプチャドライバには、キャプチャのために必要なカードの状態の読み込み、ジオメトリの設定と読み込み、属性の設定と読み込み、 ioctl(2) があります。
エラーは、 ioctl(2) で何か大変な誤りがあることを示しています、そしてアプリケーションは、それ以上キャプチャを続けるべきではありません。さらに、 meteor キャプチャドライバは、エラーが前のステップで起こりましたが、アプリケーションのプログラマによって無視されたなら、次のキャプチャステップを停止する試みを行います。
- ioctl(2) 要求 METEORSETGEO と METEORGETGEO
METEORSETGEO と METEORGETGEO は、フレームキャプチャのために入力サイズ、入力デバイス、および出力フォーマットを設定して読み込むために使用されます。
これらの ioctl(2) ルーチンは、次のエントリがある meteor_geomet 構造体を使用します:
- rows
- 出力イメージでの行 (行数) の数
- columns
- 出力イメージでの行 (幅) 内のピクセル数
- frames
-
バッファ中のフレーム数。要求フレームが 1 より大きくなるようなマルチフレーム同期キャプチャモード (
METEORCAPFRM) を使用しない場合、1 であるべきです。
注: rows, columns または frames が変更されないなら、既存の値が使用されます。システムデフォルトは、640x480x1 です。
- oformat
-
利用者は、次の出力形式の 1 つを選ぶことができます:
- METEOR_GEO_RGB16
- (RGB 16 bits xrrrrrgg gggbbbbb デフォルト)
- METEOR_GEO_RGB24
- (32 ビットでパックされた RGB 24 ビット: 00000000 rrrrrrrr gggggggg bbbbbbbb)
- METEOR_GEO_YUV_PACKED
- (パックされたバイト形式の 4-2-2 YUV 16 ビット: u0 y0 v0 y1 u1 y2 v1 y3 ...)
- METEOR_GEO_YUV_PLANER
- (プレーン形式の 4-2-2 YUV 16 ビット: rows * column bytes of y rows * column / 4 bytes of even u rows * column / 4 bytes of even v rows * column / 4 bytes of odd u rows * column / 4 bytes of odd v)
カテゴリから 2 つ以上のエントリが選択されると、 METEORSETGEO ioctl(2) は、失敗します。利用者が初期モードのカードを保証できないのでデータをキャプチャする前に METEORSETGEO を行うことを強く勧めます。
また、新しいジオメトリが古いジオメトリを超えるなら、 METEORSETGEO は、新しい連続したカーネルバッファの再割り付けを試みます。他方では、新しいジオメトリが既存のバッファに適合するなら、既存のバッファが使用されます。
METEORSETGEO が失敗すれば、 ioctl(2) は、-1 の値を返し、外部変数 errno に次の値が設定されます:
- [ EINVAL]
- 無効の meteor_geomet 構造体のポインタ、 rows, columns, frames は、無効です。
- [ ENOMEM]
- 連続ブロックを割り付けることができませんでした。
- ioctl(2) 要求 METEORSFMT と METEORGFMT
METEORSFMT と METEORGFMT は、カメラ入力標準形式を設定して読み込むために使用されます。
可能な形式は、次の通りです:
- METEOR_FMT_NTSC
- NTSC (デフォルトモード)
- METEOR_FMT_PAL
- PAL
- METEOR_FMT_SECAM
- SECAM
- METEOR_FMT_AUTOMODE
- 自動検出。
- ioctl(2) 要求 METEORSINPUT と METEORGINPUT
METEORSINPUT と METEORGINPUT は、カメラ入力デバイスを設定して読み込むために使用されます。 Meteor カードで DB9 コネクタを使用して、4 つの入力デバイスを接続することができ、この ioctl(2) で入力カメラを選択することができます。
可能な形式は、次の通りです:
- METEOR_INPUT_DEV0
- (指定がなければデフォルト)
- METEOR_INPUT_DEV_RCA
- (METEOR_INPUT_DEV0 と同じ)
- METEOR_INPUT_DEV1
- METEOR_INPUT_DEV2
- METEOR_INPUT_DEV_SVIDEO
- (METEOR_INPUT_DEV2 と同じ)
- ioctl(2) 要求 METEORSTATUS
METEORSTATUS は、 Meteor キャプチャカードの状態を読み込むために使用され、次の情報を返します:
METEOR_STATUS_ID_MASK SAA7196 スケーラチップの 4 ビット ID。 METEOR_STATUS_DIR 0 = スケーラは内部のソースを使用する。 1 = スケーラは拡張バスの外部データを使用する。 METEOR_STATUS_OEF 0 = 偶数フォールドを検出。 1 = 奇数フォールドを検出。 METEOR_STATUS_SVP VRAM ポート状態: 0 = 入力 HFL と INCADDR 非アクティブ。 1 = 入力 HFL と INCADDR アクティブ。 METEOR_STATUS_STTC 0 = TV の水平時間定数 (遅い)。 1 = VCR の水平時間定数 (速い)。 METEOR_STATUS_HCLK 0 = 水平フェーズロックループをロックする。 1 = 水平フェーズロックループをアンロックする。 METEOR_STATUS_FIDT 0 = 50 Hz フィールドを検出。 1 = 60 Hz フィールドを検出。 METEOR_STATUS_ALTD 0 = 行交替カラーバースト非検出。 1 = 行交替カラーバースト検出 (PAL/SECAM)。 METEOR_STATUS_CODE 0 = カラー情報非検出。 1 = カラー情報検出。 - ioctl(2) 要求 METEORCAPTUR
METEORCAPTUR は、シングルフレームキャプチャまたは非同期連続キャプチャのために使用されます。
シングルフレームキャプチャ ioctl(2) 要求は、フレームがキャプチャされるか、フレームバッファに転送した後だけ返ります。
非同期連続キャプチャは、すぐに返り、データは、バッファが利用可能であるとき、直接バッファ中に格納されます。これは、非同期化されているので、データは、アプリケーションで読み込まれている間に、カーネルによって書き込むことができます。
これらの ioctl(2) ルーチンは、次の設定を使用します:
- METEOR_CAP_SINGLE
- 1 フレームをキャプチャする
- METEOR_CAP_CONTINOUS
- 非同期連続キャプチャ
- METEOR_CAP_STOP_CONT
- 非同期連続キャプチャを停止する
METEORCAPTUR が失敗すれば、 ioctl(2) は、-1 の値を返し、外部変数 errno に次の値が設定されます:
- [ EINVAL]
- 無効のキャプチャコマンド値
- [ ENXIO]
- フレームを保持するための内部バッファがありません。これは、前に設定されたジオメトリの ioctl(2) が失敗したことを示します。
- [ EIO]
- カードは、既にキャプチャしています。
- ioctl(2) 要求 METEORCAPFRM
METEORCAPFRM は、複数フレームの同期キャプチャに使用されます。
この ioctl(2) ルーチンは、次のエントリがある meteor_capture 構造体を使用します:
- command
-
command のための可能な値は、次の通りです:
- METEOR_CAP_STOP_FRAMES
- キャプチャを停止します。構造体中の他の変数は、使用されません。
- METEOR_CAP_N_FRAMES
- 入力として構造体の他の変数を使用してキャプチャを開始します。
- signal
- 新しいフレームがキャプチャされたとき、アプリケーションにシグナルを送信する。このシグナルは、キャプチャされたフレームが保存された場合にだけ、発生します。
- lowat
- 下記参照。
- hiwat
- 下記参照。
新しいフレームが完了するとき、ドライバは、共用変数 (共用変数は、 meteor_mem 構造体に格納される) num_active_buf に格納された現在の読み込まれていないフレームカウント (数) をチェックします。カウント (数) が hiwat より大きいなら、ドライバは、 num_active_buf が lowat より小さくなるまで、新しいフレームを少しも格納しないし、キャプチャシグナルをユーザアプリケーションに送りません。
METEORCAPFRM が失敗すれば、 ioctl(2) は、-1 の値を返し、外部変数 errno に次の値が設定されます:
- [ EINVAL]
- 無効の meteor_geomet 構造体のポインタか悪いコマンド。
- [ ENXIO]
- フレームを保持するための内部バッファがありません。これは、前に設定されたジオメトリの ioctl(2) が失敗したことを示します。
- [ EIO]
- カードは、既にキャプチャしています。
- ioctl(2) 要求 METEORSCHCV と METEORGCHCV
METEORSCHCV と METEORGCHCV は、色調節の獲得と UV 出力振幅の効果を設定して取得するために使用されます。
METEORSCHCV または METEORGCHCV が失敗すれば、 ioctl(2) は、-1 の値を返し、外部変数 errno に次の値が設定されます:
- [ EINVAL]
- 無効の符号無し char ポインタ。
- ioctl(2) 要求 METEORGHUE と METEORSHUE
METEORGHUE と METEORSHUE は、色調を取得して設定するために使用されます。符号付き文字の正しい値は、+178.6 階級を表す +127 から -180 階級を表す -128 までです。約注: 階級は、degree の訳。度、級の可能性も有り。
METEORGHUE または METEORSHUE が失敗すれば、 ioctl(2) は、-1 の値を返し、外部変数 errno に次の値が設定されます:
- [ EINVAL]
- 無効の符号付き char ポインタ。
- ioctl(2) 要求 METEORSCOUNT と METEORGCOUNT
METEORGCOUNT は、フレームエラーのカウント、DMA エラーとデバイスがオープンされてから発生しているキャプチャされたフレームの数のカウントを得るために使用されます。 METEORSCOUNT は、カウンタを再初期化するために使用できます。
この ioctl(2) ルーチンは、次のエントリがある meteor_counts 構造体を使用します:
- fifo_errors
- デバイスがオープンされてからの FIFO エラーの数。
- dma_errors
- デバイスがオープンされてからの DMA エラーの数。
- frame_count
- デバイスがオープンされてからのキャプチャされたフレームの数。
METEORSCOUNT または METEORGCOUNT が失敗すれば、 ioctl(2) は、-1 の値を返し、外部変数 errno に次の値が設定されます:
- [ EINVAL]
- 無効の meteor_counts 構造体ポインタ。
作者
<james@miller.cs.uwm.edu>, <tinguely@plains.nodak.edu>バグ
meteor ドライバは、もはや全く動作していません。August 15, 1995 | FreeBSD |