?? sdldecode.c
字號(hào):
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <SDL/SDL.h>
#include "xvid.h"
#define USE_PNM 1
#define USE_TGA 0
static int SHXDIM = 0;//display size
static int SHYDIM = 0;
static int XDIM = 352;//real size
static int YDIM = 288;
static int ARG_SAVEDECOUTPUT = 0;
static int ARG_SAVEMPEGSTREAM = 0;
static char *ARG_INPUTFILE = NULL;
static int CSP = XVID_CSP_I420;
static int BPP = 1;
static int FORMAT = USE_PNM;
static char filepath[256] = "./";
static void *dec_handle = NULL;
#define BUFFER_SIZE (2*1024*1024)
static const int display_buffer_bytes = 0;
static SDL_Surface *screen;
static SDL_Overlay *overlay;
static SDL_Rect rect;
static double msecond();
static int dec_init(int use_assembler, int debug_level);
static int dec_main(unsigned char *istream,
unsigned char *ostream,
int istream_size,
xvid_dec_stats_t *xvid_dec_stats);
static int dec_stop();
static void usage();
static int write_image(char *prefix, unsigned char *image);
static int write_pnm(char *filename, unsigned char *image);
static int write_tga(char *filename, unsigned char *image);
const char * type2str(int type)
{
if (type==XVID_TYPE_IVOP)
return "I";
if (type==XVID_TYPE_PVOP)
return "P";
if (type==XVID_TYPE_BVOP)
return "B";
return "S";
}
static void init_SDL()
{
if (SDL_Init (SDL_INIT_VIDEO) < 0)
{
fprintf (stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
exit (1);
}
atexit (SDL_Quit);
screen = SDL_SetVideoMode (SHXDIM, SHYDIM, 0, SDL_HWSURFACE
| SDL_DOUBLEBUF
| SDL_ANYFORMAT
| SDL_RESIZABLE);
if (screen == NULL)
{
fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
exit(2);
}
if (0 == screen->flags & SDL_HWSURFACE)
{
fprintf(stderr,"Can't get hardware surface\n");
exit(3);
}
SDL_WM_SetCaption ("SDL MultiMedia Application", NULL);
overlay = SDL_CreateYUVOverlay(XDIM, YDIM, SDL_YV12_OVERLAY, screen);
if (!overlay)
{
fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError());
exit(4);
}
//show the overlay status
printf("Created %dx%dx%d %s %s overlay\n",overlay->w,overlay->h,overlay->planes,
overlay->hw_overlay?"hardware":"software",
overlay->format==SDL_YV12_OVERLAY?"YV12":
overlay->format==SDL_IYUV_OVERLAY?"IYUV":
overlay->format==SDL_YUY2_OVERLAY?"YUY2":
overlay->format==SDL_UYVY_OVERLAY?"UYVY":
overlay->format==SDL_YVYU_OVERLAY?"YVYU":
"Unknown");
rect.x=0;
rect.y=0;
rect.w=SHXDIM;
rect.h=SHYDIM;
}
int main(int argc, char *argv[])
{
SDL_Event event;
uint32_t lastftick;
unsigned char *mp4_buffer = NULL;
unsigned char *mp4_ptr = NULL;
unsigned char *out_buffer = NULL;
int useful_bytes;
xvid_dec_stats_t xvid_dec_stats;
double totaldectime;
long totalsize;
int status;
int fps = 25;
int fpsdelay;
int paused=0;
int resized=0;
int use_assembler = 1;
int debug_level = 0;
char filename[256];
FILE *in_file;
int filenr;
int i;
for (i=1; i< argc; i++) {
if (strcmp("-asm", argv[i]) == 0 ) {
use_assembler = 1;
} else if (strcmp("-debug", argv[i]) == 0 && i < argc - 1 ) {
i++;
if (sscanf(argv[i], "0x%x", &debug_level) != 1) {
debug_level = atoi(argv[i]);
}
} else if (strcmp("-d", argv[i]) == 0) {
ARG_SAVEDECOUTPUT = 1;
} else if (strcmp("-i", argv[i]) == 0 && i < argc - 1 ) {
i++;
ARG_INPUTFILE = argv[i];
} else if (strcmp("-c", argv[i]) == 0 && i < argc - 1 ) {
i++;
if (strcmp(argv[i], "rgb16") == 0) {
CSP = XVID_CSP_RGB555;
BPP = 2;
} else if (strcmp(argv[i], "rgb24") == 0) {
CSP = XVID_CSP_BGR;
BPP = 3;
} else if (strcmp(argv[i], "rgb32") == 0) {
CSP = XVID_CSP_BGRA;
BPP = 4;
} else if (strcmp(argv[i], "yv12") == 0) {
CSP = XVID_CSP_YV12;
BPP = 1;
} else {
CSP = XVID_CSP_I420;
BPP = 1;
}
} else if (strcmp("-f", argv[i]) == 0 && i < argc -1) {
i++;
if (strcmp(argv[i], "tga") == 0) {
FORMAT = USE_TGA;
} else {
FORMAT = USE_PNM;
}
} else if (strcmp("-help", argv[i]) == 0) {
usage();
return(0);
} else if(strcmp("-w", argv[i]) == 0 && i < argc -1){
i++;
SHXDIM = atoi(argv[i]);
} else if(strcmp("-h", argv[i]) == 0 && i < argc -1){
i++;
SHYDIM = atoi(argv[i]);
} else if(strcmp("-fps", argv[i]) == 0 && i < argc -1){
i++;
fps = atoi(argv[i]);
}
else {
usage();
exit(-1);
}
}
if (ARG_INPUTFILE==NULL) {
fprintf(stderr, "Warning: MSVC build does not read EOF correctly from stdin. Use the -i switch.\n\n");
}
in_file = fopen(ARG_INPUTFILE, "rb");
if (in_file == NULL) {
fprintf(stderr, "Error opening input file %s\n", ARG_INPUTFILE);
return(-1);
}
/* PNM/PGM format can't handle 16/32 bit data */
if (BPP != 1 && BPP != 3 && FORMAT == USE_PNM) {
FORMAT = USE_TGA;
}
/* Memory for encoded mp4 stream */
mp4_buffer = (unsigned char *) malloc(BUFFER_SIZE);
if (!mp4_buffer)
goto free_all_memory;
out_buffer = (unsigned char *)malloc(XDIM*YDIM*3/2);
if (!out_buffer)
goto free_all_memory;
/******************************************************************************
* INIT SDL
*******************************************************************************/
init_SDL();
/*****************************************************************************
* XviD PART Start
****************************************************************************/
status = dec_init(use_assembler, debug_level);
if (status) {
fprintf(stderr,
"Decore INIT problem, return value %d\n", status);
goto release_all;
}
/*****************************************************************************
* Main loop
****************************************************************************/
/* Fill the buffer ,create 2M buffer*/
useful_bytes = fread(mp4_buffer, 1, BUFFER_SIZE, in_file);
totaldectime = 0;
totalsize = 0;
filenr = 0;
mp4_ptr = mp4_buffer;
uint8_t *outy,*outu,*outv,*op[3];
int y;
/* set the start frame */
i=0;
fpsdelay=1000/fps;
lastftick=SDL_GetTicks();
do
{
int used_bytes = 0;
double dectime;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_VIDEORESIZE:
screen=SDL_SetVideoMode(event.resize.w, event.resize.h, 0, SDL_RESIZABLE | SDL_SWSURFACE);
rect.w=event.resize.w;
rect.h=event.resize.h;
if (paused)
{
resized=1;
}
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_SPACE)
{
paused=!paused;
break;
}
if (event.key.keysym.sym != SDLK_ESCAPE)
{
goto release_all;
}
case SDL_QUIT:
goto release_all;
}
}
/*
* If the buffer is half empty or there are no more bytes in it
* then fill it.
*/
if (mp4_ptr > mp4_buffer + BUFFER_SIZE/2)
{
int already_in_buffer = (mp4_buffer + BUFFER_SIZE - mp4_ptr);
/* Move data if needed */
if (already_in_buffer > 0)
memcpy(mp4_buffer, mp4_ptr, already_in_buffer);
/* Update mp4_ptr */
mp4_ptr = mp4_buffer;
/* read new data */
if(feof(in_file))
break;
useful_bytes += fread(mp4_buffer + already_in_buffer,
1, BUFFER_SIZE - already_in_buffer,
in_file);
}
if ((!paused)||(resized))
{
if (((SDL_GetTicks()-lastftick)>fpsdelay)||(resized))
{
lastftick=SDL_GetTicks();
/* This loop is needed to handle VOL/NVOP reading */
do{
/* Decode frame */
dectime = msecond();
used_bytes = dec_main(mp4_ptr, out_buffer, useful_bytes, &xvid_dec_stats);
dectime = msecond() - dectime;
if(xvid_dec_stats.type==XVID_TYPE_VOL
&& (xvid_dec_stats.data.vol.width != XDIM
||xvid_dec_stats.data.vol.height != YDIM))
{
//reallocate bigger out frame
free(out_buffer);
XDIM = xvid_dec_stats.data.vol.width;
YDIM = xvid_dec_stats.data.vol.height;
out_buffer = (unsigned char *) malloc(XDIM*YDIM*3/2);
if (!out_buffer)
goto free_all_memory;
//reallocate bigger yuv overlay
SDL_FreeYUVOverlay(overlay);
overlay = SDL_CreateYUVOverlay(XDIM, YDIM, SDL_YV12_OVERLAY, screen);
if (!overlay)
{
fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError());
exit(4);
}
}
/* Update buffer pointers */
if(used_bytes > 0) {
mp4_ptr += used_bytes;
useful_bytes -= used_bytes;
/* Total size */
totalsize += used_bytes;
}
}while (xvid_dec_stats.type <= 0 && useful_bytes > 0);
/* Check if there is a negative number of useful bytes left in buffer
* This means we went too far */
if(useful_bytes < 0)
break;
/* Updated data - Count only usefull decode time */
totaldectime += dectime;
//display the decoded frame
SDL_LockSurface(screen);
SDL_LockYUVOverlay(overlay);
outy = out_buffer;
outu = out_buffer+XDIM*YDIM;
outv = out_buffer+XDIM*YDIM*5/4;
for(y=0;y<screen->h && y<overlay->h;y++)
{
op[0]=overlay->pixels[0]+overlay->pitches[0]*y;
op[1]=overlay->pixels[1]+overlay->pitches[1]*(y/2);
op[2]=overlay->pixels[2]+overlay->pitches[2]*(y/2);
memcpy(op[0],outy+y*XDIM,XDIM);
if(y%2 == 0)
{
memcpy(op[1],outu+XDIM/2*y/2,XDIM/2);
memcpy(op[2],outv+XDIM/2*y/2,XDIM/2);
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -