1 /* encoderparams - class holding all the various control parameters for
2    and individual encoder instance.  For speed a lot of address offsets/sizes
3    are computed once-and-for-all and held in this object.
4 */
5 
6 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
7 
8 /*
9  * Disclaimer of Warranty
10  *
11  * These software programs are available to the user without any license fee or
12  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
13  * any and all warranties, whether express, implied, or statuary, including any
14  * implied warranties or merchantability or of fitness for a particular
15  * purpose.  In no event shall the copyright-holder be liable for any
16  * incidental, punitive, or consequential damages of any kind whatsoever
17  * arising from the use of these programs.
18  *
19  * This disclaimer of warranty extends to the user of these programs and user's
20  * customers, employees, agents, transferees, successors, and assigns.
21  *
22  * The MPEG Software Simulation Group does not represent or warrant that the
23  * programs furnished hereunder are free of infringement of any third-party
24  * patents.
25  *
26  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
27  * are subject to royalty fees to patent holders.  Many of these patents are
28  * general enough such that they are unavoidable regardless of implementation
29  * design.
30  *
31  */
32 
33 /* Modifications and enhancements (C) 2000,2001,2002,2003 Andrew Stevens */
34 
35 /* These modifications are free software; you can redistribute it
36  *  and/or modify it under the terms of the GNU General Public License
37  *  as published by the Free Software Foundation; either version 2 of
38  *  the License, or (at your option) any later version.
39  *
40  *  This program is distributed in the hope that it will be useful,
41  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
42  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
43  *  General Public License for more details.
44  *
45  * You should have received a copy of the GNU General Public License
46  * along with this program; if not, write to the Free Software
47  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
48  * 02111-1307, USA.
49  *
50  */
51 
52 #include <config.h>
53 #include "encoderparams.hh"
54 #include "format_codes.h"
55 #include "mpegconsts.h"
56 #include "mpeg2encoptions.hh"
57 //#include "mpeg2syntaxcodes.h"
58 #include "tables.h"
59 #include "ratectl.hh"
60 #include "cpu_accel.h"
61 #include "motionsearch.h"
62 #include <string.h> // REMOVE
63 
64 #define MAX(a,b) ( (a)>(b) ? (a) : (b) )
65 #define MIN(a,b) ( (a)<(b) ? (a) : (b) )
66 
EncoderParams(const MPEG2EncOptions & encoptions)67 EncoderParams::EncoderParams( const MPEG2EncOptions &encoptions)
68 {
69 }
70 
InitEncodingControls(const MPEG2EncOptions & options)71 void EncoderParams::InitEncodingControls( const MPEG2EncOptions &options)
72 {
73 
74     coding_tolerance = 0.1;
75 	/* Tune threading and motion compensation for specified number of CPU's
76 	   and specified speed parameters.
77 	 */
78 
79 	act_boost =  1.0+options.act_boost;
80     boost_var_ceil = options.boost_var_ceil;
81 	switch( options.num_cpus )
82 	{
83 
84 	case 0 : /* Special case for debugging... turns of all multi-threading */
85 		encoding_parallelism = 0;
86 		break;
87   case 1 : /* Currently this is the default option */
88 		encoding_parallelism = 1;
89 		break;
90 	case 2:
91 		encoding_parallelism = 2;
92 		break;
93 	default :
94 		encoding_parallelism = options.num_cpus > MAX_WORKER_THREADS-1 ?
95 			                  MAX_WORKER_THREADS-1 :
96 			                  options.num_cpus;
97 		break;
98 	}
99 
100 	me44_red		= options.me44_red;
101 	me22_red		= options.me22_red;
102 
103     unit_coeff_elim	= options.unit_coeff_elim;
104 
105 	/* round picture dimensions to nearest multiple of 16 or 32 */
106 	mb_width = (horizontal_size+15)/16;
107 	mb_height = prog_seq ? (vertical_size+15)/16 : 2*((vertical_size+31)/32);
108 	mb_height2 = fieldpic ? mb_height>>1 : mb_height; /* for field pictures */
109 	enc_width = 16*mb_width;
110 	enc_height = 16*mb_height;
111 
112 #ifdef DEBUG_MOTION_EST
113     static const int MARGIN = 64;
114 #else
115     static const int MARGIN = 8;
116 #endif
117 
118 #ifdef HAVE_ALTIVEC
119 	/* Pad phy_width to 64 so that the rowstride of 4*4
120 	 * sub-sampled data will be a multiple of 16 (ideal for AltiVec)
121 	 * and the rowstride of 2*2 sub-sampled data will be a multiple
122 	 * of 32. Height does not affect rowstride, no padding needed.
123 	 */
124 	phy_width = (enc_width + 63) & (~63);
125 #else
126 	phy_width = enc_width+MARGIN;
127 #endif
128 	phy_height = enc_height+MARGIN;
129 
130 	/* Calculate the sizes and offsets in to luminance and chrominance
131 	   buffers.  A.Stevens 2000 for luminance data we allow space for
132 	   fast motion estimation data.  This is actually 2*2 pixel
133 	   sub-sampled uint8_t followed by 4*4 sub-sampled.  We add an
134 	   extra row to act as a margin to allow us to neglect / postpone
135 	   edge condition checking in time-critical loops...  */
136 
137 	phy_chrom_width = phy_width>>1;
138 	phy_chrom_height = phy_height>>1;
139 	enc_chrom_width = enc_width>>1;
140 	enc_chrom_height = enc_height>>1;
141 
142 	phy_height2 = fieldpic ? phy_height>>1 : phy_height;
143 	enc_height2 = fieldpic ? enc_height>>1 : enc_height;
144 	phy_width2 = fieldpic ? phy_width<<1 : phy_width;
145 	phy_chrom_width2 = fieldpic
146         ? phy_chrom_width<<1
147         : phy_chrom_width;
148 
149 	lum_buffer_size = (phy_width*phy_height) +
150 					 sizeof(uint8_t) *(phy_width/2)*(phy_height/2) +
151 					 sizeof(uint8_t) *(phy_width/4)*(phy_height/4);
152 	chrom_buffer_size = phy_chrom_width*phy_chrom_height;
153 
154 
155 	fsubsample_offset = (phy_width)*(phy_height) * sizeof(uint8_t);
156 	qsubsample_offset =  fsubsample_offset
157         + (phy_width/2)*(phy_height/2)*sizeof(uint8_t);
158 
159 	mb_per_pict = mb_width*mb_height2;
160 
161 
162 #ifdef OUTPUT_STAT
163 	/* open statistics output file */
164 	if (!(statfile = fopen(statname,"w")))
165 	{
166 		mjpeg_error_exit1( "Couldn't create statistics output file %s",
167 						   statname);
168 	}
169 #endif
170 }
171 
172 
f_code(int max_radius)173 static int f_code( int max_radius )
174 {
175 	int c=5;
176 	if( max_radius < 64) c = 4;
177 	if( max_radius < 32) c = 3;
178 	if( max_radius < 16) c = 2;
179 	if( max_radius < 8) c = 1;
180 	return c;
181 }
182 
Init(const MPEG2EncOptions & options)183 void EncoderParams::Init( const MPEG2EncOptions &options )
184 {
185 	int i;
186     const char *msg = 0;
187 
188 	//istrm_nframes = 999999999; /* determined by EOF of stdin */
189 
190 	N_min = options.min_GOP_size;      /* I frame distance */
191 	N_max = options.max_GOP_size;
192     closed_GOPs = options.closed_GOPs;
193 	mjpeg_info( "GOP SIZE RANGE %d TO %d %s",
194                 N_min, N_max,
195                 closed_GOPs ? "(all GOPs closed)" : ""
196                 );
197 	M = options.Bgrp_size;             /* I or P frame distance */
198 	M_min = options.preserve_B ? M : 1;
199 	if( M > N_max )
200 		M = N_max;
201 	mpeg1       = (options.mpeg == 1);
202 	fieldpic        = (options.fieldenc == 2);
203     dualprime   = options.hack_dualprime == 1 && M == 1;
204 
205     pulldown_32     = options.vid32_pulldown;
206 
207     aspectratio     = options.aspect_ratio;
208     frame_rate_code = options.frame_rate;
209     // SVCD and probably DVD? mandate progressive_sequence = 0
210     switch( options.format )
211     {
212     case MPEG_FORMAT_SVCD :
213     case MPEG_FORMAT_SVCD_NSR :
214     case MPEG_FORMAT_SVCD_STILL :
215     case MPEG_FORMAT_DVD :
216     case MPEG_FORMAT_DVD_NAV :
217         prog_seq = 0;
218         break;
219     case MPEG_FORMAT_ATSC1080i :
220     case MPEG_FORMAT_ATSC480i :
221         prog_seq = frame_rate_code == 1 || frame_rate_code == 2 ? 0 : 1;
222         break;
223     case MPEG_FORMAT_ATSC720p :
224     case MPEG_FORMAT_ATSC480p :
225         prog_seq = 1;
226         break;
227     default :
228         // If we want 3:2 pulldown must code prog_seq as otherwise
229         // repeat_first_field and topfirst encode frame repetitions!!!
230         prog_seq        = (options.mpeg == 1 || (options.fieldenc == 0 && !options.vid32_pulldown));
231         break;
232     }
233 
234 	dctsatlim		= mpeg1 ? 255 : 2047;
235 
236 	/* If we're using a non standard (VCD?) profile bit-rate adjust	the vbv
237 		buffer accordingly... */
238 
239 	if(options.bitrate == 0 )
240 	{
241 		mjpeg_error_exit1( "Generic format - must specify bit-rate!" );
242 	}
243 
244 	still_size = 0;
245 	if( MPEG_STILLS_FORMAT(options.format) )
246 	{
247 		vbv_buffer_code = options.vbv_buffer_still_size / 2048;
248 		vbv_buffer_still_size = options.pad_stills_to_vbv_buffer_size;
249 		bit_rate = options.bitrate;
250 		still_size = options.still_size;
251 	}
252 	else if( options.mpeg == 1 )
253 	{
254 		/* Scale VBV relative to VCD  */
255 		bit_rate = MAX(10000, options.bitrate);
256 		vbv_buffer_code = (20 * options.bitrate  / 1151929);
257 	}
258 	else
259 	{
260 		bit_rate = MAX(10000, options.bitrate);
261 		vbv_buffer_code = MIN(112,options.video_buffer_size / 2);
262 	}
263 
264 	target_bitrate = options.target_bitrate;
265 	if( target_bitrate > bit_rate )
266 	{
267 		target_bitrate = bit_rate;
268 		mjpeg_warn( "Target bit rate may not exceed specified (max) bit-rate: reducing to %.0fKbps",
269 					target_bitrate	);
270 	}
271 
272 	stream_Xhi = options.stream_Xhi;
273 	stream_frames = options.stream_frames;
274 	vbv_buffer_size = vbv_buffer_code*16384;
275 
276 	if( options.quant )
277 	{
278 
279 		quant_floor = RateCtl::InvScaleQuant( options.mpeg == 1 ? 0 : 1,
280                                               options.quant );
281 		mjpeg_info( "Quant  code = %.0f quantizer-scale = %d", quant_floor, options.quant );
282 	}
283 	else
284 	{
285 		quant_floor = 0.0;		/* Larger than max quantisation */
286 	}
287 
288 	video_buffer_size = options.video_buffer_size * 1024 * 8;
289 
290 	seq_hdr_every_gop = options.seq_hdr_every_gop;
291 	seq_end_every_gop = options.seq_end_every_gop;
292 	svcd_scan_data = options.svcd_scan_data;
293 	ignore_constraints = options.ignore_constraints;
294 	seq_length_limit = options.seq_length_limit;
295 	nonvid_bit_rate = options.nonvid_bitrate * 1000;
296 	low_delay       = 0;
297 	constrparms     = (options.mpeg == 1 &&
298 						   !MPEG_STILLS_FORMAT(options.format));
299 	profile         = MAIN_PROFILE;
300 
301     level = options.level;
302     // Force appropriate level for standards-compliant preset-formats
303     switch(options.format)
304     {
305         case MPEG_FORMAT_ATSC720p :
306         case MPEG_FORMAT_ATSC1080i :
307             level = HIGH_LEVEL;
308             break;
309         case MPEG_FORMAT_SVCD_STILL :
310         case MPEG_FORMAT_SVCD :
311         case MPEG_FORMAT_DVD :
312         case MPEG_FORMAT_DVD_NAV :
313         case MPEG_FORMAT_VCD :
314         default :
315             level = MAIN_LEVEL;
316             break;
317     };
318     if( level == 0 )
319         level = MAIN_LEVEL;
320 
321     if( MPEG_SDTV_FORMAT(options.format) )
322     {
323         switch(options.norm)
324         {
325         case 'p': video_format = 1; break;
326         case 'n': video_format = 2; break;
327         case 's': video_format = 3; break;
328         default:  video_format = 5; break; /* unspec. */
329         }
330 
331         switch(options.norm)
332         {
333         case 's':
334         case 'p':  /* ITU BT.470  B,G */
335             color_primaries = 5;
336             transfer_characteristics = 5; /* Gamma = 2.8 (!!) */
337             matrix_coefficients = 5;
338             msg = "PAL B/G";
339             break;
340         case 'n': /* SMPTPE 170M "modern NTSC" */
341             color_primaries = 6;
342             matrix_coefficients = 6;
343             transfer_characteristics = 6;
344             msg = "NTSC";
345             break;
346         default:   /* unspec. */
347             color_primaries = 2;
348             matrix_coefficients = 2;
349             transfer_characteristics = 2;
350             msg = "unspecified";
351             break;
352         }
353     }
354     else
355     {
356         video_format = 0; // 'Component'
357         switch( options.format )
358         {
359             case MPEG_FORMAT_ATSC480i : /* SMPTPE 170M "modern NTSC" */
360             case MPEG_FORMAT_ATSC480p :
361                 color_primaries = 6;
362                 matrix_coefficients = 6;
363                 transfer_characteristics = 6;
364                 break;
365             case MPEG_FORMAT_ATSC720p :/* ITU.R BT.709 HDTV */
366             case MPEG_FORMAT_ATSC1080i :
367                 color_primaries = 1;
368                 matrix_coefficients = 1;
369                 transfer_characteristics = 1;
370                 break;
371             default :
372                 abort();
373 
374         };
375     };
376     mjpeg_info( "Setting colour/gamma parameters to \"%s\"", msg);
377 
378     horizontal_size = options.in_img_width;
379     vertical_size = options.in_img_height;
380 	switch( options.format )
381 	{
382 	case MPEG_FORMAT_SVCD_STILL :
383 	case MPEG_FORMAT_SVCD_NSR :
384 	case MPEG_FORMAT_SVCD :
385     case MPEG_FORMAT_DVD :
386     case MPEG_FORMAT_DVD_NAV :
387         /* It would seem DVD and perhaps SVCD demand a 540 pixel display size
388            for 4:3 aspect video. However, many players expect 480 and go weird
389            if this isn't set...
390         */
391         if( options.hack_svcd_hds_bug )
392         {
393             display_horizontal_size  = options.in_img_width;
394             display_vertical_size    = options.in_img_height;
395         }
396         else
397         {
398             display_horizontal_size  = aspectratio == 2 ? 540 : 720;
399             display_vertical_size    = options.in_img_height;
400         }
401 		break;
402 
403       // ATSC 1080i is unusual in that it *requires* display of 1080 lines
404       // when 1088 are coded
405      case MPEG_FORMAT_ATSC1080i :
406          display_vertical_size = 1080;
407          break;
408 
409      default:
410         if( options.display_hsize <= 0 )
411             display_horizontal_size  = options.in_img_width;
412         else
413             display_horizontal_size = options.display_hsize;
414         if( options.display_vsize <= 0 )
415 		  display_vertical_size = options.in_img_height;
416         else
417             display_vertical_size = options.display_vsize;
418 		break;
419 	}
420 
421 	dc_prec         = options.mpeg2_dc_prec;  /* 9 bits */
422     topfirst = 0;
423 	if( ! prog_seq )
424 	{
425 		int fieldorder;
426 		if( options.force_interlacing != Y4M_UNKNOWN )
427 		{
428 			mjpeg_info( "Forcing playback video to be: %s",
429 						mpeg_interlace_code_definition(	options.force_interlacing ) );
430 			fieldorder = options.force_interlacing;
431 		}
432 		else
433 			fieldorder = options.input_interlacing;
434 
435 		topfirst =
436             (fieldorder == Y4M_ILACE_TOP_FIRST || fieldorder ==Y4M_ILACE_NONE );
437 	}
438 	else
439 		topfirst = 0;
440 
441     // Restrict to frame motion estimation and DCT modes only when MPEG1
442     // or when progressive content is specified for MPEG2.
443     // Note that for some profiles although we have progressive sequence
444     // header bit = 0 we still only encode with frame modes (for speed).
445 	frame_pred_dct_tab[0]
446 		= frame_pred_dct_tab[1]
447 		= frame_pred_dct_tab[2]
448         = (options.mpeg == 1 || options.fieldenc == 0) ? 1 : 0;
449 
450     mjpeg_info( "Progressive format frames = %d", 	frame_pred_dct_tab[0] );
451 	qscale_tab[0]
452 		= qscale_tab[1]
453 		= qscale_tab[2]
454 		= options.mpeg == 1 ? 0 : 1;
455     mjpeg_info( "q_scale_type  = %d",	qscale_tab[0] );
456 	intravlc_tab[0]
457 		= intravlc_tab[1]
458 		= intravlc_tab[2]
459 		= options.mpeg == 1 ? 0 : 1;
460 
461 	altscan_tab[2]
462 		= altscan_tab[1]
463 		= altscan_tab[0]
464 		= (options.mpeg == 1 || options.hack_altscan_bug) ? 0 : 1;
465 
466 
467 	/*  A.Stevens 2000: The search radius *has* to be a multiple of 8
468 		for the new fast motion compensation search to work correctly.
469 		We simply round it up if needs be.  */
470 
471     int searchrad = options.searchrad;
472 	if(searchrad*M>127)
473 	{
474 		searchrad = 127/M;
475 		mjpeg_warn("Search radius reduced to %d",searchrad);
476 	}
477 
478 	{
479 		int radius_x = searchrad;
480 		int radius_y = searchrad*vertical_size/horizontal_size;
481 
482 		/* TODO: These f-codes should really be adjusted for each
483 		   picture type... */
484 
485 		motion_data = (struct motion_data *)malloc(M*sizeof(struct motion_data));
486 		if (!motion_data)
487 			mjpeg_error_exit1("malloc failed");
488 
489 		for (i=0; i<M; i++)
490 		{
491 			if(i==0)
492 			{
493 				motion_data[i].sxf = round_search_radius(radius_x*M);
494 				motion_data[i].forw_hor_f_code  = f_code(motion_data[i].sxf);
495 				motion_data[i].syf = round_search_radius(radius_y*M);
496 				motion_data[i].forw_vert_f_code  = f_code(motion_data[i].syf);
497 			}
498 			else
499 			{
500 				motion_data[i].sxf = round_search_radius(radius_x*i);
501 				motion_data[i].forw_hor_f_code  = f_code(motion_data[i].sxf);
502 				motion_data[i].syf = round_search_radius(radius_y*i);
503 				motion_data[i].forw_vert_f_code  = f_code(motion_data[i].syf);
504 				motion_data[i].sxb = round_search_radius(radius_x*(M-i));
505 				motion_data[i].back_hor_f_code  = f_code(motion_data[i].sxb);
506 				motion_data[i].syb = round_search_radius(radius_y*(M-i));
507 				motion_data[i].back_vert_f_code  = f_code(motion_data[i].syb);
508 			}
509 
510 			/* MPEG-1 demands f-codes for vertical and horizontal axes are
511 			   identical!!!!
512 			*/
513 			if( mpeg1 )
514 			{
515 				motion_data[i].syf = motion_data[i].sxf;
516 				motion_data[i].syb  = motion_data[i].sxb;
517 				motion_data[i].forw_vert_f_code  =
518 					motion_data[i].forw_hor_f_code;
519 				motion_data[i].back_vert_f_code  =
520 					motion_data[i].back_hor_f_code;
521 
522 			}
523 		}
524 
525 	}
526 
527 
528 
529 	/* make sure MPEG specific parameters are valid */
530 	RangeChecks();
531 
532 	/* Set the frame decode rate and frame display rates.
533 	   For 3:2 movie pulldown decode rate is != display rate due to
534 	   the repeated field that appears every other frame.
535 	*/
536 	frame_rate = Y4M_RATIO_DBL(mpeg_framerate(frame_rate_code));
537 	if( options.vid32_pulldown )
538 	{
539 		decode_frame_rate = frame_rate * (2.0 + 2.0) / (3.0 + 2.0);
540 		mjpeg_info( "3:2 Pulldown selected frame decode rate = %3.3f fps",
541 					decode_frame_rate);
542 	}
543 	else
544 		decode_frame_rate = frame_rate;
545 
546 	if ( !mpeg1)
547 	{
548 		ProfileAndLevelChecks();
549 	}
550 	else
551 	{
552 		/* MPEG-1 */
553 		if (constrparms)
554 		{
555 			if (horizontal_size>768
556 				|| vertical_size>576
557 				|| ((horizontal_size+15)/16)*((vertical_size+15)/16)>396
558 				|| ((horizontal_size+15)/16)*((vertical_size+15)/16)*frame_rate>396*25.0
559 				|| frame_rate>30.0)
560 			{
561 				mjpeg_info( "size - setting constrained_parameters_flag = 0");
562 				constrparms = 0;
563 			}
564 		}
565 
566 		if (constrparms)
567 		{
568 			for (i=0; i<M; i++)
569 			{
570 				if (motion_data[i].forw_hor_f_code>4)
571 				{
572 					mjpeg_info("Hor. motion search forces constrained_parameters_flag = 0");
573 					constrparms = 0;
574 					break;
575 				}
576 
577 				if (motion_data[i].forw_vert_f_code>4)
578 				{
579 					mjpeg_info("Ver. motion search forces constrained_parameters_flag = 0");
580 					constrparms = 0;
581 					break;
582 				}
583 
584 				if (i!=0)
585 				{
586 					if (motion_data[i].back_hor_f_code>4)
587 					{
588 						mjpeg_info("Hor. motion search setting constrained_parameters_flag = 0");
589 						constrparms = 0;
590 						break;
591 					}
592 
593 					if (motion_data[i].back_vert_f_code>4)
594 					{
595 						mjpeg_info("Ver. motion search setting constrained_parameters_flag = 0");
596 						constrparms = 0;
597 						break;
598 					}
599 				}
600 			}
601 		}
602 	}
603 
604 	/* relational checks */
605 	if ( mpeg1 )
606 	{
607 		if (!prog_seq)
608 		{
609 			mjpeg_warn("mpeg1 specified - setting progressive_sequence = 1");
610 			prog_seq = 1;
611 		}
612 
613 		if (dc_prec!=0)
614 		{
615 			mjpeg_info("mpeg1 - setting intra_dc_precision = 0");
616 			dc_prec = 0;
617 		}
618 
619 		for (i=0; i<3; i++)
620 			if (qscale_tab[i])
621 			{
622 				mjpeg_info("mpeg1 - setting qscale_tab[%d] = 0",i);
623 				qscale_tab[i] = 0;
624 			}
625 
626 		for (i=0; i<3; i++)
627 			if (intravlc_tab[i])
628 			{
629 				mjpeg_info("mpeg1 - setting intravlc_tab[%d] = 0",i);
630 				intravlc_tab[i] = 0;
631 			}
632 
633 		for (i=0; i<3; i++)
634 			if (altscan_tab[i])
635 			{
636 				mjpeg_info("mpeg1 - setting altscan_tab[%d] = 0",i);
637 				altscan_tab[i] = 0;
638 			}
639 	}
640 
641 	if ( !mpeg1 && constrparms)
642 	{
643 		mjpeg_info("not mpeg1 - setting constrained_parameters_flag = 0");
644 		constrparms = 0;
645 	}
646 
647 
648 	if( (!prog_seq || fieldpic != 0 ) &&
649 		( (vertical_size+15) / 16)%2 != 0 )
650 	{
651 		mjpeg_warn( "Frame height won't split into two equal field pictures...");
652 		mjpeg_warn( "forcing encoding as progressive video");
653 		prog_seq = 1;
654         pulldown_32 = false;
655 		fieldpic = 0;
656 	}
657 
658 
659 	if (prog_seq && fieldpic != 0)
660 	{
661 		mjpeg_info("prog sequence - forcing progressive frame encoding");
662 		fieldpic = 0;
663 	}
664 
665 
666 	if (prog_seq && topfirst )
667 	{
668 		mjpeg_info("prog sequence setting top_field_first = 0");
669 		topfirst = 0;
670 	}
671 
672 	/* search windows */
673 	for (i=0; i<M; i++)
674 	{
675 		if (motion_data[i].sxf > (4U<<motion_data[i].forw_hor_f_code)-1)
676 		{
677 			mjpeg_info(
678 				"reducing forward horizontal search width to %d",
679 						(4<<motion_data[i].forw_hor_f_code)-1);
680 			motion_data[i].sxf = (4U<<motion_data[i].forw_hor_f_code)-1;
681 		}
682 
683 		if (motion_data[i].syf > (4U<<motion_data[i].forw_vert_f_code)-1)
684 		{
685 			mjpeg_info(
686 				"reducing forward vertical search width to %d",
687 				(4<<motion_data[i].forw_vert_f_code)-1);
688 			motion_data[i].syf = (4U<<motion_data[i].forw_vert_f_code)-1;
689 		}
690 
691 		if (i!=0)
692 		{
693 			if (motion_data[i].sxb > (4U<<motion_data[i].back_hor_f_code)-1)
694 			{
695 				mjpeg_info(
696 					"reducing backward horizontal search width to %d",
697 					(4<<motion_data[i].back_hor_f_code)-1);
698 				motion_data[i].sxb = (4U<<motion_data[i].back_hor_f_code)-1;
699 			}
700 
701 			if (motion_data[i].syb > (4U<<motion_data[i].back_vert_f_code)-1)
702 			{
703 				mjpeg_info(
704 					"reducing backward vertical search width to %d",
705 					(4<<motion_data[i].back_vert_f_code)-1);
706 				motion_data[i].syb = (4U<<motion_data[i].back_vert_f_code)-1;
707 			}
708 		}
709 	}
710 
711     InitQuantMatrices( options );
712     InitEncodingControls( options );
713 
714     chapter_points.insert(chapter_points.end(),options.chapter_points.begin(),options.chapter_points.end());
715 }
716 
717 
718 /*
719   If the use has selected suppression of hf noise via quantisation
720   then we boost quantisation of hf components EXPERIMENTAL: currently
721   a linear ramp from 0 at 4pel to hf_q_boost increased
722   quantisation...
723 
724 */
725 
quant_hfnoise_filt(int orgquant,int qmat_pos,double hf_q_boost)726 static int quant_hfnoise_filt(int orgquant, int qmat_pos, double hf_q_boost )
727     {
728     int orgdist = MAX(qmat_pos % 8, qmat_pos/8);
729     double qboost;
730 
731     /* Maximum hf_q_boost quantisation boost for HF components.. */
732     qboost = 1.0 + ((hf_q_boost * orgdist) / 8);
733     return static_cast<int>(orgquant * qboost);
734     }
735 
736 
InitQuantMatrices(const MPEG2EncOptions & options)737 void EncoderParams::InitQuantMatrices( const MPEG2EncOptions &options )
738 {
739     int i, v;
740     const char *msg = NULL;
741     const uint16_t *qmat = 0;
742     const uint16_t *niqmat = 0;
743     load_iquant = 0;
744     load_niquant = 0;
745 
746     /* bufalloc to ensure alignment */
747     intra_q = static_cast<uint16_t*>(bufalloc(sizeof(uint16_t[64])));
748     inter_q = static_cast<uint16_t*>(bufalloc(sizeof(uint16_t[64])));
749 
750     switch  (options.hf_quant)
751     {
752     case  0:    /* No -N, -H or -K used.  Default matrices */
753         msg = "Using default unmodified quantization matrices";
754         qmat = default_intra_quantizer_matrix;
755         niqmat = default_nonintra_quantizer_matrix;
756         break;
757     case  1:    /* "-N value" used but not -K or -H */
758         msg = "Using -N modified default quantization matrices";
759         qmat = default_intra_quantizer_matrix;
760         niqmat = default_nonintra_quantizer_matrix;
761         load_iquant = 1;
762         load_niquant = 1;
763         break;
764     case  2:    /* -H used OR -H followed by "-N value" */
765         msg = "Setting hi-res intra Quantisation matrix";
766         qmat = hires_intra_quantizer_matrix;
767         niqmat = hires_nonintra_quantizer_matrix;
768         load_iquant = 1;
769         if(options.hf_q_boost)
770             load_niquant = 1;   /* Custom matrix if -N used */
771         break;
772     case  3:
773         msg = "KVCD Notch Quantization Matrix";
774         qmat = kvcd_intra_quantizer_matrix;
775         niqmat = kvcd_nonintra_quantizer_matrix;
776         load_iquant = 1;
777         load_niquant = 1;
778         break;
779     case  4:
780         msg = "TMPGEnc Quantization matrix";
781         qmat = tmpgenc_intra_quantizer_matrix;
782         niqmat = tmpgenc_nonintra_quantizer_matrix;
783         load_iquant = 1;
784         load_niquant = 1;
785         break;
786     case  5:
787         msg = "Flat quantization matrix for ultra high quality encoding";
788         load_iquant = 1;
789         load_niquant = 1;
790         qmat = flat_intra_quantizer_matrix;
791         niqmat = flat_nonintra_quantizer_matrix;
792         break;
793     case  6:            /* -K file=qmatrixfilename */
794         msg = "Loading custom matrices from user specified file";
795         load_iquant = 1;
796         load_niquant = 1;
797         qmat = options.custom_intra_quantizer_matrix;
798         niqmat = options.custom_nonintra_quantizer_matrix;
799         break;
800     default:
801         mjpeg_error_exit1("Help!  Unknown hf_quant value %d",
802                           options.hf_quant);
803         /* NOTREACHED */
804     }
805 
806     if  (msg)
807         mjpeg_info( "%s", msg);
808 
809     for (i = 0; i < 64; i++)
810     {
811         v = quant_hfnoise_filt(qmat[i], i, options.hf_q_boost);
812         if  (v < 1 || v > 255)
813             mjpeg_error_exit1("bad intra value after -N adjust");
814         intra_q[i] = v;
815 
816         v = quant_hfnoise_filt(niqmat[i], i, options.hf_q_boost);
817         if  (v < 1 || v > 255)
818             mjpeg_error_exit1("bad nonintra value after -N adjust");
819         inter_q[i] = v;
820     }
821 
822 }
823 
824 
825 /*
826  * Local variables:
827  *  c-file-style: "stroustrup"
828  *  tab-width: 4
829  *  indent-tabs-mode: nil
830  * End:
831  */
832