Linked list of leaf files and directories in a dir tree using C - linked-list

I'm using nftw(file tree walk) for traversing a dir(which has sub-directories and files). I've passed a directory using CLI function. Now I need to store the leaf files and dirs(empty dirs) into a linked list and print them out. I've create a function for nftw called as disp & passed it to nftw so that it'll print out some info about the files. The linked list stores the info of file produced by stat & for printing the linked Linked list printll function is used.
For files I can check that typeflag == FTW_F and then enter the following but how do I check empty directories in nftw and add them to the linked list?
I've tried the following
#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <ftw.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
typedef struct node{
long ino; //Inode number
long f_size; //file size
long a_tm; //Access time
long m_tm; //Modify time
long c_tm; //change time
struct node *next;
}node;
node *tmp = NULL;
static node *head = NULL;
void printll(node *head);
//display function
static int disp(const char *fpath,
const struct stat *s,
int typeflag,
struct FTW *ftw);
//Function to create linked list
static int linked(const char *fpath,
const struct stat *s,
int typeflag,
struct FTW *ftw);
/* ------------------Main---------------------*/
int main(int argc, char *argv[]){
int flags = 0;
if(argc > 2 && strchr(argv[2], 'd') != NULL)
flags |= FTW_DEPTH;
printf("File_type\tF_size\t\tPath\t\t\t\t\t\t\tInode\n");
if(nftw((argc < 2) ? "." : argv[1], disp, 20, flags) == -1) {
perror("nftw");
return -1;
}
printf("\n");
// nftw((argc < 2) ? "." : argv[1], linked, 20, flags);
printll(tmp);
exit(EXIT_SUCCESS);
}
static int disp(const char *fpath,
const struct stat *s,
int typeflag,
struct FTW *ftw){
printf("%-3s\t\t%7jd\t\t%-40s\t\t%ld\n",
(typeflag == FTW_D) ? "d" : (typeflag == FTW_F) ? "f": "???",
s->st_size, fpath, s->st_ino);
struct dirent *r;
if(typeflag == FTW_F){ //How to check empty dirs here?
if(head == NULL){
head = malloc(sizeof(node));
head->ino = s->st_ino;
head->f_size = s->st_size;
head->a_tm = s->st_atime;
head->m_tm = s->st_mtime;
head->c_tm = s->st_ctime;
head->next = NULL;
tmp = head;
} else if(head != NULL) {
if(tmp != NULL){
node *ptr = malloc(sizeof(node));
ptr->ino = s->st_ino;
ptr->f_size = s->st_size;
ptr->a_tm = s->st_atime;
ptr->m_tm = s->st_mtime;
ptr->c_tm = s->st_ctime;
ptr->next = NULL;
tmp->next = ptr;
tmp = tmp->next;
}
}
while(tmp != NULL){
printf("%ld\n", tmp->ino);
printf("%ld\n", tmp->f_size);
printf("%ld\n", tmp->a_tm);
printf("%ld\n", tmp->m_tm);
printf("%ld\n", tmp->c_tm);
tmp = tmp->next;
}
}
return 0;
}
void printll(node *head){
node *ptr;
if(head == NULL)
printf("The linked list is NULL\n");
ptr = head;
while(ptr != NULL){
printf("%ld\n", ptr->ino);
printf("%ld\n", ptr->f_size);
printf("%ld\n", ptr->a_tm);
printf("%ld\n", ptr->m_tm);
printf("%ld\n", ptr->c_tm);
ptr = ptr->next;
}
}

