/* global.h, global variables, function prototypes */ /* 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. * */ #include "libzmpeg3.h" #include "mpeg2enc.h" #include #include /* choose between declaration (GLOBAL_ undefined) * and definition (GLOBAL_ defined) * GLOBAL_ is defined in exactly one file (mpeg2enc.c) */ #ifndef GLOBAL_ #define EXTERN_ extern #else #define EXTERN_ #endif /* global variables */ /* zig-zag scan */ EXTERN_ unsigned char mpeg2_zig_zag_scan[64] #ifdef GLOBAL_ = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5, 12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28, 35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51, 58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 } #endif ; /* alternate scan */ EXTERN_ unsigned char alternate_scan_hv[64] #ifdef GLOBAL_ = { 0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49, 41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43, 51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45, 53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63 } #endif ; /* default intra quantization matrix */ EXTERN_ uint16_t default_intra_quantizer_matrix_hv[64] #ifdef GLOBAL_ = { 8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40, 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58, 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83 } #endif ; EXTERN_ uint16_t hires_intra_quantizer_matrix_hv[64] #ifdef GLOBAL_ = { 8, 16, 18, 20, 24, 25, 26, 30, 16, 16, 20, 23, 25, 26, 30, 30, 18, 20, 22, 24, 26, 28, 29, 31, 20, 21, 23, 24, 26, 28, 31, 31, 21, 23, 24, 25, 28, 30, 30, 33, 23, 24, 25, 28, 30, 30, 33, 36, 24, 25, 26, 29, 29, 31, 34, 38, 25, 26, 28, 29, 31, 34, 38, 42 } #endif ; /* Our default non intra quantization matrix This is *not* the MPEG default */ EXTERN_ uint16_t default_nonintra_quantizer_matrix_hv[64] #ifdef GLOBAL_ = { 16, 17, 18, 19, 20, 21, 22, 23, 17, 18, 19, 20, 21, 22, 23, 24, 18, 19, 20, 21, 22, 23, 24, 25, 19, 20, 21, 22, 23, 24, 26, 27, 20, 21, 22, 23, 25, 26, 27, 28, 21, 22, 23, 24, 26, 27, 28, 30, 22, 23, 24, 26, 27, 28, 30, 31, 23, 24, 25, 27, 28, 30, 31, 33 } #endif ; /* Hires non intra quantization matrix. THis *is* the MPEG default... */ EXTERN_ uint16_t hires_nonintra_quantizer_matrix_hv[64] #ifdef GLOBAL_ = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 } #endif ; /* non-linear quantization coefficient table */ EXTERN_ unsigned char non_linear_mquant_table_hv[32] #ifdef GLOBAL_ = { 0, 1, 2, 3, 4, 5, 6, 7, 8,10,12,14,16,18,20,22, 24,28,32,36,40,44,48,52, 56,64,72,80,88,96,104,112 } #endif ; /* non-linear mquant table for mapping from scale to code * since reconstruction levels are not bijective with the index map, * it is up to the designer to determine most of the quantization levels */ EXTERN_ unsigned char map_non_linear_mquant_hv[113] #ifdef GLOBAL_ = { 0,1,2,3,4,5,6,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16, 16,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22, 22,22,23,23,23,23,24,24,24,24,24,24,24,25,25,25,25,25,25,25,26,26, 26,26,26,26,26,26,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,29, 29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,31,31,31,31,31 } #endif ; struct mc_result { uint16_t weight; int8_t x; int8_t y; }; typedef struct mc_result mc_result_s; typedef struct motion_comp { uint8_t **oldorg, **neworg; uint8_t **oldref, **newref; uint8_t **cur, **curref; int sxf, syf, sxb, syb; } motion_comp_s; typedef struct mbinfo mbinfo_s; typedef struct pict_data { /* picture structure (header) data */ int temp_ref; /* temporal reference */ int pict_type; /* picture coding type (I, P or B) */ int vbv_delay; /* video buffering verifier delay (1/90000 seconds) */ int forw_hor_f_code, forw_vert_f_code; int back_hor_f_code, back_vert_f_code; /* motion vector ranges */ int dc_prec; /* DC coefficient prec for intra blocks */ int pict_struct; /* picture structure (frame, top / bottom) */ int topfirst; /* display top field first */ int frame_pred_dct; /* Use only frame prediction... */ int intravlc; /* Intra VLC format */ int q_scale_type; /* Quantiser scale... */ int altscan; /* Alternate scan */ int repeatfirst; /* repeat first field after second field */ int prog_frame; /* progressive frame */ /* 8*8 block data, raw (unquantised) and quantised, and (eventually but not yet inverse quantised */ int16_t (*blocks)[64]; int16_t (*qblocks)[64]; unsigned char **curorg, **curref; /* macroblock side information array */ mbinfo_s *mbinfo; /* motion estimation parameters */ } pict_data_s; typedef struct { int start_row, end_row; pthread_mutex_t input_lock, output_lock; pthread_t tid; /* ID of thread */ int done; motion_comp_s *motion_comp; pict_data_s *pict_data; int secondfield; int ipflag; #define MAX_44_MATCHES (256*256/(4*4)) int sub22_num_mcomps; int sub44_num_mcomps; mc_result_s sub44_mcomps[MAX_44_MATCHES]; mc_result_s sub22_mcomps[MAX_44_MATCHES*4]; } motion_engine_t; #if 0 typedef struct { pthread_mutex_t ratectl_lock; double R, T, d; double actsum; int Np, Nb; double S, Q; int prev_mquant; double bitcnt_EOP; double next_ip_delay; /* due to frame reordering delay */ double decoding_time; int Xi, Xp, Xb, r, d0i, d0p, d0b; double avg_act; } ratectl_t; #endif typedef struct { /* * bitcnt_EOP = 0.0; * next_ip_delay = 0.0; * decoding_time = 0.0; * P = 0; // P distance between complete intra slice refresh * r = 0; // r (reaction parameter) * avg_act = 0; // avg_act (initial average activity) * Xi = 0; // Xi (initial I frame global complexity measure) * Xp = 0; // Xp (initial P frame global complexity measure) * Xb = 0; // Xb (initial B frame global complexity measure) * d0i = 0; // d0i (initial I frame virtual buffer fullness) * d0p = 0; // d0p (initial P frame virtual buffer fullness) * d0b = 0; // d0b (initial B frame virtual buffer fullness) */ pthread_mutex_t ratectl_lock; double Xi, Xp, Xb; int r; int d0i, d0pb; double R; int d; double T; int CarryR; int CarryRLim; /* bitcnt_EOP - Position in generated bit-stream for latest end-of-picture Comparing these values with the bit-stream position for when the picture is due to be displayed allows us to see what the vbv buffer is up to. gop_undershoot - If we *undershoot* our bit target the vbv buffer calculations based on the actual length of the bitstream will be wrong because in the final system stream these bits will be padded away. I.e. frames *won't* arrive as early as the length of the video stream would suggest they would. To get it right we have to keep track of the bits that would appear in padding. */ int64_t bitcnt_EOP; int gop_undershoot; /* actsum - Total activity (sum block variances) in frame actcovered - Activity macroblocks so far quantised (used to fine tune quantisation to avoid starving highly active blocks appearing late in frame...) UNUSED avg_act - Current average activity... */ double actsum; double actcovered; double sum_avg_act; double avg_act; double peak_act; int Np, Nb; int64_t S; double IR; /* Note: eventually we may wish to tweak these to suit image content */ double Ki; /* Down-scaling of I/B/P-frame complexity */ double Kb; /* relative to others in bit-allocation */ double Kp; /* calculations. We only need 2 but have all 3 for readability */ int min_d,max_d; int min_q, max_q; /* TODO EXPERIMENT */ double avg_KI; /* TODO: These values empirically determined */ double avg_KB; /* for MPEG-1, may need tuning for MPEG-2 */ double avg_KP; #define K_AVG_WINDOW_I 4.0 /* TODO: MPEG-1, hard-wired settings */ #define K_AVG_WINDOW_P 10.0 #define K_AVG_WINDOW_B 20.0 double bits_per_mb; double SQ; double AQ; double current_quant; int64_t frame_start; int64_t frame_end; } ratectl_t; typedef struct { int start_row, end_row; pthread_mutex_t input_lock, output_lock; pthread_t tid; /* ID of thread */ int done; pict_data_s *picture; unsigned char **pred; unsigned char **cur; // Temp for MMX unsigned char temp[128]; } transform_engine_t; typedef struct { int start_row, end_row; pthread_mutex_t input_lock, output_lock; pthread_t tid; /* ID of thread */ int done; int prev_mquant; /* prediction values for DCT coefficient (0,0) */ int dc_dct_pred[3]; unsigned char *frame; unsigned char *slice_buffer; long slice_size; long slice_allocated; pict_data_s *picture; ratectl_t *ratectl; unsigned char outbfr; int outcnt; } slice_engine_t; EXTERN_ pthread_mutex_t test_lock; EXTERN_ motion_engine_t *motion_engines; EXTERN_ transform_engine_t *transform_engines; EXTERN_ transform_engine_t *itransform_engines; EXTERN_ slice_engine_t *slice_engines; EXTERN_ ratectl_t **ratectl; EXTERN_ int quiet; /* suppress warnings */ EXTERN_ pict_data_s cur_picture; /* reconstructed frames */ EXTERN_ unsigned char *newrefframe[3], *oldrefframe[3], *auxframe[3]; /* original frames */ EXTERN_ unsigned char *neworgframe[3], *oldorgframe[3], *auxorgframe[3]; /* prediction of current frame */ EXTERN_ unsigned char *predframe[3]; /* motion estimation parameters */ EXTERN_ struct motion_data *motion_data; /* SCale factor for fast integer arithmetic routines */ /* Changed this and you *must* change the quantisation routines as they depend on its absolute value */ #define IQUANT_SCALE_POW2 16 #define IQUANT_SCALE (1<