질문방에 답글 올린 내용을 다시 정리하였습니다. 방법은 여러가지가 있겠지만 제가 사용하고 있는 부분을 올리겠습니다.
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한게 됩니다.
이상입니다. ^^ 즐프~ |