Here's the code for creaiting the linked list using ftw
#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <libgen.h>
#include <ftw.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
typedef struct node{
long ino;
long f_size;
long a_tm;
long m_tm;
long c_tm;
struct node *next;
}node;
node *c, *tmp = NULL, *loc;
static node *head = NULL;
void printll(node *head); //printing of linked list
static int disp(const char *fpath,
const struct stat *s,
int typeflag,
struct FTW *ftw);
static int linked(const char *fpath,
const struct stat *s,
int typeflag,
struct FTW *ftw);
void add_at_end(node *p);
/* ------------------Main---------------------*/
int main(int argc, char *argv[]){
int flags = 0;
if(argc > 2 && strchr(argv[2], 'd') != NULL)
flags |= FTW_DEPTH;
printf("File_type\tF_size\t\tPath\t\t\t\t\t\t\tInode\n");
if(nftw((argc < 2) ? "." : argv[1], disp, 20, flags) == -1) {
perror("nftw");
return -1;
}
nftw((argc < 2) ? "." : argv[1], linked, 20, flags);
printf("\n");
printll(tmp);
int num, fd;
char f_name[100], dest[100], str_ent[100];
char c, dl;
struct stat fb;
while(1){
printf("1. Add a file\n");
printf("2. Delete a file\n");
printf("3. Add a directory\n");
printf("4. Delete a directory\n");
printf("Enter the operation num to perform\n");
scanf(" %d", &num);
switch(num){
case 1:
printf("File Name: ");
scanf("%s", f_name);
printf("Destination: ");
scanf("%s", dest);
strcat(dest, f_name);
open(dest, O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
printf("File %s is successfully added.\n", f_name);
printf("Do you want to write to this file (Y/N)? \n");
scanf(" %c", &c);
if(c == 'y' || c == 'Y'){
FILE *f;
f = fopen(dest, "w");
printf("How many lines do you want to enter: ");
scanf("%d", &num);
printf("Enter content\n");
for(int i = 0; i < num+1; i++){
fgets(str_ent, sizeof str_ent, stdin);
fputs(str_ent, f);
}
printf("The content you entered is written to the file\n");
fclose(f);
stat(dest, &fb);
loc = malloc(sizeof(node));
loc->ino = fb.st_ino;
loc->f_size = fb.st_size;
loc->a_tm = fb.st_atime;
loc->m_tm = fb.st_mtime;
loc->c_tm = fb.st_ctime;
loc->next = NULL;
node *b;
b = tmp;
while(b->next != NULL)
b = b->next;
b->next = loc;
printf("File added to linked list successfully\n");
break;
} else if( c == 'n' || c == 'N'){
stat(dest, &fb);
loc = malloc(sizeof(node));
loc->ino = fb.st_ino;
loc->f_size = fb.st_size;
loc->a_tm = fb.st_atime;
loc->m_tm = fb.st_mtime;
loc->c_tm = fb.st_ctime;
loc->next = NULL;
node *b;
b = tmp;
while(b->next != NULL)
b = b->next;
b->next = loc;
printf("File added to linked list successfully\n");
free(loc);
break;
}
case 2:
printf("File Name: ");
scanf("%s", f_name);
printf("Destination: ");
scanf("%s", dest);
strcat(dest, f_name);
stat(dest, &fb);
printf("The inode for removed file is: %ld\n", fb.st_ino);
loc = malloc(sizeof(node));
loc->ino = fb.st_ino;
loc->f_size = fb.st_size;
loc->a_tm = fb.st_atime;
loc->m_tm = fb.st_mtime;
loc->c_tm = fb.st_ctime;
loc->next = NULL;
if(loc->ino == tmp->ino){
tmp = tmp->next;
printf("The node is shifted to next and break is here\n");
break;
} else {
node *bu, *cu;
bu = tmp; //tmp
cu = tmp; //tmp2
while(cu->ino != loc->ino){
bu = cu;
cu = cu->next;
}
bu->next = cu->next;
free(cu);
cu = NULL;
unlink(dest);
printf("File %s has been removed & linked list it updated.\n", f_name);
break;
}
case 3:
printf("Dir Name: ");
scanf("%s", f_name);
printf("\nDestination: ");
scanf("%s", dest);
strcat(dest, f_name);
mkdir(dest, 00700);
stat(dest, &fb);
loc = malloc(sizeof(node));
loc->ino = fb.st_ino;
loc->f_size = fb.st_size;
loc->a_tm = fb.st_atime;
loc->m_tm = fb.st_mtime;
loc->c_tm = fb.st_ctime;
loc->next = NULL;
printf("Directory %s successfully added at %s\n", f_name, dest);
break;
case 4:
printf("Dir Name: ");
scanf("%s", f_name);
printf("Destination: ");
scanf("%s", dest);
rmdir(dest);
printf("The directory has been deleted successfully\n");
break;
default:
printf("Operation doesn't exits\n");
exit(0);
}
printf("Do you want to continue with file operations (Y/N)? ");
scanf(" %c", &c);
if(c == 'y' || c == 'Y')
continue;
else
break;
}
while(1){
printf("Do you want to print Director structure OR Linked List (D/L)? ");
scanf(" %c", &dl);
if(dl == 'd' || dl == 'D')
nftw((argc < 2) ? "." : argv[1], disp, 20, flags);
if(dl == 'l' || dl == 'L')
printll(tmp);
printf("Do you want to continue the print? ");
scanf(" %c", &c);
if(c == 'y' || c == 'Y')
continue;
else
break;
}
free(tmp);
exit(EXIT_SUCCESS);
}
/* ----------------Main exit--------------------*/
/* ----------------Display Dir tree structure --------------------*/
static int disp(const char *fpath,
const struct stat *s,
int typeflag,
struct FTW *ftw){
printf("%-3s\t\t%7jd\t\t%-40s\t\t%ld\n",
(typeflag == FTW_D) ? "d" : (typeflag == FTW_F) ? "f": "???",
s->st_size, fpath, s->st_ino);
return 0;
}
/* ----------------xx-xx-------------------*/
/* -----------------Linked list function ----------------- */
static int linked(const char *fpath,
const struct stat *s,
int typeflag,
struct FTW *ftw){
struct dirent *r;
DIR *d;
int files = 0;
if(typeflag == FTW_D){
d= opendir(fpath);
while((r = readdir(d)) != NULL)
files++;
}
if(typeflag == FTW_F || files == 2){
if(head == NULL){
head = malloc(sizeof(node));
head->ino = s->st_ino;
head->f_size = s->st_size;
head->a_tm = s->st_atime;
head->m_tm = s->st_mtime;
head->c_tm = s->st_ctime;
head->next = NULL;
tmp = head;
} else if(head != NULL) {
node *c = (struct node *)malloc(sizeof(node));
c->ino = s->st_ino;
c->f_size = s->st_size;
c->a_tm = s->st_atime;
c->m_tm = s->st_mtime;
c->c_tm = s->st_ctime;
c->next = NULL;
add_at_end(c);
}
}
return 0;
}
/* ------------------xx-------xx--------------------------- */
/* ---------------function to add at end ---------------- */
void add_at_end(node *p){
node *c2 = (struct node *)malloc(sizeof(node));
c2 = tmp;
while(c2->next != NULL)
c2 = c2->next;
c2->next = p;
}
/* --------------------------x--x-------------------------*/
/* -----------------------Printing linked list ------------------------- */
void printll(node *head){
node *ptr;
if(head == NULL)
printf("The linked list is NULL\n");
ptr = head;
while(ptr != NULL){
printf("%ld\n", ptr->ino);
printf("%ld\n", ptr->f_size);
printf("%ld\n", ptr->a_tm);
printf("%ld\n", ptr->m_tm);
printf("%ld\n", ptr->c_tm);
ptr = ptr->next;
printf("\n");
}
}
/* ------------------------x---x--------------------------------------- */

Related

ROS gpsd client Subscriber node (/fix)

I want to write subscriber node for ROS GPSD client which is publishing GPS coordinates on topic "/fix". I don't know exactly what would be the right code and what changes I have to make in CMakeList.txt and package.xml. Below is the code
#include <ros/ros.h>
#include <sensor_msgs/NavSatStatus.h>
#include <sensor_msgs/NavSatFix.h>
using namespace gps_common;
void callback(const sensor_msgs::NavSatFixConstPtr& fix) {
if (fix->status.status == sensor_msgs::NavSatStatus::STATUS_NO_FIX) {
ROS_INFO("No fix.");
return;
}
if (fix->header.stamp == ros::Time(0)) {
return;
}
printf("\n Latitude = %f and Logitude = %f ",fix->latitude, fix->logitude);
}
int main (int argc, char **argv) {
ros::init(argc, argv, "gps_collect");
ros::NodeHandle node;
ros::Subscriber fix_sub = node.subscribe("fix", 10, callback);
ros::spin();
return 0;
}
I have this code working which is in C. Source: https://github.com/felipegutierrez/raspberryExplore/blob/master/src/gps/gpsClient.c
#include <gps.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include "gpsClient.h"
int runGpsStreamClient() {
int rc;
int count = 0;
clock_t t;
struct gps_data_t gps_data;
t = clock();
if ((rc = gps_open("localhost", "2947", &gps_data)) == -1) {
printf("code: %d, reason: %s\n", rc, gps_errstr(rc));
return EXIT_FAILURE;
}
t = clock() - t;
double time_taken = ((double) t) / CLOCKS_PER_SEC; // in seconds
printf("gps_open() took %f seconds to execute \n", time_taken);
t = clock();
gps_stream(&gps_data, WATCH_ENABLE | WATCH_JSON, NULL);
t = clock() - t;
time_taken = ((double) t) / CLOCKS_PER_SEC; // in seconds
printf("gps_stream() took %f seconds to execute \n", time_taken);
while (count < 60) {
/* wait for 1 second to receive data */
if (gps_waiting(&gps_data, 1000000)) {
/* read data */
if ((rc = gps_read(&gps_data)) == -1) {
printf(
"error occurred reading gps data. code: %d, reason: %s\n",
rc, gps_errstr(rc));
} else {
/* Display data from the GPS receiver. */
double lat = gps_data.fix.latitude;
double lon = gps_data.fix.longitude;
double alt = gps_data.fix.altitude;
double speed = gps_data.fix.speed;
double climb = gps_data.fix.climb;
double t = gps_data.fix.time; // EDIT: Replaced tv.tv_sec with gps_data.fix.time
int status = gps_data.status;
int mode = gps_data.fix.mode;
/**
* MODE_NOT_SEEN 0 mode update not seen yet
* MODE_NO_FIX 1 none
* MODE_2D 2 good for latitude/longitude
* MODE_3D 3 good for altitude/climb too
*/
printf("status: %d - ", status);
printf("mode: %d - ", mode);
printf("latitude: %f - ", lat);
printf("longitude: %f - ", lon);
printf("altitude: %f - ", alt);
printf("speed: %f - ", speed);
printf("vertical speed: %f - ", climb);
printf("timestamp: %f - ", t);
printf("%d:%d:%d", (int) (t / 3600), (int) (t / 60), (int) t);
if ((status == STATUS_FIX)
&& (mode == MODE_2D || mode == MODE_3D)
&& !isnan(lat) && !isnan(lon)) {
//gettimeofday(&tv, NULL); EDIT: tv.tv_sec isn't actually the timestamp!
printf(" =) GPS data correctly received\n");
} else {
printf(" =( NO GPS data received\n");
}
}
} else {
printf("Timeout to retrieve data from gpsd.");
}
count++;
sleep(1);
}
/* When you are done... */
gps_stream(&gps_data, WATCH_DISABLE, NULL);
gps_close(&gps_data);
return EXIT_SUCCESS;
}

How can I obtain the YUV components from the GPU device?

The following program shows the flow of a transcoder from the NVIDIA's NVTranscoder project from the Video_Codec_SDK_8.0.14.
The decoder output each frame with NV12 format.
However, for my coding part, the frame I received only get the Y component channel, how can I get all the YUV components channel?
Besides, how can I write back the CUdeviceptr after some processing?
#include <time.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <pthread.h>
#endif
#include <stdio.h>
#include <string.h>
#include "dynlink_cuda.h" // <cuda.h>
#include "VideoDecoder.h"
#include "VideoEncoder.h"
#include "../common/inc/nvUtils.h"
#include <opencv2/opencv.hpp>
#include "opencv2/gpu/gpu.hpp"
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
using namespace cv;
#ifdef _WIN32
DWORD WINAPI DecodeProc(LPVOID lpParameter)
{
CudaDecoder* pDecoder = (CudaDecoder*)lpParameter;
pDecoder->Start();
return 0;
}
#else
void* DecodeProc(void *arg)
{
CudaDecoder* pDecoder = (CudaDecoder*)arg;
pDecoder->Start();
return NULL;
}
#endif
int MatchFPS(const float fpsRatio, int decodedFrames, int encodedFrames)
{
if (fpsRatio < 1.f) {
// need to drop frame
if (decodedFrames * fpsRatio < (encodedFrames + 1)) {
return -1;
}
}
else if (fpsRatio > 1.f) {
// need to duplicate frame
int duplicate = 0;
while (decodedFrames*fpsRatio > encodedFrames + duplicate + 1) {
duplicate++;
}
return duplicate;
}
return 0;
}
void PrintHelp()
{
printf("Usage : NvTranscoder \n"
"-i <string> Specify input .h264 file\n"
"-o <string> Specify output bitstream file\n"
"\n### Optional parameters ###\n"
"-size <int int> Specify output resolution <width height>\n"
"-codec <integer> Specify the codec \n"
" 0: H264\n"
" 1: HEVC\n"
"-preset <string> Specify the preset for encoder settings\n"
" hq : nvenc HQ \n"
" hp : nvenc HP \n"
" lowLatencyHP : nvenc low latency HP \n"
" lowLatencyHQ : nvenc low latency HQ \n"
" lossless : nvenc Lossless HP \n"
"-fps <integer> Specify encoding frame rate\n"
"-goplength <integer> Specify gop length\n"
"-numB <integer> Specify number of B frames\n"
"-bitrate <integer> Specify the encoding average bitrate\n"
"-vbvMaxBitrate <integer> Specify the vbv max bitrate\n"
"-vbvSize <integer> Specify the encoding vbv/hrd buffer size\n"
"-rcmode <integer> Specify the rate control mode\n"
" 0: Constant QP mode\n"
" 1: Variable bitrate mode\n"
" 2: Constant bitrate mode\n"
" 8: low-delay CBR, high quality\n"
" 16: CBR, high quality (slower)\n"
" 32: VBR, high quality (slower)\n"
"-qp <integer> Specify qp for Constant QP mode\n"
"-i_qfactor <float> Specify qscale difference between I-frames and P-frames\n"
"-b_qfactor <float> Specify qscale difference between P-frames and B-frames\n"
"-i_qoffset <float> Specify qscale offset between I-frames and P-frames\n"
"-b_qoffset <float> Specify qscale offset between P-frames and B-frames\n"
"-deviceID <integer> Specify the GPU device on which encoding will take place\n"
"-help Prints Help Information\n\n"
);
}
int main(int argc, char* argv[])
{
#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
typedef HMODULE CUDADRIVER;
#else
typedef void *CUDADRIVER;
#endif
CUDADRIVER hHandleDriver = 0;
__cu(cuInit(0, __CUDA_API_VERSION, hHandleDriver));
__cu(cuvidInit(0));
EncodeConfig encodeConfig = { 0 };
encodeConfig.endFrameIdx = INT_MAX;
encodeConfig.bitrate = 5000000;
encodeConfig.rcMode = NV_ENC_PARAMS_RC_CONSTQP;
encodeConfig.gopLength = NVENC_INFINITE_GOPLENGTH;
encodeConfig.codec = NV_ENC_H264;
encodeConfig.fps = 0;
encodeConfig.qp = 28;
encodeConfig.i_quant_factor = DEFAULT_I_QFACTOR;
encodeConfig.b_quant_factor = DEFAULT_B_QFACTOR;
encodeConfig.i_quant_offset = DEFAULT_I_QOFFSET;
encodeConfig.b_quant_offset = DEFAULT_B_QOFFSET;
encodeConfig.presetGUID = NV_ENC_PRESET_DEFAULT_GUID;
encodeConfig.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;
NVENCSTATUS nvStatus = CNvHWEncoder::ParseArguments(&encodeConfig, argc, argv);
if (nvStatus != NV_ENC_SUCCESS)
{
PrintHelp();
return 1;
}
if (!encodeConfig.inputFileName || !encodeConfig.outputFileName)
{
PrintHelp();
return 1;
}
encodeConfig.fOutput = fopen(encodeConfig.outputFileName, "wb");
if (encodeConfig.fOutput == NULL)
{
PRINTERR("Failed to create \"%s\"\n", encodeConfig.outputFileName);
return 1;
}
//init cuda
CUcontext cudaCtx;
CUdevice device;
__cu(cuDeviceGet(&device, encodeConfig.deviceID));
__cu(cuCtxCreate(&cudaCtx, CU_CTX_SCHED_AUTO, device));
CUcontext curCtx;
CUvideoctxlock ctxLock;
__cu(cuCtxPopCurrent(&curCtx));
__cu(cuvidCtxLockCreate(&ctxLock, curCtx));
CudaDecoder* pDecoder = new CudaDecoder;
FrameQueue* pFrameQueue = new CUVIDFrameQueue(ctxLock);
pDecoder->InitVideoDecoder(encodeConfig.inputFileName, ctxLock, pFrameQueue, encodeConfig.width, encodeConfig.height);
int decodedW, decodedH, decodedFRN, decodedFRD, isProgressive;
pDecoder->GetCodecParam(&decodedW, &decodedH, &decodedFRN, &decodedFRD, &isProgressive);
if (decodedFRN <= 0 || decodedFRD <= 0) {
decodedFRN = 30;
decodedFRD = 1;
}
if(encodeConfig.width <= 0 || encodeConfig.height <= 0) {
encodeConfig.width = decodedW;
encodeConfig.height = decodedH;
}
float fpsRatio = 1.f;
if (encodeConfig.fps <= 0) {
encodeConfig.fps = decodedFRN / decodedFRD;
}
else {
fpsRatio = (float)encodeConfig.fps * decodedFRD / decodedFRN;
}
encodeConfig.pictureStruct = (isProgressive ? NV_ENC_PIC_STRUCT_FRAME : 0);
pFrameQueue->init(encodeConfig.width, encodeConfig.height);
VideoEncoder* pEncoder = new VideoEncoder(ctxLock);
assert(pEncoder->GetHWEncoder());
nvStatus = pEncoder->GetHWEncoder()->Initialize(cudaCtx, NV_ENC_DEVICE_TYPE_CUDA);
if (nvStatus != NV_ENC_SUCCESS)
return 1;
encodeConfig.presetGUID = pEncoder->GetHWEncoder()->GetPresetGUID(encodeConfig.encoderPreset, encodeConfig.codec);
printf("Encoding input : \"%s\"\n", encodeConfig.inputFileName);
printf(" output : \"%s\"\n", encodeConfig.outputFileName);
printf(" codec : \"%s\"\n", encodeConfig.codec == NV_ENC_HEVC ? "HEVC" : "H264");
printf(" size : %dx%d\n", encodeConfig.width, encodeConfig.height);
printf(" bitrate : %d bits/sec\n", encodeConfig.bitrate);
printf(" vbvMaxBitrate : %d bits/sec\n", encodeConfig.vbvMaxBitrate);
printf(" vbvSize : %d bits\n", encodeConfig.vbvSize);
printf(" fps : %d frames/sec\n", encodeConfig.fps);
printf(" rcMode : %s\n", encodeConfig.rcMode == NV_ENC_PARAMS_RC_CONSTQP ? "CONSTQP" :
encodeConfig.rcMode == NV_ENC_PARAMS_RC_VBR ? "VBR" :
encodeConfig.rcMode == NV_ENC_PARAMS_RC_CBR ? "CBR" :
encodeConfig.rcMode == NV_ENC_PARAMS_RC_VBR_MINQP ? "VBR MINQP (deprecated)" :
encodeConfig.rcMode == NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ ? "CBR_LOWDELAY_HQ" :
encodeConfig.rcMode == NV_ENC_PARAMS_RC_CBR_HQ ? "CBR_HQ" :
encodeConfig.rcMode == NV_ENC_PARAMS_RC_VBR_HQ ? "VBR_HQ" : "UNKNOWN");
if (encodeConfig.gopLength == NVENC_INFINITE_GOPLENGTH)
printf(" goplength : INFINITE GOP \n");
else
printf(" goplength : %d \n", encodeConfig.gopLength);
printf(" B frames : %d \n", encodeConfig.numB);
printf(" QP : %d \n", encodeConfig.qp);
printf(" preset : %s\n", (encodeConfig.presetGUID == NV_ENC_PRESET_LOW_LATENCY_HQ_GUID) ? "LOW_LATENCY_HQ" :
(encodeConfig.presetGUID == NV_ENC_PRESET_LOW_LATENCY_HP_GUID) ? "LOW_LATENCY_HP" :
(encodeConfig.presetGUID == NV_ENC_PRESET_HQ_GUID) ? "HQ_PRESET" :
(encodeConfig.presetGUID == NV_ENC_PRESET_HP_GUID) ? "HP_PRESET" :
(encodeConfig.presetGUID == NV_ENC_PRESET_LOSSLESS_HP_GUID) ? "LOSSLESS_HP" : "LOW_LATENCY_DEFAULT");
printf("\n");
nvStatus = pEncoder->GetHWEncoder()->CreateEncoder(&encodeConfig);
if (nvStatus != NV_ENC_SUCCESS)
return 1;
nvStatus = pEncoder->AllocateIOBuffers(&encodeConfig);
if (nvStatus != NV_ENC_SUCCESS)
return 1;
unsigned long long lStart, lEnd, lFreq;
NvQueryPerformanceCounter(&lStart);
//start decoding thread
#ifdef _WIN32
HANDLE decodeThread = CreateThread(NULL, 0, DecodeProc, (LPVOID)pDecoder, 0, NULL);
#else
pthread_t pid;
pthread_create(&pid, NULL, DecodeProc, (void*)pDecoder);
#endif
//start encoding thread
int frmProcessed = 0;
int frmActual = 0;
while(!(pFrameQueue->isEndOfDecode() && pFrameQueue->isEmpty()) ) {
CUVIDPARSERDISPINFO pInfo;
if(pFrameQueue->dequeue(&pInfo)) {
CUdeviceptr dMappedFrame = 0;
unsigned int pitch;
CUVIDPROCPARAMS oVPP = { 0 };
oVPP.progressive_frame = pInfo.progressive_frame;
oVPP.second_field = 0;
oVPP.top_field_first = pInfo.top_field_first;
oVPP.unpaired_field = (pInfo.progressive_frame == 1 || pInfo.repeat_first_field <= 1);
cuvidMapVideoFrame(pDecoder->GetDecoder(), pInfo.picture_index, &dMappedFrame, &pitch, &oVPP);
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
gpu::GpuMat dimg(cv::Size(decodedW, decodedH), CV_8UC1, (void*)(dMappedFrame), pitch);
gpu::GpuMat blurImg;
gpu::GaussianBlur(dimg, blurImg, cv::Size(5, 5), 0);
cv::Mat img;
dimg.download(img);
cvtColor(img, img, CV_YUV2RGB_NV12);
cv::imshow("Decoded Frame", img);
imwrite("C:\\test\\video1.bmp", img);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
EncodeFrameConfig stEncodeConfig = { 0 };
NV_ENC_PIC_STRUCT picType = (pInfo.progressive_frame || pInfo.repeat_first_field >= 2 ? NV_ENC_PIC_STRUCT_FRAME :
(pInfo.top_field_first ? NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM : NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP));
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
stEncodeConfig.dptr = (CUdeviceptr)img.data; //dMappedFrame;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stEncodeConfig.pitch = pitch;
stEncodeConfig.width = encodeConfig.width;
stEncodeConfig.height = encodeConfig.height;
int dropOrDuplicate = MatchFPS(fpsRatio, frmProcessed, frmActual);
for (int i = 0; i <= dropOrDuplicate; i++) {
pEncoder->EncodeFrame(&stEncodeConfig, picType);
frmActual++;
}
frmProcessed++;
//cuvidUnmapVideoFrame(pDecoder->GetDecoder(), dMappedFrame);
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cuvidUnmapVideoFrame(pDecoder->GetDecoder(), (CUdeviceptr)img.data);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pFrameQueue->releaseFrame(&pInfo);
}
}
pEncoder->EncodeFrame(NULL, NV_ENC_PIC_STRUCT_FRAME, true);
#ifdef _WIN32
WaitForSingleObject(decodeThread, INFINITE);
#else
pthread_join(pid, NULL);
#endif
if (pEncoder->GetEncodedFrames() > 0)
{
NvQueryPerformanceCounter(&lEnd);
NvQueryPerformanceFrequency(&lFreq);
double elapsedTime = (double)(lEnd - lStart)/(double)lFreq;
printf("Total time: %fms, Decoded Frames: %d, Encoded Frames: %d, Average FPS: %f\n",
elapsedTime * 1000,
pDecoder->m_decodedFrames,
pEncoder->GetEncodedFrames(),
(float)pEncoder->GetEncodedFrames() / elapsedTime);
}
pEncoder->Deinitialize();
delete pDecoder;
delete pEncoder;
delete pFrameQueue;
cuvidCtxLockDestroy(ctxLock);
__cu(cuCtxDestroy(cudaCtx));
return 0;
}
The Y block is at the position 0, the U block is at position width*height and the V block is at the position width*height+(width*height)/4.
cv::cuda::GpuMat dimg(cv::Size(decodedW,decodedH+(decodedH/2)),CV_8UC1,(void*)(dMappedFrame), pitch);
dimg.download(img);
cv::cvtColor(img, img, cv::COLOR_YUV2BGR_NV12);
cv::imshow("frame", img);
cv::waitKey(1);
Further reading here.

string.match works but string.find failed in cocos lua on Android when using Chinese

I use string.find('中国', '中') and string.match('中国', '中') to search in cocos lua.
It's weird that they both worked on Win32, however, string.find('中国', '中') failed on Android.
I read the source code of lua. http://www.lua.org/source/5.1/lstrlib.c.html#str_find_aux
It seems that lmemfind and match works diffently on different platforms.
static int str_find (lua_State *L) {
return str_find_aux(L, 1);
}
static int str_match (lua_State *L) {
return str_find_aux(L, 0);
}
static int str_find_aux (lua_State *L, int find) {
size_t l1, l2;
const char *s = luaL_checklstring(L, 1, &l1);
const char *p = luaL_checklstring(L, 2, &l2);
ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
if (init < 0) init = 0;
else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
if (find && (lua_toboolean(L, 4) || /* explicit request? */
strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
/* do a plain search */
const char *s2 = lmemfind(s+init, l1-init, p, l2);
if (s2) {
lua_pushinteger(L, s2-s+1);
lua_pushinteger(L, s2-s+l2);
return 2;
}
}
else {
MatchState ms;
int anchor = (*p == '^') ? (p++, 1) : 0;
const char *s1=s+init;
ms.L = L;
ms.src_init = s;
ms.src_end = s+l1;
do {
const char *res;
ms.level = 0;
if ((res=match(&ms, s1, p)) != NULL) {
if (find) {
lua_pushinteger(L, s1-s+1); /* start */
lua_pushinteger(L, res-s); /* end */
return push_captures(&ms, NULL, 0) + 2;
}
else
return push_captures(&ms, s1, res);
}
} while (s1++ < ms.src_end && !anchor);
}
lua_pushnil(L); /* not found */
return 1;
}

How to call the function of C file in .m file for IOS Objective-C?

In a new Objective-C project , it create the file ViewController.m.
And I add the other source for C file and Header file in to this Objective-C project.
If the function in C file is like the following:
int dump(addr)
{
//function code
}
I add the Button in ViewController.m like the following code.
- (IBAction)showclient:(id)sender {
//How to call the function in C file here ?
}
How to call the dump function in ViewController.m after I push the Button?.
-----------------------------------EDIT--------------------------------
The function I want to call in .m file
/*
* Dump the entire arp table
*/
int
dump(addr)
u_long addr;
{
int mib[6];
size_t needed;
char *host, *lim, *buf, *next;
struct rt_msghdr *rtm;
struct sockaddr_inarp *sin;
struct sockaddr_dl *sdl;
extern int h_errno;
struct hostent *hp;
int found_entry = 0;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = AF_INET;
mib[4] = NET_RT_FLAGS;
mib[5] = RTF_LLINFO;
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
err(1, "route-sysctl-estimate");
if ((buf = malloc(needed)) == NULL)
err(1, "malloc");
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
err(1, "actual retrieval of routing table");
lim = buf + needed;
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
sin = (struct sockaddr_inarp *)(rtm + 1);
sdl = (struct sockaddr_dl *)(sin + 1);
if (addr) {
if (addr != sin->sin_addr.s_addr)
continue;
found_entry = 1;
}
if (nflag == 0)
hp = gethostbyaddr((caddr_t)&(sin->sin_addr),
sizeof sin->sin_addr, AF_INET);
else
hp = 0;
if (hp)
host = hp->h_name;
else {
host = "?";
if (h_errno == TRY_AGAIN)
nflag = 1;
}
printf("%s (%s) at ", host, inet_ntoa(sin->sin_addr));
if (sdl->sdl_alen)
ether_print((u_char *)LLADDR(sdl));
else
printf("(incomplete)");
if (rtm->rtm_rmx.rmx_expire == 0)
printf(" permanent");
if (sin->sin_other & SIN_PROXY)
printf(" published (proxy only)");
if (rtm->rtm_addrs & RTA_NETMASK) {
sin = (struct sockaddr_inarp *)
(sdl->sdl_len + (char *)sdl);
if (sin->sin_addr.s_addr == 0xffffffff)
printf(" published");
if (sin->sin_len != 8)
printf("(weird)");
}
printf("\n");
}
return (found_entry);
}
#import "Cfile.h" in your ViewController.m
call it like ordinary C -- function(parameters);
(3. friendly advice: buy a book on C)

HIDAPI in two threads

According to https://github.com/signal11/hidapi/issues/72 HIDAPI ought to be thread safe on Linux machines. However, I can't get it working at all. This is what I do:
#ifdef WIN32
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <assert.h>
#include "hidapi.h"
hid_device *handle;
static void *TaskCode(void *argument)
{
int res;
//hid_device *handle;
unsigned char buf[64];
// res = hid_init();
// if( res == -1 )
// {
// return (void*)1;
// }
//
// handle = hid_open(0x0911, 0x251c, NULL);
// if( handle == NULL )
// {
// return (void*)2;
// }
printf( "while 2\n");
while( 1 )
{
memset( buf, 64, 0 );
res = hid_read(handle, buf, 0);
if( res == -1 )
{
return (void*)3;
}
printf( "received %d bytes\n", res);
for (int i = 0; i < res; i++)
printf("Byte %d: %02x ", i+1, buf[i]);
//printf( "%02x ", buf[0]);
fflush(stdout);
}
return (void*)0;
}
int main(int argc, char* argv[])
{
int res;
//hid_device *handle;
unsigned char buf[65];
res = hid_init();
if( res == -1 )
{
return 1;
}
handle = hid_open(0x0911, 0x251c, NULL);
if( handle == NULL )
{
return 2;
}
hid_set_nonblocking( handle, 0 );
pthread_t thread;
int rc = pthread_create(&thread, NULL, TaskCode, NULL);
printf( "while 1\n");
while(1)
{
int a = getchar();
if( a == 'a')
{
// Get Device Type (cmd 0x82). The first byte is the report number (0x0).
buf[0] = 0x0;
buf[1] = 0x82;
res = hid_write(handle, buf, 65);
if( res != -1 )
printf( "write ok, transferred %d bytes\n", res );
else
{
printf( "write error\n" );
char* str = hid_error(handle);
printf( "error: %s\n", str );
return 1;
}
}
else if( a== 'b')
break;
}
void* trc;
rc = pthread_join(thread, &trc);
printf( "rc code: %d\n", (int)trc );
// Finalize the hidapi library
res = hid_exit();
return 0;
}
If I don't use the global handle, I get 'write error' every time. If I do, as in the example, formally everything works but hid_read always returns 0 bytes... Of course, if I do simple hid_write() followed by hid_read(), I'll get the correct reply to the command 0x82 as intended. I'm really lost here, am I overlooking something?
EDIT: to clarify, zero bytes return also for everything, incl. buttons on mouse etc. So it seems to work but the data buffer is always zero bytes.
Shame on me, a dumb mistake. The code should be:
memset( buf, 0, 64 );
res = hid_read(handle, buf, 64);
and then it works. Should sleep more and write less!

Resources