📄 main.c
字号:
fprintf(stdout,"Warning: frameskip > 256\n"); frames += (pic->PB ? 2: 1); bframes += (pic->PB ? 1 : 0); pframes += 1; if (pic->PB) { /* Code two frames as a PB-frame */ B_recon = InitImage(pels*lines); fprintf(stdout,"Coding PB frames %d and %d... ", frame_no - pdist, frame_no); fflush(stdout); } else { /* Code the next frame as a normal P-frame */ fprintf(stdout,"Coding P frame %d... ", frame_no); fflush(stdout); } curr_recon = InitImage(pels*lines); CodeOneOrTwo(curr_image, B_image, prev_image, prev_recon, QP, (bdist+pdist)*orig_frameskip, bits, pic, B_recon, curr_recon); fprintf(stdout,"done\n"); if (targetrate != 0) fprintf(stdout,"Inter QP: %d\n", QP); fflush(stdout); if (arith_used) { bits->header += encoder_flush(); arith_used = 0; } bits->header += alignbits (); /* pictures shall be byte aligned */ AddBitsPicture(bits); AddBits(total_bits, bits);#ifndef OFFLINE_RATE_CONTROL if (pic->bit_rate != 0 && pic->PB) CommBacklog -= (int) ( DelayBetweenFramesInSeconds*pic->bit_rate ) * pdist; if (pic->bit_rate != 0) { UpdateRateControl(bits->total); CommBacklog += bits->total; frameskip = 1; CommBacklog -= (int) (frameskip * DelayBetweenFramesInSeconds *pic->bit_rate); while ( (int)(DelayBetweenFramesInSeconds*pic->bit_rate) <= CommBacklog) { CommBacklog -= (int) ( DelayBetweenFramesInSeconds * pic->bit_rate ); frameskip += 1; } }#else /* Aim for the targetrate with a once per frame rate control scheme */ if (targetrate != 0) if (frame_no - start > (end - start) * start_rate_control/100.0) /* when generating the MPEG-4 anchors, rate control was started after 70% of the sequence was finished. Set start_rate_control with option "-R <n>" */ pic->QUANT = FrameUpdateQP(total_bits->total + intra_bits->total, bits->total / (pic->PB?2:1), (end-frame_no) / chosen_frameskip + PPFlag, QP, targetrate, seconds); frameskip = chosen_frameskip;#endif if (pic->PB) { if (write_repeated) wcopies = pdist; for (i = 0; i < wcopies; i++) WriteImage(B_recon,outputfile); /* write wcopies frames to disk */ ComputeSNR(B_image, B_recon, res, writediff); fprintf(stdout,"Results for B-frame:\n"); AddRes(b_res,res,pic); PrintSNR(res, 1); FreeImage(B_image); FreeImage(B_recon); } if (write_repeated) wcopies = (pb_frames ? bdist : frameskip); for (i = 0; i < wcopies; i++) WriteImage(curr_recon,outputfile); /* write wcopies frames to disk */ if (pb_frames) pic->PB = 1; ComputeSNR(curr_image, curr_recon, res, writediff); fprintf(stdout,"Results for P-frame:\n"); AddRes(total_res,res,pic); PrintSNR(res, 1); PrintResult(bits, 1, 1); FreeImage(prev_image); FreeImage(prev_recon); fflush(stdout); } /***** end of main loop *****/ /* Closing files */ fclose (streamfile); if (trace) { fclose(tf); } /* Print total results */ total_frames_passed = frame_no - start - first_frameskip; fprintf(stdout,"\n==== TOTAL ====\n"); fprintf(stdout,"for %d images of %s\n", frames, seqfilename); if (frames != 0) { if (write_repeated) fprintf(stdout,"Frames saved : %d predicted + %d intra\n", total_frames_passed,icopies); fprintf(stdout,"--------------\n"); if (pb_frames && bframes != 0) { fprintf(stdout,"SNR for %d B-frames:\n",bframes); PrintSNR(b_res,bframes); } fprintf(stdout,"SNR for %d P-frames:\n",pframes); PrintSNR(total_res,pframes); PrintResult(total_bits, pframes, frames); if (targetrate != 0 || pic->bit_rate != 0) fprintf(stdout,"Original seq time: %.2f (%.2f) sec\n", (total_frames_passed + first_frameskip) / ref_frame_rate * orig_frameskip, total_frames_passed / ref_frame_rate * orig_frameskip); fprintf(stdout,"Mean quantizer : %.2f\n", total_res->QP_mean/pframes);#if 0 fprintf(stdout,"Total frames : %3d (%3d)\n", total_frames_passed + first_frameskip, total_frames_passed);#endif fprintf(stdout,"Encoded frames : %3d (%3d)\n", frames + 1, frames); mean_frame_rate = frames / (float)total_frames_passed * ref_frame_rate / (float)orig_frameskip; fprintf(stdout,"Mean frame rate : %.2f Hz\n", mean_frame_rate); if (targetrate != 0) fprintf(stdout,"Target bit rate : %.2f kbit/sec\n", targetrate/1000.0); fprintf(stdout,"Obtained bit rate: %.2f (%.2f) kbit/sec\n", (total_bits->total + intra_bits->total) / ((total_frames_passed + first_frameskip) / ref_frame_rate * orig_frameskip)/1000.0, (total_bits->total / (float)frames) * mean_frame_rate/1000.0); fprintf(stdout,"============================================\n"); }#if 0 fprintf(stdout,"Total number of bits: %d (%d)\n", total_bits->total + intra_bits->total, (total_bits->total + intra_bits->total) / 8);#endif /* Free memory */ FreeImage(curr_recon); FreeImage(curr_image); free(streamname); free(seqfilename); free(outputfile); free(tracefile); free(bits); free(total_bits); free(intra_bits); free(res); free(total_res); free(b_res); free(pic); exit(0);}/********************************************************************** * * Name: NextTwoPB * Description: Decides whether or not to code the next * two images as PB * Speed: This is not a very smart solution considering * the encoding speed, since motion vectors * have to be calculation several times. It * can be done together with the normal * motion vector search, or a tree search * instead of a full search can be used. * * Input: pointers to previous image, potential B- * and P-image, frame distances * Returns: 1 for yes, 0 otherwise * Side effects: * * Date: 950824 Author: Karl.Lillevold@nta.no * ***********************************************************************/int NextTwoPB(PictImage *next2, PictImage *next1, PictImage *prev, int bskip, int pskip, int seek_dist){ int adv_is_on = 0, mof_is_on = 0, lv_is_on = 0; int psad1, psad2, bsad, psad; MotionVector *MV[6][MBR+1][MBC+2]; MotionVector *mvp, *mvbf, *mvbb; int x,y; int i,j,k,tmp; /* Temporarily disable some options to simplify motion estimation */ if (advanced) { advanced = OFF; adv_is_on = ON; } if (mv_outside_frame) { mv_outside_frame = OFF; mof_is_on = ON; } if (long_vectors) { long_vectors = OFF; lv_is_on = ON; } for (j = 1; j <= (lines>>4); j++) for (i = 1; i <= (pels>>4); i++) for (k = 0; k < 3; k++) { MV[k][j][i] = (MotionVector *)calloc(1,sizeof(MotionVector)); /* calloc to avoid Checker warnings about reading of unitizalized memory in the memcpy's below */ } mvbf = (MotionVector *)malloc(sizeof(MotionVector)); mvbb = (MotionVector *)malloc(sizeof(MotionVector)); psad = 0; psad1 = 0; psad2 = 0; bsad = 0; /* Integer motion estimation */ for ( j = 1; j < lines/MB_SIZE - 1; j++) { for ( i = 1; i < pels/MB_SIZE - 1 ; i++) { x = i*MB_SIZE; y = j*MB_SIZE; /* picture order: prev -> next1 -> next2 */ /* next1 and next2 can be coded as PB or PP */ /* prev is the previous encoded picture */ /* computes vectors (prev <- next2) */ MotionEstimation(next2->lum,prev->lum,x,y,0,0,seek_dist,MV,&tmp); if (MV[0][j+1][i+1]->x == 0 && MV[0][j+1][i+1]->y == 0) MV[0][j+1][i+1]->min_error += PREF_NULL_VEC; /* not necessary to prefer zero vector here */ memcpy(MV[2][j+1][i+1],MV[0][j+1][i+1],sizeof(MotionVector)); /* computes sad(prev <- next1) */ MotionEstimation(next1->lum,prev->lum,x,y,0,0,seek_dist,MV,&tmp); if (MV[0][j+1][i+1]->x == 0 && MV[0][j+1][i+1]->y == 0) MV[0][j+1][i+1]->min_error += PREF_NULL_VEC; memcpy(MV[1][j+1][i+1],MV[0][j+1][i+1],sizeof(MotionVector)); /* computes vectors for (next1 <- next2) */ MotionEstimation(next2->lum,next1->lum,x,y,0,0,seek_dist,MV,&tmp); if (MV[0][j+1][i+1]->x == 0 && MV[0][j+1][i+1]->y == 0) MV[0][j+1][i+1]->min_error += PREF_NULL_VEC; /* scales vectors for (prev <- next2 ) */ mvp = MV[2][j+1][i+1]; mvbf->x = bskip * mvp->x / (bskip + pskip); mvbb->x = - pskip * mvp->x / (bskip + pskip); mvbf->y = bskip * mvp->y / (bskip + pskip); mvbb->y = - pskip * mvp->y / (bskip + pskip); psad1 += MV[0][j+1][i+1]->min_error; psad2 += MV[1][j+1][i+1]->min_error; psad += mvp->min_error; /* computes sad(prev <- next1 -> next2) */ bsad += SAD_MB_Bidir(next1->lum + x + y*pels, next2->lum + x + mvbb->x + (y + mvbb->y)*pels, prev->lum + x + mvbf->x + (y + mvbf->y)*pels, pels, INT_MAX); } } for (j = 1; j <= (lines>>4); j++) for (i = 1; i <= (pels>>4); i++) for (k = 0; k < 3; k++) free(MV[k][j][i]); free(mvbf); free(mvbb); /* restore advanced parameters */ advanced = adv_is_on; mv_outside_frame = mof_is_on; long_vectors = lv_is_on; /* do the decision */ if (bsad < (psad1+psad2)/2) fprintf(stdout,"Chose PB - bsad %d, psad %d\n", bsad, (psad1+psad2)/2); else fprintf(stdout,"Chose PP - bsad %d, psad %d\n", bsad, (psad1+psad2)/2); if (bsad < (psad1 + psad2)/2) return 1; else return 0;}/********************************************************************** * * Name: Help * Description: Prints usage * * ***********************************************************************/void Help(){ fprintf(stderr,"Usage:\ttmn [options] -i <filename> [more options]\n"); fprintf(stderr,"Options:\n"); fprintf(stderr,"\t-i <filename> original sequence [required parameter]\n"); fprintf(stderr,"\t-o <filename> reconstructed frames [%s]\n", DEF_OUTFILENAME); fprintf(stderr,"\t-B <filename> filename for bitstream [%s]\n", DEF_STREAMNAME); fprintf(stderr,"\t-a <n> image to start at [%d]\n", DEF_START_FRAME); fprintf(stderr,"\t-b <n> image to stop at [%d]\n", DEF_STOP_FRAME); fprintf(stderr,"\t-x <n> coding format [%d]\n",DEF_CODING_FORMAT); fprintf(stderr,"\t-q <n> (1..31) quantization parameter QP [%d]\n", DEF_INTER_QUANT); fprintf(stderr,"\t-I <n> (1..31) QP for first frame [%d]\n", DEF_INTRA_QUANT); fprintf(stderr,"\t-r <n> target bitrate in bits/s, default is variable bitrate\n"); fprintf(stderr,"\t-S <n> frames to skip between each encoded frame [%d]\n", DEF_FRAMESKIP); fprintf(stderr,"\t-D use unrestricted motion vector mode (annex D) [%s]\n", DEF_UMV_MODE ? "ON" : "OFF"); fprintf(stderr,"\t-E use syntax-based arithmetic coding (annex E) [%s]\n", DEF_SAC_MODE ? "ON" : "OFF"); fprintf(stderr,"\t-F use advanced prediction mode (annex F) [%s]\n", DEF_ADV_MODE ? "ON" : "OFF"); fprintf(stderr,"\t-G use PB-frames (annex G) [%s]\n", DEF_PBF_MODE ? "ON" : "OFF"); fprintf(stderr,"\t-h Prints simple help\n"); fprintf(stderr,"\t-H Prints advanced help\n"); fprintf(stderr,"\n\tDefault filenames and other options in square brackets \n\tare chosen in config.h\n"); return;}void AdvancedHelp(){ fprintf(stderr,"Usage:\ttmn [options] -i <filename> [more options]\n"); fprintf(stderr,"Options:\n"); fprintf(stderr,"\t-i <filename> original sequence [required parameter]\n"); fprintf(stderr,"\t-o <filename> reconstructed frames [%s]\n", DEF_OUTFILENAME); fprintf(stderr,"\t-B <filename> filename for bitstream [%s]\n", DEF_STREAMNAME); fprintf(stderr,"\t-a <n> image to start at [%d]\n", DEF_START_FRAME); fprintf(stderr,"\t-b <n> image to stop at [%d]\n", DEF_STOP_FRAME); fprintf(stderr,"\t-x <n> coding format [%d]\n",DEF_CODING_FORMAT); fprintf(stderr,"\t n=1: SQCIF n=2: QCIF n=3: CIF n=4: 4CIF n=5: 16CIF\n"); fprintf(stderr,"\t 128x96 176x144 352x288 704x576 1408x1152\n"); fprintf(stderr,"\t-s <n> (0..15) integer pel search window [%d]\n", DEF_SEEK_DIST); fprintf(stderr,"\t-q <n> (1..31) quantization parameter QP [%d]\n", DEF_INTER_QUANT); fprintf(stderr,"\t-I <n> (1..31) QP for first frame [%d]\n", DEF_INTRA_QUANT); fprintf(stderr,"\t-r <n> target bitrate in bits/s, default is variable bitrate\n");#ifdef OFFLINE_RATE_CONTROL fprintf(stderr,"\t -R <n> start rate control after n%% of sequence [%d]\n", DEF_START_RATE_CONTROL);#else fprintf(stderr,"\t -R <f> target frame rate [%.2f]\n", DEF_TARGET_FRAME_RATE);#endif fprintf(stderr,"\t-S <n> frames to skip between each encoded frame [%d]\n", DEF_FRAMESKIP); fprintf(stderr,"\t-Z <n> reference frame rate (25 or 30 fps) [%.1f]\n", DEF_REF_FRAME_RATE); fprintf(stderr,"\t-O <n> frames skipped in original compared to reference frame rate [%d]\n", DEF_ORIG_SKIP); fprintf(stderr,"\t-e <n> original sequence has n bytes header [%d]\n", DEF_HEADERLENGTH); fprintf(stderr,"\t-g <n> insert sync after each n GOB (slice) [%d]\n", DEF_INSERT_SYNC); fprintf(stderr,"\t zero above means no extra syncs inserted\n"); fprintf(stderr,"\t-w write difference image to file \"%s\" [%s]\n", DEF_DIFFILENAME, DEF_WRITE_DIFF ? "ON" : "OFF"); fprintf(stderr,"\t-m write repeated reconstructed frames to disk [%s]\n", DEF_WRITE_REPEATED ? "ON" : "OFF"); fprintf(stderr,"\t-t write trace to tracefile trace.intra/trace [%s]\n", DEF_WRITE_TRACE ? "ON" : "OFF"); fprintf(stderr,"\t-D use unrestricted motion vector mode (annex D) [%s]\n", DEF_UMV_MODE ? "ON" : "OFF"); fprintf(stderr,"\t-E use syntax-based arithmetic coding (annex E) [%s]\n", DEF_SAC_MODE ? "ON" : "OFF"); fprintf(stderr,"\t-F use advanced prediction mode (annex F) [%s]\n", DEF_ADV_MODE ? "ON" : "OFF"); fprintf(stderr,"\t-G use PB-frames (annex G) [%s]\n", DEF_PBF_MODE ? "ON" : "OFF"); fprintf(stderr,"\t -Q <n> (0..3) BQUANT parameter [%d]\n",DEF_BQUANT); fprintf(stderr,"\t-h Prints simple help\n"); fprintf(stderr,"\t-H Prints advanced help\n"); fprintf(stderr,"\n\tDefault filenames and other options in square brackets \n\tare chosen in config.h\n"); return;}/********************************************************************** * * Name: PrintResult * Description: add bits and prints results * * Input: Bits struct * * Returns: * Side effects: * * Date: 940116 Author: Karl.Lillevold@nta.no * ***********************************************************************/void PrintResult(Bits *bits,int num_units, int num){ fprintf(stdout,"# intra : %d\n", bits->no_intra/num_units); fprintf(stdout,"# inter : %d\n", bits->no_inter/num_units); fprintf(stdout,"# inter4v : %d\n", bits->no_inter4v/num_units); fprintf(stdout,"--------------\n"); fprintf(stdout,"Coeff_Y: %d\n", bits->Y/num); fprintf(stdout,"Coeff_C: %d\n", bits->C/num); fprintf(stdout,"Vectors: %d\n", bits->vec/num); fprintf(stdout,"CBPY : %d\n", bits->CBPY/num); fprintf(stdout,"MCBPC : %d\n", bits->CBPCM/num); fprintf(stdout,"MODB : %d\n", bits->MODB/num); fprintf(stdout,"CBPB : %d\n", bits->CBPB/num); fprintf(stdout,"COD : %d\n", bits->COD/num); fprintf(stdout,"DQUANT : %d\n", bits->DQUANT/num); fprintf(stdout,"header : %d\n", bits->header/num); fprintf(stdout,"==============\n"); fprintf(stdout,"Total : %d\n", bits->total/num); fprintf(stdout,"\n"); return;}void PrintSNR(Results *res, int num){ fprintf(stdout,"SNR_Y : %.2f\n", res->SNR_l/num); fprintf(stdout,"SNR_Cb : %.2f\n", res->SNR_Cb/num); fprintf(stdout,"SNR_Cr : %.2f\n", res->SNR_Cr/num); fprintf(stdout,"--------------\n"); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -