📄 encoderparams.cc
字号:
/* encoderparams - class holding all the various control parameters for and individual encoder instance. For speed a lot of address offsets/sizes are computed once-and-for-all and held in this object.*//* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. *//* * Disclaimer of Warranty * * These software programs are available to the user without any license fee or * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims * any and all warranties, whether express, implied, or statuary, including any * implied warranties or merchantability or of fitness for a particular * purpose. In no event shall the copyright-holder be liable for any * incidental, punitive, or consequential damages of any kind whatsoever * arising from the use of these programs. * * This disclaimer of warranty extends to the user of these programs and user's * customers, employees, agents, transferees, successors, and assigns. * * The MPEG Software Simulation Group does not represent or warrant that the * programs furnished hereunder are free of infringement of any third-party * patents. * * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, * are subject to royalty fees to patent holders. Many of these patents are * general enough such that they are unavoidable regardless of implementation * design. * *//* Modifications and enhancements (C) 2000,2001,2002,2003 Andrew Stevens *//* These modifications are free software; you can redistribute it * and/or modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * */#include <config.h>#include "encoderparams.hh"#include "format_codes.h"#include "mpegconsts.h"#include "mpeg2encoptions.hh"//#include "mpeg2syntaxcodes.h"#include "tables.h"#include "ratectl.hh"#include "cpu_accel.h"#include "motionsearch.h"#include <string.h> // REMOVE#define MAX(a,b) ( (a)>(b) ? (a) : (b) )#define MIN(a,b) ( (a)<(b) ? (a) : (b) )EncoderParams::EncoderParams( const MPEG2EncOptions &encoptions){ memset( this, -1, sizeof(EncoderParams) ); // REMOVE}void EncoderParams::InitEncodingControls( const MPEG2EncOptions &options){ /* Tune threading and motion compensation for specified number of CPU's and specified speed parameters. */ act_boost = 1.0+options.act_boost; boost_var_ceil = options.boost_var_ceil; switch( options.num_cpus ) { case 0 : /* Special case for debugging... turns of multi-threading */ encoding_parallelism = 0; parallel_read = false; break; case 1 : encoding_parallelism = 1; parallel_read = options.allow_parallel_read; break; case 2: encoding_parallelism = 2; parallel_read = options.allow_parallel_read ; break; default : encoding_parallelism = options.num_cpus > MAX_WORKER_THREADS-1 ? MAX_WORKER_THREADS-1 : options.num_cpus; parallel_read = options.allow_parallel_read; break; } max_active_ref_frames = M == 0 ? encoding_parallelism : (encoding_parallelism+2); max_active_b_frames = M <= 1 ? 0 : encoding_parallelism+1; me44_red = options.me44_red; me22_red = options.me22_red; unit_coeff_elim = options.unit_coeff_elim; /* round picture dimensions to nearest multiple of 16 or 32 */ mb_width = (horizontal_size+15)/16; mb_height = prog_seq ? (vertical_size+15)/16 : 2*((vertical_size+31)/32); mb_height2 = fieldpic ? mb_height>>1 : mb_height; /* for field pictures */ enc_width = 16*mb_width; enc_height = 16*mb_height;#ifdef DEBUG_MOTION_EST static const int MARGIN = 64;#else static const int MARGIN = 0;#endif #ifdef HAVE_ALTIVEC /* Pad phy_width to 64 so that the rowstride of 4*4 * sub-sampled data will be a multiple of 16 (ideal for AltiVec) * and the rowstride of 2*2 sub-sampled data will be a multiple * of 32. Height does not affect rowstride, no padding needed. */ phy_width = (enc_width + 63) & (~63);#else phy_width = enc_width+MARGIN;#endif phy_height = enc_height+MARGIN; /* Calculate the sizes and offsets in to luminance and chrominance buffers. A.Stevens 2000 for luminance data we allow space for fast motion estimation data. This is actually 2*2 pixel sub-sampled uint8_t followed by 4*4 sub-sampled. We add an extra row to act as a margin to allow us to neglect / postpone edge condition checking in time-critical loops... */ phy_chrom_width = phy_width>>1; phy_chrom_height = phy_height>>1; enc_chrom_width = enc_width>>1; enc_chrom_height = enc_height>>1; phy_height2 = fieldpic ? phy_height>>1 : phy_height; enc_height2 = fieldpic ? enc_height>>1 : enc_height; phy_width2 = fieldpic ? phy_width<<1 : phy_width; phy_chrom_width2 = fieldpic ? phy_chrom_width<<1 : phy_chrom_width; lum_buffer_size = (phy_width*phy_height) + sizeof(uint8_t) *(phy_width/2)*(phy_height/2) + sizeof(uint8_t) *(phy_width/4)*(phy_height/4); chrom_buffer_size = phy_chrom_width*phy_chrom_height; fsubsample_offset = (phy_width)*(phy_height) * sizeof(uint8_t); qsubsample_offset = fsubsample_offset + (phy_width/2)*(phy_height/2)*sizeof(uint8_t); mb_per_pict = mb_width*mb_height2;#ifdef OUTPUT_STAT /* open statistics output file */ if (!(statfile = fopen(statname,"w"))) { mjpeg_error_exit1( "Couldn't create statistics output file %s", statname); }#endif}static int f_code( int max_radius ){ int c=5; if( max_radius < 64) c = 4; if( max_radius < 32) c = 3; if( max_radius < 16) c = 2; if( max_radius < 8) c = 1; return c;}void EncoderParams::Init( const MPEG2EncOptions &options ){ int i; const char *msg; //istrm_nframes = 999999999; /* determined by EOF of stdin */ N_min = options.min_GOP_size; /* I frame distance */ N_max = options.max_GOP_size; closed_GOPs = options.closed_GOPs; mjpeg_info( "GOP SIZE RANGE %d TO %d %s", N_min, N_max, closed_GOPs ? "(all GOPs closed)" : "" ); M = options.Bgrp_size; /* I or P frame distance */ M_min = options.preserve_B ? M : 1; if( M > N_max ) M = N_max; mpeg1 = (options.mpeg == 1); fieldpic = (options.fieldenc == 2); dualprime = options.hack_dualprime == 1 && M == 1; // SVCD and probably DVD? mandate progressive_sequence = 0 switch( options.format ) { case MPEG_FORMAT_SVCD : case MPEG_FORMAT_SVCD_NSR : case MPEG_FORMAT_SVCD_STILL : case MPEG_FORMAT_DVD : case MPEG_FORMAT_DVD_NAV : prog_seq = 0; break; default : prog_seq = (options.mpeg == 1 || options.fieldenc == 0); break; } pulldown_32 = options.vid32_pulldown; aspectratio = options.aspect_ratio; frame_rate_code = options.frame_rate; dctsatlim = mpeg1 ? 255 : 2047; /* If we're using a non standard (VCD?) profile bit-rate adjust the vbv buffer accordingly... */ if(options.bitrate == 0 ) { mjpeg_error_exit1( "Generic format - must specify bit-rate!" ); } still_size = 0; if( MPEG_STILLS_FORMAT(options.format) ) { vbv_buffer_code = options.vbv_buffer_still_size / 2048; vbv_buffer_still_size = options.pad_stills_to_vbv_buffer_size; bit_rate = options.bitrate; still_size = options.still_size; } else if( options.mpeg == 1 ) { /* Scale VBV relative to VCD */ bit_rate = MAX(10000, options.bitrate); vbv_buffer_code = (20 * options.bitrate / 1151929); } else { bit_rate = MAX(10000, options.bitrate); vbv_buffer_code = MIN(112,options.video_buffer_size / 2); } vbv_buffer_size = vbv_buffer_code*16384; if( options.quant ) { quant_floor = RateCtl::InvScaleQuant( options.mpeg == 1 ? 0 : 1, options.quant ); } else { quant_floor = 0.0; /* Larger than max quantisation */ } video_buffer_size = options.video_buffer_size * 1024 * 8; seq_hdr_every_gop = options.seq_hdr_every_gop; seq_end_every_gop = options.seq_end_every_gop; svcd_scan_data = options.svcd_scan_data; ignore_constraints = options.ignore_constraints; seq_length_limit = options.seq_length_limit; nonvid_bit_rate = options.nonvid_bitrate * 1000; low_delay = 0; constrparms = (options.mpeg == 1 && !MPEG_STILLS_FORMAT(options.format)); profile = 4; /* Main profile resp. */ level = 8; /* Main Level CCIR 601 rates */ switch(options.norm) { case 'p': video_format = 1; break; case 'n': video_format = 2; break; case 's': video_format = 3; break; default: video_format = 5; break; /* unspec. */ } switch(options.norm) { case 's': case 'p': /* ITU BT.470 B,G */ color_primaries = 5; transfer_characteristics = 5; /* Gamma = 2.8 (!!) */ matrix_coefficients = 5; msg = "PAL B/G"; break; case 'n': /* SMPTPE 170M "modern NTSC" */ color_primaries = 6; matrix_coefficients = 6; transfer_characteristics = 6; msg = "NTSC"; break; default: /* unspec. */ color_primaries = 2; matrix_coefficients = 2; transfer_characteristics = 2; msg = "unspecified"; break; } mjpeg_info( "Setting colour/gamma parameters to \"%s\"", msg); horizontal_size = options.in_img_width; vertical_size = options.in_img_height; switch( options.format ) { case MPEG_FORMAT_SVCD_STILL : case MPEG_FORMAT_SVCD_NSR : case MPEG_FORMAT_SVCD : case MPEG_FORMAT_DVD : case MPEG_FORMAT_DVD_NAV : /* It would seem DVD and perhaps SVCD demand a 540 pixel display size for 4:3 aspect video. However, many players expect 480 and go weird if this isn't set... */ if( options.hack_svcd_hds_bug ) { display_horizontal_size = options.in_img_width; display_vertical_size = options.in_img_height; } else { display_horizontal_size = aspectratio == 2 ? 540 : 720; display_vertical_size = options.in_img_height; } break; default: display_horizontal_size = options.in_img_width; display_vertical_size = options.in_img_height; break; } dc_prec = options.mpeg2_dc_prec; /* 9 bits */ topfirst = 0; if( ! prog_seq ) { int fieldorder; if( options.force_interlacing != Y4M_UNKNOWN ) { mjpeg_info( "Forcing playback video to be: %s", mpeg_interlace_code_definition( options.force_interlacing ) ); fieldorder = options.force_interlacing; } else fieldorder = options.input_interlacing; topfirst = (fieldorder == Y4M_ILACE_TOP_FIRST || fieldorder ==Y4M_ILACE_NONE ); } else topfirst = 0; // Restrict to frame motion estimation and DCT modes only when MPEG1 // or when progressive content is specified for MPEG2. // Note that for some profiles although we have progressive sequence // header bit = 0 we still only encode with frame modes (for speed). frame_pred_dct_tab[0] = frame_pred_dct_tab[1] = frame_pred_dct_tab[2] = (options.mpeg == 1 || options.fieldenc == 0) ? 1 : 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -