ffmpeg_decode.c:
#include
}
lcd.h:
#ifndef LCD_H_
#define LCD_H_
#include
#include
#include
#include
#include
#include "myhead.h"
#define RED (0x1f << 11)
#define GREEN (0x3f << 5)
#define BLUE (0x1f)
extern const unsigned char __CHS[];
extern const unsigned char __ASCII[];
struct lcd_info_t {
int lcdfd;
char *fbp;
int w;
int h;
int xoffset;
int yoffset;
int bpp;
int screensize;
int line_length;
};
/*
** lcd_device: such as "/dev/fb0"
** return: NULL error
*/
struct lcd_info_t *lcd_init(const char *lcd_device);
/*
** return:0 succeed
** :-1 error
*/
int lcd_release(struct lcd_info_t *lcdinfo);
void lcd_putpixel(struct lcd_info_t *lcdinfo, int x, int y, u16 color);
/*
** color:what backgroung color to show
*/
void clear_screen(struct lcd_info_t *lcdinfo, u16 color);
/*
** (xp,yp):display position
** w,h:what image size to display
** video:what image to display
*/
void show16bpp(struct lcd_info_t *lcdinfo, int xp, int yp, int w, int h, u16 *video);
/*
** print 8x16 ascii
** (xp,yp):display position
** ch:what ascii to show
** color:what text color to show
** bgc:what background color to show
** bg :1 show background color
** :0 don't show background color
*/
void lcd_put_ascii(struct lcd_info_t *lcdinfo, int xp, int yp, const unsigned char ch, u16 color, u16 bgc, u8 bg);
/*
** node:must in ANSI character encoding
** print 16x16 Chinese word
** (xp,yp):display position
** al:area number and location number
** color:what Chinese word color to show
** bgc:what background color to show
** bg :1 show background color
** :0 don't show background color
*/
void lcd_put_hz(struct lcd_info_t *lcdinfo, int xp, int yp, u16 al, u16 color, u16 bgc, u8 bg);
void lcd_printf(struct lcd_info_t *lcdinfo, int xp, int yp, u16 color, u16 bgc, u8 bg, char *fmt, ...);
#endif
lcd.c:
#include "lcd.h"
struct lcd_info_t *lcd_init(const char *lcd_device)
{
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
static struct lcd_info_t *lcdinfo = NULL;
lcdinfo = malloc(sizeof(struct lcd_info_t));
if (NULL == lcdinfo) {
my_debug("malloc");
return NULL;
}
bzero(lcdinfo, sizeof(struct lcd_info_t));
/* Open the file for reading and writing */
lcdinfo->lcdfd = open(lcd_device, O_RDWR);
if (lcdinfo->lcdfd < 0) {
my_debug("open");
return NULL;
}
my_debug("The framebuffer device was opened successfully.\n");
/* Get fixed screen information */
if (ioctl(lcdinfo->lcdfd, FBIOGET_FSCREENINFO, &finfo)) {
my_debug("ioctl");
return NULL;
}
/* Get variable screen information */
if (ioctl(lcdinfo->lcdfd, FBIOGET_VSCREENINFO, &vinfo)) {
my_debug("ioctl");
return NULL;
}
lcdinfo->w = vinfo.xres;
lcdinfo->h = vinfo.yres;
lcdinfo->xoffset = vinfo.xoffset;
lcdinfo->yoffset = vinfo.yoffset;
lcdinfo->bpp = vinfo.bits_per_pixel;
lcdinfo->line_length = finfo.line_length;
my_debug("%dx%d, %dbpp\n", lcdinfo->w, lcdinfo->h, lcdinfo->bpp);
/* Figure out the size of the screen in bytes */
lcdinfo->screensize = lcdinfo->w * lcdinfo->h * lcdinfo->bpp / 8;
/* Map the device to memory */
lcdinfo->fbp = (char *)mmap(0, lcdinfo->screensize, PROT_READ | PROT_WRITE, MAP_SHARED, lcdinfo->lcdfd, 0);
if (MAP_FAILED == lcdinfo->fbp) {
my_debug("mmap");
return NULL;
}
my_debug("The framebuffer device was mapped to memory successfully.\n");
clear_screen(lcdinfo, 0);
return lcdinfo;
}
int lcd_release(struct lcd_info_t *lcdinfo)
{
if (munmap(lcdinfo->fbp, lcdinfo->screensize)< 0) {
my_debug("munmap");
return -1;
}
my_debug("The framebuffer device was munmapped to memory successfully.\n");
close(lcdinfo->lcdfd);
my_debug("The framebuffer device was closed successfully.\n");
free(lcdinfo);
return 0;
}
void lcd_putpixel(struct lcd_info_t *lcdinfo, int x, int y, u16 color)
{
int location = 0;
if ( (x >= lcdinfo->w) || (y >= lcdinfo->h))
return;
location = (x + lcdinfo->xoffset) * (lcdinfo->bpp / 8) + (y + lcdinfo->yoffset) * lcdinfo->line_length;
*((u16 *)(lcdinfo->fbp + location)) = color;
}
void clear_screen(struct lcd_info_t *lcdinfo, u16 color)
{
int location;
for (int y = 0; y < lcdinfo->h; y++) {
for (int x = 0; x < lcdinfo->w; x++) {
location = (x + lcdinfo->w) * (lcdinfo->bpp / 8) + (y + lcdinfo->h) * lcdinfo->line_length;
lcd_putpixel(lcdinfo, x, y, color);
}
}
}
void show16bpp(struct lcd_info_t *lcdinfo, int xp, int yp, int w, int h, u16 *video)
{
if (w > lcdinfo->w - xp)
w = lcdinfo->w - xp;
if (h > lcdinfo->h - yp)
h = lcdinfo->h - yp;
for (int y = yp; y < h; y++) {
for (int x = xp; x < w; x++) {
lcd_putpixel(lcdinfo, x, y, *video++);
}
}
}
void lcd_put_ascii(struct lcd_info_t *lcdinfo, int xp, int yp, const unsigned char ch, u16 color, u16 bgc, u8 bg)
{
unsigned char *pZK, mask, buffer;
int x, y;
pZK = (unsigned char *)&__ASCII[ch * 16];
for (y = 0; y < 16; y++) {
mask = 0x80;
buffer = pZK[y];
for (x = 0; x < 8; x++) {
if(buffer & mask)
lcd_putpixel(lcdinfo, xp + x, yp + y, color);
else if(bg)
lcd_putpixel(lcdinfo, xp + x, yp + y, bgc);
mask = mask >> 1;
}
}
}
void lcd_put_hz(struct lcd_info_t *lcdinfo, int xp, int yp, u16 al, u16 color, u16 bgc, u8 bg)
{
int x, y;
unsigned char *pZK,mask,buf;
pZK = (unsigned char *)&__CHS[(((al >> 8) - 1 )*94 + (al & 0x00FF)- 1)*32];
for (y = 0 ; y < 16 ; y++) {
/* left */
mask = 0x80;
buf = pZK[y * 2];
for (x = 0; x < 8; x++) {
if (buf & mask)
lcd_putpixel(lcdinfo, xp + x, yp + y, color);
else if (bg)
lcd_putpixel(lcdinfo, xp + x, yp + y, bgc);
mask = mask >> 1;
}
/* right */
mask = 0x80;
buf = pZK[y * 2 + 1];
for (x = 0; x < 8; x++) {
if (buf & mask)
lcd_putpixel(lcdinfo, xp + x + 8, yp + y, color);
else if (bg)
lcd_putpixel(lcdinfo, xp + x + 8, yp + y, bgc);
mask = mask >> 1;
}
}
}
void lcd_printf(struct lcd_info_t *lcdinfo, int xp, int yp, u16 color, u16 bgc, u8 bg, char *fmt, ...)
{
char __LCD_Printf_Buf[256];
va_list ap;
unsigned char *pStr = (unsigned char *)__LCD_Printf_Buf;
unsigned int i = 0;
va_start(ap,fmt);
vsprintf(__LCD_Printf_Buf,fmt,ap);
va_end(ap);
while (*pStr != 0) {
switch (*pStr) {
case '\n':
break;
default:
if ( *pStr > 0xA0 && *(pStr+1) > 0xA0 ) { // Chinese
lcd_put_hz(lcdinfo, xp , yp, (*pStr - 0xA0)*0x0100 + *(pStr+1) - 0xA0, color, bgc, bg);
pStr++;
i++;
xp += 16;
}
else { /* ASCII */
lcd_put_ascii(lcdinfo, xp , yp, *pStr, color, bgc, bg);
xp += 8;
}
break;
}
pStr++;
i++;
if(i > 256) break;
}
}
myhead.h:
#ifndef MYHEAD_H_
#define MYHEAD_H_
#include
#include
#include
#include
#include
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#define err_exit(errmsg) \
do { \
fprintf(stderr, "in %s at %s : %d : %s : %s\n", __FUNCTION__, __FILE__, __LINE__ - 1, errmsg, strerror(errno)); \
exit(EXIT_FAILURE); \
} while(0)
#ifdef DEBUG
#define my_debug(fmt, arg...) fprintf(stderr, fmt, ##arg)
#else
#define my_debug(fmt,...)
#endif
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#endif
Makefile:
DEBUG = y
ifeq ($(DEBUG), y)
CFLAGS += -DDEBUG
endif
CROSS = arm-linux-
CFLAGS += -std=gnu99 -Wall -lavutil -lavformat -lavcodec -lswscale
OBJ = ffmpeg_decode
all:
$(CROSS)gcc $(CFLAGS) *.c -o $(OBJ)
install:
cp $(OBJ) /home/work/rootfs
clean:
rm -f *.o $(OBJ)