出来た!
関連記事
- 働く人の「ストレスチェック」、全事業所に義務拡大へ…昨年度の労災認定は過去最多の883人 【2024年10月11日(金)】
- 那須ハイランドパークの「時給2500円」バイトに応募殺到、10人の枠に100人超が応募 【2024年08月06日(火)】
- 荒っぽい見積書が出来たところでごわす 【2024年08月01日(木)】
- 新入社員4割が転職検討 引き留めに企業が対策 【2024年05月08日(水)】
- 【#C #CPP】謎不具合を追っかけてた.なんとなく原因は分かったけど... 【2024年04月02日(火)】
画像ひっくり返せましたわん!!
フィルターで中間データを加工しようとたくらんでましたが
だんだん、めんどくさくなって
んで、出力段に細工できないかな~と検討してみたり
データの流れはこんな感じ
カメラ(180度倒置して取り付け) ↓ DVデコーダコーデックス ↓(a) サンプルグラバフィルタ → キャプチャー静止画データ ファイル出力(c) ↓ レンダラ(b) ↓ 画面出力 |
んで、レンダラ(b)を変更しようかと
デフォルトのレンダラを使ってたんですが
VideoMixingRenderer9(VMR9)に変更
こやつ、描画時に好きな回転加えることが出来るそうで
ソースはこんな感じ
.... private IBaseFilter m_pvmr = null; private IVMRFilterConfig9 m_pconfig = null; private IVMRWindowlessControl9 m_pWC = null; private IVMRMixerControl9 m_pMix = null; m_pvmr = new VideoMixingRenderer9() as IBaseFilter; //VMR9のインスタンスを作って m_graphBuilder.AddFilter(m_pvmr, "Renderer"); //グラフに追加 ConfigVideoWindow(tmpControl); //描画系のもろもろの設定をやり pRenderIn = DsFindPin.ByDirection(m_pvmr, PinDirection.Input, 0); //接続ピンを取得 private void ConfigVideoWindow(Control hControl) { NormalizedRect r; //回転方法の設定 left > rightの場合左右反転 top > leftで上下反転 r.left = 1; r.top = 1; r.right = 0; r.bottom = 0; m_pconfig = (IVMRFilterConfig9) m_pvmr; m_pconfig.SetRenderingMode(VMR9Mode.Windowless); //Configに対して、Windowなしを指定(コントロールに対して描画?) m_pWC = (IVMRWindowlessControl9)m_pconfig; Rectangle re = new Rectangle(); //ビデオ描画位置の調整(この調整が大変だぞぉ~死ぬかと思った) re.Location = new Point(-275, -30); //適当 re.Size = new Size(920,480); //適当 m_pWC.SetVideoPosition(null, re); //ビデオ描画位置のセット m_pWC.SetAspectRatioMode(VMR9AspectRatioMode.None); //こいつはnoneで m_pWC.SetVideoClippingWindow(hControl.Handle); //描画するコントロールへのHWNDを指定 m_pMix = (IVMRMixerControl9)m_pvmr; //描画方向の指定 m_pMix.SetOutputRect(0, ref r); } ....出力段に加工を入れるんで、
もうひとつの出力側(c)の画像もひっくり返りますが
こやつは、画像バッファへのポインタが取れますんで、
力技で、画像をひっくり返して、ファイル出力へ、と
とりあえず、難問、解決しましたんで、ビールで祝杯しますぅ~
あ、フィルター版は、気が向いたら、そのうち、作ってみますわぁ~(ww
すみません。ソースをもっと詳しくみたいのですが、載せてもらうことは無理でしょうか?
>>jin さま
build the capture graph for grabber.
private void SetupGraph(DsDevice dev, int iWidth, int iHeight, short iBPP, Control hControl)
呼び出し元を全文掲載しておきます
参考にドゾー♪
///
{
int hr;
ISampleGrabber sampGrabber = null;
IBaseFilter capFilter = null;
IPin pCaptureOut = null;
IPin pSampleIn = null;
IPin pRenderIn = null;
IAMAnalogVideoDecoder vdDec;
// Get the graphbuilder object
m_graphBuilder = new FilterGraph() as IFilterGraph2;
try
{
#if DEBUG
m_rot = new DsROTEntry(m_graphBuilder);
#endif
// add the video input device
hr = m_graphBuilder.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter);
DsError.ThrowExceptionForHR( hr );
vdDec = capFilter as IAMAnalogVideoDecoder;
vdDec.put_TVFormat(AnalogVideoStandard.NTSC_M);
// Find the still pin
//m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Still, 0);
// Didn’t find one. Is there a preview pin?
//if (m_pinStill == null)
//{
// m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Preview, 0);
//}
m_pinStill = null;
// Still haven’t found one. Need to put a splitter in so we have
// one stream to capture the bitmap from, and one to display. Ok, we
// don’t *have* to do it that way, but we are going to anyway.
if (m_pinStill == null)
{
IPin pRaw = null;
IPin pSmart = null;
// There is no still pin
m_VidControl = null;
// Add a splitter
IBaseFilter iSmartTee = (IBaseFilter)new SmartTee();
try
{
hr = m_graphBuilder.AddFilter(iSmartTee, “SmartTee”);
DsError.ThrowExceptionForHR( hr );
// Find the find the capture pin from the video device and the
// input pin for the splitter, and connnect them
pRaw = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0);
pSmart = DsFindPin.ByDirection(iSmartTee, PinDirection.Input, 0);
hr = m_graphBuilder.Connect(pRaw, pSmart);
DsError.ThrowExceptionForHR( hr );
// Now set the capture and still pins (from the splitter)
m_pinStill = DsFindPin.ByName(iSmartTee, “Preview”);
pCaptureOut = DsFindPin.ByName(iSmartTee, “Capture”);
// If any of the default config items are set, perform the config
// on the actual video device (rather than the splitter)
if (iHeight + iWidth + iBPP > 0)
{
SetConfigParms(pRaw, iWidth, iHeight, iBPP);
}
}
finally
{
if (pRaw != null)
{
Marshal.ReleaseComObject(pRaw);
}
if (pRaw != pSmart)
{
Marshal.ReleaseComObject(pSmart);
}
if (pRaw != iSmartTee)
{
Marshal.ReleaseComObject(iSmartTee);
}
}
}
else
{
// Get a control pointer (used in Click())
m_VidControl = capFilter as IAMVideoControl;
pCaptureOut = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0);
// If any of the default config items are set
if (iHeight + iWidth + iBPP > 0)
{
SetConfigParms(m_pinStill, iWidth, iHeight, iBPP);
}
}
// Get the SampleGrabber interface
sampGrabber = new SampleGrabber() as ISampleGrabber;
// Configure the sample grabber
IBaseFilter baseGrabFlt = sampGrabber as IBaseFilter;
ConfigureSampleGrabber(sampGrabber);
pSampleIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0);
// Get the default video renderer
//hr = m_graphBuilder.AddFilter(pRenderer, “Renderer”);
//DsError.ThrowExceptionForHR( hr );
//pRenderIn = DsFindPin.ByDirection(pRenderer, PinDirection.Input, 0);
m_pvmr = new VideoMixingRenderer9() as IBaseFilter;
m_graphBuilder.AddFilter(m_pvmr, “Renderer”);
ConfigVideoWindow(hControl);
pRenderIn = DsFindPin.ByDirection(m_pvmr, PinDirection.Input, 0);
// Learn the video properties
// Add the sample grabber to the graph
hr = m_graphBuilder.AddFilter( baseGrabFlt, “Ds.NET Grabber” );
DsError.ThrowExceptionForHR( hr );
IPin pAVIDec1_PinI = null;
IPin pAVIDec1_PinO = null;
IPin pAVIDec2_PinI = null;
IPin pAVIDec2_PinO = null;
IBaseFilter iAVIDec1 = (IBaseFilter)new AVIDec();
hr = m_graphBuilder.AddFilter(iAVIDec1, “AVIDec1”);
DsError.ThrowExceptionForHR( hr );
IBaseFilter iAVIDec2 = (IBaseFilter)new AVIDec();
hr = m_graphBuilder.AddFilter(iAVIDec2, “AVIDec2”);
DsError.ThrowExceptionForHR( hr );
pAVIDec1_PinI = DsFindPin.ByDirection(iAVIDec1, PinDirection.Input, 0);
pAVIDec1_PinO = DsFindPin.ByDirection(iAVIDec1, PinDirection.Output, 0);
pAVIDec2_PinI = DsFindPin.ByDirection(iAVIDec2, PinDirection.Input, 0);
pAVIDec2_PinO = DsFindPin.ByDirection(iAVIDec2, PinDirection.Output, 0);
try
{
if (m_VidControl == null)
{
// Connect the Still pin to the sample grabber
hr = m_graphBuilder.Connect(m_pinStill, pAVIDec1_PinI);
DsError.ThrowExceptionForHR( hr );
hr = m_graphBuilder.Connect(pAVIDec1_PinO, pSampleIn);
DsError.ThrowExceptionForHR( hr );
hr = m_graphBuilder.Connect(pCaptureOut, pAVIDec2_PinI);
DsError.ThrowExceptionForHR( hr );
// Connect the capture pin to the renderer
hr = m_graphBuilder.Connect(pAVIDec2_PinO, pRenderIn);
DsError.ThrowExceptionForHR( hr );
}
else
{
hr = m_graphBuilder.Connect(pCaptureOut, pAVIDec1_PinI);
DsError.ThrowExceptionForHR( hr );
// Connect the capture pin to the renderer
hr = m_graphBuilder.Connect(pAVIDec1_PinO, pRenderIn);
DsError.ThrowExceptionForHR( hr );
hr = m_graphBuilder.Connect(m_pinStill, pAVIDec2_PinI);
DsError.ThrowExceptionForHR( hr );
// Connect the Still pin to the sample grabber
hr = m_graphBuilder.Connect(pAVIDec2_PinO, pSampleIn);
DsError.ThrowExceptionForHR( hr );
}
SaveSizeInfo(sampGrabber);
}
finally
{
if (pAVIDec1_PinI != null) { Marshal.ReleaseComObject(pAVIDec1_PinI); pAVIDec1_PinI = null; }
if (pAVIDec1_PinO != null) { Marshal.ReleaseComObject(pAVIDec1_PinO); pAVIDec1_PinI = null; }
if (pAVIDec2_PinI != null) { Marshal.ReleaseComObject(pAVIDec2_PinI); pAVIDec1_PinI = null; }
if (pAVIDec2_PinO != null) { Marshal.ReleaseComObject(pAVIDec2_PinO); pAVIDec1_PinI = null; }
if (iAVIDec1 != null) { Marshal.ReleaseComObject(iAVIDec1); iAVIDec1 = null; }
if (iAVIDec2 != null) { Marshal.ReleaseComObject(iAVIDec2); iAVIDec2 = null; }
}
// Start the graph
//IMediaControl mediaCtrl = m_graphBuilder as IMediaControl;
//hr = mediaCtrl.Run();
//DsError.ThrowExceptionForHR( hr );
}
finally
{
if (sampGrabber != null)
{
Marshal.ReleaseComObject(sampGrabber);
sampGrabber = null;
}
if (pCaptureOut != null)
{
Marshal.ReleaseComObject(pCaptureOut);
pCaptureOut = null;
}
if (pRenderIn != null)
{
Marshal.ReleaseComObject(pRenderIn);
pRenderIn = null;
}
if (pSampleIn != null)
{
Marshal.ReleaseComObject(pSampleIn);
pSampleIn = null;
}
}
}