virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode*mode, BMDDetectedVideoInputFormatFlags) { // This only gets called if bmdVideoInputEnableFormatDetection was set // when enabling video input HRESULT result; deckstring_t displayModeName = NULL; if (!(events & bmdVideoInputDisplayModeChanged)) { return S_OK; } mode->GetName(&displayModeName); free_deckstring(displayModeName); if (m_deckLinkInput) { m_deckLinkInput->StopStreams(); result = m_deckLinkInput->EnableVideoInput(mode->GetDisplayMode(), m_cfg_pixelFormat, m_cfg_inputFlags); if (result != S_OK) { goto bail; } m_deckLinkInput->StartStreams(); } bail: return S_OK; }
void open_input(unsigned int norm) { IDeckLinkDisplayModeIterator *it; assert(deckLink != NULL); assert(norm < sizeof(norms) / sizeof(struct decklink_norm)); if (deckLink->QueryInterface(IID_IDeckLinkInput, (void **) &deckLinkInput) != S_OK) { throw std::runtime_error( "DeckLink input: failed to get IDeckLinkInput" ); } if (deckLinkInput->GetDisplayModeIterator(&it) != S_OK) { throw std::runtime_error( "DeckLink input: failed to get display mode iterator" ); } dominance = find_dominance(norms[norm].mode, it); it->Release( ); if (deckLinkInput->EnableVideoInput(norms[norm].mode, bpf, 0) != S_OK) { throw std::runtime_error( "DeckLink input: failed to enable video input" ); } fprintf(stderr, "DeckLink: opening input using norm %s\n", norms[norm].name); }
void start_capture(void) { if (deckLinkInput->SetCallback(this) != S_OK) { throw std::runtime_error( "DeckLink input: set callback failed" ); } if (deckLinkInput->StartStreams( ) != S_OK) { throw std::runtime_error( "DeckLink input: start streams failed" ); } }
void VideoReceiverInterface::cameraFunction(bool useCompositeInput){ IDeckLink *deckLink; IDeckLinkInput *deckLinkInput; BMDVideoInputFlags inputFlags = 0; BMDDisplayMode displayMode; if (useCompositeInput){ displayMode = bmdModeNTSC; } else { displayMode = bmdModeHD1080i5994; } BMDPixelFormat pixelFormat = bmdFormat8BitYUV; IDeckLinkIterator *deckLinkIterator = CreateDeckLinkIteratorInstance(); DEBUG("Creating decklink iterator..."); if (deckLinkIterator == 0 ){ cerr << "\n\tUnable to create DeckLink Iterator. Video analysis will be disabled.\n\n"; return; } DEBUG("Creating decklink object..."); if ( deckLinkIterator->Next(&deckLink) != S_OK ) { Log::error("\n\tCould not create decklink object. Video analysis will be disabled\n"); return; } DEBUG("Querying decklink interface..."); if ( deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput) != S_OK ) { Log::error("\n\tCould not find a decklink interface. Video analysis will be disabled\n"); return; } DEBUG("Registering decklink input callback..."); if ( deckLinkInput->SetCallback(new VideoCallback(this)) != S_OK ) { Log::error("\n\tCould not set the decklink callback. Video analysis will be disabled\n"); return; } DEBUG("Enabling video input..."); if ( deckLinkInput->EnableVideoInput(displayMode,pixelFormat,inputFlags) != S_OK ) { Log::error("\n\tCould not enable video input. Video analysis will be disabled\n"); return; } DEBUG("Starting streams..."); if ( deckLinkInput->StartStreams() != S_OK ) { Log::error("\n\tCould not start streams. Video analysis will be disabled\n"); return; } }
BMDDisplayMode getDisplayMode( mlt_profile profile, int vancLines ) { IDeckLinkDisplayModeIterator* iter = NULL; IDeckLinkDisplayMode* mode = NULL; BMDDisplayMode result = (BMDDisplayMode) bmdDisplayModeNotSupported; if ( m_decklinkInput->GetDisplayModeIterator( &iter ) == S_OK ) { while ( !result && iter->Next( &mode ) == S_OK ) { int width = mode->GetWidth(); int height = mode->GetHeight(); BMDTimeValue duration; BMDTimeScale timescale; mode->GetFrameRate( &duration, ×cale ); double fps = (double) timescale / duration; int p = mode->GetFieldDominance() == bmdProgressiveFrame; m_topFieldFirst = mode->GetFieldDominance() == bmdUpperFieldFirst; m_colorspace = ( mode->GetFlags() & bmdDisplayModeColorspaceRec709 ) ? 709 : 601; mlt_log_verbose( getProducer(), "BMD mode %dx%d %.3f fps prog %d tff %d\n", width, height, fps, p, m_topFieldFirst ); if ( width == profile->width && p == profile->progressive && ( height + vancLines == profile->height || ( height == 486 && profile->height == 480 + vancLines ) ) && fps == mlt_profile_fps( profile ) ) result = mode->GetDisplayMode(); SAFE_RELEASE( mode ); } SAFE_RELEASE( iter ); } return result; }
DeckLinkCaptureDelegate(gem::plugins::videoDECKLINK*parent, IDeckLinkInput*dli) : IDeckLinkInputCallback() , m_refCount(0) , m_frameCount(0) , m_cfg_inputFlags(bmdVideoInputFlagDefault) , m_cfg_pixelFormat(bmdFormat8BitYUV) , m_deckLinkInput(dli) , m_priv(parent) { m_deckLinkInput->AddRef(); pthread_mutex_init(&m_mutex, NULL); m_deckLinkInput->SetCallback(this); //result = m_deckLinkInput->EnableVideoInput(displayMode->GetDisplayMode(), m_cfg_pixelFormat, m_cfg_inputFlags); //m_deckLinkInput->DisableAudioInput(); }
bool open( unsigned card = 0 ) { IDeckLinkIterator* decklinkIterator = NULL; try { #ifdef WIN32 HRESULT result = CoInitialize( NULL ); if ( FAILED( result ) ) throw "COM initialization failed"; result = CoCreateInstance( CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, IID_IDeckLinkIterator, (void**) &decklinkIterator ); if ( FAILED( result ) ) throw "The DeckLink drivers are not installed."; #else decklinkIterator = CreateDeckLinkIteratorInstance(); if ( !decklinkIterator ) throw "The DeckLink drivers are not installed."; #endif // Connect to the Nth DeckLink instance for ( unsigned i = 0; decklinkIterator->Next( &m_decklink ) == S_OK ; i++) { if ( i == card ) break; else SAFE_RELEASE( m_decklink ); } SAFE_RELEASE( decklinkIterator ); if ( !m_decklink ) throw "DeckLink card not found."; // Get the input interface if ( m_decklink->QueryInterface( IID_IDeckLinkInput, (void**) &m_decklinkInput ) != S_OK ) throw "No DeckLink cards support input."; // Provide this class as a delegate to the input callback m_decklinkInput->SetCallback( this ); // Initialize other members pthread_mutex_init( &m_mutex, NULL ); pthread_cond_init( &m_condition, NULL ); m_queue = mlt_deque_init(); m_started = false; m_dropped = 0; m_isBuffering = true; m_cache = mlt_cache_init(); // 3 covers YADIF and increasing framerate use cases mlt_cache_set_size( m_cache, 3 ); } catch ( const char *error ) { SAFE_RELEASE( m_decklinkInput ); SAFE_RELEASE( m_decklink ); mlt_log_error( getProducer(), "%s\n", error ); return false; } return true; }
QStringList BMDOutputDelegate::enumDeviceNames(bool forceReload) { if(!s_knownDevices.isEmpty()) { if(!forceReload) return s_knownDevices; else s_knownDevices.clear(); } IDeckLinkIterator *deckLinkIterator = CreateDeckLinkIteratorInstance(); if (deckLinkIterator == NULL) { fprintf(stderr, "BMDCaptureDelegate::enumDeviceNames: A DeckLink iterator could not be created. The DeckLink drivers may not be installed.\n"); return QStringList(); } IDeckLink *deckLink; IDeckLinkInput *deckLinkOutput; int index = 0; // Enumerate all cards in this system while (deckLinkIterator->Next(&deckLink) == S_OK) { if (deckLink->QueryInterface(IID_IDeckLinkOutput, (void**)&deckLinkOutput) == S_OK) { s_knownDevices << QString("bmd:%1").arg(index); deckLinkOutput->Release(); deckLinkOutput = NULL; } index ++; // Release the IDeckLink instance when we've finished with it to prevent leaks deckLink->Release(); } deckLinkIterator->Release(); return s_knownDevices; }
void stop() { if ( !m_started ) return; m_started = false; // Release the wait in getFrame pthread_mutex_lock( &m_mutex ); pthread_cond_broadcast( &m_condition ); pthread_mutex_unlock( &m_mutex ); m_decklinkInput->StopStreams(); m_decklinkInput->DisableVideoInput(); m_decklinkInput->DisableAudioInput(); // Cleanup queue pthread_mutex_lock( &m_mutex ); while ( mlt_frame frame = (mlt_frame) mlt_deque_pop_back( m_queue ) ) mlt_frame_close( frame ); pthread_mutex_unlock( &m_mutex ); }
void open_audio_input( ) { assert(deckLink != NULL); assert(deckLinkInput != NULL); if (deckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, n_channels) != S_OK) { throw std::runtime_error( "DeckLink audio input: failed to enable audio input" ); } audio_rate = 48000; }
IDeckLinkDisplayMode* BMDConfig::GetDeckLinkDisplayMode(IDeckLink* deckLink, int idx) { HRESULT result; IDeckLinkDisplayMode* displayMode = NULL; IDeckLinkInput* deckLinkInput = NULL; IDeckLinkDisplayModeIterator* displayModeIterator = NULL; int i = idx; result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput); if (result != S_OK) goto bail; result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK) goto bail; while ((result = displayModeIterator->Next(&displayMode)) == S_OK) { if (i == 0) break; --i; displayMode->Release(); } if (result != S_OK) goto bail; bail: if (displayModeIterator) displayModeIterator->Release(); if (deckLinkInput) deckLinkInput->Release(); return displayMode; }
~DeckLinkCaptureDelegate() { m_deckLinkInput->Release(); pthread_mutex_destroy(&m_mutex); }
bool start( mlt_profile profile = 0 ) { if ( m_started ) return false; try { // Initialize some members m_vancLines = mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( getProducer() ), "vanc" ); if ( m_vancLines == -1 ) m_vancLines = profile->height <= 512 ? 26 : 32; if ( !profile ) profile = mlt_service_profile( MLT_PRODUCER_SERVICE( getProducer() ) ); // Get the display mode BMDDisplayMode displayMode = getDisplayMode( profile, m_vancLines ); if ( displayMode == (BMDDisplayMode) bmdDisplayModeNotSupported ) { mlt_log_info( getProducer(), "profile = %dx%d %f fps %s\n", profile->width, profile->height, mlt_profile_fps( profile ), profile->progressive? "progressive" : "interlace" ); throw "Profile is not compatible with decklink."; } // Determine if supports input format detection #ifdef WIN32 BOOL doesDetectFormat = FALSE; #else bool doesDetectFormat = false; #endif IDeckLinkAttributes *decklinkAttributes = 0; if ( m_decklink->QueryInterface( IID_IDeckLinkAttributes, (void**) &decklinkAttributes ) == S_OK ) { if ( decklinkAttributes->GetFlag( BMDDeckLinkSupportsInputFormatDetection, &doesDetectFormat ) != S_OK ) doesDetectFormat = false; SAFE_RELEASE( decklinkAttributes ); } mlt_log_verbose( getProducer(), "%s format detection\n", doesDetectFormat ? "supports" : "does not support" ); // Enable video capture BMDPixelFormat pixelFormat = bmdFormat8BitYUV; BMDVideoInputFlags flags = doesDetectFormat ? bmdVideoInputEnableFormatDetection : bmdVideoInputFlagDefault; if ( S_OK != m_decklinkInput->EnableVideoInput( displayMode, pixelFormat, flags ) ) throw "Failed to enable video capture."; // Enable audio capture BMDAudioSampleRate sampleRate = bmdAudioSampleRate48kHz; BMDAudioSampleType sampleType = bmdAudioSampleType16bitInteger; int channels = mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( getProducer() ), "channels" ); if ( S_OK != m_decklinkInput->EnableAudioInput( sampleRate, sampleType, channels ) ) throw "Failed to enable audio capture."; // Start capture m_dropped = 0; mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( getProducer() ), "dropped", m_dropped ); m_started = m_decklinkInput->StartStreams() == S_OK; if ( !m_started ) throw "Failed to start capture."; } catch ( const char *error ) { m_decklinkInput->DisableVideoInput(); mlt_log_error( getProducer(), "%s\n", error ); return false; } return true; }
void BMDConfig::DisplayUsage(int status) { HRESULT result = E_FAIL; IDeckLinkIterator* deckLinkIterator = CreateDeckLinkIteratorInstance(); IDeckLinkDisplayModeIterator* displayModeIterator = NULL; IDeckLink* deckLink = NULL; IDeckLink* deckLinkSelected = NULL; int deckLinkCount = 0; char* deckLinkName = NULL; IDeckLinkAttributes* deckLinkAttributes = NULL; bool formatDetectionSupported; IDeckLinkInput* deckLinkInput = NULL; IDeckLinkDisplayMode* displayModeUsage; int displayModeCount = 0; char* displayModeName; fprintf(stderr, "Usage: Capture -d <device id> -m <mode id> [OPTIONS]\n" "\n" " -d <device id>:\n" ); // Loop through all available devices while (deckLinkIterator->Next(&deckLink) == S_OK) { result = deckLink->GetModelName((const char**)&deckLinkName); if (result == S_OK) { fprintf(stderr, " %2d: %s%s\n", deckLinkCount, deckLinkName, deckLinkCount == m_deckLinkIndex ? " (selected)" : "" ); free(deckLinkName); } if (deckLinkCount == m_deckLinkIndex) deckLinkSelected = deckLink; else deckLink->Release(); ++deckLinkCount; } if (deckLinkCount == 0) fprintf(stderr, " No DeckLink devices found. Is the driver loaded?\n"); deckLinkName = NULL; if (deckLinkSelected != NULL) deckLinkSelected->GetModelName((const char**)&deckLinkName); fprintf(stderr, " -m <mode id>: (%s)\n", deckLinkName ? deckLinkName : "" ); if (deckLinkName != NULL) free(deckLinkName); // Loop through all available display modes on the delected DeckLink device if (deckLinkSelected == NULL) { fprintf(stderr, " No DeckLink device selected\n"); goto bail; } result = deckLinkSelected->QueryInterface(IID_IDeckLinkAttributes, (void**)&deckLinkAttributes); if (result == S_OK) { result = deckLinkAttributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &formatDetectionSupported); if (result == S_OK && formatDetectionSupported) fprintf(stderr, " -1: auto detect format\n"); } result = deckLinkSelected->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput); if (result != S_OK) goto bail; result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK) goto bail; while (displayModeIterator->Next(&displayModeUsage) == S_OK) { result = displayModeUsage->GetName((const char **)&displayModeName); if (result == S_OK) { BMDTimeValue frameRateDuration; BMDTimeValue frameRateScale; displayModeUsage->GetFrameRate(&frameRateDuration, &frameRateScale); fprintf(stderr, " %2d: %-20s \t %li x %li \t %g FPS\n", displayModeCount, displayModeName, displayModeUsage->GetWidth(), displayModeUsage->GetHeight(), (double)frameRateScale / (double)frameRateDuration ); free(displayModeName); } displayModeUsage->Release(); ++displayModeCount; } bail: fprintf(stderr, " -p <pixelformat>\n" " 0: 8 bit YUV (4:2:2) (default)\n" " 1: 10 bit YUV (4:2:2)\n" " 2: 10 bit RGB (4:4:4)\n" " -t <format> Print timecode\n" " rp188: RP 188\n" " vitc: VITC\n" " serial: Serial Timecode\n" " -v <filename> Filename raw video will be written to\n" " -a <filename> Filename raw audio will be written to\n" " -l <lcm channel> Channel name to publish images to LCM\n" " -q <jpeg quality> JPEG compression quality for LCM images (1-100 - default is 90)\n" " -c <channels> Audio Channels (2, 8 or 16 - default is 2)\n" " -s <depth> Audio Sample Depth (16 or 32 - default is 16)\n" " -n <frames> Number of frames to capture (default is unlimited)\n" " -3 Capture Stereoscopic 3D (Requires 3D Hardware support)\n" "\n" "Capture video and/or audio to a file. Raw video and/or audio can be viewed with mplayer eg:\n" "\n" " Capture -d 0 -m 2 -n 50 -v video.raw -a audio.raw\n" " mplayer video.raw -demuxer rawvideo -rawvideo pal:uyvy -audiofile audio.raw -audio-demuxer 20 -rawaudio rate=48000\n" "\n" "LCM capture example command line:\n" "\n" " DecklinkCapture -d 0 -m 14 -q 95 -l DECKLINK_VIDEO_CAPTURE\n" "\n" ); if (deckLinkIterator != NULL) deckLinkIterator->Release(); if (displayModeIterator != NULL) displayModeIterator->Release(); if (deckLinkInput != NULL) deckLinkInput->Release(); if (deckLinkAttributes != NULL) deckLinkAttributes->Release(); if (deckLinkSelected != NULL) deckLinkSelected->Release(); exit(status); }
void print_output_modes(IDeckLink *deckLink) { IDeckLinkInput *deckLinkInput = NULL; IDeckLinkDisplayModeIterator *displayModeIterator = NULL; IDeckLinkDisplayMode *displayMode = NULL; HRESULT result; int displayModeCount = 0; // Query the DeckLink for its configuration interface result = deckLink->QueryInterface(IID_IDeckLinkInput, (void **)&deckLinkInput); if (result != S_OK) { fprintf( stderr, "Could not obtain the IDeckLinkInput interface - result = %08x\n", result); goto bail; } // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK) { fprintf( stderr, "Could not obtain the video output display mode iterator - result = %08x\n", result); goto bail; } // List all supported output display modes printf("Supported video output display modes and pixel formats:\n"); while (displayModeIterator->Next(&displayMode) == S_OK) { BMDProbeString str; result = displayMode->GetName(&str); if (result == S_OK) { char modeName[64]; int modeWidth; int modeHeight; BMDTimeValue frameRateDuration; BMDTimeScale frameRateScale; int pixelFormatIndex = 0; // index into the gKnownPixelFormats / gKnownFormatNames arrays BMDDisplayModeSupport displayModeSupport; // Obtain the display mode's properties modeWidth = displayMode->GetWidth(); modeHeight = displayMode->GetHeight(); displayMode->GetFrameRate(&frameRateDuration, &frameRateScale); printf(" %2d: %-20s \t %d x %d \t %7g FPS\n", displayModeCount++, ToStr(str), modeWidth, modeHeight, (double)frameRateScale / (double)frameRateDuration); FreeStr(str); } // Release the IDeckLinkDisplayMode object to prevent a leak displayMode->Release(); } // printf("\n"); bail: // Ensure that the interfaces we obtained are released to prevent a memory leak if (displayModeIterator != NULL) { displayModeIterator->Release(); } if (deckLinkInput != NULL) { deckLinkInput->Release(); } }
void krad_decklink_capture_info () { IDeckLink *deckLink; IDeckLinkInput *deckLinkInput; IDeckLinkIterator *deckLinkIterator; IDeckLinkDisplayModeIterator *displayModeIterator; IDeckLinkDisplayMode *displayMode; HRESULT result; int displayModeCount; char *displayModeString; displayModeString = NULL; displayModeCount = 0; deckLinkIterator = CreateDeckLinkIteratorInstance(); if (!deckLinkIterator) { printke ("Krad Decklink: This application requires the DeckLink drivers installed.\n"); } /* Connect to the first DeckLink instance */ result = deckLinkIterator->Next(&deckLink); if (result != S_OK) { printke ("Krad Decklink: No DeckLink PCI cards found.\n"); } result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput); if (result != S_OK) { printke ("Krad Decklink: Fail QueryInterface\n"); } result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK) { printke ("Krad Decklink: Could not obtain the video output display mode iterator - result = %08x\n", result); } while (displayModeIterator->Next(&displayMode) == S_OK) { result = displayMode->GetName((const char **) &displayModeString); if (result == S_OK) { BMDTimeValue frameRateDuration, frameRateScale; displayMode->GetFrameRate(&frameRateDuration, &frameRateScale); printkd ("%2d: %-20s \t %li x %li \t %g FPS\n", displayModeCount, displayModeString, displayMode->GetWidth(), displayMode->GetHeight(), (double)frameRateScale / (double)frameRateDuration); free (displayModeString); displayModeCount++; } displayMode->Release(); } if (displayModeIterator != NULL) { displayModeIterator->Release(); displayModeIterator = NULL; } if (deckLinkInput != NULL) { deckLinkInput->Release(); deckLinkInput = NULL; } if (deckLink != NULL) { deckLink->Release(); deckLink = NULL; } if (deckLinkIterator != NULL) { deckLinkIterator->Release(); } }
void print_input_modes (IDeckLink* deckLink) { IDeckLinkInput* deckLinkInput = NULL; IDeckLinkDisplayModeIterator* displayModeIterator = NULL; IDeckLinkDisplayMode* displayMode = NULL; HRESULT result; // Query the DeckLink for its configuration interface result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput); if (result != S_OK) { fprintf(stderr, "Could not obtain the IDeckLinkInput interface - result = %08x\n", result); goto bail; } // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on input result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK) { fprintf(stderr, "Could not obtain the video input display mode iterator - result = %08x\n", result); goto bail; } // List all supported input display modes printf("Supported video input display modes and pixel formats:\n"); while (displayModeIterator->Next(&displayMode) == S_OK) { char * displayModeString = NULL; result = displayMode->GetName((const char **) &displayModeString); if (result == S_OK) { char modeName[64]; int modeWidth; int modeHeight; BMDTimeValue frameRateDuration; BMDTimeScale frameRateScale; int pixelFormatIndex = 0; // index into the gKnownPixelFormats / gKnownFormatNames arrays BMDDisplayModeSupport displayModeSupport; // Obtain the display mode's properties modeWidth = displayMode->GetWidth(); modeHeight = displayMode->GetHeight(); displayMode->GetFrameRate(&frameRateDuration, &frameRateScale); printf(" %-20s \t %d x %d \t %7g FPS\t", displayModeString, modeWidth, modeHeight, (double)frameRateScale / (double)frameRateDuration); // Print the supported pixel formats for this display mode while ((gKnownPixelFormats[pixelFormatIndex] != 0) && (gKnownPixelFormatNames[pixelFormatIndex] != NULL)) { if ((deckLinkInput->DoesSupportVideoMode(displayMode->GetDisplayMode(), gKnownPixelFormats[pixelFormatIndex], bmdVideoInputFlagDefault, &displayModeSupport, NULL) == S_OK) && (displayModeSupport != bmdDisplayModeNotSupported)) { printf("%s\t", gKnownPixelFormatNames[pixelFormatIndex]); } pixelFormatIndex++; } printf("\n"); free(displayModeString); } // Release the IDeckLinkDisplayMode object to prevent a leak displayMode->Release(); } printf("\n"); bail: // Ensure that the interfaces we obtained are released to prevent a memory leak if (displayModeIterator != NULL) displayModeIterator->Release(); if (deckLinkInput != NULL) deckLinkInput->Release(); }