📄 main.c
字号:
/************************************************************************ *主程序 ************************************************************************/#include"sim.h"FILE *streamfile;void main(int argc, char *argv[]){ PictImage *prev_image = NULL; PictImage *curr_image = NULL; PictImage *curr_recon = NULL; PictImage *prev_recon = NULL; /* PB-frame specific */ PictImage *B_recon = NULL; PictImage *B_image = NULL; Pict *pic = (Pict *)malloc(sizeof(Pict)); unsigned char *image; FILE *cleared; int i; float mean_frame_rate, ref_frame_rate, frame_rate, seconds; int first_loop_finished=0; int total_frames_passed, PPFlag = 0, targetrate; int frames,bframes,pframes,wcopies,icopies, write_repeated,pdist=0,bdist=0; int start, end, frame_no, writediff; int first_frameskip, chosen_frameskip, orig_frameskip, frameskip; int QP,QPI; Bits *bits = (Bits *)malloc(sizeof(Bits)); Bits *total_bits = (Bits *)malloc(sizeof(Bits)); Bits *intra_bits = (Bits *)malloc(sizeof(Bits)); Results *res = (Results *)malloc(sizeof(Results)); Results *total_res = (Results *)malloc(sizeof(Results)); Results *b_res = (Results *)malloc(sizeof(Results)); char *seqfilename = (char *)malloc(sizeof(char)*100); char *streamname = (char *)malloc(sizeof(char)*100); char *outputfile = (char *)malloc(sizeof(char)*100); char *diff_filename=DEF_DIFFILENAME; char *tracefile = (char *)malloc(sizeof(char)*100);#ifndef OFFLINE_RATE_CONTROL float DelayBetweenFramesInSeconds; int CommBacklog;#else PictImage *stored_image = NULL; int start_rate_control;#endif extern int arith_used; fprintf (stdout,"\nH.263视频编码压缩标准之编码器\n"); headerlength = DEF_HEADERLENGTH;#ifndef FASTIDCT init_idctref();#endif /* Default variable values */ advanced = DEF_ADV_MODE; syntax_arith_coding = DEF_SAC_MODE; pic->unrestricted_mv_mode = DEF_UMV_MODE; mv_outside_frame = DEF_UMV_MODE || DEF_ADV_MODE; long_vectors = DEF_UMV_MODE; pb_frames = DEF_PBF_MODE; QP = DEF_INTER_QUANT; QPI = DEF_INTRA_QUANT; pic->BQUANT = DEF_BQUANT; pic->source_format = DEF_CODING_FORMAT; ref_frame_rate = (float)DEF_REF_FRAME_RATE; chosen_frameskip = DEF_FRAMESKIP + 1; orig_frameskip = DEF_ORIG_SKIP + 1;#ifdef OFFLINE_RATE_CONTROL start_rate_control = DEF_START_RATE_CONTROL;#else pic->target_frame_rate = (float)DEF_TARGET_FRAME_RATE;#endif seqfilename[0] = '\0'; strcpy(streamname, DEF_STREAMNAME); strcpy(outputfile, DEF_OUTFILENAME); writediff = DEF_WRITE_DIFF; trace = DEF_WRITE_TRACE; write_repeated = DEF_WRITE_REPEATED; pic->seek_dist = DEF_SEEK_DIST; pic->use_gobsync = DEF_INSERT_SYNC; start = DEF_START_FRAME; end = DEF_STOP_FRAME; targetrate = 0; /* default is variable bit rate (fixed quantizer) will be used */ frames = 0; pframes = 0; bframes = 0; total_frames_passed = 0; pic->PB = 0; wcopies = icopies = 1; pic->TR = 0; pic->QP_mean = (float)0.0; /* Process arguments */ for (i = 1; i < argc; i++) { if (*(argv[i]) == '-') { switch(*(++argv[i])) { case 'a': start = atoi(argv[++i]); break; case 'b': end = atoi(argv[++i]); break; case 'S': chosen_frameskip = atoi(argv[++i]) + 1; break; case 'O': orig_frameskip = atoi(argv[++i]) + 1; break; case 's': pic->seek_dist = atoi(argv[++i]); break; case 'o': strcpy(outputfile, argv[++i]); break; case 'e': headerlength = atoi(argv[++i]); break; case 'm': write_repeated = ON; break; case 'i': strcpy(seqfilename, argv[++i]); break; case 'q': QP = atoi(argv[++i]); if (QP > 31 || QP < 0) { fprintf(stderr,"QP out of range - clipping it\n"); QP = mmin(31,mmax(0,QP)); } break; case 'I': QPI = atoi(argv[++i]); if (QPI > 31 || QPI < 0) { fprintf(stderr,"QP out of range - clipping it\n"); QPI = mmin(31,mmax(0,QPI)); } break; case 'w': writediff = ON; break; case 'B': strcpy(streamname, argv[++i]); break; case 'h': Help(); exit(0); break; case 'H': AdvancedHelp(); exit(0); break; case 't': trace = 1; break; case 'g': pic->use_gobsync = atoi(argv[++i]);; break; case 'D': /* note that the Unrestricted Motion Vector mode turns on both long_vectors and mv_outside_frame */ pic->unrestricted_mv_mode = ON; mv_outside_frame = ON; long_vectors = ON; break; case 'E': syntax_arith_coding = ON; break; case 'F': /* note that the Advanced Prediction mode turns on both advanced (8x8 vectors and OBMC) and mv_outside_frame */ /* the Extended Motion Vector mode is included in the Unrestricted Motion Vector mode, which of course can be use together with the Advanced Prediction mode */ advanced = ON; mv_outside_frame = ON; break; case 'G': pb_frames = ON; break; case 'Q': pic->BQUANT = atoi(argv[++i]); break; case 'r': targetrate = atoi(argv[++i]); break;#ifdef OFFLINE_RATE_CONTROL case 'R': start_rate_control = atoi(argv[++i]); break;#else case 'R': pic->target_frame_rate = (float)atof(argv[++i]); break;#endif case 'Z': ref_frame_rate = (float)atoi(argv[++i]); break; case 'x': pic->source_format = atoi(argv[++i]); break; default: fprintf(stderr,"Illegal option: %c\n",*argv[i]); Help(); exit(-1); break; } } } switch (pic->source_format) { case (SF_SQCIF): fprintf(stdout, "Encoding format: SQCIF (128x96)\n"); pels = 128; lines = 96; break; case (SF_QCIF): fprintf(stdout, "Encoding format: QCIF (176x144)\n"); pels = 176; lines = 144; break; case (SF_CIF): fprintf(stdout, "Encoding format: CIF (352x288)\n"); pels = 352; lines = 288; break; case (SF_4CIF): fprintf(stdout, "Encoding format: 4CIF (704x576)\n"); pels = 704; lines = 576; break; case (SF_16CIF): fprintf(stdout, "Encoding format: 16CIF (1408x1152)\n"); pels = 1408; lines = 1152; break; default: fprintf(stderr,"Illegal coding format\n"); exit(-1); } cpels = pels/2; if (seqfilename[0] == '\0') { fprintf(stderr,"Required input parameter \'-i <filename>\' missing\n"); Help(); exit(-1); }#ifndef OFFLINE_RATE_CONTROL /* rate control variables */ pic->bit_rate = targetrate; pic->src_frame_rate = (int)(ref_frame_rate / orig_frameskip); DelayBetweenFramesInSeconds = (float) 1.0/(float)pic->src_frame_rate; InitializeRateControl();#endif if (QP == 0 || QPI == 0) { fprintf(stderr,"Warning:"); fprintf(stderr,"QP is zero. Bitstream will not be correctly decodable\n"); } if (ref_frame_rate != 25.0 && ref_frame_rate != 30.0) { fprintf(stderr,"Warning: Reference frame rate should be 25 or 30 fps\n"); } frame_rate = ref_frame_rate / (float)(orig_frameskip * chosen_frameskip);#ifdef OFFLINE_RATE_CONTROL fprintf(stdout,"Encoding frame rate : %.2f\n", frame_rate);#else if (pic->bit_rate == 0) fprintf(stdout,"Encoding frame rate : %.2f\n", frame_rate); else fprintf(stdout,"Encoding frame rate : variable\n");#endif fprintf(stdout,"Reference frame rate : %.2f\n", ref_frame_rate); fprintf(stdout,"Orig. seq. frame rate: %.2f\n\n", ref_frame_rate / (float)orig_frameskip); /* Open stream for writing */ streamfile = fopen (streamname, "wb"); if (streamname == NULL) { fprintf(stderr,"Unable to open streamfile\n"); exit(-1); } /* Initialize bitcounters */ initbits (); if (trace) { strcpy(tracefile, "trace.intra"); /* Open trace-file for writing */ if ((tf = fopen(tracefile,"w")) == NULL) { fprintf(stderr,"Unable to open tracefile (intra)\n"); exit(-1); } } /* Clear output files */ if ((cleared = fopen(outputfile,"wb")) == NULL) { fprintf(stderr,"Couldn't open outputfile: %s\n",outputfile); exit(-1); } else fclose(cleared); if (writediff) { if ((cleared = fopen(diff_filename,"wb")) == NULL) { fprintf(stderr,"Couldn't open diff-file: %s\n",diff_filename); exit(-1); } else fclose(cleared); } /* Intra image */ image = ReadImage(seqfilename,start,headerlength); fprintf(stderr,"Coding...\n"); curr_image = FillImage(image); pic->picture_coding_type = PCT_INTRA; pic->QUANT = QPI; curr_recon = CodeOneIntra(curr_image, QPI, bits, pic); if (arith_used) { bits->header += encoder_flush(); arith_used = 0; } bits->header += alignbits (); /* pictures shall be byte aligned */ fprintf(stdout,"Finished INTRA\n"); ComputeSNR(curr_image, curr_recon, res, writediff); AddBitsPicture(bits); PrintSNR(res, 1); PrintResult(bits, 1, 1); memcpy(intra_bits,bits,sizeof(Bits)); ZeroBits(total_bits); ZeroRes(total_res); ZeroRes(b_res); /* number of seconds to encode */ seconds = (end - start + chosen_frameskip) * orig_frameskip/ ref_frame_rate; if (trace) { strcpy(tracefile, "trace"); fclose(tf); /* Open trace-file for writing */ if ((tf = fopen(tracefile,"w")) == NULL) { fprintf(stderr,"Unable to open tracefile (non-intra)\n"); exit(-1); } } /* compute first frameskip */#ifdef OFFLINE_RATE_CONTROL first_frameskip = chosen_frameskip; frameskip = chosen_frameskip;#else CommBacklog = intra_bits->total - (int)(DelayBetweenFramesInSeconds * pic->bit_rate); if (pic->bit_rate == 0) { frameskip = chosen_frameskip; } else { /* rate control is used */ frameskip = 1; while ( (int)(DelayBetweenFramesInSeconds*pic->bit_rate) <= CommBacklog) { CommBacklog -= (int) ( DelayBetweenFramesInSeconds * pic->bit_rate ); frameskip += 1; } } first_frameskip = frameskip;#endif if (first_frameskip > 256) fprintf(stderr,"Warning: frameskip > 256\n"); pic->picture_coding_type = PCT_INTER; pic->QUANT = QP; bdist = chosen_frameskip; /* always encode the first frame after intra as P frame. This is not necessary, but something we chose to make the adaptive PB frames calculations a bit simpler */ if (pb_frames) { pic->PB = 0; pdist = 2*chosen_frameskip - bdist; } if (write_repeated) icopies = chosen_frameskip; for (i = 0; i < icopies; i++) WriteImage(curr_recon,outputfile); /* write wcopies frames to disk */ /***** Main loop *****/ for (frame_no = start + first_frameskip; frame_no <= end; frame_no += frameskip) { prev_image = curr_image; prev_recon = curr_recon; /* Set QP to pic->QUANT from previous encoded picture */ QP = pic->QUANT; if (!PPFlag) { if (pic->PB) { bdist = frameskip; pdist = 2*frameskip - bdist; pic->TRB = bdist * orig_frameskip; if (pic->TRB > 8) fprintf(stdout,"distance too large for B-frame\n"); /* Read the frame to be coded as B */ image = ReadImage(seqfilename,frame_no,headerlength); B_image = FillImage(image); first_loop_finished = 1; if (frame_no + pdist <= end) { image = ReadImage(seqfilename,frame_no + pdist,headerlength); } else { pic->PB = 0; /* end of sequence, encode as P */ image = ReadImage(seqfilename,frame_no,headerlength); } } else { image = ReadImage(seqfilename,frame_no,headerlength); } curr_image = FillImage(image); if (pic->PB) { if (pic->TRB > 8 || !NextTwoPB(curr_image, B_image, prev_image, bdist, pdist, pic->seek_dist)) { /* curr_image and B_image were not suitable to be coded as a PB-frame - encoding as two P-frames instead */ pic->PB = 0;#ifdef OFFLINE_RATE_CONTROL stored_image = curr_image;#else FreeImage(curr_image);#endif frameskip = bdist; curr_image = B_image; PPFlag = 1; } else { frame_no += pdist; } } } else { /* PPFlag is set when the second of the two P-frames is due to be coded */#ifdef OFFLINE_RATE_CONTROL curr_image = stored_image;#else image = ReadImage(seqfilename,frame_no,headerlength); curr_image = FillImage(image);#endif pic->PB = 0; PPFlag = 0; } /* Temporal Reference is the distance between encoded frames compared the reference picture rate which is 25.0 or 30 fps */ pic->TR += (( (frameskip+(pic->PB?pdist:0)) *orig_frameskip) % 256); if (frameskip+(pic->PB?pdist:0) > 256)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -