皆さん、始めまして。
VideoInfoをVideoInfo2に変換するためには、「ConvertVideoInfoToVideoInfo2」を使ってDirectsowのFilterを作くればいいことが分かったので、「http://www.independence-sys.com/weblog/item/158」を参考にしました。
GetMediaTypeで、「ConvertVideoInfoToVideoInfo2」の処理を入れれば良いと思ったのですが、映像が斜めのシマシマ映像になってしまい行き詰っています。
大きく変えた所は以下のとおりです。
御教授願えませんでしょうか。
HRESULT CTransEffectFilter::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
{
if (CanPerformTransform(mtIn))
{
if (*mtOut->Subtype() == *mtIn->Subtype())
return S_OK;
else
return VFW_E_TYPE_NOT_ACCEPTED;
//return S_OK;
}
return VFW_E_TYPE_NOT_ACCEPTED;
}
HRESULT CTransEffectFilter::GetMediaType(int iPosition, CMediaType *pMediaType)
{
if(iPosition == 0)
{
CopyMediaType(pMediaType,&(m_pInput->CurrentMediaType()));
pMediaType->SetSubtype(&MEDIASUBTYPE_UYVY);
ConvertVideoInfoToVideoInfo2(pMediaType);
return S_OK;
}
return VFW_S_NO_MORE_ITEMS;
}
HRESULT CTransEffectFilter::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pPropInputRequest)
{
IMemAllocator *InAlloc;
ALLOCATOR_PROPERTIES InProps;
CheckPointer(pAlloc,E_POINTER);
CheckPointer(pPropInputRequest,E_POINTER);
// Is the input pin connected
if(m_pInput->IsConnected() == FALSE)
{
return E_UNEXPECTED;
}
HRESULT hr = NOERROR;
pPropInputRequest->cBuffers = 1;
pPropInputRequest->cbBuffer;
m_pInput->CurrentMediaType().GetSampleSize();
HRESULT result;
result = m_pInput->GetAllocator(&InAlloc);
if(SUCCEEDED(result))
{
result = InAlloc->GetProperties(&InProps);
if(SUCCEEDED(result))
{
pPropInputRequest->cbBuffer = InProps.cbBuffer;
InAlloc = NULL;
}
} ////THIS WHOLE
//CHECK GOES OK
if(FAILED(result))
return S_FALSE;
// Ask the allocator to reserve us some sample memory, NOTE the function
// can succeed (that is return NOERROR) but still not have allocated the
// memory that we requested, so we must check we got whatever we wanted
ALLOCATOR_PROPERTIES Actual;
hr = pAlloc->SetProperties(pPropInputRequest,&Actual);
if(FAILED(hr))
{
return hr;
} ////THIS ONE FAILS
ASSERT(Actual.cBuffers == 1);
if(pPropInputRequest->cBuffers > Actual.cBuffers ||pPropInputRequest->cbBuffer > Actual.cbBuffer)
{
return E_FAIL;
} ///FAILS TOO!
return NOERROR;
}
HRESULT CTransEffectFilter::Transform(IMediaSample *pIn, IMediaSample *pOut) {
LPDWORD pSrc, pDest;
long act_size;
//unsigned int grey;
DWORD r,g,b;
pIn->GetPointer((BYTE**)&pSrc);
pOut->GetPointer((BYTE**)&pDest);
act_size = pIn->GetActualDataLength();
//ここでは適当にグレーに変換
for(LONG y=0; y<m_Vih.bmiHeader.biHeight; y++) {
for(LONG x=0; x<m_Vih.bmiHeader.biWidth; x++) {
r = ((*pSrc) & 0xff0000) >> 16;
g = ((*pSrc) & 0xff00) >> 8;
b = (*pSrc) & 0xff;
/*grey = (30 * r + 59 * g + 11 * b) / 100;
r = g = b = (BYTE) grey;*/
*pDest = (r << 16) | (g << 8) | (b);
pSrc++;
pDest++;
}
}
//サンプルタイムの設定
LONGLONG media_start, media_end;
pIn->GetMediaTime(&media_start, &media_end);
pOut->SetMediaTime(&media_start, &media_end);
REFERENCE_TIME ref_start, ref_end;
pIn->GetTime(&ref_start, &ref_end);
pOut->SetTime(&ref_start, &ref_end);
//同期ポイントのプロパティ設定
pOut->SetSyncPoint(TRUE);
//データ長設定
pOut->SetActualDataLength(act_size);
return S_OK;
}
そのサイトのソースに ConvertVideoInfoToVideoInfo2() を加えてみましたが、何の問題もないです。というか動作に変わりはありませんでした。
どういう動作にしたいのか明確にしないと何とも言えないですね。
//
// このフィルタが出力するメディアタイプを提示する
//
HRESULT CTransEffectFilter::GetMediaType(int iPosition, CMediaType *pMediaType)
{
//チェック
if(iPosition < 0){
return E_INVALIDARG;
}else if(iPosition > 0) {
return VFW_S_NO_MORE_ITEMS;
}
//入力をそのまま設定
*pMediaType=m_pInput->CurrentMediaType();
::ConvertVideoInfoToVideoInfo2(pMediaType);
return S_OK;
}
forty-fiveさん返事ありがとうございます。
私の場合、参考サイトのソースに ConvertVideoInfoToVideoInfo2() を追加して、GraphEditでは「ストリームをレンダリングするためのフィルターの組み合わせが見つかりませんでした。」とエラーが帰ってきました。
ですので、いろんな所を参考にして上記の様なソースになりました。
やりたい事は、VideoInfoをVideoInfo2に変換するFilterを作ろうとしています。Filterを作るのは初めてで、Filterの動作はなんとなくでしか把握できていません。
forty-fiveさん返事ありがとうございます。
私の場合、参考サイトのソースに ConvertVideoInfoToVideoInfo2() を追加して、GraphEditでは「ストリームをレンダリングするためのフィルターの組み合わせが見つかりませんでした。」とエラーが帰ってきました。
ですので、いろんな所を参考にして上記の様なソースになりました。
やりたい事は、VideoInfoをVideoInfo2に変換するFilterを作ろうとしています。Filterを作るのは初めてで、Filterの動作はなんとなくでしか把握できていません。
少なくとも私の環境では CTransEffectFilter::GetMediaType() 自体が呼ばれないです。なので、ここを修正してもエラーは出ないはずです。もちろん動作も変わりません。
ヘッダーでこうして、
//入力ピンのメディアフォーマット
VIDEOINFOHEADER2 m_Vih;
ソースでこうすればいいんじゃないの?
//
// ピンの接続が完了した時の処理
//
HRESULT CTransEffectFilter::CompleteConnect(PIN_DIRECTION direction, IPin *pReceivePin) {
// 入力ピンのメディアフォーマットを取得
CMediaType type = m_pInput->CurrentMediaType();
::ConvertVideoInfoToVideoInfo2(&type);
CopyMemory(&m_Vih, type.Format(), sizeof(VIDEOINFOHEADER2));
return S_OK;
}
forty-fiveさん、返事遅れてすみません。
早速やってみたら、正常な映像が表示されました。
後は、Outpinから出力されているのはVideoInfo2の映像か調べてみます。
ありがとうございます。
ツイート | ![]() |