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