linux kernel module data compression - linux

linux 2.6
I am writing a LKM. I need to compress and decompress on the fly many different chunks of text.
I prefer to call kernel api, avoiding to include and compile external libraries.
Are there kernel Api to compress and decompress memory ?
source and destination buffers can be both in kernel memory or one in kernel the other in user space.

Not sure why kernel.org excludes the compression part.
One may need to mimic from its official skcipher example, in which the procedure is like below:
tfm = crypto_alloc_tfm("yourAlg",
CRYPTO_TFM_MODE_yourAlg);
req = skcipher_request_alloc(tfm, GFP_KERNEL);
skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
test_tfm_cb,
result);
crypto_cipher_setkey(tfm, key, keylength);
crypto_cipher_encrypt(tfm, &scatterlist,
numlists);
tfm_request_free(req);
crypto_free_tfm(tfm);
Notice kernel now is moving to async, however callback is not shown in latest header file.
/**
* acomp_request_set_callback() -- Sets an asynchronous callback
*
* Callback will be called when an asynchronous operation on a given
* request is finished.
*
* #req: request that the callback will be set for
* #flgs: specify for instance if the operation may backlog
* #cmlp: callback which will be called
* #data: private data used by the caller
*/
static inline void acomp_request_set_callback(struct acomp_req *req,
u32 flgs,
crypto_completion_t cmpl,
void *data)
{
req->base.complete = cmpl;
req->base.data = data;
req->base.flags = flgs;
}
Example code:
struct comp_testvec tv, int mode;
int ilen = tv.inlen;
char *str_input = tv.input;
int olen = tv.outlen;
char *str_output = tv.output;
struct scatterlist sg[2];
struct scatterlist sg2[2];
char *input;
char *output;
char *input2;
char *output2;
struct acomp_req *req;
struct crypto_acomp *tfm;
struct tcrypt_result result;
int ret = 0;
input = kmalloc(ilen, GFP_KERNEL);
output = kmalloc(olen, GFP_KERNEL);
input2 = kmalloc(olen, GFP_KERNEL);
output2 = kmalloc(ilen, GFP_KERNEL);
char *driver = tv.alg;
tfm = crypto_alloc_acomp(driver, CRYPTO_ALG_TYPE_ACOMPRESS,
CRYPTO_ALG_TYPE_ACOMPRESS_MASK);
if (IS_ERR(tfm)) {
printk(KERN_ERR "alg: acomp: Failed to load transform for "
"%s: %ld\n", driver, PTR_ERR(tfm));
return PTR_ERR(tfm);
}
init_completion(&result.completion);
if (mode == 0)
{
//zip
memcpy(input,str_input,ilen);
printk("input => %s\n", input);
print_hex_dump(KERN_CONT, "| ", DUMP_PREFIX_OFFSET, 16, 1, input, ilen, false);
printk("alg => %s\n",driver);
sg_init_one(&sg[0], input, ilen);
sg_init_one(&sg[1], output, COMP_BUF_SIZE);
req = acomp_request_alloc(tfm);
if(!req)
{
printk("error req = null\n");
crypto_free_acomp(tfm);
return -1;
}
acomp_request_set_params(req, &sg[0], &sg[1], ilen, COMP_BUF_SIZE);
acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
tcrypt_complete, &result);
ret = crypto_acomp_compress(req);
if(ret == -EINPROGRESS || ret == -EBUSY)
{
ret = wait_for_completion_interruptible(
&result.completion);
if (!ret && !((ret = result.err)))
{
reinit_completion(&result.completion);
}
}
else if(ret == 0)
{
printk("succ\n");
}
else
{
printk("error ret = %d\n",ret);
goto out;
}
printk("compress => \n");
print_hex_dump(KERN_CONT, "| ", DUMP_PREFIX_OFFSET, 16, 1, output, olen, false);
} else if (mode == 1) {
//unzip
memcpy(input2,str_output,olen);
printk("input => \n");
print_hex_dump(KERN_CONT, "| ", DUMP_PREFIX_OFFSET, 16, 1, input2, olen, false);
char *driver = tv.alg;
printk("alg => %s\n",driver);
//sg init
sg_init_one(&sg2[0], input2, ilen);
sg_init_one(&sg2[1], output2, COMP_BUF_SIZE);
req = acomp_request_alloc(tfm);
if(!req)
{
printk("error req = null\n");
crypto_free_acomp(tfm);
return -1;
}
acomp_request_set_params(req, &sg2[0], &sg2[1], ilen, COMP_BUF_SIZE);
acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
tcrypt_complete, &result);
ret = crypto_acomp_decompress(req);
if(ret == -EINPROGRESS || ret == -EBUSY)
{
ret = wait_for_completion_interruptible(
&result.completion);
if (!ret && !((ret = result.err)))
{
reinit_completion(&result.completion);
}
}
else if(ret == 0)
{
printk("succ\n");
}
else
{
printk("error ret = %d\n",ret);
goto out;
}
printk("decompress => %s\n", output2);
print_hex_dump(KERN_CONT, "| ", DUMP_PREFIX_OFFSET, 16, 1, output2, ilen, false);

Related

Multithread decoding of Video PID of Mpeg2Ts using FFMPEG

I'm working on an app in VC++ to display video frames of a video Pid of mpeg2ts stream using FFMPEG and need to do the same, for other mpeg2stream simultaneously by using multi thread process,my source code is:
int main (int argc, char* argv[])
{
av_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context();
if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){
printf("Couldn't open input stream.\n");
return -1;
}
if(avformat_find_stream_info(pFormatCtx,NULL)<0){
printf("Couldn't find stream information.\n");
return -1;
}
videoindex=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
videoindex=i;
break;
}
if(videoindex==-1){
printf("Didn't find a video stream.\n");
return -1;
}
pCodecCtx=pFormatCtx->streams[videoindex]->codec;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL){
printf("Codec not found.\n");
return -1;
}
if(avcodec_open2(pCodecCtx, pCodec,NULL)<0){
printf("Could not open codec.\n");
return -1;
}
pFrame=av_frame_alloc();
pFrameYUV=av_frame_alloc();
out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
packet=(AVPacket *)av_malloc(sizeof(AVPacket));
//Output Info-----------------------------
printf("--------------- File Information ----------------\n");
av_dump_format(pFormatCtx,0,filepath,0);
printf("-------------------------------------------------\n");
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
#if OUTPUT_YUV420P
fp_yuv=fopen("output.yuv","wb+");
#endif
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
printf( "Could not initialize SDL - %s\n", SDL_GetError());
return -1;
}
screen_w = pCodecCtx->width;
screen_h = pCodecCtx->height;
//SDL 2.0 Support for multiple windows
screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
screen_w, screen_h, SDL_WINDOW_OPENGL);
if(!screen) {
printf("SDL: could not create window - exiting:%s\n",SDL_GetError());
return -1;
}
sdlRenderer = SDL_CreateRenderer(screen, -1, 0);
//IYUV: Y + U + V (3 planes)
//YV12: Y + V + U (3 planes)
sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width,pCodecCtx->height);
sdlRect.x=0;
sdlRect.y=0;
sdlRect.w=screen_w;
sdlRect.h=screen_h;
//SDL End----------------------
BYTE buffer [4] ;
int nSize = 0 ;
int nByteCnt = 0 ;
int nPreviuosPos = 0 ;
mpgfile = fopen ("D:\\00_Projects\\Farzan II\\SampleData\\Yahsat1996V_N_PID(2101).pes", "rb");
while(av_read_frame(pFormatCtx, packet)>=0 /*&& nSize > 0*/)
{
if(packet->stream_index==videoindex)
{
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
if(ret < 0)
{
printf("Decode Error.\n");
return -1;
}
if(got_picture)
{
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
pFrameYUV->data, pFrameYUV->linesize);
#if OUTPUT_YUV420P
y_size=pCodecCtx->width*pCodecCtx->height;
fwrite(pFrameYUV->data[0],1,y_size,fp_yuv); //Y
fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv); //U
fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv); //V
#endif
//SDL---------------------------
#if 0
SDL_UpdateTexture( sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0] );
#else
SDL_UpdateYUVTexture(sdlTexture, &sdlRect,
pFrameYUV->data[0], pFrameYUV->linesize[0],
pFrameYUV->data[1], pFrameYUV->linesize[1],
pFrameYUV->data[2], pFrameYUV->linesize[2]);
#endif
SDL_RenderClear( sdlRenderer );
SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect);
SDL_RenderPresent( sdlRenderer );
//SDL End-----------------------
//Delay 40ms
SDL_Delay(40);
}
}
av_free_packet(packet);
}
//flush decoder
//FIX: Flush Frames remained in Codec
while (1) {
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
if (ret < 0)
break;
if (!got_picture)
break;
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
pFrameYUV->data, pFrameYUV->linesize);
#if OUTPUT_YUV420P
int y_size=pCodecCtx->width*pCodecCtx->height;
fwrite(pFrameYUV->data[0],1,y_size,fp_yuv); //Y
fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv); //U
fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv); //V
#endif
//SDL---------------------------
SDL_UpdateTexture( sdlTexture, &sdlRect, pFrameYUV->data[0], pFrameYUV->linesize[0] );
SDL_RenderClear( sdlRenderer );
SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect);
SDL_RenderPresent( sdlRenderer );
//SDL End-----------------------
//Delay 40ms
SDL_Delay(40);
}
sws_freeContext(img_convert_ctx);
#if OUTPUT_YUV420P
fclose(fp_yuv);
#endif
SDL_Quit();
av_frame_free(&pFrameYUV);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}
it works well when i call it in One thread but,after calling this function in multi thread ,the error of access violation occurred , is there anyone to guide me to solution?

