📄 main.c
字号:
/************************************************************************ * * main.c, main module of tmn (TMN encoder). * tmn is an H.263+ (H.263 ver. 2.0) encoder somewhat based on the * Test Model Near-term (TMN8) in the ITU-T LBC Experts Group. * * Copyright (C) 1997 University of BC, Canada * * Contacts: * Michael Gallant <mikeg@ee.ubc.ca> * Guy Cote <guyc@ee.ubc.ca> * Berna Erol <bernae@ee.ubc.ca> * * UBC Image Processing Laboratory http://www.ee.ubc.ca/image * 2356 Main Mall tel.: +1 604 822 4051 * Vancouver BC Canada V6T1Z4 fax.: +1 604 822 5949 * ************************************************************************//* * Disclaimer of Warranty * * These software programs are available to the user without any * license fee or royalty on an "as is" basis. The University of * British Columbia disclaims any and all warranties, whether * express, implied, or statuary, including any implied warranties * or merchantability or of fitness for a particular purpose. In no * event shall the copyright-holder be liable for any incidental, * punitive, or consequential damages of any kind whatsoever arising * from the use of these programs. * * This disclaimer of warranty extends to the user of these programs * and user's customers, employees, agents, transferees, successors, * and assigns. * * The University of British Columbia does not represent or warrant * that the programs furnished hereunder are free of infringement of * any third-party patents. * * Commercial implementations of H.263, including shareware, are * subject to royalty fees to patent holders. Many of these patents * are general enough such that they are unavoidable regardless of * implementation design. **/#include <time.h>#include"sim.h"#include"main.h"FILE *streamfile;/********************************************************************** * * Name: main * Description: initializes coder, processes arguments, main * coding loop, generates statistics * * Input: * * Returns: * Side effects: * * Date: 970930 Author: Michael Gallant <mikeg@ee.ubc.ca> * ***********************************************************************/void main(int argc, char *argv[]){ PictImage *prev_image = NULL; PictImage *curr_image = NULL; PictImage *curr_recon = NULL; PictImage *prev_recon = NULL; /* To be used for temporal scalability. */ PictImage *next_P_image = NULL; PictImage *next_P_recon = NULL; PictImage *prev_P_image = NULL; PictImage *prev_P_recon = NULL; /* To be used for SNR/spatial scalability. */ PictImage *prev_enhancement_image = NULL; PictImage *prev_enhancement_recon = NULL; PictImage *curr_reference_recon = NULL; PictImage *curr_enhancement_recon = NULL; DiffImage *diff_image = NULL; DiffImage *diff_recon= NULL; /* PB-frame specific */ PictImage *B_recon = NULL; PictImage *B_image = NULL; Pict *pic = (Pict *)malloc(sizeof(Pict)); unsigned char *image; int i,j; int prev_I_P_quant, first_P = 1; int True_B_frameskip, P_frameskip; int TR_new = 0, TR_old = 0; int rtype[MAX_LAYERS] = {0}; /* Off line rate control variables */ PictImage *stored_image = NULL; /* Reference Picture Selection variables */ int thread_count = 0; int frame_in_thread = 0; Thread ***thread; bits = (Bits *)calloc(1,sizeof(Bits)); total_bits = (Bits *)calloc(1,sizeof(Bits)); total_res = (Results *)calloc(1,sizeof(Results)); intra_bits = (Bits *)calloc(1,sizeof(Bits)); intra_res = (Results *)calloc(1,sizeof(Results)); inter_bits = (Bits *)calloc(1,sizeof(Bits)); inter_res = (Results *)calloc(1,sizeof(Results)); scal_bits = (Bits *)calloc(1,sizeof(Bits)); scal_res = (Results *)calloc(1,sizeof(Results)); ei_bits = (Bits *)calloc(1,sizeof(Bits)); ei_res = (Results *)calloc(1,sizeof(Results)); ep_bits = (Bits *)calloc(1,sizeof(Bits)); ep_res = (Results *)calloc(1,sizeof(Results)); res = (Results *)calloc(1,sizeof(Results)); pic->BCM = (BCM *)calloc(1,sizeof(BCM)); fprintf (stdout,"\nTMN (H.263) coder version 3.0, University of British Columbia, CANADA, based on Telenor's coder version 2.0, Copyright (C) 1995, 1996 Telenor R&D, Norway\n");#ifndef FASTIDCT init_idctref();#endif InitializeCoder(pic); ProcessArguments(argc,argv, pic); /* Allocate memory for thread structure */ if (pic->reference_picture_selection) { thread = (Thread ***) malloc(number_of_threads*sizeof(Thread)); for (j=0; j<number_of_threads; ++j) { thread[j] = (Thread **)malloc(frames_per_thread*sizeof(Thread) ); for (i=0; i<frames_per_thread; ++i) { thread[j][i] = (Thread *)calloc(1,sizeof(Thread) ); } } } /* rate control variables */ if (targetrate == 0) { rate_control_method = NO; } else { pic->bit_rate = targetrate; InitializeRateControl(); } /* pic->src_frame_rate needed to update UFEP */ pic->src_frame_rate = (int)(ref_frame_rate / orig_frameskip); frame_rate = ref_frame_rate / (float)(orig_frameskip * chosen_frameskip); if (rate_control_method == OFFLINE_RC) fprintf(stdout,"Encoding frame rate : %.2f\n", frame_rate); else fprintf(stdout,"Encoding frame rate : variable\n"); 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); /* Initialize bitcounters */ initbits (); /* Needed for Annex O temporal scalability * fixed_frameskip = chosen_frameskip x orig_frameskip; * True_B_frameskip = fixed_frameskip; */ True_B_frameskip = frameskip / (successive_B_frames + 1); /* number of seconds to encode */ seconds = (end - start + chosen_frameskip) * orig_frameskip/ ref_frame_rate; if (trace) { strcpy(tracefile, "trace.enc"); /* Open trace-file for writing */ if ((tf = fopen(tracefile,"w")) == NULL) { fprintf(stderr,"Unable to open tracefile\n"); exit(-1); } } if (pb_frames || improved_pb_frames) { pb_bits = (Bits *)calloc(1,sizeof(Bits)); pb_res = (Results *)calloc(1,sizeof(Results)); } if (successive_B_frames) { b_bits = (Bits *)calloc(1,sizeof(Bits)); b_res = (Results *)calloc(1,sizeof(Results)); } if (scalability_mode) { scal_bits = (Bits *)calloc(1,sizeof(Bits)); scal_res = (Results *)calloc(1,sizeof(Results)); } pic->UFEP = 0; prev_I_P_frame_no = start; /***** Main loop *****/ for (frame_no = start, i = 0; i <= (end - start) && frame_no <= end; ++i) { DeterminePictureType(&frame_no, pic, P_frameskip, True_B_frameskip, i); if (-1 == pic->picture_coding_type) { break; } if (pic->picture_coding_type != prev_pict_type) ++pic->GFID; pic->RTYPE = 0; /* Set the reference picture according to the thread and frame in thread */ /* frame in thread is reset to zero after a sync frame */ if (pic->reference_picture_selection) { pic->TRPI = YES; pic->TRP = thread[thread_count][frame_in_thread]->TRP; pic->RPSMF = NO_ACK_NACK; pic->BCM->present = NO; thread[thread_count][frame_in_thread]->TR = pic->TR; if (pic->picture_coding_type != PCT_INTRA) { if (!frame_in_thread && thread_count != 0) { /* this is a sync frame: code the same TR again if GOBs are used, only the a certain number of GOBs will be encoded as sync GOBs (not the whole picture) */ frame_no = prev_I_P_frame_no = prev_frame_no; pic->TR = prev_I_P_pic_TR = thread[0][frame_in_thread]->TR; fprintf(stdout, "Coding Sync frame \n"); pic->sync = 1; } else { pic->sync = 0; } GetReferencePicture(pic->TRP, prev_image, prev_recon); } else { thread_count = frame_in_thread = 0; } /* previous frame number is needed to code a sync frame */ prev_frame_no = frame_no; fprintf(stdout, "Thread no: %d Frame in thread: %d (TR: %d TRP: %d)\n", thread_count+1, frame_in_thread+1, pic->TR, pic->TRP); } switch (pic->picture_coding_type) { case PCT_INTRA: ++Iframes; pels = base_pels; lines = base_lines; cpels = base_pels/2; image = ReadImage(seqfilename,frame_no,headerlength); curr_image = FillImage(image); fprintf(stdout,"Coding I frame... ", frame_no); fflush(stdout); pic->QUANT = QP = i_picture_quant; pic->DQUANT = 0; if (EPTYPE) { /* Alternate picture rounding type */ pic->RTYPE = rtype[0] % 2; rtype[0]++; } curr_recon = CodeOneIntra(curr_image, QP, bits, pic); CalculateStatistics(curr_image, curr_recon, NULL, NULL, bits, QP, pic); /* Special handling if temporal scalability. B frames will be * inserted between the first I-P pair. So the future P frame will * be the next frame coded. It sets prev_P_image and prev_P_recon * based on to the previous next_P_image and next_P_recon, * respectively. */ if (successive_B_frames) { /* Free the past prev_P_image and prev_P_recon, no longer needed */ if (NULL != prev_P_image) { FreeImage(prev_P_image); FreeImage(prev_P_recon); } /* Set new prev_P_image and prev_P_recon to old next_P_image and * next_P_recon respectively */ prev_P_image = next_P_image; prev_P_recon = next_P_recon; /* For future I_P pictures, curr_image and curr_recon are set to * prev_image and prev_recon. For B picture prediction, curr_image * and curr_recon represent next_P_image and next_P_recon. */ prev_image = next_P_image = curr_image; prev_recon = next_P_recon = curr_recon; } else { if (NULL != prev_image) { FreeImage(prev_image); FreeImage(prev_recon); } prev_image = curr_image; prev_recon = curr_recon; } prev_I_P_quant = pic->QUANT; /* Frame layer Rate Control */ frameskip = FrameLayerRC(pic); fprintf(stdout,"Finished INTRA\n"); break; case PCT_INTER: pframes++; frames++; pels = base_pels; lines = base_lines; cpels = base_pels/2; image = ReadImage(seqfilename,frame_no,headerlength); curr_image = FillImage(image); fprintf(stdout,"Coding P frame %d... ", frame_no); fflush(stdout); /* Set QP to pic->QUANT from previous encoded picture */ if (first_P) { first_P = 0; prev_I_P_quant = p_picture_quant; } QP = prev_I_P_quant; pic->DQUANT = 0; if (EPTYPE) { /* Alternate picture rounding type */ pic->RTYPE = rtype[0] % 2; rtype[0]++; } curr_recon = InitImage(pels*lines); CodeOneOrTwo( curr_image, NULL, prev_image, prev_recon, QP, P_frameskip * orig_frameskip, bits, pic, NULL, curr_recon); CalculateStatistics(curr_image, curr_recon, NULL, NULL, bits, QP, pic); /* Special handling for case of temporal scalability. The P frame being coded * is the future P frame. */ if (successive_B_frames) { /* Free the past prev_P_image and prev_P_recon, no longer needed */ if (NULL != prev_P_image) { FreeImage(prev_P_image); FreeImage(prev_P_recon); } /* Set new prev_P_image and prev_P_recon to old next_P_image and * next_P_recon respectively */ prev_P_image = next_P_image; prev_P_recon = next_P_recon; /* For future I_P pictures, curr_image and curr_recon are set to * prev_image and prev_recon. For B picture prediction, curr_image * and curr_recon represent next_P_image and next_P_recon. */ prev_image = next_P_image = curr_image; prev_recon = next_P_recon = curr_recon; } else { if (NULL != prev_recon) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -