static gboolean gst_phoenixsrc_start (GstBaseSrc * src) { GstPhoenixSrc *phoenixsrc = GST_PHOENIX_SRC (src); etStat eStat = PHX_OK; /* Status variable */ etParamValue eParamValue = PHX_INVALID_PARAMVALUE; ui32 dwParamValue = 0; guint eCamConfig; GST_DEBUG_OBJECT (phoenixsrc, "start"); if (phoenixsrc->config_filepath == NULL) { GST_WARNING_OBJECT (phoenixsrc, "No config file set, using default 640x480x8bpp"); } else if (!g_file_test (phoenixsrc->config_filepath, G_FILE_TEST_EXISTS)) { GST_ELEMENT_ERROR (phoenixsrc, RESOURCE, NOT_FOUND, ("Camera config file does not exist: %s", phoenixsrc->config_filepath), (NULL)); goto Error; } /* TODO: hacky, use enums or something */ eCamConfig = PHX_DIGITAL; switch (phoenixsrc->board) { case 0: eCamConfig |= PHX_BOARD_AUTO; break; case 1: eCamConfig |= PHX_BOARD1; break; case 2: eCamConfig |= PHX_BOARD2; break; case 3: eCamConfig |= PHX_BOARD3; break; case 4: eCamConfig |= PHX_BOARD4; break; case 5: eCamConfig |= PHX_BOARD5; break; case 6: eCamConfig |= PHX_BOARD6; break; case 7: eCamConfig |= PHX_BOARD7; break; default: g_assert_not_reached (); } switch (phoenixsrc->channel) { case 0: eCamConfig |= PHX_CHANNEL_AUTO; break; case 1: eCamConfig |= PHX_CHANNEL1; break; case 2: eCamConfig |= PHX_CHANNEL2; break; } /* Initialize board */ eStat = PHX_CameraConfigLoad (&phoenixsrc->hCamera, phoenixsrc->config_filepath, (etCamConfigLoad) eCamConfig, PHX_ErrHandlerDefault); if (eStat != PHX_OK) { GST_ELEMENT_ERROR (phoenixsrc, LIBRARY, INIT, (NULL), (NULL)); goto Error; } /* capture frames continuously */ eParamValue = PHX_ENABLE; eStat = PHX_ParameterSet (phoenixsrc->hCamera, PHX_ACQ_CONTINUOUS, &eParamValue); if (PHX_OK != eStat) goto ResourceSettingsError; /* capture in blocking fashion, i.e. don't overwrite un-processed buffers */ eParamValue = PHX_DISABLE; eStat = PHX_ParameterSet (phoenixsrc->hCamera, PHX_ACQ_BLOCKING, &eParamValue); if (PHX_OK != eStat) goto ResourceSettingsError; /* use event counter to count time from start of acquisition */ eParamValue = PHX_EVENTCOUNT_TIME; eStat = PHX_ParameterSet (phoenixsrc->hCamera, PHX_EVENTCOUNT_SRC, &eParamValue); if (PHX_OK != eStat) goto ResourceSettingsError; eParamValue = PHX_EVENTGATE_ACQ; eStat = PHX_ParameterSet (phoenixsrc->hCamera, PHX_EVENTGATE_SRC, &eParamValue); if (PHX_OK != eStat) goto ResourceSettingsError; /* Tell Phoenix to use N buffers. */ eParamValue = phoenixsrc->num_capture_buffers; PHX_ParameterSet (phoenixsrc->hCamera, PHX_ACQ_NUM_IMAGES, &eParamValue); /* Setup a one second timeout value (milliseconds) */ dwParamValue = 1000; eStat = PHX_ParameterSet (phoenixsrc->hCamera, PHX_TIMEOUT_DMA, (void *) &dwParamValue); if (PHX_OK != eStat) goto ResourceSettingsError; /* The BUFFER_READY interrupt is already enabled by default, * but we must enable other interrupts here. */ eParamValue = PHX_INTRPT_TIMEOUT | PHX_INTRPT_FIFO_OVERFLOW | PHX_INTRPT_FRAME_END | PHX_INTRPT_FRAME_START; eStat = PHX_ParameterSet (phoenixsrc->hCamera, PHX_INTRPT_SET, (void *) &eParamValue); if (PHX_OK != eStat) goto ResourceSettingsError; return TRUE; ResourceSettingsError: GST_ELEMENT_ERROR (phoenixsrc, RESOURCE, SETTINGS, (("Failed to get Phoenix parameters.")), (NULL)); Error: /* Now cease all captures */ if (phoenixsrc->hCamera) PHX_Acquire (phoenixsrc->hCamera, PHX_ABORT, NULL); /* TODO Free all the user allocated memory */ //psImageBuff = pasImageBuffs; //if ( NULL != pasImageBuffs ) { // while ( NULL != psImageBuff->pvAddress ) { // free( psImageBuff->pvAddress ); // psImageBuff++; // } // free( pasImageBuffs ); //} /* Release the Phoenix board */ if (phoenixsrc->hCamera) PHX_CameraRelease (&phoenixsrc->hCamera); return FALSE; }
/* phxlive(ForBrief) Simple live capture application code */ int phxliveFrame( etCamConfigLoad eCamConfigLoad, /* Board number, ie 1, 2, or 0 for next available */ char *pszConfigFileName, /* Name of config file */ double exposure_time, int gain, unsigned short *frame_out // added by NC to allow output to another window ) { etStat eStat = PHX_OK; /* Status variable */ etParamValue eParamValue; /* Parameter for use with PHX_ParameterSet/Get calls */ tHandle hCamera = 0; /* Camera Handle */ tPHX hDisplay = 0; /* Display handle */ tPHX hBuffer1 = 0; /* First Image buffer handle */ tPHX hBuffer2 = 0; /* Second Image buffer handle */ //tPhxLive sPhxLive; /* User defined Event Context */ ui32 nBufferReadyLast = 0;/* Previous BufferReady count value */ int i,length; /* Initialise the user defined Event context structure */ memset( &sPhxLive, 0, sizeof( tPhxLive ) ); /* Allocate the board with the config file */ eStat = PHX_CameraConfigLoad( &hCamera, pszConfigFileName, eCamConfigLoad, PHX_ErrHandlerDefault ); if ( PHX_OK != eStat ) goto Error; /* set camera to live acquisition mode */ init_camera_internal_trigger(hCamera); set_exposure(hCamera, exposure_time); set_gain(hCamera, gain); #ifndef _USE_QT // We create our display with a NULL hWnd, this will automatically create an image window. eStat = PDL_DisplayCreate( &hDisplay, NULL, hCamera, PHX_ErrHandlerDefault ); if ( PHX_OK != eStat ) goto Error; // We create two display buffers for our double buffering eStat = PDL_BufferCreate( &hBuffer1, hDisplay, (etBufferMode)PDL_BUFF_SYSTEM_MEM_DIRECT ); if ( PHX_OK != eStat ) goto Error; eStat = PDL_BufferCreate( &hBuffer2, hDisplay, (etBufferMode)PDL_BUFF_SYSTEM_MEM_DIRECT ); if ( PHX_OK != eStat ) goto Error; // Initialise the display, this associates the display buffers with the display eStat = PDL_DisplayInit( hDisplay ); if ( PHX_OK != eStat ) goto Error; // The above code has created 2 display (acquisition) buffers. // Therefore ensure that the Phoenix is configured to use 2 buffers, by overwriting // the value already loaded from the config file. eParamValue = (etParamValue) 2; eStat = PHX_ParameterSet( hCamera, PHX_ACQ_NUM_IMAGES, &eParamValue ); if ( PHX_OK != eStat ) goto Error; #endif /* Enable FIFO Overflow events */ eParamValue = PHX_INTRPT_FIFO_OVERFLOW; eStat = PHX_ParameterSet( hCamera, PHX_INTRPT_SET, &eParamValue ); if ( PHX_OK != eStat ) goto Error; /* Setup our own event context */ eStat = PHX_ParameterSet( hCamera, PHX_EVENT_CONTEXT, (void *) &sPhxLive ); if ( PHX_OK != eStat ) goto Error; /* Now start our capture, using the callback method */ eStat = PHX_Acquire( hCamera, PHX_START, (void*) phxliveFrame_callback ); if ( PHX_OK != eStat ) goto Error; /* Continue processing data until the user presses a key in the console window * or Phoenix detects a FIFO overflow */ //printf("Press a key to exit\n"); /* while(!PhxCommonKbHit() && !sPhxLive.fFifoOverFlow)*/ while(!sPhxLive.fFifoOverFlow) { /* Temporarily sleep, to avoid burning CPU cycles. * An alternative method is to wait on a semaphore, which is signalled * within the callback function. This approach would ensure that the * data processing would only start when there was data to process */ _PHX_SleepMs(10); /* If there are any buffers waiting to display, then process them here */ if ( nBufferReadyLast != sPhxLive.nBufferReadyCount ) { stImageBuff stBuffer; int nStaleBufferCount; /* If the processing is too slow to keep up with acquisition, * then there may be more than 1 buffer ready to process. * The application can either be designed to process all buffers * knowing that it will catch up, or as here, throw away all but the * latest */ nStaleBufferCount = sPhxLive.nBufferReadyCount - nBufferReadyLast; nBufferReadyLast += nStaleBufferCount; /* Throw away all but the last image */ while ( nStaleBufferCount-- > 1 ) { eStat = PHX_Acquire( hCamera, PHX_BUFFER_RELEASE, NULL ); if ( PHX_OK != eStat ) goto Error; } /* Get the info for the last acquired buffer */ eStat = PHX_Acquire( hCamera, PHX_BUFFER_GET, &stBuffer ); if ( PHX_OK != eStat ) goto Error; /* Process the newly acquired buffer, * which in this simple example is a call to display the data. * For our display function we use the pvContext member variable to * pass a display buffer handle. * Alternatively the actual video data can be accessed at stBuffer.pvAddress */ #ifndef _USE_QT PDL_BufferPaint( (tPHX)stBuffer.pvContext ); #elif defined _USE_QT // Load a numpy array here!!!! for(i = 0; i < 1000000; i++) { *(frame_out + i) = *((short unsigned int*)(stBuffer.pvAddress) + i); } //fflush(stdout); //length = sizeof(frame_out); //write(1, frame_out, length); #else printf("EventCount = %5d\r", sPhxLive.nBufferReadyCount ); #endif /* Having processed the data, release the buffer ready for further image data */ eStat = PHX_Acquire( hCamera, PHX_BUFFER_RELEASE, NULL ); if ( PHX_OK != eStat ) goto Error; } } printf("\n"); /* In this simple example we abort the processing loop on an error condition (FIFO overflow). * However handling of this condition is application specific, and generally would involve * aborting the current acquisition, and then restarting. */ if ( sPhxLive.fFifoOverFlow ) { printf("FIFO OverFlow detected..Aborting\n"); } Error: /* Now cease all captures */ if ( hCamera ) PHX_Acquire( hCamera, PHX_ABORT, NULL ); #if defined _PHX_DISPLAY /* Free our display double buffering resources */ if ( hBuffer1 ) PDL_BufferDestroy( (tPHX*) &hBuffer1 ); if ( hBuffer2 ) PDL_BufferDestroy( (tPHX*) &hBuffer2 ); /* Destroy our display */ if ( hDisplay ) PDL_DisplayDestroy( (tPHX*) &hDisplay ); #endif /* Release the Phoenix board */ if ( hCamera ) PHX_CameraRelease( &hCamera ); printf("Exiting\n"); return 0; }