C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[949] 아래 팁과 관련한 DirectShow (SampleGrabber, DSPACK, Graphics32) 이용 예제
Nibble [gameover] 10511 읽음    2010-01-29 15:38
__fastcall TMainForm::TMainForm(TComponent* Owner)
    : TForm(Owner)
{
    Buffer = new TBitmap32();
    Buffer->StretchFilter = sfDraft;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::Button1Click(TObject *Sender)
{
    if (OpenDialog->Execute())
    {
        FilterGraph->Stop();
        FilterGraph->ClearGraph();
        FilterGraph->Active = false;
        FilterGraph->Active = true;
        FilterGraph->RenderFile(OpenDialog->FileName);
        IBasicVideo* BV;
        FilterGraph->QueryInterface(IID_IBasicVideo, &BV);
        long w, h;
        BV->get_VideoWidth(&w);
        BV->get_VideoHeight(&h);
        BV->Release();
        Buffer->SetSize(w, h);
        Caption = String(w) + " x " + h;
        FilterGraph->Play();
    }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
{
    FilterGraph->Stop();
    FilterGraph->Active = false;
    delete Buffer;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::SampleGrabberBuffer(TObject *sender,
      double SampleTime, Pointer pBuffer, int BufferLen)
{
    TColor32* src = (TColor32*)pBuffer
                  + (Buffer->Height - 1) * Buffer->Width;
    TColor32* tgt = Buffer->Bits;
    for(int y = 0; y < Buffer->Height; y++)
    {
        for(int x = 0; x < Buffer->Width; x++) tgt[x] = src[x];
        src -= Buffer->Width;
        tgt += Buffer->Width;
    }
    Stage1->Invalidate();
    Stage2->Invalidate();
    Stage3->Invalidate();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::PaintBuffer(TObject *Sender)
{
    if (!Buffer->Width) return;
    Types::TRect dstRect;
    TPaintBox32* stage      = (TPaintBox32*)Sender;
    double srcAspectRatio   = (double)Buffer->Height / Buffer->Width;
    if (srcAspectRatio > (double)stage->Height / stage->Width)
    {
        int w = stage->Height / srcAspectRatio;
        int l = stage->Width - w >> 1;
        dstRect = Rect(l, 0, l + w, stage->Height);
    }
    else
    {
        int h = stage->Width * srcAspectRatio;
        int t = stage->Height - h >> 1;
        dstRect = Rect(0, t, stage->Width, t + h);
    }
    stage->Buffer->Clear(0); // Tuning point
    Buffer->DrawTo(stage->Buffer, dstRect);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormResize(TObject *Sender)
{
    Panel3->Width  = ClientWidth  / 2;
    Panel2->Height = ClientHeight / 2;
    VideoWindow->Height = Panel2->Height / 2;
}
//---------------------------------------------------------------------------

길게 짜는건 싫어하는 Nibble입니다.
몇 몇 Decoder 필터에선 SampleGrabber 에게 rgb32 형태의 샘플을 주지 않아 연결이 안되는 경우가 있고,
manual 로 pin connection 하는건 코딩량이 많아져서 간단히 AVI Splitter와 AVI Decompressor를 얹어버렸습니다.
Graphics32의 TPaintBox32를 이용해 다중 출력을 구현했으니 성능도 좋고 마음껏 수정하기도 좋지요.
* 게으른 코드 때문에 몇 몇 자막 필터와 연결이 원활하지 않을 수 있습니다.
박영목.월천 [gsbsoft]   2010-02-01 09:59 X
음...  Nibble님...  역시 고수군....  감사요 ^^  담에 좀 더 연구를 해봐야겠습니다...

void __fastcall TMainForm::SampleGrabberBuffer(TObject *sender,
      double SampleTime, Pointer pBuffer, int BufferLen)  여기까지는 해보았습니다.

그리고 TBitmap에 복사를 해서... StretchBlt()로 바닥에 뿌리니... 색들의 경계지점에 알록달록 선들이 그어지고...  문제는 어느 정도 시간이 가면 Error가 발생... 이 방법도 안되겠구나 했는 데...  GR32에서 표현이 잘 되는 것 같군요... 역시 소문대로 GR32가 빠른 모양입니다. GR32도 왠만하면 잘 사용하지 않는 편이라... 이번에도 아예 TEST 대상에서 제외했는데..

TFilter AVIDecompressor, AviSplitter 이놈들 용도는 뭔지 잘 모르겠네요... 아직 DS에 대해 아는 것이 없어서...?

DSPack에 대한 자료가 너무 부족한 것 같습니다. 저같은 초보를 위해 시간 나시면 연재라도 부탁드립니다. 감사합니다 ^^  
Nibble [gameover]   2010-02-02 00:28 X
StretchBlt에 보간법을 적용하는 예는 다른 분이 글로 올려주신 것이 있었던 걸로 기억합니다.
(기본적으론 Nearest 라 가로 세로줄이 알록달록해지죠)
저도 DirectShow 관련 프로젝트를 했던게 8년정도 전의 일이고, DirectShow 도움말 링크만 달랑 걸어 놓는게 무성의해 보여
정말 간만에 DSPack을 설치해서 예제를 짜 본거라, 강좌를 기획할 처지는 못되는 것 같습니다.
자료가 부족한건 맞는데, 10여년전에 비하면 많은 것 같기도 하구요. 델파이 진영에선 짬짬이 강좌가 올라오니
참고하시면 될 것 같습니다.
Nibble [gameover]   2010-02-02 00:30 X
사실 조금만 요구사항이 복잡해 져도, DSPack을 쓰느니 그냥 DirectShow API를 직접 래핑하는 쪽이 편하고 안전합니다. (버그가 많아서)

+ -

관련 글 리스트
949 아래 팁과 관련한 DirectShow (SampleGrabber, DSPACK, Graphics32) 이용 예제 Nibble 10511 2010/01/29
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.