핀 연결하고 끊기 (기초)


질문방에 답글 올린 내용을 다시 정리하였습니다.

방법은 여러가지가 있겠지만 제가 사용하고 있는 부분을 올리겠습니다.

 

1. 핀 연결하기

 

기본적으로 Graph Builder에서 제공하는 Connect 메소드를 사용합니다.

 

pGraph->Connect(IPin pOut, IPin pIn)

 

로 사용할 수 있죠..

문제는 여기서 연결하고자 하는 두 개의 필터에서 연결을 원하는 핀에 대한 포인터를 얻는 것인데요.

 

아래의 함수는 사용자가 지정한 필터(pFilter)의 출력 또는 입력측(PinDir)에 있는 현재 연결되지 않은 핀의 포인터(**ppPin)를

얻어오는 루틴입니다. 얻어오는 방법은 현재 필터의 임의의 뱡향의 핀들을 모두 열거한 뒤에 연결상태를 점검하고

연결되있지 않은 핀이 나오면 바로 포인터를 리턴하고 빠져 나오는것입니다.

 

HRESULT CTestDlg::GetUnconnectedPin(IBaseFilter * pFilter, PIN_DIRECTION PinDir, IPin **ppPin)

{

// 초기화

    *ppPin = 0;

    IEnumPins * pEnum = 0;

    IPin * pPin = 0;

 

// 지정된 필터의 핀들을 가져오고

    HRESULT hr = pFilter->EnumPins(&pEnum);

 

    if(FAILED(hr))

    {

        return hr;

    }

// 리스트의 처음 위치로

    pEnum->Reset();

 

// 하나씩 옮겨가며 연결상태를 점검한다.

    while(pEnum->Next(1, &pPin, NULL) == S_OK)

    {

        PIN_DIRECTION ThisPinDir;

 

// 현재 가져온 핀의 방향 정보를 가져온다.

        pPin->QueryDirection(&ThisPinDir);

 

// 현재 가져온 핀의 방향 정보가 지정한 방향 정보와 일치하면

        if(ThisPinDir == PinDir)

        {

            IPin * pTmp = 0;

 

// 만약 연결되있는 핀이라면 pTmp에 연결되 있는 핀의 포인터를 얻어올 수 있다.

            hr = pPin->ConnectedTo(&pTmp);

 

// 성공이면 연결되 있다라는 의미..

            if(SUCCEEDED(hr))

            {

                pTmp->Release();

            }

// 가져올 핀 정보가 없다면 끊어진 핀 이다.

// 포인터를 넘겨주고 return S_OK

            else

            {

                pEnum->Release();

                *ppPin = pPin;

                return S_OK;

            }

        }

        pPin->Release();

    }

    pEnum->Release();

 

    return E_FAIL;

}

 

이 함수를 두 필터의 연결하는 곳에 사용할 수 있습니다.

연결하고자 하는두개의 필터쪽에서 연결되 있지 않은 핀 정보를 차례로 가져온 다음..

예를 들어 AVIMux 필터와 FileWriter 필터의 연결에 사용한다면

AVIMux 쪽에서는 pOut 정보를 FileWriter 쪽에서는 pIn 정보를 가져온 다음..

pGraph->Connect(pOut, pIn) 하면 되죠..

 

그런데 여기서 한가지 주의해야 할 점은 GetUnconnectedPin 함수가 결정적으로 사용자가 원하는

임의 번째 핀 정보를 넘겨주는게 아니라 핀들을 주욱 살펴 보다가 연결되지 않은 핀이 있으면 바로 return한다는 겁니다.

만약 연결을 원하고자 하는 필터들이 연결되지 않은 핀들을 다수 가지고 있다면 이 함수를 사용할 때

핀들의 연결 순서를 잘 생각해서 코딩을 하셔야 합니다.

물론, 각 필터들의 연결되지 않은 핀들의 첫번째끼리 연결하신다면 문제가 안되죠

 

좀 더 개선을 한다면 GetUnconnectedPin 함수를 PIN_INFO 정보를 가져온 다음 achName 을 비교해서 원하는

이름을 가진 핀의 포인터를 가져온다면 최상이 될 듯 합니다.

이 부분은 회원님들께서 업글해서 올려 주시면 감사하겠습니다. ^^

 

—–

2. 핀 연결 끊기

 

사용자가 지정한 필터(pFilter) 에서 입력핀이냐 출력핀이냐를 선택한 뒤에 (dirrequired) 몇번째(iNum) 핀에 대한 포인터(**ppPin)를 얻어옵니다.

 

HRESULT CTestDlg::GetPin( IBaseFilter * pFilter, PIN_DIRECTION dirrequired, int iNum, IPin **ppPin)

 

{

    IEnumPins * pEnum = NULL;

    *ppPin = NULL;

 

    if (!pFilter)

       return E_POINTER;

 

// 지정된 필터의 핀들을 가져오고

    HRESULT hr = pFilter->EnumPins(&pEnum);

 

    if(FAILED(hr))

        return hr;

 

    ULONG ulFound;

    IPin *pPin;

 

    hr = E_FAIL;

 

// 리스트의 처음 위치로

    pEnum->Reset(); 

 

// 하나씩 옮기면서

    while(S_OK == pEnum->Next(1, &pPin, &ulFound))

    {

        PIN_DIRECTION pindir = (PIN_DIRECTION)3;

 

// 핀의 방향 정보를 가져온다.

        pPin->QueryDirection(&pindir);

 

// 지정한 핀의 방향과 일치하는지 확인한다.

        if(pindir == dirrequired)

        {

// 지정한 순서의 핀 정보를 찾는다.

            if(iNum == 0)

            {

                *ppPin = pPin;  // Return the pin’s interface

                hr = S_OK;      // Found requested pin, so clear error

                break;

            }

            iNum–;

        }

        pPin->Release();

    }

 

    pEnum->Release();

    return hr;

}

 

사용방법은

만약 AviMux 필터와 FileWriter의 연결을 끊는다면

아시겠지만 필터들의 연결을 끊을 때는 연결되있는 두개의 필터쪽 모두에서 끊어줘야 합니다.

 

    IPin *pOutPin = NULL;

    IPin *pInPin = NULL;

 

// AVIMux 필터 출력측에서 끊어주고

 

    hr = GetPin(pAVIMux, PINDIR_OUTPUT, 0, &pOutPin);    // 핀이 입력 측이면 당연히 PINDIR_INPUT 으로 하면 되죠

    hr = pGraph->Disconnect(pOutPin);    // 여기서 pGraph 는 Graph Builder 입니다.

 

// FileWriter 필터 입력측에서 끊어줍니다.

 

    hr = GetPin(pAVIWriter, PINDIR_INPUT, 0, &pInPin);    // 핀이 입력 측이면 당연히 PINDIR_INPUT 으로 하면 되죠

    hr = pGraph->Disconnect(pInPin);    // 여기서 pGraph 는 Graph Builder 입니다.

 

이렇게 해줘야 정상적으로 Pin 연결을 Disconnect한게 됩니다.

 

이상입니다. ^^ 즐프~


답글 남기기

이메일 주소는 공개되지 않습니다.