私は、Visual C++用のSDKを使用したビデオキャプチャカードを持っています。カラーフレーム(640 x 480)はSDKのコールバックで30 fpsで利用できます。現時点では、画像シーケンス全体を1つずつ個別のスレッドとして個別のスレッドとして書き出しています。つまり、1時間に108,000ファイル、1時間に約100GBのデータを扱うことができません。私はこれらの着信フレームをオプションの圧縮を使用して1つのAVIファイルにプッシュしたいと考えています。私はどこから始めるのですか? MSDNのDirectShowのドキュメントを読んでいると、これまで私は混乱していました。そこに良い例がありますか? OpenCVは答えですか?私はいくつかの例を見てきましたが、OpenCVがカードをキャプチャデバイスとして認識するかどうか分からず、最初にキャプチャデバイスをどのように認識するかもわかりません。また、私はすでにフレームをに入れていますが、を私のプロデューサースレッドをバックアップしていないコンシューマスレッドのAVIにはにする必要があります。助けてくれてありがとう。ビットマップ(640x480)をAVIファイルにプッシュするVisual C++ AVIライター機能?
答えて
Video for WindowsまたはDirectShowを使用できます。それぞれに独自のコーデックが付属しています。 (および拡張可能)
MicrosoftはVfWの使用は推奨されていないと考えていますが、DirectShowよりもセットアップが簡単です。
これまでにCAviFileを使用しました。それはかなりうまくいく、私はそれを少し調整して、ユーザーがコーデックを選ぶことができるようにしなければならなかった。私はそのコードをCAviGeneratorから取った。
CAviFile *Avi = new CAviFile(fileName.c_str(), 0, 10);
HRESULT res = Avi->AppendNewFrame(Width, Height, ImageBuffer, BitsPerPixel);
if (FAILED(res))
{
std::cout << "Error recording AVI: " << Avi->GetLastErrorMessage() << std::endl;
}
delete Avi;
はもちろん、あなたのImageBuffer適切なフォーマットなどのデータが含まれていることを確認する必要がある。しかし、私はすべてが、選別のもののようなものを持ったら、それは素晴らしい仕事:CAviFileためのインタフェースは、ここではいくつかのサンプルコードです、非常に簡単です。
@JCoenia、私はちょうど1600x1200でビデオをキャプチャするために使用したので、VFWに制限がある場合は、かなり高いです。 – Gabe
よくキャプチャカードにAVI Mux(CLSID_AviDest)を添付する必要があります。その後、ファイルライター(CLSID_FileWriter)を添付する必要があり、すべてのものを書き出します。
確かに、DirectShowは100万回と1回のジャンプでジャンプするので、キャプチャグラフを設定することは必ずしも容易ではありません。
ICaptureGraphBuilder2インターフェイスを使用する方がずっと簡単です。ありがたいことに、Microsoftはエンコーダを追加するこれを行う方法の本当に素晴らしい荒廃...
http://msdn.microsoft.com/en-us/library/dd318627.aspx
を与えていることは便利、そのリンクにオーバー練り、しかし容易ではないと。
ここでは、私のMFCアプリケーション用に書いたシステムのすべてのビデオコンプレッサーを列挙する方法の例を示します。
BOOL LiveInputDlg::EnumerateVideoCompression()
{
CComboBox* pVideoCompression = (CComboBox*)GetDlgItem(IDC_COMBO_VIDEOCOMPRESSION);
pVideoCompression->SetExtendedUI(TRUE);
pVideoCompression->SetCurSel(pVideoCompression->AddString(_T("<None>")));
ICreateDevEnum* pDevEnum = NULL;
IEnumMoniker* pEnum = NULL;
HRESULT hr = S_OK;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pDevEnum);
if (FAILED(hr))
{
return FALSE;
}
hr = pDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnum, 0);
pDevEnum->Release();
if (FAILED(hr))
{
return FALSE;
}
if (pEnum)
{
IMoniker* pMoniker = NULL;
hr = pEnum->Next(1, &pMoniker, NULL);
while(hr == S_OK)
{
IPropertyBag* pPropertyBag = NULL;
hr = pMoniker->BindToStorage(NULL, NULL, IID_IPropertyBag, (void**)&pPropertyBag);
if (FAILED(hr))
{
pMoniker->Release();
pEnum->Release();
return FALSE;
}
VARIANT varName;
VariantInit(&varName);
hr = pPropertyBag->Read(L"Description", &varName, NULL);
if (FAILED(hr))
{
hr = pPropertyBag->Read(L"FriendlyName", &varName, NULL);
if (FAILED(hr))
{
pPropertyBag->Release();
pMoniker->Release();
pEnum->Release();
return FALSE;
}
}
IBaseFilter* pBaseFilter = NULL;
pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pBaseFilter);
{
USES_CONVERSION;
TCHAR* pName = OLE2T(varName.bstrVal);
int index = pVideoCompression->AddString(pName);
pVideoCompression->SetItemDataPtr(index, pMoniker);
VariantClear(&varName);
pPropertyBag->Release();
}
hr = pEnum->Next(1, &pMoniker, NULL);
}
pEnum->Release();
}
return TRUE;
}
Good Luck! :)
合計サイドの質問ですが、カード/ SDKの名前は何ですか?私はいつかすぐにこの種のものを調べたいと思う。 – GManNickG