Displaying two translucent images on each other with XRender - c

So I was trying to display one translucent farbfeld image on top of another, often opaque farbfeld image (named f2.ff and f.ff in order) with the use of XRender to get the alpha compositing but due to the lack of examples on XRender and me being new to Xlib it does not work :)
and the translucent image which should have been displayed on top(f2.ff) is flickering weirdly.
Here is the code :
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#include "stb_image_resize.h"
#include <string.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xrender.h>
typedef struct XWindow XWindow;
struct XWindow
{
Display * dpy;
Window root;
Visual * vis;
Colormap cmap;
XWindowAttributes attr;
XSetWindowAttributes swa;
Window win;
int screen;
unsigned int width;
unsigned int height;
Atom wm_delete_window;
};
struct head
{
char ma [7];
unsigned int w;
unsigned int h;
};
unsigned char * ffread(const char * path,unsigned int * w,unsigned int * h)
{
struct head * hh;
size_t filelen;
unsigned char * buffer;
unsigned short temp=0;
size_t i=0;
FILE * file;
file=fopen(path,"rb");
if(file == NULL)
{
puts("cant open the file");
exit(1);
}
hh=malloc(16*sizeof(unsigned short));
fread(hh,2,15,file);
if(strcmp("farbfeld",hh->ma))
{
puts("Invalid file format");
exit(1);
}
*w=ntohl(hh->w);
*h=ntohl(hh->h);
printf("%d %d\n",*w,*h);
filelen=(*w)*(*h)*4;
buffer=malloc(filelen*sizeof(char));
fseek(file,16,SEEK_SET);
for(; i<filelen; i++)
{
fread(&temp,2,1,file);
if(i%4==0||i==0)
{
buffer[i+2]=(ntohs(temp)/257);
}
else if(i%2==0)
{
buffer[i-2]=(ntohs(temp)/257);
}
else
{
buffer[i]=(ntohs(temp)/257);
}
}
fclose(file);
return buffer;
}
int main(void)
{
XWindow xw;
unsigned char * data;
unsigned char * bdata;
unsigned char * im2;
unsigned int wim=0,him=0, w=0,h=0, wim2=0,him2 =0;
XImage * image;
Pixmap pix;
Picture pic;
Picture picdst;
GC gc;
XImage * imagebg;
Pixmap pix2;
Picture pic2bg;
memset(&xw, 0, sizeof xw);
xw.dpy = XOpenDisplay(NULL);
if(!xw.dpy) puts("Could not open a display; perhaps $DISPLAY is not set?");
xw.root = DefaultRootWindow(xw.dpy);
xw.screen = XDefaultScreen(xw.dpy);
xw.vis = XDefaultVisual(xw.dpy, xw.screen);
xw.cmap = XCreateColormap(xw.dpy,xw.root,xw.vis,AllocNone);
xw.swa.colormap = xw.cmap;
xw.swa.event_mask =
ExposureMask | KeyPressMask | KeyReleaseMask |
ButtonPress | ButtonReleaseMask| ButtonMotionMask |
Button1MotionMask | Button3MotionMask | Button4MotionMask | Button5MotionMask|
PointerMotionMask | KeymapStateMask;
h=DisplayHeight(xw.dpy,xw.screen);
w=DisplayWidth(xw.dpy,xw.screen);
xw.win = XCreateWindow(xw.dpy, xw.root, 0, 0, w, h, 0,
XDefaultDepth(xw.dpy, xw.screen), InputOutput,
xw.vis, CWEventMask | CWColormap, &xw.swa);
XStoreName(xw.dpy, xw.win, "X11");
XMapWindow(xw.dpy, xw.win);
xw.wm_delete_window = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
XSetWMProtocols(xw.dpy, xw.win, &xw.wm_delete_window, 1);
XGetWindowAttributes(xw.dpy, xw.win, &xw.attr);
xw.width = (unsigned int)xw.attr.width;
xw.height = (unsigned int)xw.attr.height;
data=ffread("./f.ff",&wim,&him);
bdata=(unsigned char *)malloc(w*h*4);
stbir_resize_uint8(data,wim,him,0,bdata,w,h,0,4);
im2=ffread("./f2.ff",&wim2,&him2);
picdst=XRenderCreatePicture(xw.dpy,xw.win,XRenderFindStandardFormat(xw.dpy, PictStandardRGB24),0,0);
image=XCreateImage(xw.dpy,CopyFromParent,32,ZPixmap, 0,(char *)im2,wim2, him2,4*8, 4 * wim2);
pix=XCreatePixmap(xw.dpy,xw.win,wim2,him2,32);
gc=XCreateGC(xw.dpy,pix,0,NULL);
XPutImage(xw.dpy,pix,gc,image,0,0,0,0,wim2,him2);
pic=XRenderCreatePicture(xw.dpy,pix,XRenderFindStandardFormat(xw.dpy, PictStandardARGB32),0,0);
imagebg =XCreateImage(xw.dpy,CopyFromParent,32,ZPixmap, 0,(char *)bdata,w, h,4*8, 4 * w);
pix2=XCreatePixmap(xw.dpy,xw.win,w,h,32);
gc=XCreateGC(xw.dpy,pix2,0,NULL);
XPutImage(xw.dpy,pix2,gc,imagebg,0,0,0,0,w,h);
pic2bg=XRenderCreatePicture(xw.dpy,pix2,XRenderFindStandardFormat(xw.dpy, PictStandardARGB32),0,0);
while(1)
{
pic2bg=XRenderCreatePicture(xw.dpy,pix2,XRenderFindStandardFormat(xw.dpy, PictStandardARGB32),0,0);
picdst=XRenderCreatePicture(xw.dpy,xw.win,XRenderFindStandardFormat(xw.dpy, PictStandardRGB24),0,0);
pic=XRenderCreatePicture(xw.dpy,pix,XRenderFindStandardFormat(xw.dpy, PictStandardARGB32),0,0);
XRenderComposite(xw.dpy,PictOpSrc,pic,None,picdst,0,0,0,0,0,0,wim2,him2);
XRenderComposite(xw.dpy,PictOpSrc,pic2bg,None,picdst,0,0,0,0,0,0,w,h);
XRenderFreePicture(xw.dpy,picdst);
XRenderFreePicture(xw.dpy,pic2bg);
XRenderFreePicture(xw.dpy,pic);
}
}

Related

how to read data using ffmpeg in c?

I have followed this tutorial:http://dranger.com/ffmpeg/tutorial01.html for using ffmpeg in android studio using android NDK.
I have made some minor correction as some functions used here are depreciated now.Here's my code can anyone point out whats wrong with my code as i am getting errorand couldn't find out what's wrong
#include <jni.h>
#include <string.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame);
JNICALL
JNIEXPORT jstring
Java_com_viralsam_root_tester_MainActivity_trtest(JNIEnv *env, jobject obj , jint argc,
jstring argv_){
const char *name;
int i,videostream;
name= (*env)->GetStringUTFChars(env, argv_,0);
AVFormatContext *pFormatctx=NULL;
if (avformat_open_input(&pFormatctx,name,NULL,NULL)!=0){
return (*env)->NewStringUTF(env,"a");
}
if(pFormatctx==NULL){
return (*env)->NewStringUTF(env,"b");
}
if(avformat_find_stream_info(pFormatctx,NULL)<0){
return (*env)->NewStringUTF(env,"c");
}
av_dump_format(pFormatctx, 0, name, 0);
videostream=-1;
AVCodecContext *pCodecCtxOrig = NULL;
AVCodecContext *pCodecCtx = NULL;
for (i=0;i<pFormatctx->nb_streams;i++){
if((pFormatctx->streams[i]->codecpar->codec_type)==AVMEDIA_TYPE_VIDEO){
videostream=i;
break;
}
}
if(videostream==-1){
return (*env)->NewStringUTF(env,"d");
}
pCodecCtx=pFormatctx->streams[videostream]->codecpar;
AVCodec *pCodec = NULL;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL){
return (*env)->NewStringUTF(env,"e");
}
pCodecCtx=avcodec_alloc_context3(pCodec);
if(avcodec_open2(pCodecCtx,pCodec,NULL)<0){
return (*env)->NewStringUTF(env,"g");
}
AVFrame *pFrame = NULL,*pFrameRBG=NULL;
pFrame=av_frame_alloc();
pFrameRBG=av_frame_alloc();
if(pFrameRBG==NULL){
return (*env)->NewStringUTF(env,"h");
}
uint8_t *buffer=NULL;
int numBytes;
numBytes=av_image_get_buffer_size(AV_PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height,1);
buffer=(uint8_t *)av_malloc(numBytes* sizeof(uint8_t));
av_image_fill_arrays(pFrameRBG->data,pFrameRBG->linesize,buffer,AV_PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height,1);
struct SwsContext *sws_ctx = NULL;
int frameFinished;
AVPacket *packet=av_packet_alloc();
sws_ctx=sws_getContext(pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt,pCodecCtx->width,pCodecCtx->height,AV_PIX_FMT_RGB24,SWS_BILINEAR,NULL,NULL,NULL);
i=0;
while(av_read_frame(pFormatctx,&packet)>=0){
if(packet->stream_index==videostream){
int used=avcodec_send_packet(pCodecCtx,&packet);
used=avcodec_receive_frame(pCodecCtx,pFrame);
if (used < 0 && used != AVERROR(EAGAIN) && used != AVERROR_EOF){
break;
} else{
if (used == AVERROR(EAGAIN) || used == AVERROR_EOF){
break;
}
}
sws_scale(sws_ctx,(uint8_t const * const *)pFrame->data,pFrame->linesize,0,pCodecCtx->height,pFrameRBG->data,pFrameRBG->linesize);
if(++i<=5){
SaveFrame(pFrameRBG,pCodecCtx->width,pCodecCtx->height,i);
}
}
av_packet_free(&packet);
}
char blubuk[50];
sprintf(blubuk,"%d",buffer);
av_free(buffer);
av_frame_free(&pFrameRBG);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
avcodec_close(pCodecCtxOrig);
avformat_close_input(&pFormatctx);
return (*env)->NewStringUTF(env,blubuk);
}
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame){
FILE *pFile;
char szFilename[32];
int y;
sprintf(szFilename, "frame%d.ppm", iFrame);
pFile=fopen(szFilename,"wb");
if(pFile==NULL){
return;
}
fprintf(pFile, "P6\n%d %d\n255\n", width, height);
for(y=0; y<height; y++){
fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
}
fclose(pFile);
}
UPDATE:
I am getting "-22" from "int used=avcodec_send_packet(pCodecCtx,packet);".Can't figure out where i went wrong.

How to get the raw data of CR2 image using LibRaw(c++)

LibRaw is a library for reading RAW files from digital photo cameras (CRW/CR2, NEF, RAF, DNG, MOS, KDC, DCR, etc.; virtually all RAW formats are supported).
I want to know how to use LibRaw to get the raw data of a Canon CR2 image.
typedef struct
{
ushort (*image)[4] ;
libraw_image_sizes_t sizes;
libraw_iparams_t idata;
libraw_lensinfo_t lens;
libraw_makernotes_t makernotes;
libraw_shootinginfo_t shootinginfo;
libraw_output_params_t params;
unsigned int progress_flags;
unsigned int process_warnings;
libraw_colordata_t color;
libraw_imgother_t other;
libraw_thumbnail_t thumbnail;
libraw_rawdata_t rawdata;
void *parent_class;
} libraw_data_t;
typedef struct
{
void *raw_alloc;
ushort *raw_image;
ushort (*color4_image)[4] ;
ushort (*color3_image)[3];
float *float_image;
float (*float3_image)[3];
float (*float4_image)[4];
short (*ph1_cblack)[2];//
short (*ph1_rblack)[2];//
libraw_iparams_t iparams;//
libraw_image_sizes_t sizes;//
libraw_internal_output_params_t ioparams;//
libraw_colordata_t color;//
} libraw_rawdata_t;
This is the data structure of RAW data, I don't know which structure the most primitive data is stored in.
I have already got the answer, now download it below, I hope to help those in need.
int i,ret,verbose = 0,output_thumbs = 0;
char outfn [1024],thumbfn [1024];
//Create object
LibRaw RawProcessor;
putenv((char *)"TZ = UTC+8");
//
#define P1 RawProcessor.imgdata.idata
#define S RawProcessor.imgdata.sizes
#define C RawProcessor.imgdata.color
#define T RawProcessor.imgdata.thumbnail
#define P2 RawProcessor.imgdata.other
#define OUT RawProcessor.imgdata.params
OUT.output_tiff = 0; //
OUT.no_auto_scale=1;//
OUT.no_auto_bright=1;//
OUT.output_bps=16;//16bit
OUT.output_color=0;//RAW
//openfile
if((ret = RawProcessor.open_file(szFile))!= LIBRAW_SUCCESS)
{
fprintf(stderr,"Can not open%s:%s\n",szFile,libraw_strerror(ret));
RawProcessor.recycle();
return FALSE;
}
//RAW size
int height=S.raw_height;
int width=S.raw_width;
//image info
memset(LinsnData.imgdata.make,0,64*sizeof(char));
memset(LinsnData.imgdata.model,0,64*sizeof(char));
memcpy(LinsnData.imgdata.make,P1.make,strlen(P1.make));
memcpy(LinsnData.imgdata.model,P1.model,strlen(P1.model));
LinsnData.imgdata.aperture=P2.aperture;
LinsnData.imgdata.iso_speed=P2.iso_speed;
LinsnData.imgdata.shutter=P2.shutter;
char timestamp[64]= {0};
tm* local = localtime(&P2.timestamp); //
strftime(LinsnData.imgdata.timestamp, 64, "%Y-%m-%d %H:%M:%S", local);
/***************************************************************************************************/
//
if((ret = RawProcessor.unpack())!= LIBRAW_SUCCESS)
{
fprintf(stderr,"Can not unpack_thumb%s:%s\n",szFile,libraw_strerror(ret));
//if(LIBRAW_FATAL_ERROR(ret))
goto end;
}
WORD *bmpData=RawProcessor.imgdata.rawdata.raw_image;
int nWidth = width/2;
int nHeight = height/2;
WORD *m_bmpDataR = new WORD[nWidth*nHeight];
WORD *m_bmpDataG = new WORD[nWidth*nHeight];
WORD *m_bmpDataB = new WORD[nWidth*nHeight];
//
for(int i=0;i<nHeight;i++)
{
for(int j=0;j<nWidth;j++)
{
m_bmpDataB[i*nWidth+j] = bmpData[i*nWidth*4+nWidth*2+j*2+1];
m_bmpDataG[i*nWidth+j] = ((bmpData[i*nWidth*4+nWidth*2+j*2]+bmpData[i*nWidth*4+j*2+1])>>1);
m_bmpDataR[i*nWidth+j] = bmpData[i*nWidth*4+j*2];
}
}

XGetImage is mangled for chrome, firefox, electron, when using XCompositeRedirectWindow

I am attempting to create a thumbnailer (for i3wm on linux) which generates an icon from a screenshot for all the available windows. The aim being to replicate something like how windows uses Alt-Tab to produce a pane of windows to choose from;
The current prototype uses pygtk to generate the dialog, and it creates thumbnails of the windows in the _NET_CLIENT_LIST using XGetImage where the windows have been redirected using XCompositeRedirectWindow. It works pretty well except for that images captured from windows which are browsers, (e.g. firefox, chrome, electron) are mangled, or wrong;
Basically, tools like xwd, scrot and import don't work for the hidden windows in i3, presumably because they are unmapped. So I have pulled some code together to create the thumbnails. The core of it is based on an example using XCompositeRedirectWindow from X11/extensions/Xcomposite.h from here.
My attempt at creating a short example is here;
https://gist.github.com/tolland/4bb1e97db258b92618adfb783ce66fac
it can be compiled with;
$ gcc example.c -lX11 -lXcomposite -lXrender -lpng -o example
and then to output png files for each of the windows;
$ mkdir -p /tmp/png_out && ./example
will produce pngs for each of the images
window found was 58720312
found window name for 58720312 : build : sudo
filename /tmp/png_out/58720312_test3.png
window found was 79691781
found window name for 79691781 : .xsession-errors - glogg
filename /tmp/png_out/79691781_test3.png
window found was 62914576
found window name for 62914576 : Edit - Stack Overflow - Mozilla Firefox
filename /tmp/png_out/62914576_test3.png
So the code I am currently using to walk the _NET_CLIENT_LIST is this;
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <libpng16/png.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xrender.h>
//Compile hint: gcc -shared -O3 -lX11 -fPIC -Wl,-soname,prtscn -o prtscn.so prtscn.c
typedef int bool;
#define true 1
#define false 0
const int DEBUG = 0;
void getScreen2(const int, const int, const int, const int, const XID);
void write_png_for_image(XImage *image, XID xid, int width, int height,
char *filename);
typedef int (*handler)(Display *, XErrorEvent *);
XID getWindows(Display *display, Window parent, Window window, XID xid,
int depth);
int main() {
Display *display = XOpenDisplay(NULL);
Window root = DefaultRootWindow(display);
uint nwindows;
Window root_return, parent_return, *windows;
Atom a = XInternAtom(display, "_NET_CLIENT_LIST", true);
Atom actualType;
int format;
unsigned long numItems, bytesAfter;
unsigned char *data = 0;
int status = XGetWindowProperty(display, root, a, 0L, (~0L),
false,
AnyPropertyType, &actualType, &format, &numItems, &bytesAfter, &data);
char* window_name_return;
if (status >= Success && numItems) {
long *array = (long*) data;
for (long k = 0; k < numItems; k++) {
Window window = (Window) array[k];
//not finding chrome window name
printf("window found was %d \n", window);
if (XFetchName(display, window, &window_name_return)) {
printf("found window name for %d : %s \n", window,
window_name_return);
}
//XMapWindow(display, parent);
XMapWindow(display, window);
XWindowAttributes attr;
Status status = XGetWindowAttributes(display, window, &attr);
if (status == 0)
printf("Fail to get window attributes!\n");
getScreen2(0, 0, attr.width, attr.height, window);
}
XFree(data);
}
return 0;
}
which calls this function to map the window and call XCompositeRedirectWindow;
void getScreen2(const int xx, const int yy, const int W, const int H,
const XID xid) {
Display *display = XOpenDisplay(NULL);
Window root = DefaultRootWindow(display);
// turn on --sync to force error on correct method
//https://www.x.org/releases/X11R7.6/doc/man/man3/XSynchronize.3.xhtml
XSynchronize(display, True);
int counter = 1;
// select which xid to operate on, the winder or its parent
//XID xwid = fparent;
XID xwid = xid;
// Requests the X server to direct the hierarchy starting at window to off-screen storage
XCompositeRedirectWindow(display, xwid, CompositeRedirectAutomatic);
XWindowAttributes attr;
Status status = XGetWindowAttributes(display, xwid, &attr);
int width = attr.width;
int height = attr.height;
int depth = attr.depth;
Pixmap xc_pixmap = XCompositeNameWindowPixmap(display, xwid);
if (!xc_pixmap) {
printf("xc_pixmap not found\n");
}
//XWriteBitmapFile(display, "test1.xpm", pixmap, W, H, -1, -1);
XRenderPictFormat *format = XRenderFindVisualFormat(display, attr.visual);
XRenderPictureAttributes pa;
pa.subwindow_mode = IncludeInferiors;
Picture picture = XRenderCreatePicture(display, xwid, format,
CPSubwindowMode, &pa);
char buffer[50];
int n;
int file_counter = 1;
n = sprintf(buffer, "/tmp/%d_test%d.xpm", xid, file_counter++);
XWriteBitmapFile(display, buffer, xc_pixmap, W, H, -1, -1);
n = sprintf(buffer, "/tmp/%d_test%d.xpm", xid, file_counter++);
XWriteBitmapFile(display, buffer, xid, W, H, -1, -1);
XImage *image = XGetImage(display, xid, 0, 0, W, H, AllPlanes, ZPixmap);
if (!image) {
printf("XGetImage failed\n");
}
char filename[255];
int n2;
n2 = sprintf(filename, "/tmp/png_out/%d_test%d.png", xid, file_counter++);
printf("filename %s \n", filename);
write_png_for_image(image, xid, W, H, filename);
//XFree(image);
XDestroyImage(image);
XDestroyWindow(display, root);
XCloseDisplay(display);
}
and then this to write out the png;
void write_png_for_image(XImage *image, XID xid, int width, int height,
char *filename) {
int code = 0;
FILE *fp;
png_structp png_ptr;
png_infop png_info_ptr;
png_bytep png_row;
char buffer[50];
int n;
n = sprintf(buffer, filename, xid);
// Open file
fp = fopen(buffer, "wb");
if (fp == NULL) {
fprintf(stderr, "Could not open file for writing\n");
code = 1;
}
// Initialize write structure
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
fprintf(stderr, "Could not allocate write struct\n");
code = 1;
}
// Initialize info structure
png_info_ptr = png_create_info_struct(png_ptr);
if (png_info_ptr == NULL) {
fprintf(stderr, "Could not allocate info struct\n");
code = 1;
}
// Setup Exception handling
if (setjmp(png_jmpbuf (png_ptr))) {
fprintf(stderr, "Error during png creation\n");
code = 1;
}
png_init_io(png_ptr, fp);
// Write header (8 bit colour depth)
png_set_IHDR(png_ptr, png_info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
// Set title
char *title = "Screenshot";
if (title != NULL) {
png_text title_text;
title_text.compression = PNG_TEXT_COMPRESSION_NONE;
title_text.key = "Title";
title_text.text = title;
png_set_text(png_ptr, png_info_ptr, &title_text, 1);
}
png_write_info(png_ptr, png_info_ptr);
// Allocate memory for one row (3 bytes per pixel - RGB)
png_row = (png_bytep) malloc(3 * width * sizeof(png_byte));
unsigned long red_mask = image->red_mask;
unsigned long green_mask = image->green_mask;
unsigned long blue_mask = image->blue_mask;
// Write image data
//int xxx, yyy;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
unsigned long pixel = XGetPixel(image, x, y);
unsigned char blue = pixel & blue_mask;
unsigned char green = (pixel & green_mask) >> 8;
unsigned char red = (pixel & red_mask) >> 16;
png_byte *ptr = &(png_row[x * 3]);
ptr[0] = red;
ptr[1] = green;
ptr[2] = blue;
}
png_write_row(png_ptr, png_row);
}
// End write
png_write_end(png_ptr, NULL);
// Free
fclose(fp);
if (png_info_ptr != NULL)
png_free_data(png_ptr, png_info_ptr, PNG_FREE_ALL, -1);
if (png_ptr != NULL)
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
if (png_row != NULL)
free(png_row);
}
However when the windows is browser based, the image is mangled like so;
Do I need to do something special to get browser windows working?
References;
https://www.talisman.org/~erlkonig/misc/x11-composite-tutorial/
Get a screenshot of a window that is cover or not visible or minimized with Xcomposite extension for X11

I can not understand how to use buffers in the audio resampling

What i have tryed:
Player.c
const int BITS=8;
int isPaused=0;
static mpg123_handle *mh;
static unsigned char *buffer;
static size_t buffer_size;
static size_t done;
char * resBuffer;
//from global stat!
int outfreq=22050; int infreq=44100;
int resetMp3(char * song)
{
int err;
int channels, encoding;
long rate;
/* Inizialize */
mpg123_init();
mh = mpg123_new(NULL, &err);
buffer_size = mpg123_outblock(mh);
buffer = (unsigned char*) malloc(buffer_size * sizeof(unsigned char));
resBuffer=(unsigned char*) malloc(buffer_size * sizeof(unsigned char) * (1.0+(outfreq/infreq)));
/* open the file and get the decoding format */
mpg123_open(mh,song);
mpg123_getformat(mh, &rate, &channels, &encoding);
/* set the output format and open the output device */
int bits=(mpg123_encsize(encoding) * BITS);
initAudioDev(bits,rate,channels);
//Add for resampling
inizializeResample(infreq,outfreq);
}
int playMp3(){
/* decode and play */
if (isPaused==0 && mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK)
{
//char * resBuffer=malloc(sizeof(unsigned char)*buffer_size/(outfreq/infreq));
resBuffer=&buffer[0];
resample(buffer,resBuffer,done);
writeAudio((char*)resBuffer,done);
} else {
if (isPaused==0) return 2;
}
return 0;
}
int freeMp3()
{
free(buffer);
mpg123_close(mh);
mpg123_delete(mh);
mpg123_exit();
freeAudioDev();
endResample();
}
void setMp3Status(int value)
{
if(value==0||value==1)
{
isPaused=value;
} else {
isPaused=!isPaused;
}
}
Resampling.c
#include <assert.h>
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include "libavcodec/avcodec.h"
#define LENGTH_MS 1000 // how many milliseconds of speech to store
#define RATE 44100 // the sampling rate (input)
struct AVResampleContext* audio_cntx = 0;
int samples_consumed;
void inizializeResample(int inRate, int outRate)
{
//char out_buffer[ sizeof( in_buffer ) * 4];
audio_cntx = av_resample_init( outRate, //out rate
inRate, //in rate
4, //filter length 16
3, //phase count 10
0, //linear FIR filter
0.6 ); //cutoff frequency
assert( audio_cntx && "Failed to create resampling context!");
}
void resample(char dataIn[],char dataOut[],int nsamples)
{
int samples_output = av_resample( audio_cntx, //resample context
(short*)dataOut, //buffout
(short*)dataIn, //buffin
&samples_consumed, //&consumed
nsamples, //nb_samples
(sizeof(dataOut)*nsamples),//lenout sizeof(out_buffer)/2
0);//is_last
assert( samples_output > 0 && "Error calling av_resample()!" );
}
void endResample()
{
av_resample_close( audio_cntx );
}
Now, when I execute this code, the audio isn't clear and resampling isn't done, problably because have wrong something with pointers and buffers.I review this code hundreds of time without find the error.
Can help me to find it and explain right how i should correctly size the buffers?
Now i think another problem is that i can't define what mpg123_read give me, if you explain this i love you.
Library used:Libmpg123 - The decoder function: mpg123_read
Resampling Library: FFMpeg AVCodec Library.
Ps: yes problaby a noob question, but after many attempts, StackOverflow is the only thing that can help me, THANK YOU

how to stop linux framebuffer to clear automatically while drawing multiple frames

I am writing a gif decoder, This image is an animated image.When I write the first frame, it displays fine. When, I display the second frame, it displays only the changed pixels. Other pixels are automatically changed to black. I don't know why?.
My first frame has the complete picture.
The second frame has again only the pixel changed and it contains the rest of the unchanged pixels.
Now, when I draw the second buffer, it redraws the unchanged pixels also. And the unchanged pixels are drawn as black ( or precisely in monitor I see these unchanged pixels are absent). That's when it has to draw the second frame.It draws the changed pixels( which is correct), but it re-draws the unchanged pixel as well. And this unchanged pixel are seen as a black ( that is no color). I feel it is a refreshing issue. Or It could be something else. Help is appreciated.
Required: It should redraw the complete image.
In short, this is the snippet of my function.
Unfortunately, it clears off the previous display - linux framebuffer.
I want to stop clearning the linux framebuffer.
here is the complete file.
/** This is using the Direct Fb calls here; and is tightly coupled with Linux Framebuffer **/
static int fbfd = 0;
static struct fb_var_screeninfo vinfo;
static struct fb_fix_screeninfo finfo;
static long int screensize = 0;
static char *fbp = 0;
static int x = 0, y = 0;
static long int location = 0;
/** This is a clone to linux Frame buffer, and will be called to dump on Framebuffer **/
char *local_display_mem;
/** local functions **/
static void SetBackground(FrameData *tempInfo);
static void SetPixel(char *fbp, unsigned int x, unsigned int y, Byte red, Byte green, Byte blue);
/** This is the entry function to initialize the display **/
void display_init()
{
// Open the file for reading and writing
fbfd = open("/dev/fb0", O_RDWR);
if (fbfd == -1)
{
perror("cannot open framebuffer device");
exit(1);
}
#ifdef DEBUG
printf("The framebuffer device was opened successfully.\n");
#endif
/** Read the Screen Information **/
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1)
{
perror("Driver error-- reading fixed information");
exit(1);
}
// Get variable screen information
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1)
{
perror("Error reading variable information");
exit(1);
}
#ifdef DEBUG
printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
#endif
// Figure out the size of the screen in bytes
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
// Map the device to memory
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
local_display_mem = (char*)malloc(screensize);
if ((int)fbp == -1)
{
perror("Error: mmap failed\r\n");
exit(1);
}
#ifdef DEBUG
printf("The framebuffer device was mapped to memory successfully.\n");
#endif
printf("Shreyas..Display Initialized..\r\n");
//munmap(fbp, screensize);
//close(fbfd);
}
/** This function is called by gif_read to display the Image **/
void Display(FrameData *FrameInfo)
{
short int ImageStartX = 0;
short int ImageStartY = 0;
int Index = 0;
printf("\r\n INFO: Display Called.\r\n");
while(1)
{
Index = 0;
ImageStartX = (FrameInfo->frameScreenInfo.LeftPosition);
ImageStartY = (FrameInfo->frameScreenInfo.TopPosition);
while(ImageStartY < ((FrameInfo->frameScreenInfo.ImageHeight)+(FrameInfo->frameScreenInfo.TopPosition)))
{
while(ImageStartX < ((FrameInfo->frameScreenInfo.ImageWidth)+(FrameInfo->frameScreenInfo.LeftPosition)))
{
if(FrameInfo->frame[Index] != FrameInfo->transperencyindex)
{
SetPixel(local_display_mem,ImageStartX,ImageStartY,((FrameInfo->CMAP)+(FrameInfo->frame[Index]))->Red,((FrameInfo->CMAP)+(FrameInfo->frame[Index]))->Green,((FrameInfo->CMAP)+(FrameInfo->frame[Index]))->Blue);
}
Index++;
ImageStartX++;
}
ImageStartY++;
ImageStartX=(FrameInfo->frameScreenInfo.LeftPosition);
}
printf("INFO:..Dumping Framebuffer\r\n");
memcpy(fbp,local_display_mem,screensize);
/** Tune this multiplication to meet the right output on the display **/
usleep((FrameInfo->InterFrameDelay)*100000);
if( FrameInfo->DisposalMethod == 2)
{
printf("set the Background\r\n");
SetBackground(FrameInfo);
}
FrameInfo = FrameInfo->Next;
}
}
static void SetBackground(FrameData *tempInfo)
{
unsigned int ImageStartX=0;
unsigned int ImageStartY=0;
ImageStartX=(tempInfo->frameScreenInfo.LeftPosition);
ImageStartY=(tempInfo->frameScreenInfo.TopPosition);
while(ImageStartY<(tempInfo->frameScreenInfo.ImageHeight))
{
while(ImageStartX<(tempInfo->frameScreenInfo.ImageWidth))
{
SetPixel(local_display_mem,ImageStartX,ImageStartY,255,255,255);
ImageStartX++;
}
ImageStartX=(tempInfo->frameScreenInfo.LeftPosition);
ImageStartY++;
}
}
static void SetPixel(char *fbp_lc, unsigned int x, unsigned int y, Byte red, Byte green, Byte blue)
{
//printf("Shreyas..set pixel called\r\n");
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
if (vinfo.bits_per_pixel == 32)
{
*(fbp_lc + location) = blue; // Some blue
*(fbp_lc + location + 1) = green; // A little green
*(fbp_lc + location + 2) = red; // A lot of red
*(fbp_lc + location + 3) = 0; // No transparency
//location += 4;
}
else
{ //assume 16bpp
unsigned short int t = red<<11 | green << 5 | blue;
*((unsigned short int*)(fbp_lc + location)) = t;
}
//printf("Shreyas..set pixel exit called\r\n");
}
/** This is windows version of display function, and it works correctly.
void Display(FrameData *FrameInfo)
{
short int ImageStartX=0;
short int ImageStartY=0;
int Index=0;
DisplayCntrl=GetDC(hWnd);
printf("Shreyas.. Display Init is called\r\n");
//display_init();
while(1)
{
Index=0;
ImageStartX=(FrameInfo->frameScreenInfo.LeftPosition);
ImageStartY=(FrameInfo->frameScreenInfo.TopPosition);
while(ImageStartY<((FrameInfo->frameScreenInfo.ImageHeight)+(FrameInfo->frameScreenInfo.TopPosition)))
{
while(ImageStartX<((FrameInfo->frameScreenInfo.ImageWidth)+(FrameInfo->frameScreenInfo.LeftPosition)))
{
if(FrameInfo->frame[Index]!=FrameInfo->transperencyindex)
SetPixel(DisplayCntrl,ImageStartX,ImageStartY,RGB(((FrameInfo->CMAP)+(FrameInfo->frame[Index]))->Red,((FrameInfo->CMAP)+(FrameInfo->frame[Index]))->Green,((FrameInfo->CMAP)+(FrameInfo->frame[Index]))->Blue));
Index++;
ImageStartX++;
}
ImageStartY++;
ImageStartX=(FrameInfo->frameScreenInfo.LeftPosition);
}
Sleep((FrameInfo->InterFrameDelay*10));
WaitForSingleObject(hWnd,10);
if( FrameInfo->DisposalMethod==2)
{
SETBACKGROUND(FrameInfo);
}
FrameInfo=FrameInfo->Next;
}
}
This is the windows version of the same code.
extern hWnd;
HDC DisplayCntrl;
void SETBACKGROUND(FrameData *tempInfo)
{
unsigned int ImageStartX=0;
unsigned int ImageStartY=0;
ImageStartX=(tempInfo->frameScreenInfo.LeftPosition);
ImageStartY=(tempInfo->frameScreenInfo.TopPosition);
while(ImageStartY<(tempInfo->frameScreenInfo.ImageHeight))
{
while(ImageStartX<(tempInfo->frameScreenInfo.ImageWidth))
{
SetPixel(DisplayCntrl,ImageStartX,ImageStartY,RGB(255,255,255));
ImageStartX++;
}
ImageStartX=(tempInfo->frameScreenInfo.LeftPosition);
ImageStartY++;
}
}
void Display(FrameData *FrameInfo)
{
short int ImageStartX=0;
short int ImageStartY=0;
int Index=0;
DisplayCntrl=GetDC(hWnd);
printf("the size of short int is %d",sizeof(short int));
while(1)
{
Index=0;
ImageStartX=(FrameInfo->frameScreenInfo.LeftPosition);
ImageStartY=(FrameInfo->frameScreenInfo.TopPosition);
while(ImageStartY<((FrameInfo->frameScreenInfo.ImageHeight)+(FrameInfo->frameScreenInfo.TopPosition)))
{
while(ImageStartX<((FrameInfo->frameScreenInfo.ImageWidth)+(FrameInfo->frameScreenInfo.LeftPosition)))
{
if(FrameInfo->frame[Index]!=FrameInfo->transperencyindex)
{
SetPixel(DisplayCntrl,ImageStartX,ImageStartY,RGB(((FrameInfo->CMAP)+(FrameInfo->frame[Index]))->Red,((FrameInfo->CMAP)+(FrameInfo->frame[Index]))->Green,((FrameInfo->CMAP)+(FrameInfo->frame[Index]))->Blue));
}
Index++;
ImageStartX++;
}
ImageStartY++;
ImageStartX=(FrameInfo->frameScreenInfo.LeftPosition);
}
Sleep((FrameInfo->InterFrameDelay*10));
WaitForSingleObject(hWnd,10);
if( FrameInfo->DisposalMethod==2)
{
SETBACKGROUND(FrameInfo);
}
FrameInfo=FrameInfo->Next;
}
}
Since you use a local memory buffer local_display_mem, it doesn't matter if somebody would clear the framebuffer - the memcpy will overwrite every pixel.
This means that the condition FrameInfo->frame[Index] != FrameInfo->transperencyindex is always true for some reason since that would cause the algorithm to set each pixel again instead of only updating the changed pixels.

Resources