1 /* mpeg2enc.c, main() and parameter file reading */
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
6 * Disclaimer of Warranty
8 * These software programs are available to the user without any license fee or
9 * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
10 * any and all warranties, whether express, implied, or statuary, including any
11 * implied warranties or merchantability or of fitness for a particular
12 * purpose. In no event shall the copyright-holder be liable for any
13 * incidental, punitive, or consequential damages of any kind whatsoever
14 * arising from the use of these programs.
16 * This disclaimer of warranty extends to the user of these programs and user's
17 * customers, employees, agents, transferees, successors, and assigns.
19 * The MPEG Software Simulation Group does not represent or warrant that the
20 * programs furnished hereunder are free of infringement of any third-party
23 * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
24 * are subject to royalty fees to patent holders. Many of these patents are
25 * general enough such that they are unavoidable regardless of implementation
33 #define GLOBAL /* used by global.h */
37 /* private prototypes */
38 static void init _ANSI_ARGS_((void));
39 static void readparmfile _ANSI_ARGS_((char *fname));
40 static void readquantmat _ANSI_ARGS_((void));
49 printf("\n%s, %s\n",version,author);
50 printf("Usage: mpeg2encode in.par out.m2v\n");
54 /* read parameter file */
55 readparmfile(argv[1]);
57 /* read quantization matrices */
60 /* open output file */
61 if (!(outfile=fopen(argv[2],"wb")))
63 sprintf(errortext,"Couldn't create output file %s",argv[2]);
79 static int block_count_tab[3] = {6,8,12};
85 /* round picture dimensions to nearest multiple of 16 or 32 */
86 mb_width = (horizontal_size+15)/16;
87 mb_height = prog_seq ? (vertical_size+15)/16 : 2*((vertical_size+31)/32);
88 mb_height2 = fieldpic ? mb_height>>1 : mb_height; /* for field pictures */
90 height = 16*mb_height;
92 chrom_width = (chroma_format==CHROMA444) ? width : width>>1;
93 chrom_height = (chroma_format!=CHROMA420) ? height : height>>1;
95 height2 = fieldpic ? height>>1 : height;
96 width2 = fieldpic ? width<<1 : width;
97 chrom_width2 = fieldpic ? chrom_width<<1 : chrom_width;
99 block_count = block_count_tab[chroma_format-1];
102 if (!(clp = (unsigned char *)malloc(1024)))
103 error("malloc failed\n");
105 for (i=-384; i<640; i++)
106 clp[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
110 size = (i==0) ? width*height : chrom_width*chrom_height;
112 if (!(newrefframe[i] = (unsigned char *)malloc(size)))
113 error("malloc failed\n");
114 if (!(oldrefframe[i] = (unsigned char *)malloc(size)))
115 error("malloc failed\n");
116 if (!(auxframe[i] = (unsigned char *)malloc(size)))
117 error("malloc failed\n");
118 if (!(neworgframe[i] = (unsigned char *)malloc(size)))
119 error("malloc failed\n");
120 if (!(oldorgframe[i] = (unsigned char *)malloc(size)))
121 error("malloc failed\n");
122 if (!(auxorgframe[i] = (unsigned char *)malloc(size)))
123 error("malloc failed\n");
124 if (!(predframe[i] = (unsigned char *)malloc(size)))
125 error("malloc failed\n");
128 mbinfo = (struct mbinfo *)malloc(mb_width*mb_height2*sizeof(struct mbinfo));
131 error("malloc failed\n");
134 (short (*)[64])malloc(mb_width*mb_height2*block_count*sizeof(short [64]));
137 error("malloc failed\n");
139 /* open statistics output file */
140 if (statname[0]=='-')
142 else if (!(statfile = fopen(statname,"w")))
144 sprintf(errortext,"Couldn't create statistics output file %s",statname);
152 fprintf(stderr,text);
157 static void readparmfile(fname)
164 static double ratetab[8]=
165 {24000.0/1001.0,24.0,25.0,30000.0/1001.0,30.0,50.0,60000.0/1001.0,60.0};
166 extern int r,Xi,Xb,Xp,d0i,d0p,d0b; /* rate control */
167 extern double avg_act; /* rate control */
169 if (!(fd = fopen(fname,"r")))
171 sprintf(errortext,"Couldn't open parameter file %s",fname);
175 fgets(id_string,254,fd);
176 fgets(line,254,fd); sscanf(line,"%s",tplorg);
177 fgets(line,254,fd); sscanf(line,"%s",tplref);
178 fgets(line,254,fd); sscanf(line,"%s",iqname);
179 fgets(line,254,fd); sscanf(line,"%s",niqname);
180 fgets(line,254,fd); sscanf(line,"%s",statname);
181 fgets(line,254,fd); sscanf(line,"%d",&inputtype);
182 fgets(line,254,fd); sscanf(line,"%d",&nframes);
183 fgets(line,254,fd); sscanf(line,"%d",&frame0);
184 fgets(line,254,fd); sscanf(line,"%d:%d:%d:%d",&h,&m,&s,&f);
185 fgets(line,254,fd); sscanf(line,"%d",&N);
186 fgets(line,254,fd); sscanf(line,"%d",&M);
187 fgets(line,254,fd); sscanf(line,"%d",&mpeg1);
188 fgets(line,254,fd); sscanf(line,"%d",&fieldpic);
189 fgets(line,254,fd); sscanf(line,"%d",&horizontal_size);
190 fgets(line,254,fd); sscanf(line,"%d",&vertical_size);
191 fgets(line,254,fd); sscanf(line,"%d",&aspectratio);
192 fgets(line,254,fd); sscanf(line,"%d",&frame_rate_code);
193 fgets(line,254,fd); sscanf(line,"%lf",&bit_rate);
194 fgets(line,254,fd); sscanf(line,"%d",&vbv_buffer_size);
195 fgets(line,254,fd); sscanf(line,"%d",&low_delay);
196 fgets(line,254,fd); sscanf(line,"%d",&constrparms);
197 fgets(line,254,fd); sscanf(line,"%d",&profile);
198 fgets(line,254,fd); sscanf(line,"%d",&level);
199 fgets(line,254,fd); sscanf(line,"%d",&prog_seq);
200 fgets(line,254,fd); sscanf(line,"%d",&chroma_format);
201 fgets(line,254,fd); sscanf(line,"%d",&video_format);
202 fgets(line,254,fd); sscanf(line,"%d",&color_primaries);
203 fgets(line,254,fd); sscanf(line,"%d",&transfer_characteristics);
204 fgets(line,254,fd); sscanf(line,"%d",&matrix_coefficients);
205 fgets(line,254,fd); sscanf(line,"%d",&display_horizontal_size);
206 fgets(line,254,fd); sscanf(line,"%d",&display_vertical_size);
207 fgets(line,254,fd); sscanf(line,"%d",&dc_prec);
208 fgets(line,254,fd); sscanf(line,"%d",&topfirst);
209 fgets(line,254,fd); sscanf(line,"%d %d %d",
210 frame_pred_dct_tab,frame_pred_dct_tab+1,frame_pred_dct_tab+2);
212 fgets(line,254,fd); sscanf(line,"%d %d %d",
213 conceal_tab,conceal_tab+1,conceal_tab+2);
215 fgets(line,254,fd); sscanf(line,"%d %d %d",
216 qscale_tab,qscale_tab+1,qscale_tab+2);
218 fgets(line,254,fd); sscanf(line,"%d %d %d",
219 intravlc_tab,intravlc_tab+1,intravlc_tab+2);
220 fgets(line,254,fd); sscanf(line,"%d %d %d",
221 altscan_tab,altscan_tab+1,altscan_tab+2);
222 fgets(line,254,fd); sscanf(line,"%d",&repeatfirst);
223 fgets(line,254,fd); sscanf(line,"%d",&prog_frame);
224 /* intra slice interval refresh period */
225 fgets(line,254,fd); sscanf(line,"%d",&P);
226 fgets(line,254,fd); sscanf(line,"%d",&r);
227 fgets(line,254,fd); sscanf(line,"%lf",&avg_act);
228 fgets(line,254,fd); sscanf(line,"%d",&Xi);
229 fgets(line,254,fd); sscanf(line,"%d",&Xp);
230 fgets(line,254,fd); sscanf(line,"%d",&Xb);
231 fgets(line,254,fd); sscanf(line,"%d",&d0i);
232 fgets(line,254,fd); sscanf(line,"%d",&d0p);
233 fgets(line,254,fd); sscanf(line,"%d",&d0b);
236 error("N must be positive");
238 error("M must be positive");
240 error("N must be an integer multiple of M");
242 motion_data = (struct motion_data *)malloc(M*sizeof(struct motion_data));
244 error("malloc failed\n");
249 sscanf(line,"%d %d %d %d",
250 &motion_data[i].forw_hor_f_code, &motion_data[i].forw_vert_f_code,
251 &motion_data[i].sxf, &motion_data[i].syf);
256 sscanf(line,"%d %d %d %d",
257 &motion_data[i].back_hor_f_code, &motion_data[i].back_vert_f_code,
258 &motion_data[i].sxb, &motion_data[i].syb);
264 /* make flags boolean (x!=0 -> x=1) */
266 fieldpic = !!fieldpic;
267 low_delay = !!low_delay;
268 constrparms = !!constrparms;
269 prog_seq = !!prog_seq;
270 topfirst = !!topfirst;
274 frame_pred_dct_tab[i] = !!frame_pred_dct_tab[i];
275 conceal_tab[i] = !!conceal_tab[i];
276 qscale_tab[i] = !!qscale_tab[i];
277 intravlc_tab[i] = !!intravlc_tab[i];
278 altscan_tab[i] = !!altscan_tab[i];
280 repeatfirst = !!repeatfirst;
281 prog_frame = !!prog_frame;
283 /* make sure MPEG specific parameters are valid */
286 frame_rate = ratetab[frame_rate_code-1];
288 /* timecode -> frame number */
292 tc0 = (int)(frame_rate+0.5)*tc0 + f;
296 profile_and_level_checks();
303 if (horizontal_size>768
305 || ((horizontal_size+15)/16)*((vertical_size+15)/16)>396
306 || ((horizontal_size+15)/16)*((vertical_size+15)/16)*frame_rate>396*25.0
310 fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n");
319 if (motion_data[i].forw_hor_f_code>4)
322 fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n");
327 if (motion_data[i].forw_vert_f_code>4)
330 fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n");
337 if (motion_data[i].back_hor_f_code>4)
340 fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n");
345 if (motion_data[i].back_vert_f_code>4)
348 fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n");
357 /* relational checks */
364 fprintf(stderr,"Warning: setting progressive_sequence = 1\n");
368 if (chroma_format!=CHROMA420)
371 fprintf(stderr,"Warning: setting chroma_format = 1 (4:2:0)\n");
372 chroma_format = CHROMA420;
378 fprintf(stderr,"Warning: setting intra_dc_precision = 0\n");
386 fprintf(stderr,"Warning: setting qscale_tab[%d] = 0\n",i);
394 fprintf(stderr,"Warning: setting intravlc_tab[%d] = 0\n",i);
402 fprintf(stderr,"Warning: setting altscan_tab[%d] = 0\n",i);
407 if (!mpeg1 && constrparms)
410 fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n");
414 if (prog_seq && !prog_frame)
417 fprintf(stderr,"Warning: setting progressive_frame = 1\n");
421 if (prog_frame && fieldpic)
424 fprintf(stderr,"Warning: setting field_pictures = 0\n");
428 if (!prog_frame && repeatfirst)
431 fprintf(stderr,"Warning: setting repeat_first_field = 0\n");
438 if (!frame_pred_dct_tab[i])
441 fprintf(stderr,"Warning: setting frame_pred_frame_dct[%d] = 1\n",i);
442 frame_pred_dct_tab[i] = 1;
446 if (prog_seq && !repeatfirst && topfirst)
449 fprintf(stderr,"Warning: setting top_field_first = 0\n");
456 if (motion_data[i].sxf > (4<<motion_data[i].forw_hor_f_code)-1)
460 "Warning: reducing forward horizontal search width to %d\n",
461 (4<<motion_data[i].forw_hor_f_code)-1);
462 motion_data[i].sxf = (4<<motion_data[i].forw_hor_f_code)-1;
465 if (motion_data[i].syf > (4<<motion_data[i].forw_vert_f_code)-1)
469 "Warning: reducing forward vertical search width to %d\n",
470 (4<<motion_data[i].forw_vert_f_code)-1);
471 motion_data[i].syf = (4<<motion_data[i].forw_vert_f_code)-1;
476 if (motion_data[i].sxb > (4<<motion_data[i].back_hor_f_code)-1)
480 "Warning: reducing backward horizontal search width to %d\n",
481 (4<<motion_data[i].back_hor_f_code)-1);
482 motion_data[i].sxb = (4<<motion_data[i].back_hor_f_code)-1;
485 if (motion_data[i].syb > (4<<motion_data[i].back_vert_f_code)-1)
489 "Warning: reducing backward vertical search width to %d\n",
490 (4<<motion_data[i].back_vert_f_code)-1);
491 motion_data[i].syb = (4<<motion_data[i].back_vert_f_code)-1;
498 static void readquantmat()
505 /* use default intra matrix */
508 intra_q[i] = default_intra_quantizer_matrix[i];
512 /* read customized intra matrix */
514 if (!(fd = fopen(iqname,"r")))
516 sprintf(errortext,"Couldn't open quant matrix file %s",iqname);
524 error("invalid value in quant matrix");
533 /* use default non-intra matrix */
540 /* read customized non-intra matrix */
542 if (!(fd = fopen(niqname,"r")))
544 sprintf(errortext,"Couldn't open quant matrix file %s",niqname);
552 error("invalid value in quant matrix");