したがって、最終年度のプロジェクトでは、Video4Linux2を使用してカメラからYUV420画像をプルし、それらをx264(これらの画像をネイティブに使用)に解析してから、エンコードされたストリームをLive555経由でRTP/RTCP準拠のビデオプレーヤーに送信します。ワイヤレスネットワークを介したクライアント。これらすべてをリアルタイムで実行しようとしているので、制御アルゴリズムがありますが、それはこの質問の範囲ではありません。Live555を除くこれらすべてはCで書かれています。現在、私はビデオのエンコードが終わりに近づいていますが、パフォーマンスを向上させたいと考えています。
控えめに言っても、私は問題にぶつかりました... V4L2のユーザースペースポインターを避け、mmap()を使用しようとしています。私はビデオをエンコードしていますが、YUV420なので、x264が読み取るためにY'、U、V平面を3つの異なる変数に保持するために新しいメモリをmallocしています。これらの変数をmmapされたメモリへのポインタとして保持したいと思います。
ただし、V4L2デバイスにはバッファリングされたストリーム用の単一のファイル記述子があり、ストリームをYUV420標準に準拠した3つのmmap変数に分割する必要があります...
buffers[n_buffers].y_plane = mmap(NULL, (2 * width * height) / 3,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset);
buffers[n_buffers].u_plane = mmap(NULL, width * height / 6,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset +
((2 * width * height) / 3 + 1) /
sysconf(_SC_PAGE_SIZE));
buffers[n_buffers].v_plane = mmap(NULL, width * height / 6,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset +
((2 * width * height) / 3 +
width * height / 6 + 1) /
sysconf(_SC_PAGE_SIZE));
ここで、「幅」と「高さ」はビデオの解像度です(例:640x480)。
私が理解していることから...MMAPは次のようなファイルを検索します(疑似コード):
fd = v4l2_open(...);
lseek(fd, buf.m.offset + (2 * width * height) / 3);
read(fd, buffers[n_buffers].u_plane, width * height / 6);
私のコードはここのLaunchpadリポジトリにあります(詳細については):http: //bazaar.launchpad.net/~alex-stevens/+junk/spyPanda/files(リビジョン11)
そして、YUV420フォーマットはこのWikiの図からはっきりと見ることができます:http://en.wikipedia.org/wiki/File :Yuv420.svg (私は基本的にY、U、Vバイトを各mmapに分割したいメモリー)
1つのファイル記述子から3つの変数をメモリにmmapする方法を説明したい人はいますか、それともなぜ私が失敗したのですか?または、YUV420バッファをx264に解析するためのより良いアイデアを示唆することさえできますか?:P
乾杯!^^