www.pudn.com > avi 到 mpeg 的转换程序及源代码.zip > AVI2M1V.C
/* avi2m1v.c - originally mpeg2enc.c */ /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ /* * Disclaimer of Warranty * * These software programs are available to the user without any license fee or * royalty on an "as is" basis. The MPEG Software Simulation Group 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 MPEG Software Simulation Group does not represent or warrant that the * programs furnished hereunder are free of infringement of any third-party * patents. * * Commercial implementations of MPEG-1 and MPEG-2 video, 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. * */ /* * 4/4/97 - John Schlichther * * extensively altered to create avi2mpg1 - avi to mpeg-1 encoder * * Since avi file, and the avi subsystem are platform dependant, cross * platform compatibility removed, many optional features disabled or * removed, code generally trimmed to a minimum. * * 7/30/97 - added support for 10, 12, and 15 FPS video, by frame replication * - round up odd frame sizes to even, pad with blank pixels * - open horizontal size up to 384 * */ #include#include #include #include #include "global.h" #include "avi2mpg1.h" #include "video.h" /* private prototypes */ static void init(void); static void setparm(void); static void initquantmat(void); int avi2m1v(outputfile) char *outputfile; { /* set up parameterse */ setparm(); /* initialize quantization matrices */ initquantmat(); /* open output file */ if (!(outfile=fopen(outputfile,"wb"))) fprintf(stderr, "\nCouldn't create video stream file %s", outputfile); init(); putseq(); fclose(outfile); #ifdef DEBUG fclose(statfile); #endif return 0; } void error(text) char *text; { putc('\n',stderr); fprintf(stderr,text); putc('\n',stderr); exit(1); } static void init() { int i, size; static int block_count_tab[3] = {6,8,12}; initbits(); init_fdct(); init_idct(); /* round picture dimensions to nearest multiple of 16 or 32 */ mb_width = (horizontal_size+15)/16; mb_height = prog_seq ? (vertical_size+15)/16 : 2*((vertical_size+31)/32); mb_height2 = fieldpic ? mb_height>>1 : mb_height; /* for field pictures */ width = 16*mb_width; height = 16*mb_height; chrom_width = (chroma_format==CHROMA444) ? width : width>>1; chrom_height = (chroma_format!=CHROMA420) ? height : height>>1; height2 = fieldpic ? height>>1 : height; width2 = fieldpic ? width<<1 : width; chrom_width2 = fieldpic ? chrom_width<<1 : chrom_width; block_count = block_count_tab[chroma_format-1]; /* 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); for (i=0; i<3; i++) { size = (i==0) ? width*height : chrom_width*chrom_height; if (!(newrefframe[i] = (unsigned char *)malloc(size))) error("malloc failed\n"); if (!(oldrefframe[i] = (unsigned char *)malloc(size))) error("malloc failed\n"); if (!(auxframe[i] = (unsigned char *)malloc(size))) error("malloc failed\n"); if (!(neworgframe[i] = (unsigned char *)malloc(size))) error("malloc failed\n"); if (!(oldorgframe[i] = (unsigned char *)malloc(size))) error("malloc failed\n"); if (!(auxorgframe[i] = (unsigned char *)malloc(size))) error("malloc failed\n"); if (!(predframe[i] = (unsigned char *)malloc(size))) error("malloc failed\n"); } // now allocate space U and V buffers for readpic routine if (!(Ubuffer = (unsigned char *)malloc(width*height))) error("malloc failed\n"); if (!(Vbuffer = (unsigned char *)malloc(width*height))) error("malloc failed\n"); mbinfo = (struct mbinfo *)malloc(mb_width*mb_height2*sizeof(struct mbinfo)); if (!mbinfo) error("malloc failed\n"); blocks = (short (*)[64])malloc(mb_width*mb_height2*block_count*sizeof(short [64])); if (!blocks) error("malloc failed\n"); #ifdef DEBUG /* open statistics output file */ if (statname[0]=='-') statfile = stdout; else if (!(statfile = fopen(statname,"w"))) { sprintf(errortext,"Couldn't create statistics output file %s",statname); error(errortext); } #endif } static void setparm() { int i; int h,m,s,f; static double ratetab[8]= {24000.0/1001.0,24.0,25.0,30000.0/1001.0,30.0,50.0,60000.0/1001.0,60.0}; extern int r,Xi,Xb,Xp,d0i,d0p,d0b; /* rate control */ extern double avg_act; /* rate control */ FILE *fd; char line[256]; // several of the encoding parameters are implied by the source file // format, lets get these parameters from the .avi file. strcpy(tplref, "-"); strcpy(statname, "nul:"); i = (int)((float)pfi.dwRate/(float)pfi.dwScale*100.0); frame_rate_code = 0; frame_repl = 1; if(!forced_frame_rate) { if((i>950)&&(i<1010)) { frame_rate_code = 5; frame_repl = 3; } if((i>1150)&&(i<1250)) { frame_rate_code = 2; frame_repl = 2; } if((i>1450)&&(i<1550)) { frame_rate_code = 5; frame_repl = 2; } if((i>2350)&&(i<2400)) frame_rate_code = 1; if((i>=2400)&&(i<2450)) frame_rate_code = 2; if((i>2450)&&(i<2550)) frame_rate_code = 3; if((i>2950)&&(i<3000)) frame_rate_code = 4; if((i>=3000)&&(i<3050)) frame_rate_code = 5; if(frame_rate_code == 0) { fprintf(stderr, "\nsource frame rate must be 10, 12, 15, 23.976, 24, 25, 29.97, or 30 FPS!"); fprintf(stderr, "\nif you don not require audio, try using forced frame rate option (-f).\n"); exit(-1); } } else { frame_rate_code = forced_frame_rate; } if(vcd_parm) { crop_size = 1; crop_horz = 352; if((frame_rate_code<2)||(frame_rate_code>3)) crop_vert = 240; else crop_vert = 288; } inputtype = 1; // set no. of frames to frames in avi file nframes = (pfi.dwLength * frame_repl) - 1; // lets assume starts at frame 0 frame0 = 0; fieldpic = 0; // frame pictures only for mpeg1 if(!crop_size) { //horizontal_size = ((pfi.dwWidth + 1)>>1)<<1; // make it even // at least one software player couldn't seem to handle some videos that were not // a multiple of 16 wide (ie: 290 x 228), therefore round up to nearest 16 horizontal_size = ((pfi.dwWidth + 15)>>4)<<4; // make it multiple of 16 vertical_size = ((pfi.dwHeight + 1)>>1)<<1; } else { horizontal_size = ((crop_horz + 1)>>1)<<1; // make it even vertical_size = ((crop_vert + 1)>>1)<<1; } if(vcd_parm) bit_rate = 1150000; // Video CD Video stream data rate else if(video_only) bit_rate = system_byterate_parm*8*1024; else { bit_rate = (float)(system_byterate_parm*8*1024) - (float)(audio_bitrate_parm*1024) - (float)(4*8*1024); if(bit_rate <= 81920) { fprintf(stderr, "\n specified parameters would result in video bitrate of less than 81920!"); fprintf(stderr, "\n Try adjusting audio bit-rate (-a), or use video only stream (-n)\n"); exit(-1); } } fprintf(stderr, " using bitrate of %u", (unsigned int)bit_rate); fprintf(stderr, ":\n"); if((pfi.dwWidth!=horizontal_size)||(pfi.dwHeight!=vertical_size)) { fprintf(stderr, "*** WARNING: cropping video to %i x %i\n", horizontal_size, vertical_size); } if(frame_repl!=1) { fprintf(stderr, "Source FPS of %u will be upsampled to %u FPS,", (i+50)/100, (i+50)/100*frame_repl); fprintf(stderr, " New total frames = %u\n", nframes); } if(forced_frame_rate) { fprintf(stderr, "\n Forcing frame rate of "); switch (forced_frame_rate) { case 1: fprintf(stderr, "23.976"); break; case 2: fprintf(stderr, "24"); break; case 3: fprintf(stderr, "25"); break; case 4: fprintf(stderr, "29.97"); break; case 5: fprintf(stderr, "30"); break; } fprintf(stderr, " FPS, video only stream.\n"); } // bit_rate = 1856000; // max SIF low_delay = 0; prog_seq = 1; chroma_format = 1; // 4:2:0 display_horizontal_size = pfi.dwWidth; display_vertical_size = pfi.dwHeight; conceal_tab[0] = 0; conceal_tab[1] = 0; conceal_tab[2] = 0; topfirst = 0; prog_frame = 1; if(use_v_param_file) { // if user wishes to fine tune encoding parameters, then read in parameter file if (!(fd = fopen(video_param_filename,"r"))) { sprintf(errortext,"Couldn't open video parameter file %s",video_param_filename); error(errortext); } fgets(id_string,254,fd); fgets(line,254,fd); sscanf(line,"%s",iqname); fgets(line,254,fd); sscanf(line,"%s",niqname); fgets(line,254,fd); sscanf(line,"%d:%d:%d:%d",&h,&m,&s,&f); fgets(line,254,fd); sscanf(line,"%d",&N); fgets(line,254,fd); sscanf(line,"%d",&M); fgets(line,254,fd); sscanf(line,"%d",&aspectratio); fgets(line,254,fd); sscanf(line,"%d",&vbv_buffer_size); fgets(line,254,fd); sscanf(line,"%d",&constrparms); fgets(line,254,fd); sscanf(line,"%d",&profile); fgets(line,254,fd); sscanf(line,"%d",&level); fgets(line,254,fd); sscanf(line,"%d",&video_format); fgets(line,254,fd); sscanf(line,"%d",&color_primaries); fgets(line,254,fd); sscanf(line,"%d",&transfer_characteristics); fgets(line,254,fd); sscanf(line,"%d",&matrix_coefficients); fgets(line,254,fd); sscanf(line,"%d",&dc_prec); fgets(line,254,fd); sscanf(line,"%d %d %d", frame_pred_dct_tab,frame_pred_dct_tab+1,frame_pred_dct_tab+2); fgets(line,254,fd); sscanf(line,"%d %d %d", qscale_tab,qscale_tab+1,qscale_tab+2); fgets(line,254,fd); sscanf(line,"%d %d %d", intravlc_tab,intravlc_tab+1,intravlc_tab+2); fgets(line,254,fd); sscanf(line,"%d %d %d", altscan_tab,altscan_tab+1,altscan_tab+2); fgets(line,254,fd); sscanf(line,"%d",&repeatfirst); /* intra slice interval refresh period */ fgets(line,254,fd); sscanf(line,"%d",&P); fgets(line,254,fd); sscanf(line,"%d",&r); fgets(line,254,fd); sscanf(line,"%lf",&avg_act); fgets(line,254,fd); sscanf(line,"%d",&Xi); fgets(line,254,fd); sscanf(line,"%d",&Xp); fgets(line,254,fd); sscanf(line,"%d",&Xb); fgets(line,254,fd); sscanf(line,"%d",&d0i); fgets(line,254,fd); sscanf(line,"%d",&d0p); fgets(line,254,fd); sscanf(line,"%d",&d0b); if (N<1) error("N must be positive"); if (M<1) error("M must be positive"); if (N%M != 0) error("N must be an integer multiple of M"); motion_data = (struct motion_data *)malloc(M*sizeof(struct motion_data)); if (!motion_data) error("malloc failed\n"); for (i=0; i 3) N=15; else N=12; M=3; aspectratio = 1; // square pels (VGA?) vbv_buffer_size = vbv_size; // vbv_buffer_size (in multiples of 16 kbit) // vbv_buffer_size = 20; // max SIF constrparms = 1; profile = 4; // Main level = 10; // Main video_format = 0; color_primaries = 5; transfer_characteristics = 5; matrix_coefficients = 5; dc_prec = 0; // 8 bit frame_pred_dct_tab[0] = 1; frame_pred_dct_tab[1] = 1; frame_pred_dct_tab[2] = 1; qscale_tab[0] = 0; qscale_tab[1] = 0; qscale_tab[2] = 0; intravlc_tab[0] = 0; intravlc_tab[1] = 0; intravlc_tab[2] = 0; altscan_tab[0] = 0; altscan_tab[1] = 0; altscan_tab[2] = 0; repeatfirst = 0; /* intra slice interval refresh period */ P = 0; r = 0; avg_act = 0; Xi = 0; Xp = 0; Xb = 0; d0i = 0; d0p = 0; d0b = 0; motion_data = (struct motion_data *)malloc(M*sizeof(struct motion_data)); if (!motion_data) error("malloc failed\n"); switch (m_search_size) { case 0: motion_data[0].forw_hor_f_code = motion_data[0].forw_vert_f_code = 2; motion_data[0].sxf = motion_data[0].syf = 11; motion_data[1].forw_hor_f_code = motion_data[1].forw_vert_f_code = 1; motion_data[1].sxf = motion_data[1].syf = 3; motion_data[1].back_hor_f_code = motion_data[1].back_vert_f_code = 1; motion_data[1].sxb = motion_data[1].syb = 7; motion_data[2].forw_hor_f_code = motion_data[2].forw_vert_f_code = 1; motion_data[2].sxf = motion_data[2].syf = 7; motion_data[2].back_hor_f_code = motion_data[2].back_vert_f_code = 1; motion_data[2].sxb = motion_data[2].syb = 3; break; case 1: motion_data[0].forw_hor_f_code = motion_data[0].forw_vert_f_code = 2; motion_data[0].sxf = motion_data[0].syf = 15; motion_data[1].forw_hor_f_code = motion_data[1].forw_vert_f_code = 1; motion_data[1].sxf = motion_data[1].syf = 7; motion_data[1].back_hor_f_code = motion_data[1].back_vert_f_code = 2; motion_data[1].sxb = motion_data[1].syb = 15; motion_data[2].forw_hor_f_code = motion_data[2].forw_vert_f_code = 2; motion_data[2].sxf = motion_data[2].syf = 15; motion_data[2].back_hor_f_code = motion_data[2].back_vert_f_code = 1; motion_data[2].sxb = motion_data[2].syb = 7; break; case 2: motion_data[0].forw_hor_f_code = motion_data[0].forw_vert_f_code = 3; motion_data[0].sxf = motion_data[0].syf = 31; motion_data[1].forw_hor_f_code = motion_data[1].forw_vert_f_code = 2; motion_data[1].sxf = motion_data[1].syf = 15; motion_data[1].back_hor_f_code = motion_data[1].back_vert_f_code = 3; motion_data[1].sxb = motion_data[1].syb = 31; motion_data[2].forw_hor_f_code = motion_data[2].forw_vert_f_code = 3; motion_data[2].sxf = motion_data[2].syf = 31; motion_data[2].back_hor_f_code = motion_data[2].back_vert_f_code = 2; motion_data[2].sxb = motion_data[2].syb = 15; break; case 3: motion_data[0].forw_hor_f_code = motion_data[0].forw_vert_f_code = 4; motion_data[0].sxf = motion_data[0].syf = 63; motion_data[1].forw_hor_f_code = motion_data[1].forw_vert_f_code = 3; motion_data[1].sxf = motion_data[1].syf = 31; motion_data[1].back_hor_f_code = motion_data[1].back_vert_f_code = 4; motion_data[1].sxb = motion_data[1].syb = 63; motion_data[2].forw_hor_f_code = motion_data[2].forw_vert_f_code = 4; motion_data[2].sxf = motion_data[2].syf = 63; motion_data[2].back_hor_f_code = motion_data[2].back_vert_f_code = 3; motion_data[2].sxb = motion_data[2].syb = 31; break; case 4: motion_data[0].forw_hor_f_code = motion_data[0].forw_vert_f_code = 4; motion_data[0].sxf = motion_data[0].syf = 63; motion_data[1].forw_hor_f_code = motion_data[1].forw_vert_f_code = 4; motion_data[1].sxf = motion_data[1].syf = 63; motion_data[1].back_hor_f_code = motion_data[1].back_vert_f_code = 4; motion_data[1].sxb = motion_data[1].syb = 63; motion_data[2].forw_hor_f_code = motion_data[2].forw_vert_f_code = 4; motion_data[2].sxf = motion_data[2].syf = 63; motion_data[2].back_hor_f_code = motion_data[2].back_vert_f_code = 4; motion_data[2].sxb = motion_data[2].syb = 63; break; } } if(vcd_parm) { vbv_buffer_size = 20; aspectratio = 14; } /* make flags boolean (x!=0 -> x=1) */ fieldpic = !!fieldpic; low_delay = !!low_delay; constrparms = !!constrparms; prog_seq = !!prog_seq; topfirst = !!topfirst; for (i=0; i<3; i++) { frame_pred_dct_tab[i] = !!frame_pred_dct_tab[i]; conceal_tab[i] = !!conceal_tab[i]; qscale_tab[i] = !!qscale_tab[i]; intravlc_tab[i] = !!intravlc_tab[i]; altscan_tab[i] = !!altscan_tab[i]; } repeatfirst = !!repeatfirst; prog_frame = !!prog_frame; /* make sure MPEG specific parameters are valid */ range_checks(); frame_rate = ratetab[frame_rate_code-1]; /* timecode -> frame number */ tc0 = h; tc0 = 60*tc0 + m; tc0 = 60*tc0 + s; tc0 = (int)(frame_rate+0.5)*tc0 + f; /* MPEG-1 */ if (constrparms) { if (horizontal_size>768 || vertical_size>576 || ((horizontal_size+15)/16)*((vertical_size+15)/16)>396 || ((horizontal_size+15)/16)*((vertical_size+15)/16)*frame_rate>396*25.0 || frame_rate>30.0) { if (!quiet) fprintf(stderr,"\n*** WARNING: VIDEO EXCEEDS CPB STANDARD!\n"); constrparms = 0; } } if (constrparms) { for (i=0; i 4) { if (!quiet) fprintf(stderr,"\n*** WARNING: VIDEO EXCEEDS CPB STANDARD!\n"); constrparms = 0; break; } if (motion_data[i].forw_vert_f_code>4) { if (!quiet) fprintf(stderr,"\n*** WARNING: VIDEO EXCEEDS CPB STANDARD!\n"); constrparms = 0; break; } if (i!=0) { if (motion_data[i].back_hor_f_code>4) { if (!quiet) fprintf(stderr,"\n*** WARNING: VIDEO EXCEEDS CPB STANDARD!\n"); constrparms = 0; break; } if (motion_data[i].back_vert_f_code>4) { if (!quiet) fprintf(stderr,"\n*** WARNING: VIDEO EXCEEDS CPB STANDARD!\n"); constrparms = 0; break; } } } } /* relational checks */ if (!prog_seq) { if (!quiet) fprintf(stderr,"\nWarning: setting progressive_sequence = 1\n"); prog_seq = 1; } if (chroma_format!=CHROMA420) { if (!quiet) fprintf(stderr,"\nWarning: setting chroma_format = 1 (4:2:0)\n"); chroma_format = CHROMA420; } if (dc_prec!=0) { if (!quiet) fprintf(stderr,"\nWarning: setting intra_dc_precision = 0\n"); dc_prec = 0; } for (i=0; i<3; i++) if (qscale_tab[i]) { if (!quiet) fprintf(stderr,"\nWarning: setting qscale_tab[%d] = 0\n",i); qscale_tab[i] = 0; } for (i=0; i<3; i++) if (intravlc_tab[i]) { if (!quiet) fprintf(stderr,"\nWarning: setting intravlc_tab[%d] = 0\n",i); intravlc_tab[i] = 0; } for (i=0; i<3; i++) if (altscan_tab[i]) { if (!quiet) fprintf(stderr,"\nWarning: setting altscan_tab[%d] = 0\n",i); altscan_tab[i] = 0; } if (prog_seq && !prog_frame) { if (!quiet) fprintf(stderr,"\nWarning: setting progressive_frame = 1\n"); prog_frame = 1; } if (prog_frame && fieldpic) { if (!quiet) fprintf(stderr,"\nWarning: setting field_pictures = 0\n"); fieldpic = 0; } if (!prog_frame && repeatfirst) { if (!quiet) fprintf(stderr,"\nWarning: setting repeat_first_field = 0\n"); repeatfirst = 0; } if (prog_frame) { for (i=0; i<3; i++) if (!frame_pred_dct_tab[i]) { if (!quiet) fprintf(stderr,"\nWarning: setting frame_pred_frame_dct[%d] = 1\n",i); frame_pred_dct_tab[i] = 1; } } if (prog_seq && !repeatfirst && topfirst) { if (!quiet) fprintf(stderr,"\nWarning: setting top_field_first = 0\n"); topfirst = 0; } /* search windows */ for (i=0; i (4< (4< (4< (4< 255) error("invalid value in quant matrix"); intra_q[i] = v; } fclose(fd); } if (niqname[0]=='-') { /* use default non-intra matrix */ load_niquant = 0; for (i=0; i<64; i++) inter_q[i] = 16; } else { /* read customized non-intra matrix */ load_niquant = 1; if (!(fd = fopen(niqname,"r"))) { sprintf(errortext,"Couldn't open quant non-intra matrix file %s",niqname); error(errortext); } for (i=0; i<64; i++) { fscanf(fd,"%d",&v); if (v<1 || v>255) error("invalid value in quant matrix"); inter_q[i] = v; } fclose(fd); } }