Chibios and the SIM900 Shiled

i have this problem,
i have STM32 Nucleo L152RE and a Shield SIM 900,
now if i write this easy thread all work well,
'static THD_WORKING_AREA(waRead, 128);
static THD_FUNCTION(Thread,arg) {
(void)arg;
chRegSetThreadName("th_callback");
while (TRUE){
/* This will wait for a character to be received */
uint8_t c = sdGet(&SD1); //questo prende il carattere
sdPut(&SD2, c); // questo lo spara alla terminale
}
}
'
when i sand a AT commnad i see the ok answer.
Now i create this buffer
'static uint8_t bufferMsg[128];'
and i use this thread for store the answer
' static THD_WORKING_AREA(waRead5, 128);
static THD_FUNCTION(Thread5,arg) {
chRegSetThreadName("th_Riempio_Buffer");
msg_t charbuf;
int count=0;
uint8_t c;
event_listener_t Uart1Data;
eventmask_t flags;
chEvtRegisterMask((event_source_t *)chnGetEventSource(&SD1), &Uart1Data, EVENT_MASK(1));
while (TRUE) {
chEvtWaitOneTimeout(EVENT_MASK(1), MS2ST(10));
chSysLock();
flags =chEvtGetAndClearFlags(&Uart1Data);
chSysUnlock();
if (flags & CHN_INPUT_AVAILABLE)
{
do
{
charbuf = chnGetTimeout(&SD1,TIME_IMMEDIATE);
if (charbuf != Q_TIMEOUT)
{
while((charbuf != '\n') && (count < 128)) {
sdWrite(&SD2, (uint8_t *)B3,4); // va bene
bufferMsg[count]= charbuf;
count++;
}
}
}
while (charbuf != Q_TIMEOUT);
}
}
}
'
this threads don't work and don't store the answer, can you help me?
best regards
A.
fot me i use,
Define
#define buffer_size 128
char buffer[buffer_size + 1];
int nbytes = 0;
Function
void SIM_callback(){ /* GSM900 Serial */
char x = SIM.getc();
buffer[nbytes] = x;
nbytes++; if (nbytes > buffer_size) nbytes = buffer_size;
buffer[nbytes] = '\0';
}
Main
main (){
// Clear Buffer
buffer[nbytes] = '\0';
...
while(1);
...
}

How to pass the pointer of a memory buffer created by calloc to a sub function?

Here is my code:
I have to dynamically create some memory for the string Str1 and pass its pointer to the other two functions in a recursive manner. The code compiles but when it enters Function2 it generates an exception saying that cannot write c[i], bad pointer? (i.e. it does not write to Str1)
What am i doing wrong?
void Function1(void)
{
char *Str1;
Str1 = calloc(25, sizeof(char));
pFileIn = fopen("in.txt", "r");
pFileOut = fopen("out.txt", "w+");
if (pFileIn==NULL) printf("Error opening file");
else
{
while (Function2(pFileIn, Str1))
{
if (! Function3(pFileOut, Str1))
{
fseek(pFileOut, 0, SEEK_END);
fprintf(pFileOut, "%s", Str1);
rewind(pFileOut);
}
}
fclose(pFileIn);
fclose(pFileOut);
}
int Function2(FILE* f, char * c)
{
int i=0;
do
{
c[i] = fgetc(f);
if (c[i]==EOF)
return FALSE;
} while (c[i++]!='\n');
c[i] = '\0';
return TRUE;
}
int Function3(FILE* f, char * c)
{
char *Str2;
Str2 = calloc(25, sizeof(char));
while (Function2(f, Str2))
{
if (strcmp(c, Str2)==0)
return TRUE;
}
rewind(f);
return FALSE;
}

libusb bulk transfer

I am trying to implement user space usb driver using libusb1.0.9. I have lpc2148 blueboard(ARM7) with me..This board is loaded with opensource USB stack/firmware by Mr. Bertrik Sikken. Now my user space driver is trying read write with board. I am getting garbage data.
I want to know about the flow of bulk tranfer.
For any transfer/transaction is there kernel device driver involved??
and do we need usb gadget device driver also??
I am not able to understand that where the data gets copied.
Important thing is that when I read/write interrupt gets generated and I can see correct data on LCD. Do I need to read/write USBRxData/USBTxData?
Please do the needfull.
I tried the below code for bulk transfer read and write..
int usb_read(struct libusb_device *dev,struct libusb_device_handle *hDevice)
{
char *data,*data1;
struct libusb_endpoint_descriptor *ep;
struct libusb_interface_descriptor *id;
int len=64,r,ret_alt,ret_clm,ret_rst,i;
struct libusb_device **list;
data = (char *)malloc(512); //allocation of buffers
data1 = (char *)malloc(512);
memset(data,'\0',512);
memset(data1,'\0',512);
if(hDevice==NULL)
{
printf("\nNO device found\n");
return 0;
}
int ret_open = libusb_open(dev,&hDevice);
if(ret_open!=0)
{
printf("Error in libusb_open\n");
libusb_free_device_list(list,1);
return -1;
}
char str_tx[512]="G"; //data to send to device
char str_rx[512]; //receive string
data = str_tx;
printf("data::%s\t,str::%s\n",data,str_tx);
//printf("%c\n",data);
ep = active_config(dev,hDevice);
printf("after ep\n");
//printf("alt_interface = %d\n",alt_interface);
ret_rst = libusb_reset_device(hDevice);
if(ret_rst < 0)
{
printf("Error in reset :: %d",ret_rst);
return -1;
}
printf("original data1 : %s\n",data1);
r = libusb_bulk_transfer(hDevice,0x08,str_tx,512,&len,0);
//write to device buffer from data
printf("Error number :: %d\n",r);
int le = ep->bEndpointAddress;
int ty = ep->bDescriptorType;
int y = ep->bmAttributes;
printf("y::%d\tatt:: %d\n",y,ep->bmAttributes);
if(r==-1)
printf("Error in io\n");
if(r==0)
{
printf("data returned :: %s\n",data);
printf("len= %d\n",len);
printf("Device Button Pressed!!!!\n");
}
else
{
printf("Error in bulk transfer\n");
return -1;
}
r = libusb_bulk_transfer(hDevice,0x82,data1,512,&len,0);
//read from device buffer to data1
//str_rx = data1;
//printf("End point address::%d\n",le);
//printf("End point desc.type::%d\n",ty);
if(r==-1)
printf("Error in io\n");
if(r==0)
{
printf("data1 returned::%s\n",data1); //received string in data1
printf("len= %d\n",len);
printf("Device Button Pressed!!!!\n");
}
else
{
printf("Error in bulk transfer\n");
return -1;
}
return 0;
}
Try the code given below and it should work on lpc2148.
I have tested this with a lpc2148 configured to receive an interrupt from USB after a write happens (from user-space) and RTC starts running.
Answering to your question whether it involves kernel driver in read/write or not, as far as I have studied, You have to detach the kernel driver and claim the interface using libusb APIs. Though I am not sure whether it can be done without detaching it or not.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include </usr/local/include/libusb-1.0/libusb.h>
#define BULK_EP_OUT 0x82
#define BULK_EP_IN 0x08
int interface_ref = 0;
int alt_interface,interface_number;
int print_configuration(struct libusb_device_handle *hDevice,struct libusb_config_descriptor *config)
{
char *data;
int index;
data = (char *)malloc(512);
memset(data,0,512);
index = config->iConfiguration;
libusb_get_string_descriptor_ascii(hDevice,index,data,512);
printf("\nInterface Descriptors: ");
printf("\n\tNumber of Interfaces : %d",config->bNumInterfaces);
printf("\n\tLength : %d",config->bLength);
printf("\n\tDesc_Type : %d",config->bDescriptorType);
printf("\n\tConfig_index : %d",config->iConfiguration);
printf("\n\tTotal length : %lu",config->wTotalLength);
printf("\n\tConfiguration Value : %d",config->bConfigurationValue);
printf("\n\tConfiguration Attributes : %d",config->bmAttributes);
printf("\n\tMaxPower(mA) : %d\n",config->MaxPower);
free(data);
data = NULL;
return 0;
}
struct libusb_endpoint_descriptor* active_config(struct libusb_device *dev,struct libusb_device_handle *handle)
{
struct libusb_device_handle *hDevice_req;
struct libusb_config_descriptor *config;
struct libusb_endpoint_descriptor *endpoint;
int altsetting_index,interface_index=0,ret_active;
int i,ret_print;
hDevice_req = handle;
ret_active = libusb_get_active_config_descriptor(dev,&config);
ret_print = print_configuration(hDevice_req,config);
for(interface_index=0;interface_index<config->bNumInterfaces;interface_index++)
{
const struct libusb_interface *iface = &config->interface[interface_index];
for(altsetting_index=0;altsetting_index<iface->num_altsetting;altsetting_index++)
{
const struct libusb_interface_descriptor *altsetting = &iface->altsetting[altsetting_index];
int endpoint_index;
for(endpoint_index=0;endpoint_index<altsetting->bNumEndpoints;endpoint_index++)
{
const struct libusb_endpoint_desriptor *ep = &altsetting->endpoint[endpoint_index];
endpoint = ep;
alt_interface = altsetting->bAlternateSetting;
interface_number = altsetting->bInterfaceNumber;
}
printf("\nEndPoint Descriptors: ");
printf("\n\tSize of EndPoint Descriptor : %d",endpoint->bLength);
printf("\n\tType of Descriptor : %d",endpoint->bDescriptorType);
printf("\n\tEndpoint Address : 0x0%x",endpoint->bEndpointAddress);
printf("\n\tMaximum Packet Size: %x",endpoint->wMaxPacketSize);
printf("\n\tAttributes applied to Endpoint: %d",endpoint->bmAttributes);
printf("\n\tInterval for Polling for data Tranfer : %d\n",endpoint->bInterval);
}
}
libusb_free_config_descriptor(NULL);
return endpoint;
}
int main(void)
{
int r = 1;
struct libusb_device **devs;
struct libusb_device_handle *handle = NULL, *hDevice_expected = NULL;
struct libusb_device *dev,*dev_expected;
struct libusb_device_descriptor desc;
struct libusb_endpoint_descriptor *epdesc;
struct libusb_interface_descriptor *intdesc;
ssize_t cnt;
int e = 0,config2;
int i = 0,index;
char str1[64], str2[64];
char found = 0;
// Init libusb
r = libusb_init(NULL);
if(r < 0)
{
printf("\nfailed to initialise libusb\n");
return 1;
}
else
printf("\nInit Successful!\n");
// Get a list os USB devices
cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0)
{
printf("\nThere are no USB devices on bus\n");
return -1;
}
printf("\nDevice Count : %d\n-------------------------------\n",cnt);
while ((dev = devs[i++]) != NULL)
{
r = libusb_get_device_descriptor(dev, &desc);
if (r < 0)
{
printf("failed to get device descriptor\n");
libusb_free_device_list(devs,1);
libusb_close(handle);
break;
}
e = libusb_open(dev,&handle);
if (e < 0)
{
printf("error opening device\n");
libusb_free_device_list(devs,1);
libusb_close(handle);
break;
}
printf("\nDevice Descriptors: ");
printf("\n\tVendor ID : %x",desc.idVendor);
printf("\n\tProduct ID : %x",desc.idProduct);
printf("\n\tSerial Number : %x",desc.iSerialNumber);
printf("\n\tSize of Device Descriptor : %d",desc.bLength);
printf("\n\tType of Descriptor : %d",desc.bDescriptorType);
printf("\n\tUSB Specification Release Number : %d",desc.bcdUSB);
printf("\n\tDevice Release Number : %d",desc.bcdDevice);
printf("\n\tDevice Class : %d",desc.bDeviceClass);
printf("\n\tDevice Sub-Class : %d",desc.bDeviceSubClass);
printf("\n\tDevice Protocol : %d",desc.bDeviceProtocol);
printf("\n\tMax. Packet Size : %d",desc.bMaxPacketSize0);
printf("\n\tNo. of Configuraions : %d\n",desc.bNumConfigurations);
e = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, (unsigned char*) str1, sizeof(str1));
if (e < 0)
{
libusb_free_device_list(devs,1);
libusb_close(handle);
break;
}
printf("\nManufactured : %s",str1);
e = libusb_get_string_descriptor_ascii(handle, desc.iProduct, (unsigned char*) str2, sizeof(str2));
if(e < 0)
{
libusb_free_device_list(devs,1);
libusb_close(handle);
break;
}
printf("\nProduct : %s",str2);
printf("\n----------------------------------------");
if(desc.idVendor == 0xffff && desc.idProduct == 0x4)
{
found = 1;
break;
}
}//end of while
if(found == 0)
{
printf("\nDevice NOT found\n");
libusb_free_device_list(devs,1);
libusb_close(handle);
return 1;
}
else
{
printf("\nDevice found");
dev_expected = dev;
hDevice_expected = handle;
}
e = libusb_get_configuration(handle,&config2);
if(e!=0)
{
printf("\n***Error in libusb_get_configuration\n");
libusb_free_device_list(devs,1);
libusb_close(handle);
return -1;
}
printf("\nConfigured value : %d",config2);
if(config2 != 1)
{
libusb_set_configuration(handle, 1);
if(e!=0)
{
printf("Error in libusb_set_configuration\n");
libusb_free_device_list(devs,1);
libusb_close(handle);
return -1;
}
else
printf("\nDevice is in configured state!");
}
libusb_free_device_list(devs, 1);
if(libusb_kernel_driver_active(handle, 0) == 1)
{
printf("\nKernel Driver Active");
if(libusb_detach_kernel_driver(handle, 0) == 0)
printf("\nKernel Driver Detached!");
else
{
printf("\nCouldn't detach kernel driver!\n");
libusb_free_device_list(devs,1);
libusb_close(handle);
return -1;
}
}
e = libusb_claim_interface(handle, 0);
if(e < 0)
{
printf("\nCannot Claim Interface");
libusb_free_device_list(devs,1);
libusb_close(handle);
return -1;
}
else
printf("\nClaimed Interface\n");
active_config(dev_expected,hDevice_expected);
// Communicate
char *my_string, *my_string1;
int transferred = 0;
int received = 0;
int length = 0;
my_string = (char *)malloc(nbytes + 1);
my_string1 = (char *)malloc(nbytes + 1);
memset(my_string,'\0',64);
memset(my_string1,'\0',64);
strcpy(my_string,"prasad divesd");
length = strlen(my_string);
printf("\nTo be sent : %s",my_string);
e = libusb_bulk_transfer(handle,BULK_EP_IN,my_string,length,&transferred,0);
if(e == 0 && transferred == length)
{
printf("\nWrite successful!");
printf("\nSent %d bytes with string: %s\n", transferred, my_string);
}
else
printf("\nError in write! e = %d and transferred = %d\n",e,transferred);
sleep(3);
i = 0;
for(i = 0; i < length; i++)
{
e = libusb_bulk_transfer(handle,BULK_EP_OUT,my_string1,64,&received,0); //64 : Max Packet Lenght
if(e == 0)
{
printf("\nReceived: ");
printf("%c",my_string1[i]); //will read a string from lcp2148
sleep(1);
}
else
{
printf("\nError in read! e = %d and received = %d\n",e,received);
return -1;
}
}
e = libusb_release_interface(handle, 0);
libusb_close(handle);
libusb_exit(NULL);
printf("\n");
return 0;
}
To handle kernal detaching.
if(libusb_kernel_driver_active(dev_handle, 0) == 1) //find out if kernel driver is attached
{
cout << "Kernel Driver Active" << endl;
if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it
{
cout << "Kernel Driver Detached!" << endl;
}
}

encoding direcshow frame buffers by using libavcodec

I am trying to encode a stream buffer of frames grabbed by ISampleGrabber(directshow) by using libavcodec. After encoding those frame I am writing it into a file. But after completion file contains only green frames.
hers is code for grabbing frames and encoding it...
void DSGrabberCallback::initFFMpeg(){
const char* filename="G:/test1.mpg";
avcodec_register_all();
printf("Encode video file %s\n", filename);
AVCodecID codec_id=AV_CODEC_ID_MPEG2VIDEO;
codec = avcodec_find_encoder(codec_id);
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate video codec context\n");
}
c->bit_rate = 4000000;
c->width = 320;
c->height = 240;
AVRational test;
test.den=25;
test.num=1;
c->time_base= test;
c->gop_size = 10;
//c->max_b_frames=1;
c->pix_fmt = AV_PIX_FMT_YUV420P;
if(codec_id == AV_CODEC_ID_H264)
av_opt_set(c->priv_data, "preset", "slow", 0);
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
}
f = fopen(filename, "wb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename);
}
picture = alloc_picture(c->pix_fmt, c->width, c->height);
/*picture->format = c->pix_fmt;
picture->width = c->width;
picture->height = c->height;*/
av_init_packet(&pkt);
}
void DSGrabberCallback::encodeFrame(unsigned char *frame,ULONG size){
std::cout<<"called.....";
pkt.data = NULL;
pkt.size = 0;
picture->data[0]=frame;
fflush(stdout);
picture->pts=counter;
ret = avcodec_encode_video2(c, &pkt, picture, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding frame\n");
}
if (got_output) {
printf("Write frame %3d (size=%5d)\n", counter, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}
STDMETHODIMP DSGrabberCallback::SampleCB(double time, IMediaSample* sample)
{
BYTE* data = NULL;
ULONG length = 0;
m_bytes=NULL;
counter=counter+1;
if(FAILED(sample->GetPointer(&data)))
{
return E_FAIL;
}
length = sample->GetActualDataLength();
if(length == 0)
{
return S_OK;
}
if(!m_bytes || m_bytesLength < length)
{
if(m_bytes)
{
delete[] m_bytes;
}
m_bytes = new unsigned char[length];
m_bytesLength = length;
}
if(true)
{
for(size_t row = 0 ; row < 480 ; row++)
{
memcpy((m_bytes + row * 640 * 2), data + (480 - 1 - row) * 640 * 2,
640 * 2);
}
}
std::cout<<"hiiiiiiiiiiiiiiiiiiiiiiii";
// memcpy(m_bytes, data, length);
// std::cout<<"called............... "<<m_bytes<<"\n";
if(counter<500){
encodeFrame(m_bytes,length);
}else{
fwrite(endcode, 1, sizeof(endcode), f);
fclose(f);
avcodec_close(c);
av_free(c);
av_freep(&picture->data[0]);
avcodec_free_frame(&picture);
printf("\n");
exit(1);
}
//rtp.sendRTP(data,length);
//sample->Release();
//printf("Sample received: %p %u\n", data, length);
return S_OK;
}
can anyone tell me where is the problem.
Now working fine. Actually I forgot to convert the image buffer into YUV420P format. I have added some code for scaling the buffer into YUV format and everything is fine now. Thank you Wimmel and Roman R.

Resources