📄 tmndec.c
字号:
/************************************************************************** tmndec.c, main(), initialization, options for tmndecode (H.263 decoder)* Copyright (C) 1996 Telenor R&D, Norway* Karl Olav Lillevold <Karl.Lillevold@nta.no>*设定初始化选项* This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.** Karl Olav Lillevold <Karl.Lillevold@nta.no>* Telenor Research and Development* P.O.Box 83 tel.: +47 63 84 84 00* N-2007 Kjeller, Norway fax.: +47 63 81 00 76** Robert Danielsen e-mail: Robert.Danielsen@nta.no* Telenor Research and Development www: http://www.nta.no/brukere/DVC/* P.O.Box 83 tel.: +47 63 84 84 00* N-2007 Kjeller, Norway fax.: +47 63 81 00 76************************************************************************//** based on mpeg2decode, (C) 1994, MPEG Software Simulation Group* and mpeg2play, (C) 1994 Stefan Eckart* <stefan@lis.e-technik.tu-muenchen.de>**/#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <fcntl.h>#define GLOBAL#include "config.h"#include "tmndec.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
#ifndef STRING_H
#include <string.h>
#endif#ifdef WINDOWSint 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 g_frame;
int able_yuv_num=0;
char yuvfile[10][30];
//定义用于存贮所得yuv文件的文件名的结构,用来传递unitestream()的参数
void unitestream(char yuvfile[10][30],int able_yuv_num,int m_nWidth,int m_nHeight,int picsize)
//added by cjx 20070927
//把所有yuv文件按照顺序写到同一个文件中
{
FILE *writestream;
FILE *readstream[10];
char buf[210000];
unsigned int size;
int num;
int flag=0;
for(num = 0;num < able_yuv_num;num++)
{
if((readstream[num]=fopen(yuvfile[num],"rb"))==NULL)
{
printf("can't open the %s file!\n",yuvfile[num]);
return;
}
}
if((writestream=fopen(".\\mother_daughter_cif.yuv","wb+"))==NULL)
{
printf("can't open the mother_daughter_cif.yuv file!\n");
return;
}
size=picsize*3/2;
while (1)//循环的写入
{
for(num = 0;num < able_yuv_num,g_frame%able_yuv_num == num;num++)
{
if(size==fread(buf, 1 , 3*picsize/2, readstream[num]))
fwrite(buf,1 , 3*picsize/2, writestream);
else
{
flag = 1;
break;
}
g_frame++;
}
if(flag == 1)//若读入的一帧大小为零则完成任务
break;
}
for(num = 0;num < able_yuv_num;num++)
{
fclose(readstream[num]);
}
fclose(writestream);//关闭所有文件
return;
}
#define FILEnum 10//最多解析的文件数目
int i263,iyuv,j;int main(argc,argv)int argc;char *argv[];{ int first, framenum;
int yuvnum;
char H263stream[50],YUVstream[50];//存储输入文件输出文件的名字#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//没有执行? ld = &base; //??? /* open MPEG input file(s) */
// if ((base.infile=open(argv[1],O_RDONLY|O_BINARY))<0)
strcpy(H263stream,argv[1]);//读入命令行中263格式的文件名
strcpy(YUVstream,argv[2]);//读入命令行中yuv格式的文件名
// added by cjx 20070921
for(i263 = 0; i263 < 50; i263++)
{
if(H263stream[i263]=='.')
{
for(j=5;j >= 0;j--)
{
H263stream[j+i263]=H263stream[j+i263-1];
}
break;
}
}//变换文件名263
for(iyuv = 0; iyuv < 50; iyuv++)
{
if(YUVstream[iyuv]=='.')
{
for(j=5;j >= 0;j--)
{
YUVstream[j+iyuv]=YUVstream[j+iyuv-1];
}
break;
}
}//变换文件名yuv
// char *strncat(char *s1, const char *s2, size_t n)
for(yuvnum = 1; yuvnum < FILEnum; yuvnum++)
{
H263stream[i263]= '0' + yuvnum;
YUVstream[iyuv]= '0' + yuvnum;
outputname = YUVstream;
if ((base.infile=open(H263stream,O_RDONLY|O_BINARY))<0) //识别文件
//以二进制打开文件
{
continue;
//sprintf(errortext,"Input file %s not found\n",argv[1]);
//error(errortext);
}
first = 1;
do {
if (base.infile!=0)
lseek(base.infile,0l,0); //对文件的读写位置操作,SEEK_SET=0文件偏移量被设置为 01
initbits();
framenum = 0;
temp_ref = 0;
prev_temp_ref= -1;
while (getheader()) /* 开始解一帧,保存为YUV*/
//条件函数返回怎样的值?为何以他作为条件?这个函数获得一帧的有效载荷头
{
if (first) //只有最外层循环的一次开始时才会执行
{
initdecoder();//获取263文件的解析度信息
#ifdef USE_TIME
#ifndef WIN32
//防止头文件重用
gettimeofday(&tstart,(struct timezone *)NULL);
//取的时间,返回类型数组
//"sec" - 秒 ;"usec" - 百万分之一秒 ;"minuteswest" - 格林威治时间的分 ;"dsttime" - 目的的时区
if (framerate > 0)
gettimeofday(&tftarget,(struct timezone *)NULL);
#else
startTime = timeGetTime();//时间差?调节频率
if (framerate > 0)
targetTime = timeGetTime();
#endif
#endif
first = 0;
}
getpicture(&framenum); //run这个函数是解码的执行函数
framenum++; //run
} /* 开始解一帧结束,保存为YUV*/
} while (loopflag); //what is loopflag?loopflag为一时
close(base.infile);//关闭打开的263文件
for(j = 0;j < 30;j++)
yuvfile[able_yuv_num][j]=YUVstream[j];
able_yuv_num++;
}//263文件转换成yuv文件结束
#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
unitestream(yuvfile,able_yuv_num,352, 288, 352*288); //added by cjx 20070921 return 0; //run}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) {//H.263支持的五种解析度
//每帧图象都被分为许多块组。一个块组(GOB)由k*16行组成,k由解析度决定 case (SF_SQCIF): horizontal_size = 128; vertical_size = 96; break; case (SF_QCIF)://本程序选取的是这一种,每幅图像有9个GOB.......QCIF格式中,一个GOB包含一个宏块 horizontal_size = 176;//亮度取样的象素个数 vertical_size = 144; break;
//QCIF的全称Quarter common intermediate format
//每个宏块包含16行每行16个象素的Y信息,和8行每行8个象素的CB和CR信息 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -