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