How to get multiple av_read_frame with FFmpeg - c++

I want to get "2 signals" when I read an audio file. I know that I must use the FFmpeg function av_read_frame, but I have just that I call "1 signal". How can I have multiple signals to treat each signal in different way ?
My code is like that :
while (av_read_frame(pFormatCtx, packet) >= 0)
{
/* AVPacket == Audio */
if (packet->stream_index == audioStream)
{
/* Décodage des packets */
ret = avcodec_decode_audio4(pCodecCtx, pFrame, &got_picture, packet);
if (ret < 0)
{
fprintf(stderr, "%s\n", "Error in decoding audio frame");
return (-1);
}
if (got_picture > 0)
{
/* Convertissage de l'audio */
swr_convert(au_convert_ctx, &out_buffer, MAX_AUDIO_FRAME_SIZE, (const uint8_t **)pFrame->data, pFrame->nb_samples);
#if 1
/* Affichage des informations dans la console */
printf("Index : %5d\t Points : %lld\t Packet size : %d\n", index, packet->pts, packet->size);
#endif /* 1 */
#if OUTPUT_PCM
/* Fonction pour écrire dans le fichier */
fwrite(out_buffer, 1, out_buffer_size, pFile);
#endif /* OUTPUT_PCM */
/* Incrémentation */
index = index + 1;
}
#if USE_SDL
while (audio_len > 0)
SDL_Delay(1);
/* Attribution des valeurs avec les variables globales */
audio_chunk = (Uint8 *)out_buffer;
audio_len = out_buffer_size;
audio_pos = audio_chunk;
SDL_PauseAudio(0);
#endif /* USE_SDL */
}
/* Libérer la structure AVPacket */
av_free_packet(packet);
}

Related

FFMPEG using AV_PIX_FMT_D3D11 gives "Error registering the input resource" from NVENC

Input frames start on the GPU as ID3D11Texture2D pointers.
I encode them to H264 using FFMPEG + NVENC. NVENC works perfectly if I download the textures to CPU memory as format AV_PIX_FMT_BGR0, but I'd like to cut out the CPU texture download entirely, and pass the GPU memory pointer directly into the encoder in native format. I write frames like this:
int write_gpu_video_frame(ID3D11Texture2D* gpuTex, AVFormatContext* oc, OutputStream* ost) {
AVFrame *hw_frame = ost->hw_frame;
printf("gpuTex address = 0x%x\n", &gpuTex);
hw_frame->data[0] = (uint8_t *) gpuTex;
hw_frame->data[1] = (uint8_t *) (intptr_t) 0;
hw_frame->pts = ost->next_pts++;
return write_frame(oc, ost->enc, ost->st, hw_frame);
// write_frame is identical to sample code in ffmpeg repo
}
Running the code with this modification gives the following error:
gpuTex address = 0x4582f6d0
[h264_nvenc # 00000191233e1bc0] Error registering an input resource: invalid call (9):
[h264_nvenc # 00000191233e1bc0] Could not register an input HW frame
Error sending a frame to the encoder: Unknown error occurred
Here's some supplemental code used in setting up and configuring the hw context and encoder:
/* A few config flags */
#define ENABLE_NVENC TRUE
#define USE_D3D11 TRUE // Skip downloading textures to CPU memory and send it straight to NVENC
/* Init hardware frame context */
static int set_hwframe_ctx(AVCodecContext* ctx, AVBufferRef* hw_device_ctx) {
AVBufferRef* hw_frames_ref;
AVHWFramesContext* frames_ctx = NULL;
int err = 0;
if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx))) {
fprintf(stderr, "Failed to create HW frame context.\n");
throw;
}
frames_ctx = (AVHWFramesContext*) (hw_frames_ref->data);
frames_ctx->format = AV_PIX_FMT_D3D11;
frames_ctx->sw_format = AV_PIX_FMT_NV12;
frames_ctx->width = STREAM_WIDTH;
frames_ctx->height = STREAM_HEIGHT;
//frames_ctx->initial_pool_size = 20;
if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0) {
fprintf(stderr, "Failed to initialize hw frame context. Error code: %s\n", av_err2str(err));
av_buffer_unref(&hw_frames_ref);
throw;
}
ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ref);
if (!ctx->hw_frames_ctx)
err = AVERROR(ENOMEM);
av_buffer_unref(&hw_frames_ref);
return err;
}
/* Add an output stream. */
static void add_video_stream(
OutputStream* ost,
AVFormatContext* oc,
const AVCodec** codec,
enum AVCodecID codec_id,
int width,
int height
) {
AVCodecContext* c;
int i;
bool nvenc = false;
/* find the encoder */
if (ENABLE_NVENC) {
printf("Getting nvenc encoder\n");
*codec = avcodec_find_encoder_by_name("h264_nvenc");
nvenc = true;
}
if (!ENABLE_NVENC || *codec == NULL) {
printf("Getting standard encoder\n");
avcodec_find_encoder(codec_id);
nvenc = false;
}
if (!(*codec)) {
fprintf(stderr, "Could not find encoder for '%s'\n",
avcodec_get_name(codec_id));
exit(1);
}
ost->st = avformat_new_stream(oc, NULL);
if (!ost->st) {
fprintf(stderr, "Could not allocate stream\n");
exit(1);
}
ost->st->id = oc->nb_streams - 1;
c = avcodec_alloc_context3(*codec);
if (!c) {
fprintf(stderr, "Could not alloc an encoding context\n");
exit(1);
}
ost->enc = c;
printf("Using video codec %s\n", avcodec_get_name(codec_id));
c->codec_id = codec_id;
c->bit_rate = 4000000;
/* Resolution must be a multiple of two. */
c->width = STREAM_WIDTH;
c->height = STREAM_HEIGHT;
/* timebase: This is the fundamental unit of time (in seconds) in terms
* of which frame timestamps are represented. For fixed-fps content,
* timebase should be 1/framerate and timestamp increments should be
* identical to 1. */
ost->st->time_base = {1, STREAM_FRAME_RATE};
c->time_base = ost->st->time_base;
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
if (nvenc && USE_D3D11) {
const std::string hw_device_name = "d3d11va";
AVHWDeviceType device_type = av_hwdevice_find_type_by_name(hw_device_name.c_str());
// set up hw device context
AVBufferRef *hw_device_ctx;
// const char* device = "0"; // Default GPU (may be integrated in the case of switchable graphics!)
const char* device = "1";
ret = av_hwdevice_ctx_create(&hw_device_ctx, device_type, device, nullptr, 0);
if (ret < 0) {
fprintf(stderr, "Could not create hwdevice context; %s", av_err2str(ret));
}
set_hwframe_ctx(c, hw_device_ctx);
c->pix_fmt = AV_PIX_FMT_D3D11;
} else if (nvenc && !USE_D3D11)
c->pix_fmt = AV_PIX_FMT_BGR0;
else
c->pix_fmt = STREAM_PIX_FMT;
if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
/* just for testing, we also add B-frames */
c->max_b_frames = 2;
}
if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
/* Needed to avoid using macroblocks in which some coeffs overflow.
* This does not happen with normal video, it just happens here as
* the motion of the chroma plane does not match the luma plane. */
c->mb_decision = 2;
}
/* Some formats want stream headers to be separate. */
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}

Encoded video made using the Nvidia encoded SDK is not correct

I am trying to integrate the Nvidia Encoder SDK with the Nvidia Frame Buffer Capture SDK. I am capturing frames in a cuda buffer and then sending then to the Nvidia Encoder to be encoded in H.264 format.
The encoded video however, is not what I want it to be, it is a completely pink screen.
Are there any reasons as to why it might be happening?
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <dlfcn.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>
#include<dlfcn.h>
#include"nvEncodeAPI.h"
#include <NvFBC.h>
// If you have the CUDA Toolkit Installed, you can include the CUDA headers
// #include "cuda.h"
//#include "cuda_drvapi_dynlink_cuda.h"
#include"cuda.h"
#include "NvFBCUtils.h"
#define APP_VERSION 4
#define LIB_NVFBC_NAME "libnvidia-fbc.so.1"
#define LIB_CUDA_NAME "libcuda.so.1"
#define N_FRAMES 10
/*
* CUDA entry points
*/
typedef CUresult (* CUINITPROC) (unsigned int Flags);
typedef CUresult (* CUDEVICEGETPROC) (CUdevice *device, int ordinal);
typedef CUresult (* CUCTXCREATEV2PROC) (CUcontext *pctx, unsigned int flags, CUdevice dev);
typedef CUresult (* CUMEMCPYDTOHV2PROC) (void *dstHost, CUdeviceptr srcDevice, size_t ByteCount);
typedef CUresult (* CUGETDEVICEPTR) (CUdeviceptr *dptr, size_t bytesize);
static CUINITPROC cuInit_ptr = NULL;
static CUDEVICEGETPROC cuDeviceGet_ptr = NULL;
static CUCTXCREATEV2PROC cuCtxCreate_v2_ptr = NULL;
static CUMEMCPYDTOHV2PROC cuMemcpyDtoH_v2_ptr = NULL;
static CUGETDEVICEPTR cuGetDevicePtr=NULL;
typedef NVENCSTATUS (*PNVENCCREATEINSTANCE) (NV_ENCODE_API_FUNCTION_LIST* pFuncList);
/**
* Dynamically opens the CUDA library and resolves the symbols that are
* needed for this application.
*
* \param [out] libCUDA
* A pointer to the opened CUDA library.
*
* \return
* NVFBC_TRUE in case of success, NVFBC_FALSE otherwise.
*/
static NVFBC_BOOL cuda_load_library(void *libCUDA)
{
libCUDA = dlopen(LIB_CUDA_NAME, RTLD_NOW);
if (libCUDA == NULL) {
fprintf(stderr, "Unable to open '%s'\n", LIB_CUDA_NAME);
return NVFBC_FALSE;
}
cuInit_ptr = (CUINITPROC) dlsym(libCUDA, "cuInit");
if (cuInit_ptr == NULL) {
fprintf(stderr, "Unable to resolve symbol 'cuInit'\n");
return NVFBC_FALSE;
}
cuDeviceGet_ptr = (CUDEVICEGETPROC) dlsym(libCUDA, "cuDeviceGet");
if (cuDeviceGet_ptr == NULL) {
fprintf(stderr, "Unable to resolve symbol 'cuDeviceGet'\n");
return NVFBC_FALSE;
}
cuCtxCreate_v2_ptr = (CUCTXCREATEV2PROC) dlsym(libCUDA, "cuCtxCreate_v2");
if (cuCtxCreate_v2_ptr == NULL) {
fprintf(stderr, "Unable to resolve symbol 'cuCtxCreate_v2'\n");
return NVFBC_FALSE;
}
cuMemcpyDtoH_v2_ptr = (CUMEMCPYDTOHV2PROC) dlsym(libCUDA, "cuMemcpyDtoH_v2");
if (cuMemcpyDtoH_v2_ptr == NULL) {
fprintf(stderr, "Unable to resolve symbol 'cuMemcpyDtoH_v2'\n");
return NVFBC_FALSE;
}
cuGetDevicePtr = (CUGETDEVICEPTR) dlsym(libCUDA,"cuMemAlloc");
if(cuGetDevicePtr==NULL){
fprintf(stderr, "Unable to resolve symbol 'cuMemAlloc'\n");
return NVFBC_FALSE;
}
return NVFBC_TRUE;
}
/**
* Initializes CUDA and creates a CUDA context.
*
* \param [in] cuCtx
* A pointer to the created CUDA context.
*
* \return
* NVFBC_TRUE in case of success, NVFBC_FALSE otherwise.
*/
static NVFBC_BOOL cuda_init(CUcontext *cuCtx)
{
CUresult cuRes;
CUdevice cuDev;
cuRes = cuInit_ptr(0);
if (cuRes != CUDA_SUCCESS) {
fprintf(stderr, "Unable to initialize CUDA (result: %d)\n", cuRes);
return NVFBC_FALSE;
}
cuRes = cuDeviceGet_ptr(&cuDev, 0);
if (cuRes != CUDA_SUCCESS) {
fprintf(stderr, "Unable to get CUDA device (result: %d)\n", cuRes);
return NVFBC_FALSE;
}
cuRes = cuCtxCreate_v2_ptr(cuCtx, CU_CTX_SCHED_AUTO, cuDev);
if (cuRes != CUDA_SUCCESS) {
fprintf(stderr, "Unable to create CUDA context (result: %d)\n", cuRes);
return NVFBC_FALSE;
}
return NVFBC_TRUE;
}
/**
* Initializes the NvFBC and CUDA libraries and creates an NvFBC instance.
*
* Creates and sets up a capture session to video memory using the CUDA interop.
*
* Captures a bunch of frames every second, converts them to BMP and saves them
* to the disk.
*/
int main(int argc, char *argv[])
{
//handing the opening of the nvidia encoder library
void* handle = dlopen("libnvidia-encode.so",RTLD_NOW);
if(handle==NULL)
{
printf("Unable to load the nvidia encoder library");
return EXIT_FAILURE;
}
PNVENCCREATEINSTANCE NvEncCreateInstance_ptr;
NvEncCreateInstance_ptr = (PNVENCCREATEINSTANCE) dlsym(handle,"NvEncodeAPICreateInstance");
if(NvEncCreateInstance_ptr==NULL)
{
printf("Failure to load the nv encode lib");
}
static struct option longopts[] = {
{ "get-status", no_argument, NULL, 'g' },
{ "track", required_argument, NULL, 't' },
{ "frames", required_argument, NULL, 'f' },
{ "size", required_argument, NULL, 's' },
{ "format", required_argument, NULL, 'o' },
{ NULL, 0, NULL, 0 }
};
int opt, ret;
unsigned int i, nFrames = N_FRAMES;
NVFBC_SIZE frameSize = { 0, 0 };
NVFBC_BOOL printStatusOnly = NVFBC_FALSE;
NVFBC_TRACKING_TYPE trackingType = NVFBC_TRACKING_DEFAULT;
char outputName[NVFBC_OUTPUT_NAME_LEN];
uint32_t outputId = 0;
void *libNVFBC = NULL, *libCUDA = NULL;
PNVFBCCREATEINSTANCE NvFBCCreateInstance_ptr = NULL;
NVFBC_API_FUNCTION_LIST pFn;
CUcontext cuCtx;
NVFBCSTATUS fbcStatus;
NVFBC_BOOL fbcBool;
NVFBC_SESSION_HANDLE fbcHandle;
NVFBC_CREATE_HANDLE_PARAMS createHandleParams;
NVFBC_GET_STATUS_PARAMS statusParams;
NVFBC_CREATE_CAPTURE_SESSION_PARAMS createCaptureParams;
NVFBC_DESTROY_CAPTURE_SESSION_PARAMS destroyCaptureParams;
NVFBC_DESTROY_HANDLE_PARAMS destroyHandleParams;
NVFBC_TOCUDA_SETUP_PARAMS setupParams;
NVFBC_BUFFER_FORMAT bufferFormat = NVFBC_BUFFER_FORMAT_NV12;
char videoFile[64]="video.h264";
FILE* fd;
/*
* Parse the command line.
*/
while ((opt = getopt_long(argc, argv, "hgt:f:s:o:", longopts, NULL)) != -1) {
switch (opt) {
case 'g':
printStatusOnly = NVFBC_TRUE;
break;
case 't':
NvFBCUtilsParseTrackingType(optarg, &trackingType, outputName);
break;
case 'f':
nFrames = (unsigned int) atoi(optarg);
break;
case 's':
ret = sscanf(optarg, "%ux%u", &frameSize.w, &frameSize.h);
if (ret != 2) {
fprintf(stderr, "Invalid size format: '%s'\n", optarg);
return EXIT_FAILURE;
}
break;
case 'o':
if (!strcasecmp(optarg, "rgb")) {
bufferFormat = NVFBC_BUFFER_FORMAT_RGB;
} else if (!strcasecmp(optarg, "argb")) {
bufferFormat = NVFBC_BUFFER_FORMAT_ARGB;
} else if (!strcasecmp(optarg, "nv12")) {
bufferFormat = NVFBC_BUFFER_FORMAT_NV12;
} else if (!strcasecmp(optarg, "yuv444p")) {
bufferFormat = NVFBC_BUFFER_FORMAT_YUV444P;
} else {
fprintf(stderr, "Unknown buffer format: '%s'\n", optarg);
return EXIT_FAILURE;
}
break;
case 'h':
default:
usage(argv[0]);
return EXIT_SUCCESS;
}
}
NvFBCUtilsPrintVersions(APP_VERSION);
/*
* Dynamically load the NvFBC library.
*/
libNVFBC = dlopen(LIB_NVFBC_NAME, RTLD_NOW);
if (libNVFBC == NULL) {
fprintf(stderr, "Unable to open '%s'\n", LIB_NVFBC_NAME);
return EXIT_FAILURE;
}
fbcBool = cuda_load_library(libCUDA);
if (fbcBool != NVFBC_TRUE) {
return EXIT_FAILURE;
}
fbcBool = cuda_init(&cuCtx);
if (fbcBool != NVFBC_TRUE) {
return EXIT_FAILURE;
}
//input output buffer the contains all the pointers to the functions for the api
NV_ENCODE_API_FUNCTION_LIST nvencFunctionList;
nvencFunctionList.version=NV_ENCODE_API_FUNCTION_LIST_VER;
//this function call populates the passed pointer to the nvidia api function list with
//the function pointers to the routines implemented by the encoder api
NVENCSTATUS status = NvEncCreateInstance_ptr(&nvencFunctionList);//NvEncodeAPICreateInstance(&nvencFunctionList);
//exit code if failed to create instance of the api
if(status!=NV_ENC_SUCCESS)
{
printf("The nvidia encoder could not be initialized");
EXIT_FAILURE;
}
//creating the encode session params
NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS openSessionExParams;
//initializing them and then adding the values
// memset(&openSessionExParams,0,sizeof(openSessionExParams));
//setting the version
openSessionExParams.version = NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER;
openSessionExParams.deviceType = NV_ENC_DEVICE_TYPE_CUDA;
//Note - Maybe change the next line
//ading the device pointer which in this case will be a cuda context
openSessionExParams.device = (void*)cuCtx;
openSessionExParams.reserved = NULL;
openSessionExParams.apiVersion = NVENCAPI_VERSION;
//setting all values of the reserved 1 array to 0
//Note - check the next two lines
memset(openSessionExParams.reserved1,0,253*sizeof(uint32_t));//sizeof(openSessionExParams.reserved1)/sizeof(openSessionExParams.reserved1[0]));
memset(openSessionExParams.reserved2,NULL,64*sizeof(void*));//sizeof(openSessionExParams.reserved2)/sizeof(openSessionExParams.reserved2[0]));
//handle for the encoder
void* encoder;
//Note- Seg fault
status = nvencFunctionList.nvEncOpenEncodeSessionEx(&openSessionExParams,&encoder);
//NvEncOpenEncodeSessionEx(&openSessionExParams,encoder);
if(status!=NV_ENC_SUCCESS)
{
printf("Failure opening encoding session: %u\n",status);
return EXIT_FAILURE;
}
//getting the count of the available encoder settings
uint32_t guidCount;
status =nvencFunctionList.nvEncGetEncodeGUIDCount(encoder,&guidCount);
if(status!=NV_ENC_SUCCESS)
{
printf("Failure getting GUID count");
return EXIT_FAILURE;
}
//allocating a buffer that holds that count
GUID* GUIDs = malloc(guidCount*sizeof(GUID));
//number of supported guid
uint32_t supportedGUID;
//adding all the guids to the previously allocated buffer
status =nvencFunctionList.nvEncGetEncodeGUIDs(encoder,GUIDs,guidCount,&supportedGUID);
if(status!=NV_ENC_SUCCESS)
{
printf("Failure filling the guid buffer");
return EXIT_FAILURE;
}
//setting the encode guid
GUID encodeGuid = NV_ENC_CODEC_H264_GUID;
//settin up the presets
uint32_t encodePresetCount;
status =nvencFunctionList.nvEncGetEncodePresetCount(encoder,encodeGuid,&encodePresetCount);
if(status!=NV_ENC_SUCCESS)
{
printf("Failure getting the encoder preset count");
return EXIT_FAILURE;
}
//allocating a buffer to hold the suppoting preset guid
GUID *presetGUIDs = malloc(encodePresetCount*sizeof(GUID));
uint32_t supportedPresetGUIDs;
status =nvencFunctionList.nvEncGetEncodePresetGUIDs(encoder,encodeGuid,presetGUIDs,encodePresetCount,&supportedPresetGUIDs);
if(status!=NV_ENC_SUCCESS)
{
printf("Failure filling up the preset buffer");
return EXIT_FAILURE;
}
//getting a preset guid Note - check this line later
GUID presetGuid = NV_ENC_PRESET_LOW_LATENCY_HQ_GUID;
//setting up a preset congif Note - check this
NV_ENC_PRESET_CONFIG encPresetConfig;
encPresetConfig.version = NV_ENC_PRESET_CONFIG_VER;
encPresetConfig.presetCfg.version=NV_ENC_CONFIG_VER;
status = nvencFunctionList.nvEncGetEncodePresetConfig(encoder,encodeGuid,presetGuid,&encPresetConfig);
if(status!=NV_ENC_SUCCESS)
{
printf("Error getting the preset configuration");
return EXIT_FAILURE;
}
//getting the input format which is YUV for our solution
//retrieving the input formats
uint32_t inputFormatCount;
status = nvencFunctionList.nvEncGetInputFormatCount(encoder,encodeGuid,&inputFormatCount);
if(status!=NV_ENC_SUCCESS)
{
printf("Error getting the input buffer format count");
return EXIT_FAILURE;
}
//allocating a buffer for the input formats
NV_ENC_BUFFER_FORMAT* encodeBufferFormats = malloc(inputFormatCount*sizeof(encodeBufferFormats));
//holding the size of the supported formats
uint32_t supportedInputFormats;
//filling up the above buffer
status = nvencFunctionList.nvEncGetInputFormats(encoder,encodeGuid, encodeBufferFormats,inputFormatCount,&supportedInputFormats);
if(status!=NV_ENC_SUCCESS)
{
printf("Error getting the supported input formats");
return EXIT_FAILURE;
}
//selecting a buffer format
//NV_ENC_BUFFER_FORMAT bufferFormat = NV_ENC_BUFFER_FORMAT_IYUV;
//querying the underlying hardware encoder capabilities can be done using the API
//initializing the hardware encoder
NV_ENC_INITIALIZE_PARAMS initializationParams;
/* NV_ENC_PRESET_CONFIG presetConfig;
presetConfig.version = NV_ENC_PRESET_CONFIG_VER;
NV_ENC_CONFIG encoderConfig;
encoderConfig.version = NV_ENC_CONFIG_VER;
encoderConfig.profileGUID=NV_ENC_CODEC_PROFILE_AUTOSELECT_GUID;
presetConfig.presetCfg=encoderConfig;
status = nvencFunctionList.nvEncGetEncodePresetConfig(encoder,encodeGuid,presetGuid,&presetConfig);*/
if(status!=NV_ENC_SUCCESS)
{
printf("\nUnable to get preset config %u",status);
return EXIT_FAILURE;
}
//initializing the encoder params
initializationParams.version = NV_ENC_INITIALIZE_PARAMS_VER;
initializationParams.encodeConfig = &encPresetConfig.presetCfg;
initializationParams.encodeGUID = encodeGuid;
initializationParams.presetGUID=presetGuid;
initializationParams.encodeWidth = 600;
initializationParams.encodeHeight = 600;
initializationParams.frameRateNum = 60;
initializationParams.frameRateDen = 1;
initializationParams.enablePTD=1;
status = nvencFunctionList.nvEncInitializeEncoder(encoder,&initializationParams);
if(status!=NV_ENC_SUCCESS)
{
printf("Error initializing encoder, %u",status);
return EXIT_FAILURE;
}
//allocating the nvidia input output buffers
int num_macroblocks = ((600 + 15) / 16) * ((600 + 15) / 16);
int max_surfaces = (num_macroblocks >= 8160) ? 16 : 32;
NV_ENC_INPUT_PTR* inputBuffers = (NV_ENC_INPUT_PTR*) malloc(max_surfaces * sizeof(NV_ENC_INPUT_PTR));
NV_ENC_OUTPUT_PTR* outputBuffers = (NV_ENC_OUTPUT_PTR*) malloc(max_surfaces * sizeof(NV_ENC_OUTPUT_PTR));
//CUdeviceptr* cudaDevicePtrs = (CUdeviceptr*) malloc(max_surfaces*sizeof(CUdeviceptr));
for(int i=0;i<max_surfaces;i++)
{
//creating the input buffer
NV_ENC_CREATE_INPUT_BUFFER inputBufferParams;
inputBufferParams.version = NV_ENC_CREATE_INPUT_BUFFER_VER;
inputBufferParams.width =(600 + 31) & ~31;
inputBufferParams.height=(600 + 31) & ~31;
inputBufferParams.bufferFmt = NV_ENC_BUFFER_FORMAT_IYUV;
inputBufferParams.reserved=0;
memset(inputBufferParams.reserved1,0,57*sizeof(uint32_t));
memset(inputBufferParams.reserved2,NULL,63*sizeof(void*));
status = nvencFunctionList.nvEncCreateInputBuffer(encoder,&inputBufferParams);
if(status!=NV_ENC_SUCCESS)
{
printf("Input buffer could not be created");
return EXIT_FAILURE;
}
//creating the output buffer
NV_ENC_CREATE_BITSTREAM_BUFFER bitstreamBufferParams;
bitstreamBufferParams.version = NV_ENC_CREATE_BITSTREAM_BUFFER_VER;
bitstreamBufferParams.reserved=0;
memset(bitstreamBufferParams.reserved1,0,58*sizeof(uint32_t));
memset(bitstreamBufferParams.reserved2,NULL,64*sizeof(void*));
//This line is giving me the error, NV_ENC_ERR_UNIMPLEMENTED
status = nvencFunctionList.nvEncCreateBitstreamBuffer(encoder,&bitstreamBufferParams);
if(status!=NV_ENC_SUCCESS)
{
printf("Bitstream could not be created %i",status);
return EXIT_FAILURE;
}
/* CUresult cuResult = cuGetDevicePtr(&cudaDevicePtrs[i],600);
if(cuResult!=CUDA_SUCCESS)
{
printf("Could not allocate cuda device pointer, %u\n",cuResult);
return EXIT_FAILURE;
}*/
inputBuffers[i]=inputBufferParams.inputBuffer;
outputBuffers[i]=bitstreamBufferParams.bitstreamBuffer;
}
/*
* Resolve the 'NvFBCCreateInstance' symbol that will allow us to get
* the API function pointers.
*/
NvFBCCreateInstance_ptr =
(PNVFBCCREATEINSTANCE) dlsym(libNVFBC, "NvFBCCreateInstance");
if (NvFBCCreateInstance_ptr == NULL) {
fprintf(stderr, "Unable to resolve symbol 'NvFBCCreateInstance'\n");
return EXIT_FAILURE;
}
/*
* Create an NvFBC instance.
*
* API function pointers are accessible through pFn.
*/
memset(&pFn, 0, sizeof(pFn));
pFn.dwVersion = NVFBC_VERSION;
fbcStatus = NvFBCCreateInstance_ptr(&pFn);
if (fbcStatus != NVFBC_SUCCESS) {
fprintf(stderr, "Unable to create NvFBC instance (status: %d)\n",
fbcStatus);
return EXIT_FAILURE;
}
/*
* Create a session handle that is used to identify the client.
*/
memset(&createHandleParams, 0, sizeof(createHandleParams));
createHandleParams.dwVersion = NVFBC_CREATE_HANDLE_PARAMS_VER;
fbcStatus = pFn.nvFBCCreateHandle(&fbcHandle, &createHandleParams);
if (fbcStatus != NVFBC_SUCCESS) {
fprintf(stderr, "%s\n", pFn.nvFBCGetLastErrorStr(fbcHandle));
return EXIT_FAILURE;
}
/*
* Get information about the state of the display driver.
*
* This call is optional but helps the application decide what it should
* do.
*/
memset(&statusParams, 0, sizeof(statusParams));
statusParams.dwVersion = NVFBC_GET_STATUS_PARAMS_VER;
fbcStatus = pFn.nvFBCGetStatus(fbcHandle, &statusParams);
if (fbcStatus != NVFBC_SUCCESS) {
fprintf(stderr, "%s\n", pFn.nvFBCGetLastErrorStr(fbcHandle));
return EXIT_FAILURE;
}
if (printStatusOnly) {
NvFBCUtilsPrintStatus(&statusParams);
return EXIT_SUCCESS;
}
if (statusParams.bCanCreateNow == NVFBC_FALSE) {
fprintf(stderr, "It is not possible to create a capture session "
"on this system.\n");
return EXIT_FAILURE;
}
if (trackingType == NVFBC_TRACKING_OUTPUT) {
if (!statusParams.bXRandRAvailable) {
fprintf(stderr, "The XRandR extension is not available.\n");
fprintf(stderr, "It is therefore not possible to track an RandR output.\n");
return EXIT_FAILURE;
}
outputId = NvFBCUtilsGetOutputId(statusParams.outputs,
statusParams.dwOutputNum,
outputName);
if (outputId == 0) {
fprintf(stderr, "RandR output '%s' not found.\n", outputName);
return EXIT_FAILURE;
}
}
/*
* Create a capture session.
*/
printf("Creating an asynchronous capture session of %u frames with 1 "
"second internal between captures.\n", nFrames);
memset(&createCaptureParams, 0, sizeof(createCaptureParams));
createCaptureParams.dwVersion = NVFBC_CREATE_CAPTURE_SESSION_PARAMS_VER;
createCaptureParams.eCaptureType = NVFBC_CAPTURE_SHARED_CUDA;
createCaptureParams.bWithCursor = NVFBC_TRUE;
createCaptureParams.frameSize = frameSize;
createCaptureParams.eTrackingType = trackingType;
if (trackingType == NVFBC_TRACKING_OUTPUT) {
createCaptureParams.dwOutputId = outputId;
}
fbcStatus = pFn.nvFBCCreateCaptureSession(fbcHandle, &createCaptureParams);
if (fbcStatus != NVFBC_SUCCESS) {
fprintf(stderr, "%s\n", pFn.nvFBCGetLastErrorStr(fbcHandle));
return EXIT_FAILURE;
}
/*
* Set up the capture session.
*/
memset(&setupParams, 0, sizeof(setupParams));
setupParams.dwVersion = NVFBC_TOCUDA_SETUP_PARAMS_VER;
setupParams.eBufferFormat = bufferFormat;
fbcStatus = pFn.nvFBCToCudaSetUp(fbcHandle, &setupParams);
if (fbcStatus != NVFBC_SUCCESS) {
fprintf(stderr, "%s\n", pFn.nvFBCGetLastErrorStr(fbcHandle));
return EXIT_FAILURE;
}
/*
* We are now ready to start grabbing frames.
*/
fd = fopen(videoFile, "wb");
if (fd == NULL)
{
fprintf(stderr,"Unable to create '%s'\n", videoFile);
return EXIT_FAILURE;
}
//configuring the per frame encode parameters
NV_ENC_PIC_PARAMS encoderPicParams;
//Codec specific params
/* NV_ENC_CODEC_PIC_PARAMS h264Params;
h264Params.h264PicParams.reserved3=0;
h264Params.h264PicParams.reservedBitFields=0;
h264Params.h264PicParams.ltrUsageMode=0;
memset(h264Params.h264PicParams.reserved,0,242*sizeof(uint32_t));
memset(h264Params.h264PicParams.reserved2,NULL,61*sizeof(void*));*/
encoderPicParams.version = NV_ENC_PIC_PARAMS_VER;
//encoderPicParams.codecPicParams=h264Params;
encoderPicParams.inputWidth=(600+ 31) & ~31;
encoderPicParams.inputHeight=(600+ 31) & ~31;
encoderPicParams.inputPitch = (600+ 31) & ~31;
//encoderPicParams.encodePicFlags=NV_ENC_PIC_FLAG_FORCEIDR;
//encoderPicParams.bufferFmt=NV_ENC_BUFFER_FORMAT_IYUV;
encoderPicParams.pictureStruct=NV_ENC_PIC_STRUCT_FRAME;
for (i = 0; i < 60; i++) {
static CUdeviceptr cuDevicePtr;
static unsigned char *frame = NULL;
static uint32_t lastByteSize = 0;
//char filename[64];
int index=i;
if(i>=max_surfaces)
{
index=i%max_surfaces;
}
int res;
uint64_t t1, t2, t1_total, t2_total, t_delta, wait_time_ms;
CUresult cuRes;
NVFBC_TOCUDA_GRAB_FRAME_PARAMS grabParams;
NVFBC_FRAME_GRAB_INFO frameInfo;
t1 = NvFBCUtilsGetTimeInMillis();
t1_total = t1;
memset(&grabParams, 0, sizeof(grabParams));
memset(&frameInfo, 0, sizeof(frameInfo));
grabParams.dwVersion = NVFBC_TOCUDA_GRAB_FRAME_PARAMS_VER;
/*
* Use asynchronous calls.
*
* The application will not wait for a new frame to be ready. It will
* capture a frame that is already available. This might result in
* capturing several times the same frame. This can be detected by
* checking the frameInfo.bIsNewFrame structure member.
*/
grabParams.dwFlags = NVFBC_TOCUDA_GRAB_FLAGS_NOWAIT;
/*
* This structure will contain information about the captured frame.
*/
grabParams.pFrameGrabInfo = &frameInfo;
/*
* The frame will be mapped in video memory through this CUDA
* device pointer.
*/
grabParams.pCUDADeviceBuffer = &cuDevicePtr;
/*
* Capture a frame.
*/
fbcStatus = pFn.nvFBCToCudaGrabFrame(fbcHandle, &grabParams);
if (fbcStatus != NVFBC_SUCCESS) {
fprintf(stderr, "%s\n", pFn.nvFBCGetLastErrorStr(fbcHandle));
return EXIT_FAILURE;
}
t2 = NvFBCUtilsGetTimeInMillis();
/*
* Allocate or re-allocate the destination buffer in system memory
* when necessary.
*
* This is to handle change of resolution.
*/
if (lastByteSize < frameInfo.dwByteSize) {
frame = (unsigned char *)realloc(frame, frameInfo.dwByteSize);
if (frame == NULL) {
fprintf(stderr, "Unable to allocate system memory\n");
return EXIT_FAILURE;
}
printf("Reallocated %u KB of system memory\n",
frameInfo.dwByteSize / 1024);
lastByteSize = frameInfo.dwByteSize;
}
printf("%s id %u grabbed in %llu ms",
(frameInfo.bIsNewFrame ? "New frame" : "Frame"),
frameInfo.dwCurrentFrame,
(unsigned long long) (t2 - t1));
/*
* Download frame from video memory to system memory.
*/
t1 = NvFBCUtilsGetTimeInMillis();
cuRes = cuMemcpyDtoH_v2_ptr((void *) frame, cuDevicePtr,
frameInfo.dwByteSize);
if (cuRes != CUDA_SUCCESS) {
fprintf(stderr, "CUDA memcpy failure (result: %d)\n", cuRes);
return EXIT_FAILURE;
}
//creating the params for the nv enc lock input buffer
//inputBufferParams.pSysMemBuffer=(void*) frame;
//status = nvencFunctionList.nvEncCreateInputBuffer(encoder,&inputBufferParams);
//setting up the input params
NV_ENC_REGISTER_RESOURCE registerResource;
registerResource.version=NV_ENC_REGISTER_RESOURCE_VER;
registerResource.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR;
registerResource.width = (600+31)&~31;
registerResource.height=(600+31)&~31;
registerResource.pitch=(600+31)&~31;
registerResource.resourceToRegister = (void*)cuDevicePtr;
registerResource.bufferFormat = NV_ENC_BUFFER_FORMAT_NV12;
status = nvencFunctionList.nvEncRegisterResource(encoder,&registerResource);
if(status!=NV_ENC_SUCCESS)
{
printf("Failed to register resource, %u",status);
return EXIT_FAILURE;
}
//mapping these resources
NV_ENC_MAP_INPUT_RESOURCE mappedResource;
mappedResource.version = NV_ENC_MAP_INPUT_RESOURCE_VER;
mappedResource.registeredResource=registerResource.registeredResource;
status = nvencFunctionList.nvEncMapInputResource(encoder,&mappedResource);
if(status!=NV_ENC_SUCCESS)
{
printf("Could not map resource: %u,",status);
return EXIT_FAILURE;
}
encoderPicParams.outputBitstream=outputBuffers[index];
encoderPicParams.inputBuffer=mappedResource.mappedResource;
encoderPicParams.bufferFmt=mappedResource.mappedBufferFmt;
/* memset(encoderPicParams.reserved1,0,6*sizeof(uint32_t));
memset(encoderPicParams.reserved2,NULL,2*sizeof(void*));
memset(encoderPicParams.reserved3,0,286*sizeof(uint32_t));
memset(encoderPicParams.reserved4,0,60*sizeof(void*));*/
//sending the picture to be encoded
status=nvencFunctionList.nvEncEncodePicture(encoder,&encoderPicParams);
if(status!=NV_ENC_SUCCESS)
{
printf("\n Unable to encode video, Error code: %u",status);
return EXIT_FAILURE;
}
//setting up the lock bitstream params
//sending the data to the output stream
NV_ENC_LOCK_BITSTREAM lockBitstreamParams;
lockBitstreamParams.version=NV_ENC_LOCK_BITSTREAM_VER;
lockBitstreamParams.doNotWait=0;
lockBitstreamParams.outputBitstream=outputBuffers[index];
lockBitstreamParams.reservedBitFields=0;
memset(lockBitstreamParams.reserved,0,219*sizeof(uint32_t));
memset(lockBitstreamParams.reserved1,0,13*sizeof(uint32_t));
memset(lockBitstreamParams.reserved2,NULL,64*sizeof(uint32_t));
status = nvencFunctionList.nvEncLockBitstream(encoder,&lockBitstreamParams);
if(status!=NV_ENC_SUCCESS)
{
printf("error locking bitstream");
return EXIT_FAILURE;
}
//writing the video data to the file
int bytes = fwrite(lockBitstreamParams.bitstreamBufferPtr,1,lockBitstreamParams.bitstreamSizeInBytes ,fd);
printf("\nNumber of bytes: %u\n",bytes);
if(bytes==0)
{
fprintf(stderr, "Unable to write to '%s'\n", videoFile);
return EXIT_FAILURE;
}
status = nvencFunctionList.nvEncUnlockBitstream(encoder,outputBuffers[index]);
status = nvencFunctionList.nvEncUnmapInputResource(encoder,mappedResource.mappedResource);
if(status!=NV_ENC_SUCCESS)
{
printf("failure to map resource, %u",status);
return EXIT_FAILURE;
}

LNK2005 and LNK 1160 in vc++

I'm new to c++ and vc++ and i used 3rd party library bioapi. I successfully integrated it but when I tried to use the sample working program of bioapi, the misc.h and misc.cpp, i got an error LNK2005 AND LNK1160.
By the way I created this as CLR project in vc++ and it seems I cannot use /FORCE or /FORCE:MULTIPLE.
Here's the misc.h
/*---------------------------------------------------------------*/
/* */
/* Copyright (C) NEC Corporation 2011 */
/* NEC CONFIDENTIAL AND PROPRIETARY */
/* */
/* All rights reserved by NEC Corporation. This program must be */
/* used solely for the purpose for which it was furnished by NEC */
/* Corporation. No part of this program may be reproduced or */
/* disclosed to others, in any form, without the prior written */
/* permission of NEC Corporation. Use of copyright notice does */
/* not evidence publication of this program. */
/* */
/* NEC Corporation accepts no responsibility for any damages */
/* resulting from the use of this sample code. */
/* This sample code is provided "AS IS", and its user assume all */
/* risks when using it. */
/* */
/*---------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <sys/types.h> /* for stat() */
#include <sys/stat.h> /* for stat() */
#include <direct.h> /* for _mkdir() */
//#include "stdafx.h"
//#include "resource.h"
#include "BioAPI.h" /* include BioAPI Framework */
#include "BioAPI_util.h" /* include BioAPI Framework */
#include "hf-pid-bsp.h"
/*--------------------------------------------------------------------
*
* define
*
*--------------------------------------------------------------------*/
#define MaxN 1000 /* Max Identify Num */
#define MaxEnrollNum 999 /* Max Enroll Num */
#define MaxID 9999 /* Max Enroll ID */
#define MinID 0 /* Min Enroll ID */
#define Timeout 10000 /* Capture Timeout */
#define ERRCODE_ID_INPUT_ERROR -100
#define ERRCODE_NOT_ENROLLED -101
#define SECTION_IDENTIFYPARAM "IdentifyParam"
#define KEY_MAXNUMBEROFRESULTS "MaxNumberOfResults"
#define MESS_ALLEADY_STARTED "Application is already started."
#define MESS_USERREG "UserReg"
#define MESS_AP_ERROR "Error"
#define MESS_ID_INPUT_ERROR TEXT("Please input a value in the range of 0001-9999")
#define MESS_NOT_ENROLLED TEXT("The ID does not exist for")
#define MESS_BIOAPI_ERROR TEXT("BioAPI Error")
#define MESS_BIOAPI_ERROR_CODE TEXT("BioAPI Error Code: %ld")
#define MESS_ENROLL "Enrollment"
#define MESS_ENROLL_FAILED "Enroll process is failed."
#define MESS_ENROLL_SUCCESSED "Enroll process is successed."
#define MESS_VERIFY "Verification"
#define MESS_VERIFY_FAILED "Verification failed."
#define MESS_VERIFY_OK "Verification process is successed."
#define MESS_VERIFY_NG "Verification process is failed."
#define MESS_IDENTIFY "Identification"
#define MESS_IDENTIFY_FAILED "Identification failed."
#define MESS_IDENTIFY_OK "Identification process is successed."
#define MESS_IDENTIFY_NG "Identification process is failed."
#define MESS_CAPTION "Sample Application"
#define MESS_END "Exit"
#define MESS_MESSAGE1 "Please choose the function."
#define MESS_CLOSE "Close"
#define MESS_ENROLL1 "Enroll"
#define MESS_ENROLL2 "CreateTemplate"
#define MESS_MESSAGE2 "After entering ID(0001`9999), Please click [Enroll] button or [CreateTemplate] button."
#define MESS_ID "ID:"
#define MESS_ONETOONE "1:1 Verification"
#define MESS_ONETON "1:N Identification"
#define MESS_MESSAGE3 "Please choose the verification method."
#define MESS_VERIFY1 "VerifyMatch"
#define MESS_VERIFY2 "Verify"
#define MESS_MESSAGE4 "After entering ID(0001`9999), Please click [Verify] button or [Verification] button."
#define MESS_IDENTIFY1 "IdentifyMatch"
#define MESS_IDENTIFY2 "Identify"
#define MESS_MESSAGE5 "Please click [Identify] button or [Identification] button."
#define MESS_AUTH_MESSAGE "Identification process is successed.\r\nMaxNumberOfResults = (%d)\r\nNumberOfResults = (%d)\r\nID:"
#define MESS_INIFILE_GET_FAILED "sample.ini get failed."
#define PATH_ENROLLED_FILE ".\\enroll\\*.dat"
#define PATH_ENROLLED_FILE_IN_ID ".\\enroll\\%04d_*.dat"
#define PATH_ENROLLED_DIRECTORY ".\\enroll"
#define PATH_ENROLLED_NAME TEXT(".\\enroll\\%s_%03d.dat")
#define PATH_ENROLLED_DIRECTORY ".\\enroll"
#define INIFILE_NAME ".\\sample.ini"
/*--------------------------------------------------------------------
*
* global
*
*--------------------------------------------------------------------*/
static BioAPI_HANDLE gModuleHandle;
static BioAPI_RETURN bioReturn;
static BioAPI_BIR_HANDLE StoredTemplate;
static BioAPI_INPUT_BIR CapturedBIR;
static BioAPI_INPUT_BIR ProcessedBIR;
static BioAPI_INPUT_BIR StoredBIR;
static BioAPI_BIR_HANDLE CapturedTemplate;
static BioAPI_BOOL boolie = BioAPI_FALSE;
static BioAPI_BOOL result;
static BioAPI_FRR frr = HF_PID_BSP_LEVEL_MIDDLE; // Security Level
static BioAPI_FAR AchievedFAR = 1;
static uint32 MaxNumberOfResults = 1;
static uint32 NumberOfResults;
static BioAPI_CANDIDATE_ARRAY_PTR Candidates;
static BioAPI_INPUT_BIR InputBirProcessed_PopulationElem[MaxN];
static BioAPI_IDENTIFY_POPULATION *Population;
static BioAPI_BIR_PTR lpPopulationAryBIRData_Member;
static HANDLE hSearch;
static char fname_db[MAX_PATH + 1];
static char fid_db[MAX_PATH + 1];
static WIN32_FIND_DATA fd;
static BioAPI_BIR_ARRAY_POPULATION lPopulationAryBIRData;
static BioAPI_BIR_PTR FullBIR;
static BioAPI_UUID BSPUuid = HF_PID_BSP_UUID;
typedef struct stBIR_AND_FileName {
BioAPI_BIR* pPopulationBIRPointer;
char lptszUserName[_MAX_PATH];
}BIR_AND_FILENAME;
static BIR_AND_FILENAME RetBIR_And_FileName[MaxN];
static BioAPI_CANDIDATE_ARRAY lpWorkCandidates;
static char IdentificationMessage[MAX_PATH + 1];
/*--------------------------------------------------------------------
*
* function
*
*--------------------------------------------------------------------*/
void PrintErrorCode(BioAPI_RETURN bioReturn);
void LoadBSP(BioAPI_HANDLE_PTR gModuleHandle);
void ReleaseBSP(BioAPI_HANDLE_PTR gModuleHandle);
BioAPI_RETURN OutputToFile(BioAPI_HANDLE gModuleHandle, LPTSTR lptszUserName, BioAPI_BIR_HANDLE BirHandle);
BioAPI_RETURN InputFromFile(LPTSTR lptszUserName, BioAPI_INPUT_BIR * InputBir, uint32 count);
/*--------------------------------------------------------------------
*
* End of misc.h
*
*--------------------------------------------------------------------*/
misc.cpp
/*---------------------------------------------------------------*/
/* */
/* Copyright (C) NEC Corporation 2011 */
/* NEC CONFIDENTIAL AND PROPRIETARY */
/* */
/* All rights reserved by NEC Corporation. This program must be */
/* used solely for the purpose for which it was furnished by NEC */
/* Corporation. No part of this program may be reproduced or */
/* disclosed to others, in any form, without the prior written */
/* permission of NEC Corporation. Use of copyright notice does */
/* not evidence publication of this program. */
/* */
/* NEC Corporation accepts no responsibility for any damages */
/* resulting from the use of this sample code. */
/* This sample code is provided "AS IS", and its user assume all */
/* risks when using it. */
/* */
/*---------------------------------------------------------------*/
//#include "stdafx.h"
#include "misc.h"
/*--------------------------------------------------------------------
*
* PrintErrorCode
*
*--------------------------------------------------------------------*/
void PrintErrorCode(
BioAPI_RETURN bioReturn /* INPUT : BioAPI Error Code */
)
{
TCHAR szMessage[_MAX_PATH];
// ID Input Error
if (bioReturn == ERRCODE_ID_INPUT_ERROR)
{
wsprintf(szMessage, MESS_ID_INPUT_ERROR);
MessageBox(GetActiveWindow(), szMessage, MESS_BIOAPI_ERROR, MB_OK | MB_ICONSTOP);
}
// Not Enrolled Error
else if (bioReturn == ERRCODE_NOT_ENROLLED)
{
wsprintf(szMessage, MESS_NOT_ENROLLED);
MessageBox(GetActiveWindow(), szMessage, MESS_BIOAPI_ERROR, MB_OK | MB_ICONSTOP);
}
// BioAPI Error
else
{
wsprintf(szMessage, MESS_BIOAPI_ERROR_CODE, bioReturn);
MessageBox(GetActiveWindow(), szMessage, MESS_BIOAPI_ERROR, MB_OK | MB_ICONSTOP);
}
return;
}
/*--------------------------------------------------------------------
*
* LoadBSP
*
*--------------------------------------------------------------------*/
void LoadBSP(
BioAPI_HANDLE_PTR gModuleHandle /* INPUT : BSP Module Handle */
)
{
BioAPI_VERSION bioVersion;
bioVersion.Major = BioAPI_MAJOR;
bioVersion.Minor = BioAPI_MINOR;
bioReturn = BioAPI_Init(&bioVersion, 0, NULL, 0, NULL);
if (BioAPI_OK != bioReturn)
{
PrintErrorCode(bioReturn);
return;
}
bioReturn = BioAPI_ModuleLoad(&BSPUuid, 0, NULL, 0);
if (BioAPI_OK != bioReturn)
{
PrintErrorCode(bioReturn);
return;
}
bioReturn = BioAPI_ModuleAttach(&BSPUuid, &bioVersion, &BioAPIWinMemoryFuncs, 0, 0, 0, 0, NULL, 0, NULL, gModuleHandle);
if (BioAPI_OK != bioReturn)
{
PrintErrorCode(bioReturn);
return;
}
return;
}
/*--------------------------------------------------------------------
*
* ReleaseBSP
*
*--------------------------------------------------------------------*/
void ReleaseBSP(
BioAPI_HANDLE_PTR gModuleHandle /* INPUT : BSP Module Handle */
)
{
if (gModuleHandle != 0)
{
bioReturn = BioAPI_ModuleDetach(*gModuleHandle);
if (BioAPI_OK != bioReturn)
{
PrintErrorCode(bioReturn);
return;
}
gModuleHandle = 0;
}
bioReturn = BioAPI_ModuleUnload(&BSPUuid, NULL, 0);
if (BioAPI_OK != bioReturn)
{
PrintErrorCode(bioReturn);
return;
}
bioReturn = BioAPI_Terminate();
if (BioAPI_OK != bioReturn)
{
PrintErrorCode(bioReturn);
return;
}
return;
}
/*--------------------------------------------------------------------
*
* OutputToFile
*
*--------------------------------------------------------------------*/
BioAPI_RETURN OutputToFile(
BioAPI_HANDLE gModuleHandle, /* INPUT : BSP Module Handle */
LPTSTR lptszUserName, /* INPUT : Save File Neme */
BioAPI_BIR_HANDLE BirHandle /* INPUT : Save BIR Data */
)
{
TCHAR szFileName[_MAX_PATH];
HANDLE hFile;
DWORD dwBytesToWrite, dwBytesWritten;
BioAPI_BIR_PTR birData = NULL;
BioAPI_RETURN bioReturn;
uint32 count = 0;
struct stat buff;
// Retrieve the BIR from the BSP
bioReturn = BioAPI_GetBIRFromHandle(gModuleHandle, BirHandle, &birData);
if (bioReturn != BioAPI_OK)
{
return bioReturn;
}
// Search Save FileName
_mkdir(PATH_ENROLLED_DIRECTORY);
while (1)
{
if (++count > MaxEnrollNum)
{
return -1; // Can't make file
}
wsprintf(szFileName, PATH_ENROLLED_NAME, lptszUserName, count);
if ((stat(szFileName, &buff) != 0))
{
break;
}
}
// Open the file
hFile = CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return 0; // this return value is ignored anyway
}
// Write the header
WriteFile(hFile, &(birData->Header), sizeof(BioAPI_BIR_HEADER), &dwBytesWritten, NULL);
// Write the biometric data
dwBytesToWrite = LocalEndian4(birData->Header.Length) - sizeof(BioAPI_BIR_HEADER);
WriteFile(hFile, birData->BiometricData, dwBytesToWrite, &dwBytesWritten, NULL);
// Write the signature if present
if (birData->Signature)
{
WriteFile(hFile, &(birData->Signature->Length), 4, &dwBytesWritten, NULL);
dwBytesToWrite = LocalEndian4(birData->Signature->Length);
WriteFile(hFile, birData->Signature->Data, dwBytesToWrite, &dwBytesWritten, NULL);
}
// Close the file
CloseHandle(hFile);
// Free all the memory allocated for the BIR
if (birData != NULL) {
GlobalFree(birData->BiometricData);
if (birData->Signature)
{
GlobalFree(birData->Signature->Data);
GlobalFree(birData->Signature);
}
GlobalFree(birData);
}
return BioAPI_OK;
}
/*--------------------------------------------------------------------
*
* InputFromFile
*
*--------------------------------------------------------------------*/
BioAPI_RETURN InputFromFile(
LPTSTR lptszUserName, /* INPUT : Load File Name */
BioAPI_INPUT_BIR * InputBir, /* OUTPUT : Load BIR Data */
uint32 count /* INPUT : User Enroll Number */
)
{
TCHAR szFileName[_MAX_PATH];
HANDLE hFile;
DWORD dwBytesToRead, dwBytesRead;
BioAPI_BIR *bir;
// Open the file
wsprintf(szFileName, PATH_ENROLLED_NAME, lptszUserName, count);
hFile = CreateFile(szFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return BioAPIERR_BSP_RECORD_NOT_FOUND; // Return this BSP error if the file isn't present
}
// Read the header in, to determine the size
dwBytesToRead = sizeof(BioAPI_BIR_HEADER);
bir = (BioAPI_BIR*)GlobalAlloc(GPTR, sizeof(BioAPI_BIR));
if (!bir)
{
return !BioAPI_OK;
}
ReadFile(hFile, &(bir->Header), dwBytesToRead, &dwBytesRead, NULL);
// Read the biometric data
dwBytesToRead = LocalEndian4(bir->Header.Length) - sizeof(BioAPI_BIR_HEADER);
bir->BiometricData = (BioAPI_BIR_BIOMETRIC_DATA_PTR)GlobalAlloc(GPTR, dwBytesToRead);
if (!bir->BiometricData)
{
return !BioAPI_OK;
}
ReadFile(hFile, bir->BiometricData, dwBytesToRead, &dwBytesRead, NULL);
// Read the signature if present
dwBytesToRead = 0;
if (ReadFile(hFile, &dwBytesToRead, 4, &dwBytesRead, NULL) != 0 && dwBytesToRead != 0)
{
bir->Signature = (BioAPI_DATA_PTR)GlobalAlloc(GPTR, sizeof(BioAPI_DATA));
if (!bir->Signature)
{
return !BioAPI_OK;
}
bir->Signature->Length = dwBytesToRead;
dwBytesToRead = LocalEndian4(dwBytesToRead);
bir->Signature->Data = (uint8 *)GlobalAlloc(GPTR, dwBytesToRead);
if (!bir->Signature->Data)
{
return !BioAPI_OK;
}
ReadFile(hFile, bir->Signature->Data, dwBytesToRead, &dwBytesRead, NULL);
}
// Close the file
CloseHandle(hFile);
// Set up the return values
InputBir->InputBIR.BIR = bir;
InputBir->Form = BioAPI_FULLBIR_INPUT;
return BioAPI_OK;
}
/*--------------------------------------------------------------------
*
* End of misc.cpp
*
*--------------------------------------------------------------------*/
Errors:
1>libucrt.lib(exit.obj) : error LNK2005: _cexit already defined in ucrtd.lib(ucrtbased.dll)
1>libucrt.lib(onexit.obj) : error LNK2005: _crt_at_quick_exit already defined in ucrtd.lib(ucrtbased.dll)
1>libucrt.lib(onexit.obj) : error LNK2005: _crt_atexit already defined in ucrtd.lib(ucrtbased.dll)
1>libucrt.lib(onexit.obj) : error LNK2005: _execute_onexit_table already defined in ucrtd.lib(ucrtbased.dll)
1>libucrt.lib(onexit.obj) : error LNK2005: _initialize_onexit_table already defined in ucrtd.lib(ucrtbased.dll)
1>libucrt.lib(onexit.obj) : error LNK2005: _register_onexit_function already defined in ucrtd.lib(ucrtbased.dll)
1>libucrt.lib(environment_initialization.obj) : error LNK2005: _initialize_narrow_environment already defined in ucrtd.lib(ucrtbased.dll)
1>libucrt.lib(exception_filter.obj) : error LNK2005: _seh_filter_dll already defined in ucrtd.lib(ucrtbased.dll)
1>LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library
1>LINK : warning LNK4098: defaultlib 'ucrtd.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
1>C:\Users\Laptop-attendance\source\repos\Bioapitest\x64\Debug\Bioapitest.exe : fatal error LNK1169: one or more multiply defined symbols found

Sending an integer using COM4

#include <dos.h>
#include <stdio.h>
#include <conio.h>
#define PORT1 0x2E8 /* Port Address Goes Here */
/* Defines Serial Ports Base Address */
/* COM4 0x2E8 */
#define INTVECT 0x0B /* Com Port's IRQ here */
/* (Must also change PIC setting) */
int bufferin = 0;
int bufferout = 0;
char ch;
char buffer[1025];
void interrupt PORT1INT() /* Interrupt Service Routine (ISR) for PORT1 */
{
int c;
do {
c = inportb(PORT1 + 5);
if (c & 1) {
buffer[bufferin] = inportb(PORT1);
bufferin++;
if (bufferin == 1024) bufferin = 0;
}
} while (c & 1);
outportb(0x20, 0x20);
}
void main(void)
{
int c;
//outportb(PORT1 + 1, 0); /* Turn off interrupts - Port1 */
//oldport1isr = getvect(INTVECT); /* Save old Interrupt Vector for */
/* later recovery */
setvect(INTVECT, PORT1INT); /* Set Interrupt Vector Entry */
/* COM1 - 0x0C */
/* COM2 - 0x0B */
/* COM3 - 0x0C */
/* COM4 - 0x0B */
outportb(PORT1 +3 , 0x80); /* SET DLAB ON */
outportb(PORT1 +0, 0x03); /* Set Baud rate - Divisor Latch Low Byte */
/* Default 0x03 = 38,400 BPS */
/* 0x01 = 115,200 BPS */
/* 0x02 = 56,700 BPS */
/* 0x06 = 19,200 BPS */
/* 0x0C = 9,600 BPS */
/* 0x18 = 4,800 BPS */
/* 0x30 = 2,400 BPS */
outportb(PORT1 + 1, 0x00); /* Set Baud rate - Divisor Latch High Byte */
outportb(PORT1 + 3, 0x03); /* 8 Bits, No Parity, 1 Stop Bit */
outportb(PORT1 + 2, 0xC7); /* FIFO Control Register */
outportb(PORT1 + 4, 0x0B); /* Turn on DTR, RTS, and OUT2 */
outportb(0x21, (inportb(0x21) & 0xF7)); /* Set Programmable Interrupt */
/* Controller */
/* COM1 (IRQ4) - 0xEF */
/* COM2 (IRQ3) - 0xF7 */
/* COM3 (IRQ4) - 0xEF */
/* COM4 (IRQ3) - 0xF7 */
outportb(PORT1 + 1, 0x01); /* Interrupt when data received */
printf("\nSample Comm's Program. Press ESC to quit \n");
do {
if (bufferin != bufferout){
ch = buffer[bufferout];
bufferout++;
if (bufferout == 1024) bufferout = 0;
printf("%c", ch);
}
if (kbhit()){
c = getch();
outportb(PORT1, c);
}
} while
(c != 27);
outportb(PORT1 + 1, 0); /* Turn off interrupts - Port1 */
outportb(0x21, (inportb(0x21) | 0x08)); /* MASK IRQ using PIC */
/* COM1 (IRQ4) - 0x10 */
/* COM2 (IRQ3) - 0x08 */
/* COM3 (IRQ4) - 0x10 */
/* COM4 (IRQ3) - 0x08 */
setvect(INTVECT, oldport1isr); /* Restore old interrupt vector */
}
So I have to send some data from an UART to an UART using COM4 Serial Port, I have this small program here as an example but can't figure out why I can't compile it in Visual Studion ( C++ Win32 Project )
Any ideas? I also have to implement an timer with RQ3.
It can't compile because access to the hardware is managed by the OS. Your example states in the very first line which OS it applies to, and it's not Windows.
As for your second claim, you don't. IRQ3 is not used for timers in Windows programs. There are plenty of answers about timers already on StackOverflow, so check that first.

Timeout on recvfrom ( winsock2 & udp )

I'm trying to implement a timeout on the recvfrom() function.
To do so, I use the select() function. I take the code from the great Internet, but don't know why, my program crash when I use it.
I launch this server in athread if that coudl help.
Here's what I try to do :
...
// Setup timeval variable
timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
// Setup fd_set structure
fd_set fds;
FD_ZERO(&fds);
FD_SET(id_de_la_socket, &fds);
// Return value:
// -1: error occurred
// 0: timed out
// > 0: data ready to be read
int retval = select(id_de_la_socket+1, &fds, NULL, NULL, &timeout);
if(retval == -1){
printf("Error");
return NULL;
}
else if(retval == 0){
printf("Timeout");
return NULL;
}
else{
nombre_de_caractere=recvfrom(id_de_la_socket,buffer,1515,/*MSG_PARTIAL*/0,(struct sockaddr*)&information_sur_la_source,&tempo);
...
Before trying to implement the timeout, everything works fine, my recvfrom() was in block mode. So I think the problem come from this code that I add. Maybe it's a parameter of a function that I don't understand well.
Thanks for your help.
EDIT : Full code :
#include "serveur.h"
#include <unistd.h>
#include <fcntl.h>
serveur::serveur()
{
}
StructureSupervision::T_StructureSupervision* serveur::receiveDataUDP(){
WSADATA initialisation_win32;
int erreur;
int tempo;
int nombre_de_caractere;
char buffer[65535];
SOCKET id_de_la_socket;
SOCKADDR_IN information_sur_la_source;
erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
if (erreur!=0)
printf("\nDesole, je ne peux pas initialiser Winsock du a l'erreur : %d %d",erreur,WSAGetLastError());
else
printf("\nWSAStartup : OK");
id_de_la_socket=socket(AF_INET,SOCK_DGRAM,0);
if (id_de_la_socket==INVALID_SOCKET)
printf("\nDesole, je ne peux pas creer la socket du a l'erreur : %d",WSAGetLastError());
else
printf("\nsocket : OK");
information_sur_la_source.sin_family=AF_INET;
information_sur_la_source.sin_addr.s_addr = inet_addr("10.100.13.129"); // Ecoute sur toutes les IP locales
information_sur_la_source.sin_port=htons(4000); // Ecoute sur le port 4000
erreur=bind(id_de_la_socket,(struct sockaddr*)&information_sur_la_source,sizeof(information_sur_la_source));
if (erreur!=0)
printf("\nDesole, je ne peux pas ecouter ce port : %d %d",erreur,WSAGetLastError());
else
printf("\nbind : OK \n");
tempo=sizeof(information_sur_la_source); // Passe par une variable afin d'utiliser un pointeur
// Setup timeval variable
timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
// Setup fd_set structure
fd_set fds;
FD_ZERO(&fds);
FD_SET(id_de_la_socket, &fds);
// Return value:
// -1: error occurred
// 0: timed out
// > 0: data ready to be read
ULONG NonBlock = 1; ioctlsocket(id_de_la_socket, FIONBIO, &NonBlock);
int retval = select(id_de_la_socket+1, &fds, NULL, NULL, &timeout);
if(retval == -1){
printf("Error");
return NULL;
}
else if(retval == 0){
printf("Timeout");
return NULL;
}
else{
nombre_de_caractere=recvfrom(id_de_la_socket,buffer,1515,/*MSG_PARTIAL*/0,(struct sockaddr*)&information_sur_la_source,&tempo);
buffer[nombre_de_caractere]=0; // Permet de fermer le tableau apr�s le contenu des data, car la fonction recvfrom ne le fait pas
//printf("\nVoici les donnees : %s",buffer);
StructureSupervision::T_StructureSupervision *structureReception = (StructureSupervision::T_StructureSupervision *) buffer;
std::cout << "Voici le numero de Statut Ground Flight : " << structureReception->SystemData._statutGroundFlight;
erreur=closesocket(id_de_la_socket);
if (erreur!=0)
printf("\nDesole, je ne peux pas liberer la socket du a l'erreur : %d %d",erreur,WSAGetLastError());
else
printf("\nclosesocket : OK");
// ********************************************************
// Quitte proprement le winsock ouvert avec la commande WSAStartup
// ********************************************************
erreur=WSACleanup(); // A appeler autant de fois qu'il a �t� ouvert.
if (erreur!=0)
printf("\nDesole, je ne peux pas liberer winsock du a l'erreur : %d %d",erreur,WSAGetLastError());
else
printf("\nWSACleanup : OK");
return structureReception;
}
}
Thanks for your help, the problem was : This program runs in a loop, so I was opening and closing the socket at the wrong time.