📄 main.c
字号:
/* -------------------- H.263 Decoder ------------------- */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
#define GLOBAL
#include "config.h"
#include "main.h"
#include "global.h"
#ifdef USE_TIME
#ifndef WIN32
#include <sys/time.h>
#else
#include <windows.h>
#endif
#endif
#ifdef WIN32
#include <io.h>
#endif
#ifdef WINDOWS
int initDisplay (int pels, int lines);
int closeDisplay ();
#endif
/* private prototypes */
static void initdecoder _ANSI_ARGS_((void));
static void options _ANSI_ARGS_((int *argcp, char **argvp[]));
static int getval _ANSI_ARGS_((char *argv[]));
/* private data */
static int loopflag;
int main(argc,argv)
int argc;
char *argv[];
{
int first, framenum;
#ifdef USE_TIME
int runtime;
#ifndef WIN32
struct timeval tstart,tstop;
#else
unsigned int startTime, stopTime;
#endif
#endif
#ifdef USE_TIME
/* default is read frame rate from bitstream */
framerate=99;
#endif
options(&argc,&argv);
/* pointer to name of output files */
#if (defined DISPLAY || defined WINDOWS)
if (outtype==T_X11 || outtype == T_WIN)
outputname = "";
else
#endif
outputname = argv[argc-1];
ld = &base;
/* open MPEG input file(s) */
if ((base.infile=open(argv[1],O_RDONLY|O_BINARY))<0) {
sprintf(errortext,"Input file %s not found\n",argv[1]);
error(errortext);
}
first = 1;
do {
if (base.infile!=0)
lseek(base.infile,0l,0);
initbits();
framenum = 0;
temp_ref = 0;
prev_temp_ref -1;
while (getheader()) {
if (first) {
initdecoder();
#ifdef USE_TIME
#ifndef WIN32
gettimeofday(&tstart,(struct timezone *)NULL);
if (framerate > 0)
gettimeofday(&tftarget,(struct timezone *)NULL);
#else
startTime = timeGetTime();
if (framerate > 0)
targetTime = timeGetTime();
#endif
#endif
first = 0;
}
getpicture(&framenum);
framenum++;
}
} while (loopflag);
close(base.infile);
#ifdef USE_TIME
#ifndef WIN32
gettimeofday(&tstop,(struct timezone *)NULL);
runtime = 100*(tstop.tv_sec-tstart.tv_sec)
+ (tstop.tv_usec-tstart.tv_usec)/10000;
#else
stopTime = timeGetTime();
runtime = (stopTime - startTime) / 10;
#endif
if (!quiet && runtime!=0)
printf("%d.%02d seconds, %d frames, %d.%02d fps\n",
runtime/100, runtime%100,
framenum, ((10000*framenum+runtime/2)/runtime)/100,
((10000*framenum+runtime/2)/runtime)%100);
#endif
#ifdef DISPLAY
if (outtype==T_X11)
exit_display();
#endif
#ifdef WINDOWS
if (outtype == T_WIN)
closeDisplay();
#endif
return 0;
}
static void initdecoder()
{
int i, cc, size;
FILE *cleared;
/* clip table */
if (!(clp=(unsigned char *)malloc(1024)))
error("malloc failed\n");
clp += 384;
for (i=-384; i<640; i++)
clp[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
/* MPEG-1 = TMN parameters */
matrix_coefficients = 5;
switch (source_format) {
case (SF_SQCIF):
horizontal_size = 128;
vertical_size = 96;
break;
case (SF_QCIF):
horizontal_size = 176;
vertical_size = 144;
break;
case (SF_CIF):
horizontal_size = 352;
vertical_size = 288;
break;
case (SF_4CIF):
horizontal_size = 704;
vertical_size = 576;
break;
case (SF_16CIF):
horizontal_size = 1408;
vertical_size = 1152;
break;
default:
printf("ERROR: Illegal input format\n");
exit(-1);
break;
}
mb_width = horizontal_size/16;
mb_height = vertical_size/16;
coded_picture_width = horizontal_size;
coded_picture_height = vertical_size;
chrom_width = coded_picture_width>>1;
chrom_height = coded_picture_height>>1;
blk_cnt = 6;
for (cc=0; cc<3; cc++) {
if (cc==0)
size = coded_picture_width*coded_picture_height;
else
size = chrom_width*chrom_height;
if (!(refframe[cc] = (unsigned char *)malloc(size)))
error("malloc failed\n");
if (!(oldrefframe[cc] = (unsigned char *)malloc(size)))
error("malloc failed\n");
if (!(bframe[cc] = (unsigned char *)malloc(size)))
error("malloc failed\n");
}
for (cc=0; cc<3; cc++) {
if (cc==0) {
size = (coded_picture_width+64)*(coded_picture_height+64);
if (!(edgeframeorig[cc] = (unsigned char *)malloc(size)))
error("malloc failed\n");
edgeframe[cc] = edgeframeorig[cc] + (coded_picture_width+64) * 32 + 32;
}
else {
size = (chrom_width+32)*(chrom_height+32);
if (!(edgeframeorig[cc] = (unsigned char *)malloc(size)))
error("malloc failed\n");
edgeframe[cc] = edgeframeorig[cc] + (chrom_width+32) * 16 + 16;
}
}
if (expand) {
for (cc=0; cc<3; cc++) {
if (cc==0)
size = coded_picture_width*coded_picture_height*4;
else
size = chrom_width*chrom_height*4;
if (!(exnewframe[cc] = (unsigned char *)malloc(size)))
error("malloc failed\n");
}
}
/* Clear output file for concatenated storing */
if (outtype == T_YUV_CONC) {
if ((cleared = fopen(outputname,"wb")) == NULL)
error("couldn't clear outputfile\n");
else
fclose(cleared);
}
/* IDCT */
if (refidct)
init_idctref();
else
init_idct();
#ifdef DISPLAY
if (outtype==T_X11) {
init_display("");
}
#endif
#ifdef WINDOWS
if (outtype==T_WIN) {
initDisplay(coded_picture_width, coded_picture_height);
}
#endif
}
void error(text)
char *text;
{
fprintf(stderr,text);
exit(1);
}
/* trace output */
void printbits(code,bits,len)
int code,bits,len;
{
int i;
for (i=0; i<len; i++)
printf("%d",(code>>(bits-1-i))&1);
}
/* option processing */
static void options(argcp,argvp)
int *argcp;
char **argvp[];
{
while (*argcp>1 && (*argvp)[1][0]=='-')
{
while ((*argvp)[1][1])
{
switch (toupper((*argvp)[1][1]))
{
#ifdef USE_TIME
case 'F':
framerate = getval(*argvp);
break;
#endif
case 'V':
verbose = getval(*argvp);
break;
case 'O':
outtype = getval(*argvp);
break;
case 'R':
refidct = 1;
break;
case 'L':
loopflag = 1;
break;
case 'X':
expand = 1;
break;
case 'T':
trace = 1;
break;
case 'Q':
quiet = 1;
break;
default:
fprintf(stderr,"undefined option -%c ignored\n",(*argvp)[1][1]);
}
(*argvp)[1]++;
}
(*argvp)++;
(*argcp)--;
}
if (outtype != T_X11 && outtype != T_WIN) {
loopflag = 0; /* No looping for output to file */
#ifdef USE_TIME
framerate = 0; /* No delay necessary when output to file */
#endif
}
#ifdef DISPLAY
if (outtype==T_X11)
{
(*argcp)++; /* fake outfile parameter */
}
#endif
#ifdef WINDOWS
if (outtype==T_WIN)
{
(*argcp)++; /* fake outfile parameter */
}
#endif
if (*argcp!=3 && *argcp!=4)
{
printf("\n%s\n",version);
printf("Usage: H263decode {options} bitstream {outputfilename%%d}\n\
Options: -vn verbose output (n: level)\n\
-on output format \n\
n=0 : YUV\n\
n=1 : SIF\n\
n=2 : TGA\n\
n=3 : PPM\n");
#ifdef DISPLAY
printf("\
n=4 : X11 Display\n");
#endif
printf("\
n=5 : YUV concatenated\n");
#ifdef WINDOWS
printf("\
n=6 : Windows 95/NT Display\n");
#endif
printf("\
You have to choose one output format!\n\
-q disable warnings to stderr\n\
-r use double precision reference IDCT\n\
-t enable low level tracing\n");
#ifdef DISPLAY
printf("\
-x interpolate pictures to double size before display\n");
#endif
#ifdef USE_TIME
printf("\
-fn frame rate\n\
n=0 : as fast as possible\n\
n=99 : read frame rate from bitstream (default)\n");
#endif
#ifdef DISPLAY
printf("\
-l loop sequence\n");
#endif
exit(0);
}
}
static int getval(argv)
char *argv[];
{
int val;
if (sscanf(argv[1]+2,"%d",&val)!=1)
return 0;
while (isdigit(argv[1][2]))
argv[1]++;
return val;
}
#ifdef USE_TIME
#ifndef WINDOWS
/* Unix version */
void doframerate(int pb)
{
struct timeval tfdiff;
const float REF_FRAME_RATE = 29.97;
/* Compute desired frame rate */
if (framerate <= 0)
return;
if (framerate != 99) {
tftarget.tv_usec += 1000000 / framerate;
}
else {
if (pb) {
tftarget.tv_usec += 1000000 / (REF_FRAME_RATE/trb);
}
else {
tftarget.tv_usec += 1000000 / (REF_FRAME_RATE/(trd-trb));
}
}
/* this is where we should be */
if (tftarget.tv_usec >= 1000000)
{
tftarget.tv_usec -= 1000000;
tftarget.tv_sec++;
}
/* this is where we are */
gettimeofday(&tfdiff,(struct timezone *)NULL);
tfdiff.tv_usec = tftarget.tv_usec - tfdiff.tv_usec;
tfdiff.tv_sec = tftarget.tv_sec - tfdiff.tv_sec;
if (tfdiff.tv_usec < 0)
{
tfdiff.tv_usec += 1000000;
tfdiff.tv_sec--;
}
/* See if we are already lagging behind */
if (tfdiff.tv_sec < 0 || (tfdiff.tv_sec == 0 && tfdiff.tv_usec <= 0))
return;
/* Spin for awhile */
select(0,NULL,NULL,NULL,&tfdiff);
}
#else
/* Win32 version */
void doframerate(int pb)
{
DWORD currentTime;
int diffTime;
const float REF_FRAME_RATE = (float)29.97;
/* Compute desired frame rate */
if (framerate <= 0)
return;
if (framerate != 99) {
targetTime += 1000 / framerate;
}
else {
if (pb) {
targetTime += (int)(1000 / (REF_FRAME_RATE/trb));
}
else {
targetTime += (int)(1000 / (REF_FRAME_RATE/(trd-trb)));
}
}
/* this is where we are */
currentTime = timeGetTime();
diffTime = targetTime - currentTime;
/* See if we are already lagging behind */
if (diffTime <= 0)
return;
/* Spin for awhile */
Sleep(diffTime);
/* this is not a very accurate timer */
}
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -