/* * Class: sage_DShowCaptureDevice * Method: switchToConnector0 * Signature: (JIILjava/lang/String;II)V */ JNIEXPORT void JNICALL Java_sage_DShowCaptureDevice_switchToConnector0 (JNIEnv *env, jobject jo, jlong capInfo, jint crossType, jint crossIndex, jstring tuningMode, jint countryCode, jint videoFormatCode) { char szTuningMode[16]; if (!capInfo) return; DShowCaptureInfo* pCapInfo = (DShowCaptureInfo*) capInfo; pCapInfo->videoFormatCode = videoFormatCode; const char* pTuningMode = env->GetStringUTFChars(tuningMode, NULL); strncpy( szTuningMode, pTuningMode, sizeof(szTuningMode) ); env->ReleaseStringUTFChars(tuningMode, pTuningMode); slog((env, "switchToConnector0 tuningMode:%s.\r\n", szTuningMode )); if ( String2TVType( szTuningMode ) && BDATypeNum( pCapInfo->captureConfig ) > 0 ) //ZQ REMOVE ME { TV_TYPE newBDAType = String2TVType( szTuningMode ); if ( pCapInfo->dwBDAType != newBDAType && pCapInfo->dwBDAType > 0 ) { int i, CaptureNum = pCapInfo->captureNum; for ( i = 0; i < CaptureNum; i++ ) if ( pCapInfo->captures[i] && pCapInfo->captures[i]->dwBDAType == pCapInfo->dwBDAType ) break; if ( i >= CaptureNum ) { slog((env, "switchToConnector0 ERROR: Orignal BDA Capture :%d is not found\r\n", pCapInfo->dwBDAType )); ASSERT( 0 ); return; } //save back memcpy( pCapInfo->captures[i], pCapInfo, sizeof(DShowCaptureInfo) ); for ( i = 0; i < CaptureNum; i++ ) if ( pCapInfo->captures[i] && pCapInfo->captures[i]->dwBDAType == newBDAType ) break; if ( i >= CaptureNum ) { slog((env, "switchToConnector0 ERROR: BDA Capture :%s is not found\r\n", szTuningMode )); ASSERT( 0 ); return; } memcpy( pCapInfo, pCapInfo->captures[i], sizeof(DShowCaptureInfo) ); setChannelDev( (CHANNEL_DATA*)pCapInfo->channel, (void*)pCapInfo ); slog((env, "switchToConnector0 BDA Capture :%s is switched.\r\n", szTuningMode )); } //strncpy( pCapInfo->tvType, szTuningMode, sizeof(pCapInfo->tvType) ); return; } if (!pCapInfo->pCrossbar) return; slog((env, "switchToConnector0 %d type:%d index:%d country:%d format:%d Mode:%s\r\n", (int)capInfo, crossType, crossIndex, countryCode, videoFormatCode, szTuningMode )); strncpy( pCapInfo->TuningMode, szTuningMode, sizeof(pCapInfo->TuningMode) ); // Setup the tuner first since it's upstream from the crossbar if (crossType == 1 && pCapInfo->pTVTuner) { IAMTVTuner* pTunerProps = NULL; HRESULT hr = pCapInfo->pTVTuner->QueryInterface(IID_IAMTVTuner, (void**)&pTunerProps); if (SUCCEEDED(hr)) { HRESULT ccHr = S_OK; if (countryCode) { long currCountry = 0; hr = pTunerProps->get_CountryCode(&currCountry); if (FAILED(hr) || currCountry != countryCode) { hr = ccHr = pTunerProps->put_CountryCode(countryCode); HTESTPRINT(hr); } hr = pTunerProps->put_TuningSpace(countryCode); HTESTPRINT(hr); } AMTunerModeType currMode; TunerInputType currTuneType; HRESULT currModehr = pTunerProps->get_Mode(&currMode); HTESTPRINT(currModehr); HRESULT currTypehr = pTunerProps->get_InputType(0, &currTuneType); HTESTPRINT(currTypehr); AMTunerModeType newMode; TunerInputType tuneType; slog((env, "Tuning mode:%s; current tuning type:%d current tuning model:%d\r\n", pCapInfo->TuningMode, currTuneType, currMode )); if (!strcmp(pCapInfo->TuningMode, "Air")) { newMode = AMTUNER_MODE_TV; tuneType = TunerInputAntenna; } else if (!strcmp(pCapInfo->TuningMode, "FM Radio")) { newMode = AMTUNER_MODE_FM_RADIO; tuneType = TunerInputAntenna; } else if (!strcmp(pCapInfo->TuningMode, "HRC")) { newMode = AMTUNER_MODE_TV; tuneType = (TunerInputType)2; } else { newMode = AMTUNER_MODE_TV; tuneType = TunerInputCable; } if (FAILED(currModehr) || newMode != currMode) { hr = pTunerProps->put_Mode(newMode); HTESTPRINT(hr); } if (FAILED(currTypehr) || tuneType != currTuneType) { hr = pTunerProps->put_InputType(0, tuneType); HTESTPRINT(hr); } long currConnInput = 0; hr = pTunerProps->get_ConnectInput(&currConnInput); if (FAILED(hr) || currConnInput != 0) { hr = pTunerProps->put_ConnectInput(0); HTESTPRINT(hr); } //long tvFormat; //hr = pTunerProps->get_TVFormat(&tvFormat); //ZQ test /* { IKsPropertySet *pKSProp=NULL; KSPROPERTY_TUNER_STANDARD_S Standard; hr = pCapInfo->pTVTuner->QueryInterface(IID_IKsPropertySet, (PVOID *)&pKSProp); if ( SUCCEEDED(hr) ) { memset(&Standard,0,sizeof(KSPROPERTY_TUNER_STANDARD_S)); Standard.Standard=videoFormatCode; HRESULT hr=pKSProp->Set(PROPSETID_TUNER, KSPROPERTY_TUNER_STANDARD, INSTANCE_DATA_OF_PROPERTY_PTR(&Standard), INSTANCE_DATA_OF_PROPERTY_SIZE(Standard), &Standard, sizeof(Standard)); if(FAILED(hr)) { slog(( env, "Failed set Video Format:%d on TVTuner hr=0x%x \r\n", videoFormatCode, hr )); } else { slog(( env, "Force to set Video Format:%d on TVTuner hr=0x%x \r\n", videoFormatCode, hr )); } SAFE_RELEASE( pKSProp ); } else { slog(( env, "Failed to get IKsPropertySet to set Video Format:%d on TVTuner hr=0x%x \r\n", videoFormatCode, hr )); } }*/ SAFE_RELEASE(pTunerProps); } if (pCapInfo->pTVAudio) { IAMTVAudio* pAudioProps = NULL; hr = pCapInfo->pTVAudio->QueryInterface(IID_IAMTVAudio, (void**)&pAudioProps); if (SUCCEEDED(hr)) { // For Vista+; there's the 'PRESET' flags which we want to use instead for setting the TV audio // selections. OSVERSIONINFOEX osInfo; ZeroMemory(&osInfo, sizeof(OSVERSIONINFOEX)); osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); DWORD vistaPlus = 0; if (GetVersionEx((LPOSVERSIONINFO)&osInfo)) { if (osInfo.dwMajorVersion >= 6) vistaPlus = 1; } if (vistaPlus) hr = pAudioProps->put_TVAudioMode(AMTVAUDIO_PRESET_STEREO | AMTVAUDIO_PRESET_LANG_A); else hr = pAudioProps->put_TVAudioMode(AMTVAUDIO_MODE_STEREO | AMTVAUDIO_MODE_LANG_A); HTESTPRINT(hr); } SAFE_RELEASE(pAudioProps); } } // Setup the crossbar for the graph IAMCrossbar *pXBar1 = NULL; HRESULT hr = pCapInfo->pCrossbar->QueryInterface(IID_IAMCrossbar, (void**)&pXBar1); HTESTPRINT(hr); // Look through the pins on the crossbar and find the correct one for the type of // connector we're routing. Also find the aligned audio pin and set that too. int tempCrossIndex = crossIndex; long i; long videoOutNum = -1; long audioOutNum = -1; long numIn, numOut; hr = pXBar1->get_PinCounts(&numOut, &numIn); HTESTPRINT(hr); long relatedPin, pinType; for (i = 0; i < numOut; i++) { hr = pXBar1->get_CrossbarPinInfo(FALSE, i, &relatedPin, &pinType); HTESTPRINT(hr); if (pinType == PhysConn_Video_VideoDecoder) videoOutNum = i; else if (pinType == PhysConn_Audio_AudioDecoder) audioOutNum = i; } for (i = 0; i < numIn; i++) { hr = pXBar1->get_CrossbarPinInfo(TRUE, i, &relatedPin, &pinType); HTESTPRINT(hr); if (pinType == crossType || (pinType == PhysConn_Video_YRYBY && crossType == 90)) // 90 is Component+SPDIF { if ((crossType != 1 && tempCrossIndex > 0) || tempCrossIndex == 1) { tempCrossIndex--; continue; } // Route the video long currRoute = -1; // hr = pXBar1->get_IsRoutedTo(videoOutNum, &currRoute); // if (FAILED(hr) || currRoute != i) { hr = pXBar1->Route(videoOutNum, i); HTESTPRINT(hr); } if (audioOutNum >= 0) { if (crossType == PhysConn_Video_YRYBY || crossType == 90) { long relatedPinType = 0; long junk = 0; pXBar1->get_CrossbarPinInfo(TRUE, relatedPin, &junk, &relatedPinType); if ((relatedPinType != PhysConn_Audio_SPDIFDigital && crossType == 90) || (relatedPinType == PhysConn_Audio_SPDIFDigital && crossType == PhysConn_Video_YRYBY)) { // Find the other audio input pin that's related to the component input and use that int j; long otherRelatedPin = 0; for (j = 0; j < numIn; j++) { if (j == relatedPin) continue; otherRelatedPin = 0; pXBar1->get_CrossbarPinInfo(TRUE, j, &otherRelatedPin, &junk); if (otherRelatedPin == i) { slog(( env, "Crossbar swapping related audio pins on component video input old:%d new:%d\r\n", relatedPin, j)); relatedPin = j; break; } } } } // Route any related audio // hr = pXBar1->get_IsRoutedTo(audioOutNum, &currRoute); // if (FAILED(hr) || currRoute != relatedPin) { hr = pXBar1->Route(audioOutNum, relatedPin); HTESTPRINT(hr); } } slog(( env, "Crossbar route: video:%d, auido:%d\r\n", i, relatedPin )); break; } } SAFE_RELEASE(pXBar1); if (audioOutNum == -1) { // It may have 2 crossbars, like ATI. Search for the second one. hr = pCapInfo->pBuilder->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pCapInfo->pCrossbar, IID_IAMCrossbar, (void**)&pXBar1); if (SUCCEEDED(hr)) { slog((env, "Found secondary audio crossbar, routing it\r\n")); tempCrossIndex = crossIndex; hr = pXBar1->get_PinCounts(&numOut, &numIn); HTESTPRINT(hr); for (i = 0; i < numOut; i++) { hr = pXBar1->get_CrossbarPinInfo(FALSE, i, &relatedPin, &pinType); HTESTPRINT(hr); if (pinType == PhysConn_Audio_AudioDecoder) { audioOutNum = i; break; } } for (i = 0; i < numIn && audioOutNum >= 0; i++) { hr = pXBar1->get_CrossbarPinInfo(TRUE, i, &relatedPin, &pinType); HTESTPRINT(hr); if (pinType == crossType) { if ((crossType != 1 && tempCrossIndex > 0) || tempCrossIndex == 1) { tempCrossIndex--; continue; } // Route any related audio hr = pXBar1->Route(audioOutNum, relatedPin); HTESTPRINT(hr); break; } } SAFE_RELEASE(pXBar1); } } IAMAnalogVideoDecoder *vidDec = NULL; hr = pCapInfo->pVideoCaptureFilter->QueryInterface(IID_IAMAnalogVideoDecoder, (void**)&vidDec); if (SUCCEEDED(hr)) { /*if (FAILED(ccHr) && countryCode == 54) { tvFormat = AnalogVideo_PAL_N; }*/ hr = vidDec->put_TVFormat(videoFormatCode); HTESTPRINT(hr); /*if (FAILED(hr) && tvFormat == AnalogVideo_PAL_N) { hr = vidDec->put_TVFormat(AnalogVideo_PAL_B); } */ SAFE_RELEASE(vidDec); } slog((env, "DONE: switchToConnector0 %d type=%d index=%d\r\n", (int)capInfo, crossType, crossIndex)); }
/* * Class: sage_DShowCaptureDevice * Method: autoTuneChannel0 * Signature: (JLjava/lang/String;I)Z */ JNIEXPORT jboolean JNICALL Java_sage_DShowCaptureDevice_autoTuneChannel0 (JNIEnv *env, jobject jo, jlong capInfo, jstring jnum, jint streamType ) { if (!capInfo) return JNI_FALSE; DShowCaptureInfo* pCapInfo = (DShowCaptureInfo*)capInfo; ////ZQ audio leaking //pCapInfo->pMC->Run(); //slog((env, ">>>> Start (capture:%s) \r\n")); //ZQ if (capMask(pCapInfo->captureConfig, sage_DShowCaptureDevice_BDA_VIDEO_CAPTURE_MASK )) { HRESULT hr; const char* cnum = env->GetStringUTFChars(jnum, NULL); if ( cnum == NULL || *cnum == 0x0 ) cnum = "0"; slog((env, "autotune0 digital tuner '%s-%d' num=%s (ver 3.1)\r\n", pCapInfo->videoCaptureFilterName, pCapInfo->videoCaptureFilterNum, cnum )); //setup output format hr = SetupBDAStreamOutFormat( env, pCapInfo, streamType ); hr = TurnBDAChannel( env, pCapInfo, cnum ); env->ReleaseStringUTFChars(jnum, cnum); int locked = SageCheckLocked( pCapInfo ); slog((env, "DONE: autotune0 hr=0x%x locked:%d\r\n", hr, locked )); return hr == S_OK ? JNI_TRUE : JNI_FALSE; }else //ZQ { if (!pCapInfo->pTVTuner) return JNI_FALSE; const char* cnum = env->GetStringUTFChars(jnum, NULL); int numericChannel = atoi(cnum); env->ReleaseStringUTFChars(jnum, cnum); IAMTVTuner* pTunerProps = NULL; long tuneResult = 0; if ( numericChannel == 0 || numericChannel < 0 ) return JNI_FALSE; long lFreq = 0; HRESULT hr = pCapInfo->pTVTuner->QueryInterface(IID_IAMTVTuner, (void**)&pTunerProps); slog((env, "autotune0 analog tuner '%s-%d' hr=0x%x num=%d\r\n", pCapInfo->videoCaptureFilterName, pCapInfo->videoCaptureFilterNum, hr, numericChannel)); if (SUCCEEDED(hr)) { hr = pTunerProps->AutoTune(numericChannel, &tuneResult); HRESULT hr2 = pTunerProps->get_VideoFrequency( &lFreq ); //if ( tuneResult ) // pTunerProps->StoreAutoTune(); pCapInfo->dwTuneState = 0x01; //Fusion Card, FIX: after ATSC tune, fail to tune TV if ( strstr( pCapInfo->videoCaptureFilterName, "Fusion" ) ) pTunerProps->put_Mode( AMTUNER_MODE_FM_RADIO ); pTunerProps->put_Mode( AMTUNER_MODE_TV ); //ZQ. SAFE_RELEASE(pTunerProps); } slog((env, "DONE: autotune0 %d hr=0x%x result=%d freq:%d.\r\n", (int)capInfo, hr, tuneResult, lFreq )); return (SUCCEEDED(hr) && (tuneResult != 0)); } return JNI_FALSE; }