1 /* mpeg2encoptions.cc - Encoder control parameter class   */
2 
3 /* (C) 2000/2001/2003 Andrew Stevens, Rainer Johanni */
4 
5 /* This software is free software; you can redistribute it
6  *  and/or modify it under the terms of the GNU General Public License
7  *  as published by the Free Software Foundation; either version 2 of
8  *  the License, or (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18  * 02111-1307, USA.
19  *
20  */
21 
22 #include <config.h>
23 #include "format_codes.h"
24 #include "mpegconsts.h"
25 #include "mpeg2encoder.hh"
26 
MPEG2EncOptions()27 MPEG2EncOptions::MPEG2EncOptions()
28 {
29     // Parameters initialised to -1 indicate a format-dependent
30     // or stream inferred default.
31     format = MPEG_FORMAT_MPEG1;
32     level = 0;          // Use default
33     display_hsize  = 0; // Use default
34     display_vsize  = 0; // Use default
35     bitrate    = 0;
36     target_bitrate = 0;
37     nonvid_bitrate = 0;
38     stream_frames = 0;   			// none specified by default
39     stream_Xhi = 0.0;				// off by default
40     quant      = 0;
41     searchrad  = 0;     // Use default
42     mpeg       = 1;
43     aspect_ratio = 0;
44     frame_rate  = 0;
45     fieldenc   = -1; /* 0: progressive, 1 = frame pictures,
46                         interlace frames with field MC and DCT
47                         in picture 2 = field pictures
48                      */
49     norm       = 0;  /* 'n': NTSC, 'p': PAL, 's': SECAM, else unspecified */
50     rate_control = 0;
51     me44_red	= 2;
52     me22_red	= 3;
53     hf_quant = 0;
54     hf_q_boost = 0.0;
55     act_boost = 0.0;
56     boost_var_ceil = 10*10;
57     video_buffer_size = 0;
58     seq_length_limit = 0;
59     min_GOP_size = -1;
60     max_GOP_size = -1;
61     closed_GOPs = 0;
62     preserve_B = 0;
63     Bgrp_size = 1;
64 /*
65  * Set the default to 0 until this error:
66      INFO: [mpeg2enc] Signaling last frame = 499
67      mpeg2enc: seqencoder.cc:433: void SeqEncoder::EncodeStream(): Assertion `pass1coded.size() == 0' failed.
68      Abort
69  * Is fixed.
70 */
71     num_cpus = 0;
72     vid32_pulldown = 0;
73     svcd_scan_data = -1;
74     seq_hdr_every_gop = 0;
75     seq_end_every_gop = 0;
76     still_size = 0;
77     pad_stills_to_vbv_buffer_size = 0;
78     vbv_buffer_still_size = 0;
79     force_interlacing = Y4M_UNKNOWN;
80     input_interlacing = Y4M_UNKNOWN;
81     mpeg2_dc_prec = 1;
82     ignore_constraints = 0;
83     unit_coeff_elim = 0;
84     force_cbr = 0;
85     verbose = 1;
86     hack_svcd_hds_bug = 1;
87     hack_altscan_bug = 0;
88     /* dual prime Disabled by default. --dualprime-mpeg2 to enable (set to 1) */
89     hack_dualprime = 0;
90     force_cbr = 0;
91 };
92 
93 
infer_mpeg1_aspect_code(char norm,mpeg_aspect_code_t mpeg2_code)94 static int infer_mpeg1_aspect_code( char norm, mpeg_aspect_code_t mpeg2_code )
95 {
96 	switch( mpeg2_code )
97 	{
98 	case 1 :					/* 1:1 */
99 		return 1;
100 	case 2 :					/* 4:3 */
101 		if( norm == 'p' || norm == 's' )
102 			return 8;
103 	    else if( norm == 'n' )
104 			return 12;
105 		else
106 			return 0;
107 	case 3 :					/* 16:9 */
108 		if( norm == 'p' || norm == 's' )
109 			return 3;
110 	    else if( norm == 'n' )
111 			return 6;
112 		else
113 			return 0;
114 	default :
115 		return 0;				/* Unknown */
116 	}
117 }
118 
119 
InferStreamDataParams(const MPEG2EncInVidParams & strm)120 int MPEG2EncOptions::InferStreamDataParams( const MPEG2EncInVidParams &strm)
121 {
122 	int nerr = 0;
123 
124 
125 	/* Infer norm, aspect ratios and frame_rate if not specified */
126 	if( frame_rate == 0 )
127 	{
128 		if(strm.frame_rate_code<1 || strm.frame_rate_code>8)
129 		{
130 			mjpeg_error("Input stream with unknown frame-rate and no frame-rate specified with -a!");
131 			++nerr;
132 		}
133 		else
134 			frame_rate = strm.frame_rate_code;
135 	}
136 
137 	if( norm == 0 && (strm.frame_rate_code==3 || strm.frame_rate_code == 2) )
138 	{
139 		mjpeg_info("Assuming norm PAL");
140 		norm = 'p';
141 	}
142 	if( norm == 0 && (strm.frame_rate_code==4 || strm.frame_rate_code == 1) )
143 	{
144 		mjpeg_info("Assuming norm NTSC");
145 		norm = 'n';
146 	}
147 
148 
149 
150 
151 
152 	if( frame_rate != 0 )
153 	{
154 		if( strm.frame_rate_code != frame_rate &&
155             mpeg_valid_framerate_code(strm.frame_rate_code) )
156 		{
157 			mjpeg_warn( "Specified display frame-rate %3.2f will over-ride",
158 						Y4M_RATIO_DBL(mpeg_framerate(frame_rate)));
159 			mjpeg_warn( "(different!) frame-rate %3.2f of the input stream",
160 						Y4M_RATIO_DBL(mpeg_framerate(strm.frame_rate_code)));
161 		}
162 	}
163 
164 	if( aspect_ratio == 0 )
165 	{
166 		aspect_ratio = strm.aspect_ratio_code;
167 	}
168 
169 	if( aspect_ratio == 0 )
170 	{
171 		mjpeg_warn( "No aspect ratio specifed and no guess possible: assuming 4:3 display aspect!");
172 		aspect_ratio = 2;
173 	}
174 
175 	/* Convert to MPEG1 coding if we're generating MPEG1 */
176 	if( mpeg == 1 )
177 	{
178 		aspect_ratio = infer_mpeg1_aspect_code( norm, aspect_ratio );
179 	}
180 
181     input_interlacing = strm.interlacing_code;
182     if (input_interlacing == Y4M_UNKNOWN) {
183         mjpeg_warn("Unknown input interlacing; assuming progressive.");
184         input_interlacing = Y4M_ILACE_NONE;
185     }
186 
187     /* 'fieldenc' is dependent on input stream interlacing:
188          a) Interlaced streams are subsampled _per_field_;
189              progressive streams are subsampled over whole frame.
190          b) 'fieldenc' sets/clears the MPEG2 'progressive-frame' flag,
191             which tells decoder how subsampling was performed.
192     */
193     if (fieldenc == -1) {
194         /* not set yet... so set fieldenc from input interlacing */
195         switch (input_interlacing) {
196         case Y4M_ILACE_TOP_FIRST:
197         case Y4M_ILACE_BOTTOM_FIRST:
198             fieldenc = 1; /* interlaced frames */
199             mjpeg_info("Interlaced input - selecting interlaced encoding.");
200             break;
201         case Y4M_ILACE_NONE:
202             fieldenc = 0; /* progressive frames */
203             mjpeg_info("Progressive input - selecting progressive encoding.");
204             break;
205         default:
206             mjpeg_warn("Unknown input interlacing; assuming progressive.");
207             fieldenc = 0;
208             break;
209         }
210     } else {
211         /* fieldenc has been set already... so double-check for user */
212         switch (input_interlacing) {
213         case Y4M_ILACE_TOP_FIRST:
214         case Y4M_ILACE_BOTTOM_FIRST:
215             if (fieldenc == 0) {
216                 mjpeg_warn("Progressive encoding selected with interlaced input!");
217                 mjpeg_warn("  (This will damage the chroma channels.)");
218             }
219             break;
220         case Y4M_ILACE_NONE:
221             if (fieldenc != 0) {
222                 mjpeg_warn("Interlaced encoding selected with progressive input!");
223                 mjpeg_warn("  (This will damage the chroma channels.)");
224             }
225             break;
226         }
227     }
228 
229 	return nerr;
230 }
231 
CheckBasicConstraints()232 int MPEG2EncOptions::CheckBasicConstraints()
233 {
234 	int nerr = 0;
235 	if( vid32_pulldown )
236 	{
237 		if( mpeg == 1 )
238 			mjpeg_error_exit1( "MPEG-1 cannot encode 3:2 pulldown (for transcoding to VCD set 24fps)!" );
239 
240 		if( frame_rate != 4 && frame_rate != 5  )
241 		{
242 			if( frame_rate == 1 || frame_rate == 2 )
243 			{
244 				frame_rate += 3;
245 				mjpeg_warn("3:2 movie pulldown with frame rate set to decode rate not display rate");
246 				mjpeg_warn("3:2 Setting frame rate code to display rate = %d (%2.3f fps)",
247 						   frame_rate,
248 						   Y4M_RATIO_DBL(mpeg_framerate(frame_rate)));
249 
250 			}
251 			else
252 			{
253 				mjpeg_error( "3:2 movie pulldown not sensible for %2.3f fps dispay rate",
254 							Y4M_RATIO_DBL(mpeg_framerate(frame_rate)));
255 				++nerr;
256 			}
257 		}
258 		if( fieldenc == 2 )
259 		{
260 			mjpeg_error( "3:2 pulldown only possible for frame pictures (-I 1 or -I 0)");
261 			++nerr;
262 		}
263 	}
264 
265     if ((mpeg == 1) && (fieldenc != 0)) {
266         mjpeg_error("Interlaced encoding (-I != 0) is not supported by MPEG-1.");
267         ++nerr;
268     }
269 
270 
271 	if(  !mpeg_valid_aspect_code(mpeg, aspect_ratio) )
272 	{
273 		mjpeg_error("For MPEG-%d, aspect ratio code  %d is illegal",
274 					mpeg, aspect_ratio);
275 		++nerr;
276 	}
277 
278 
279 
280 	if( min_GOP_size > max_GOP_size )
281 	{
282 		mjpeg_error( "Min GOP size must be <= Max GOP size" );
283 		++nerr;
284 	}
285 
286 	if( stream_frames > 0 && stream_frames < 4*max_GOP_size )
287 	{
288 		mjpeg_error( "-L must be at at least 4 GOP lengths (4 * -G)" );
289 		++nerr;
290 	}
291     if( preserve_B && Bgrp_size == 0 )
292     {
293 		mjpeg_error_exit1("Preserving I/P frame spacing is impossible for still encoding" );
294     }
295 
296 	if( preserve_B &&
297 		( min_GOP_size % Bgrp_size != 0 ||
298 		  max_GOP_size % Bgrp_size != 0 )
299 		)
300 	{
301 		mjpeg_error("Preserving I/P frame spacing is impossible if min and max GOP sizes are" );
302 		mjpeg_error_exit1("Not both divisible by %d", Bgrp_size );
303 	}
304 
305 	switch( format )
306 	{
307 	case MPEG_FORMAT_SVCD_STILL :
308 	case MPEG_FORMAT_SVCD_NSR :
309 	case MPEG_FORMAT_SVCD :
310 		if( aspect_ratio != 2 && aspect_ratio != 3 )
311 			mjpeg_error_exit1("SVCD only supports 4:3 and 16:9 aspect ratios");
312 		if( svcd_scan_data )
313 		{
314 			mjpeg_warn( "Generating dummy SVCD scan-data offsets to be filled in by \"vcdimager\"");
315 			mjpeg_warn( "If you're not using vcdimager you may wish to turn this off using -d");
316 		}
317 		break;
318      case MPEG_FORMAT_ATSC480i :
319          if( frame_rate != 4 && frame_rate != 5 )
320          {
321              mjpeg_warn( "ATSC 480p only supports 29.97 and 30 frames/sec" );
322          }
323      case MPEG_FORMAT_ATSC480p :
324          if(    (in_img_width != 704 && in_img_width != 640)
325              || in_img_height != 480 )
326          {
327              mjpeg_warn( "ATSC 480i/480p requires 640x480 or 704x480 input images!" );
328          }
329          if( in_img_width == 704 && aspect_ratio != 2 && aspect_ratio != 3 )
330          {
331              mjpeg_warn( "ATSC 480i/480p 704x480 only supports aspect ratio codes 2 and 3 (4:3 and 16:9)" );
332          }
333          if( in_img_width == 640 && aspect_ratio != 1 && aspect_ratio != 2 )
334          {
335              mjpeg_warn( "ATSC 480i/480p 704x480 only supports aspect ratio codes 1 and 2 (square pixel and 4:3)" );
336          }
337          break;
338      case MPEG_FORMAT_ATSC720p :
339          if(  in_img_width != 1280 || in_img_height != 720 )
340          {
341              mjpeg_warn( "ATSC 720p requires 1280x720 input images!" );
342          }
343          if( aspect_ratio != 1 && aspect_ratio != 3 )
344          {
345              mjpeg_warn( "ATSC 720p only supports aspect ratio codes 1 and 3 (square pixel and 16:9)" );
346          }
347          break;
348      case MPEG_FORMAT_ATSC1080i :
349          if(  in_img_width != 1920 || in_img_height != 1088 )
350          {
351              mjpeg_warn( "ATSC 1080i requires  1920x1088 input images!" );
352          }
353          if( aspect_ratio != 1 && aspect_ratio != 3 )
354          {
355              mjpeg_warn( "ATSC 1080i only supports aspect ratio codes 1 and 3 (square pixel and 16:9)" );
356          }
357          if( frame_rate > 7 )
358          {
359              mjpeg_warn( "ATSC 1080i only supports frame rates up to 30 frame/sec/" );
360          }
361          break;
362 	}
363 
364 
365  if( MPEG_ATSC_FORMAT(format) )
366     {
367          if( bitrate > 38800000 )
368         {
369             mjpeg_warn( "ATSC specifies a maximum high data rate mode bitrate of 38.8Mbps" );
370         }
371 
372         if( frame_rate == 3 || frame_rate == 6 )
373         {
374             mjpeg_warn( "ATSC does not support 25 or 50 frame/sec video" );
375         }
376     }
377 
378 	return nerr;
379 }
380 
381 
382 
SetFormatPresets(const MPEG2EncInVidParams & strm)383 bool MPEG2EncOptions::SetFormatPresets( const MPEG2EncInVidParams &strm )
384 {
385     int nerr = 0;
386     in_img_width = strm.horizontal_size;
387     in_img_height = strm.vertical_size;
388     mjpeg_info( "Selecting %s output profile",
389                 mpeg_format_code_defintion(format));
390 	switch( format  )
391 	{
392 	case MPEG_FORMAT_MPEG1 :  /* Generic MPEG1 */
393 		if( video_buffer_size == 0 )
394 			video_buffer_size = 46;
395 		if (bitrate == 0)
396 			bitrate = 1151929;
397         if (searchrad == 0)
398             searchrad = 16;
399 		break;
400 
401 	case MPEG_FORMAT_VCD :
402 		mpeg = 1;
403 		bitrate = 1151929;
404 		video_buffer_size = 46;
405         	preserve_B = true;
406         	Bgrp_size = 3;
407         	min_GOP_size = 9;
408 		max_GOP_size = norm == 'n' ? 18 : 15;
409 
410 	case MPEG_FORMAT_VCD_NSR : /* VCD format, non-standard rate */
411 		mpeg = 1;
412 		svcd_scan_data = 0;
413 		seq_hdr_every_gop = 1;
414 		if (bitrate == 0)
415 			bitrate = 1151929;
416 		if (video_buffer_size == 0)
417 			video_buffer_size = 46 * bitrate / 1151929;
418         	if (seq_length_limit == 0 )
419             		seq_length_limit = 700;
420         	if (nonvid_bitrate == 0)
421             		nonvid_bitrate = 230;
422 		break;
423 
424 	case  MPEG_FORMAT_MPEG2 :
425 		mpeg = 2;
426 		if (!force_cbr && quant == 0)
427 			quant = 8;
428 		if (video_buffer_size == 0)
429 			video_buffer_size = 230;
430 		break;
431 
432 	case MPEG_FORMAT_SVCD :
433 		if (nonvid_bitrate == 0)
434 		   /* 224 kbps for audio + around 2% of 2788800 bits */
435 		   nonvid_bitrate = 288;
436 		if (bitrate == 0 || bitrate > 2788800 - nonvid_bitrate * 1000)
437 		   bitrate = 2788800 - nonvid_bitrate * 1000;
438 		max_GOP_size = norm == 'n' ? 18 : 15;
439 		video_buffer_size = 230;
440 
441 	case  MPEG_FORMAT_SVCD_NSR :		/* Non-standard data-rate */
442 		mpeg = 2;
443 		if (!force_cbr && quant == 0)
444 			quant = 8;
445 		if( svcd_scan_data == -1 )
446 			svcd_scan_data = 1;
447 		if (video_buffer_size == 0)
448 			video_buffer_size = 230;
449 		if( min_GOP_size == -1 )
450             		min_GOP_size = 9;
451         	seq_hdr_every_gop = 1;
452         	if (seq_length_limit == 0)
453             		seq_length_limit = 700;
454         	if (nonvid_bitrate == 0)
455             		nonvid_bitrate = 230;
456         	break;
457 
458 	case MPEG_FORMAT_VCD_STILL :
459 		mpeg = 1;
460 		quant = 0;	/* We want to try and hit our size target */
461 
462 		/* We choose a generous nominal bit-rate as there's only
463 		   one frame per sequence ;-).  It *is* too small to fill
464 		   the frame-buffer in less than one PAL/NTSC frame
465 		   period though...*/
466 		bitrate = 8000000;
467 
468 		/* Now we select normal/hi-resolution based on the input stream
469 		   resolution.
470 		*/
471 
472 		if( in_img_width == 352 &&
473 			(in_img_height == 240 || in_img_height == 288 ) )
474 		{
475 			/* VCD normal resolution still */
476 			if( still_size == 0 )
477 				still_size = 30*1024;
478 			if( still_size < 20*1024 || still_size > 42*1024 )
479 			{
480 				mjpeg_error_exit1( "VCD normal-resolution stills must be >= 20KB and <= 42KB each");
481 			}
482 			/* VBV delay encoded normally */
483 			vbv_buffer_still_size = 46*1024;
484 			video_buffer_size = 46;
485 			pad_stills_to_vbv_buffer_size = 0;
486 		}
487 		else if( in_img_width == 704 &&
488 				 (in_img_height == 480 || in_img_height == 576) )
489 		{
490 			/* VCD high-resolution stills: only these use vbv_delay
491 			 to encode picture size...
492 			*/
493 			if( still_size == 0 )
494 				still_size = 125*1024;
495 			if( still_size < 46*1024 || still_size > 220*1024 )
496 			{
497 				mjpeg_error_exit1( "VCD normal-resolution stills should be >= 46KB and <= 220KB each");
498 			}
499 			vbv_buffer_still_size = still_size;
500 			video_buffer_size = 224;
501 			pad_stills_to_vbv_buffer_size = 1;
502 		}
503 		else
504 		{
505 			mjpeg_error("VCD normal resolution stills must be 352x288 (PAL) or 352x240 (NTSC)");
506 			mjpeg_error_exit1( "VCD high resolution stills must be 704x576 (PAL) or 704x480 (NTSC)");
507 		}
508 		seq_hdr_every_gop = 1;
509 		seq_end_every_gop = 1;
510 		min_GOP_size = 1;
511 		max_GOP_size = 1;
512 		break;
513 
514 	case MPEG_FORMAT_SVCD_STILL :
515 		mpeg = 2;
516 		quant = 0;	/* We want to try and hit our size target */
517 
518 		/* We choose a generous nominal bitrate as there's only one
519 		   frame per sequence ;-). It *is* too small to fill the
520 		   frame-buffer in less than one PAL/NTSC frame
521 		   period though...
522 		*/
523 		bitrate = 2500000;
524 		video_buffer_size = 230;
525 		vbv_buffer_still_size = 220*1024;
526 		pad_stills_to_vbv_buffer_size = 0;
527 
528 		/* Now we select normal/hi-resolution based on the input stream
529 		   resolution.
530 		*/
531 
532 		if( in_img_width == 480 &&
533 			(in_img_height == 480 || in_img_height == 576 ) )
534 		{
535 			mjpeg_info( "SVCD normal-resolution stills selected." );
536 			if( still_size == 0 )
537 				still_size = 90*1024;
538 		}
539 		else if( in_img_width == 704 &&
540 				 (in_img_height == 480 || in_img_height == 576) )
541 		{
542 			mjpeg_info( "SVCD high-resolution stills selected." );
543 			if( still_size == 0 )
544 				still_size = 125*1024;
545 		}
546 		else
547 		{
548 			mjpeg_error("SVCD normal resolution stills must be 480x576 (PAL) or 480x480 (NTSC)");
549 			mjpeg_error_exit1( "SVCD high resolution stills must be 704x576 (PAL) or 704x480 (NTSC)");
550 		}
551 
552 		if( still_size < 30*1024 || still_size > 200*1024 )
553 		{
554 			mjpeg_error_exit1( "SVCD resolution stills must be >= 30KB and <= 200KB each");
555 		}
556 
557 
558 		seq_hdr_every_gop = 1;
559 		seq_end_every_gop = 1;
560 		min_GOP_size = 1;
561 		max_GOP_size = 1;
562 		break;
563 
564 	case MPEG_FORMAT_DVD :
565 	case MPEG_FORMAT_DVD_NAV :
566 		mpeg = 2;
567 		if (bitrate == 0)
568 			bitrate = 7500000;
569     	if (video_buffer_size == 0)
570     		video_buffer_size = 230;
571 		if (!force_cbr && quant == 0)
572 			quant = 8;
573 		seq_hdr_every_gop = 1;
574 		break;
575 
576      case MPEG_FORMAT_ATSC720p :
577      case MPEG_FORMAT_ATSC1080i :
578          // Need a bigger pixel search radius for HD
579          // images :-(
580          if (searchrad == 0)
581              searchrad = 32;
582      case MPEG_FORMAT_ATSC480i :
583      case MPEG_FORMAT_ATSC480p :
584          mpeg = 2;
585          video_buffer_size = 488;
586          if (bitrate == 0)
587              bitrate = 19400000;
588  		if (!force_cbr && quant == 0)
589  			quant = 8;
590 
591 	}
592 
593     /*
594      * At this point the command line arguments have been processed, the format (-f)
595      * selection has had a chance to set the bitrate.  IF --cbr was used and we
596      * STILL do not have a bitrate set then declare an error because a Constant
597      * Bit Rate of 0 makes no sense (most of the time CBR doesn't either ... ;))
598      */
599      if (force_cbr && bitrate == 0)
600         {
601         nerr++;
602         mjpeg_error("--cbr used but no bitrate set with -b or -f!");
603         }
604 
605 
606     switch( mpeg )
607     {
608     case 1 :
609         if( min_GOP_size == -1 )
610             min_GOP_size = 12;
611         if( max_GOP_size == -1 )
612             max_GOP_size = 12;
613         break;
614     case 2:
615         if( max_GOP_size == -1 )
616             max_GOP_size = (norm == 'n' ? 18 : 15);
617         if( min_GOP_size == -1 )
618             min_GOP_size = max_GOP_size/2;
619         break;
620     }
621 	if( svcd_scan_data == -1 )
622 		svcd_scan_data = 0;
623     if (searchrad == 0)
624         searchrad = 16;
625 	nerr += InferStreamDataParams(strm);
626 	nerr += CheckBasicConstraints();
627 
628 	return nerr != 0;
629 }
630 
631 
632 
633 /*
634  * Local variables:
635  *  c-file-style: "stroustrup"
636  *  tab-width: 4
637  *  indent-tabs-mode: nil
638  * End:
639  */
640