/***************************************************************************** * Open: probe the encoder *****************************************************************************/ static int Open ( vlc_object_t *p_this ) { encoder_t *p_enc = (encoder_t *)p_this; encoder_sys_t *p_sys; int i_val; char *psz_val; int i_qmin = 0, i_qmax = 0; x264_nal_t *nal; int i, i_nal; if( p_enc->fmt_out.i_codec != VLC_CODEC_H264 && !p_enc->b_force ) { return VLC_EGENERIC; } /* X264_POINTVER or X264_VERSION are not available */ msg_Dbg ( p_enc, "version x264 0.%d.X", X264_BUILD ); config_ChainParse( p_enc, SOUT_CFG_PREFIX, ppsz_sout_options, p_enc->p_cfg ); p_enc->fmt_out.i_cat = VIDEO_ES; p_enc->fmt_out.i_codec = VLC_CODEC_H264; p_enc->fmt_in.i_codec = VLC_CODEC_I420; p_enc->pf_encode_video = Encode; p_enc->pf_encode_audio = NULL; p_enc->p_sys = p_sys = malloc( sizeof( encoder_sys_t ) ); if( !p_sys ) return VLC_ENOMEM; p_sys->i_interpolated_dts = 0; p_sys->psz_stat_name = NULL; p_sys->p_buffer = NULL; x264_param_default( &p_sys->param ); p_sys->param.i_width = p_enc->fmt_in.video.i_width; p_sys->param.i_height = p_enc->fmt_in.video.i_height; p_sys->param.rc.f_qcompress = var_GetFloat( p_enc, SOUT_CFG_PREFIX "qcomp" ); /* transcode-default bitrate is 0, * set more to ABR if user specifies bitrate */ if( p_enc->fmt_out.i_bitrate > 0 ) { p_sys->param.rc.i_bitrate = p_enc->fmt_out.i_bitrate / 1000; p_sys->param.rc.i_rc_method = X264_RC_ABR; } else /* Set default to CRF */ { i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "crf" ); if( i_val > 0 && i_val <= 51 ) { p_sys->param.rc.f_rf_constant = i_val; p_sys->param.rc.i_rc_method = X264_RC_CRF; } } i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qpstep" ); if( i_val >= 0 && i_val <= 51 ) p_sys->param.rc.i_qp_step = i_val; i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qpmin" ); if( i_val >= 0 && i_val <= 51 ) { i_qmin = i_val; p_sys->param.rc.i_qp_min = i_qmin; } i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qpmax" ); if( i_val >= 0 && i_val <= 51 ) { i_qmax = i_val; p_sys->param.rc.i_qp_max = i_qmax; } i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qp" ); if( i_val >= 0 && i_val <= 51 ) { if( i_qmin > i_val ) i_qmin = i_val; if( i_qmax < i_val ) i_qmax = i_val; /* User defined QP-value, so change ratecontrol method */ p_sys->param.rc.i_rc_method = X264_RC_CQP; p_sys->param.rc.i_qp_constant = i_val; p_sys->param.rc.i_qp_min = i_qmin; p_sys->param.rc.i_qp_max = i_qmax; } p_sys->param.rc.f_rate_tolerance = var_GetFloat( p_enc, SOUT_CFG_PREFIX "ratetol" ); p_sys->param.rc.f_vbv_buffer_init = var_GetFloat( p_enc, SOUT_CFG_PREFIX "vbv-init" ); p_sys->param.rc.i_vbv_buffer_size = var_GetInteger( p_enc, SOUT_CFG_PREFIX "vbv-bufsize" ); /* max bitrate = average bitrate -> CBR */ i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "vbv-maxrate" ); if( !i_val && p_sys->param.rc.i_rc_method == X264_RC_ABR ) p_sys->param.rc.i_vbv_max_bitrate = p_sys->param.rc.i_bitrate; else if ( i_val ) p_sys->param.rc.i_vbv_max_bitrate = i_val; p_sys->param.b_cabac = var_GetBool( p_enc, SOUT_CFG_PREFIX "cabac" ); /* disable deblocking when nf (no loop filter) is enabled */ p_sys->param.b_deblocking_filter = !var_GetBool( p_enc, SOUT_CFG_PREFIX "nf" ); psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "deblock" ); if( psz_val ) { char *p = strchr( psz_val, ':' ); p_sys->param.i_deblocking_filter_alphac0 = atoi( psz_val ); p_sys->param.i_deblocking_filter_beta = p ? atoi( p+1 ) : p_sys->param.i_deblocking_filter_alphac0; free( psz_val ); } psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "psy-rd" ); if( psz_val ) { char *p = strchr( psz_val, ':' ); p_sys->param.analyse.f_psy_rd = us_atof( psz_val ); p_sys->param.analyse.f_psy_trellis = p ? us_atof( p+1 ) : 0; free( psz_val ); } psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "level" ); if( psz_val ) { if( us_atof (psz_val) < 6 ) p_sys->param.i_level_idc = (int) (10 * us_atof (psz_val) + .5); else p_sys->param.i_level_idc = atoi (psz_val); free( psz_val ); } p_sys->param.b_interlaced = var_GetBool( p_enc, SOUT_CFG_PREFIX "interlaced" ); p_sys->param.rc.f_ip_factor = var_GetFloat( p_enc, SOUT_CFG_PREFIX "ipratio" ); p_sys->param.rc.f_pb_factor = var_GetFloat( p_enc, SOUT_CFG_PREFIX "pbratio" ); p_sys->param.rc.f_complexity_blur = var_GetFloat( p_enc, SOUT_CFG_PREFIX "cplxblur" ); p_sys->param.rc.f_qblur = var_GetFloat( p_enc, SOUT_CFG_PREFIX "qblur" ); p_sys->param.rc.i_aq_mode = var_GetInteger( p_enc, SOUT_CFG_PREFIX "aq-mode" ); p_sys->param.rc.f_aq_strength = var_GetFloat( p_enc, SOUT_CFG_PREFIX "aq-strength" ); if( var_GetBool( p_enc, SOUT_CFG_PREFIX "verbose" ) ) p_sys->param.i_log_level = X264_LOG_DEBUG; if( var_GetBool( p_enc, SOUT_CFG_PREFIX "quiet" ) ) p_sys->param.i_log_level = X264_LOG_NONE; i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "sps-id" ); if( i_val >= 0 ) p_sys->param.i_sps_id = i_val; if( var_GetBool( p_enc, SOUT_CFG_PREFIX "aud" ) ) p_sys->param.b_aud = true; i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "keyint" ); if( i_val > 0 ) p_sys->param.i_keyint_max = i_val; i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "min-keyint" ); if( i_val > 0 ) p_sys->param.i_keyint_min = i_val; i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "bframes" ); if( i_val >= 0 && i_val <= 16 ) p_sys->param.i_bframe = i_val; #if X264_BUILD >= 78 psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "bpyramid" ); p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_NONE; if( !strcmp( psz_val, "none" ) ) { p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_NONE; } else if ( !strcmp( psz_val, "strict" ) ) { p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_STRICT; } else if ( !strcmp( psz_val, "normal" ) ) { p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_NORMAL; } free( psz_val ); #else p_sys->param.b_bframe_pyramid = var_GetBool( p_enc, SOUT_CFG_PREFIX "bpyramid" ); #endif i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "ref" ); if( i_val > 0 && i_val <= 15 ) p_sys->param.i_frame_reference = i_val; i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "scenecut" ); if( i_val >= -1 && i_val <= 100 ) p_sys->param.i_scenecut_threshold = i_val; p_sys->param.b_deterministic = var_GetBool( p_enc, SOUT_CFG_PREFIX "non-deterministic" ); i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "subme" ); if( i_val >= 1 && i_val <= SUBME_MAX ) p_sys->param.analyse.i_subpel_refine = i_val; //TODO: psz_val == NULL ? psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "me" ); if( !strcmp( psz_val, "dia" ) ) { p_sys->param.analyse.i_me_method = X264_ME_DIA; } else if( !strcmp( psz_val, "hex" ) ) { p_sys->param.analyse.i_me_method = X264_ME_HEX; } else if( !strcmp( psz_val, "umh" ) ) { p_sys->param.analyse.i_me_method = X264_ME_UMH; } else if( !strcmp( psz_val, "esa" ) ) { p_sys->param.analyse.i_me_method = X264_ME_ESA; } else if( !strcmp( psz_val, "tesa" ) ) { p_sys->param.analyse.i_me_method = X264_ME_TESA; } free( psz_val ); i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "merange" ); if( i_val >= 0 && i_val <= 64 ) p_sys->param.analyse.i_me_range = i_val; p_sys->param.analyse.i_mv_range = var_GetInteger( p_enc, SOUT_CFG_PREFIX "mvrange" ); p_sys->param.analyse.i_mv_range_thread = var_GetInteger( p_enc, SOUT_CFG_PREFIX "mvrange-thread" ); psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "direct" ); if( !strcmp( psz_val, "none" ) ) { p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_NONE; } else if( !strcmp( psz_val, "spatial" ) ) { p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL; } else if( !strcmp( psz_val, "temporal" ) ) { p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_TEMPORAL; } else if( !strcmp( psz_val, "auto" ) ) { p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO; } free( psz_val ); p_sys->param.analyse.b_psnr = var_GetBool( p_enc, SOUT_CFG_PREFIX "psnr" ); p_sys->param.analyse.b_ssim = var_GetBool( p_enc, SOUT_CFG_PREFIX "ssim" ); p_sys->param.analyse.b_weighted_bipred = var_GetBool( p_enc, SOUT_CFG_PREFIX "weightb" ); p_sys->param.i_bframe_adaptive = var_GetInteger( p_enc, SOUT_CFG_PREFIX "b-adapt" ); i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "b-bias" ); if( i_val >= -100 && i_val <= 100 ) p_sys->param.i_bframe_bias = i_val; p_sys->param.analyse.b_chroma_me = var_GetBool( p_enc, SOUT_CFG_PREFIX "chroma-me" ); p_sys->param.analyse.i_chroma_qp_offset = var_GetInteger( p_enc, SOUT_CFG_PREFIX "chroma-qp-offset" ); p_sys->param.analyse.b_mixed_references = var_GetBool( p_enc, SOUT_CFG_PREFIX "mixed-refs" ); i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "trellis" ); if( i_val >= 0 && i_val <= 2 ) p_sys->param.analyse.i_trellis = i_val; p_sys->param.analyse.b_fast_pskip = var_GetBool( p_enc, SOUT_CFG_PREFIX "fast-pskip" ); i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "nr" ); if( i_val >= 0 && i_val <= 1000 ) p_sys->param.analyse.i_noise_reduction = i_val; p_sys->param.analyse.b_dct_decimate = var_GetBool( p_enc, SOUT_CFG_PREFIX "dct-decimate" ); i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "deadzone-inter" ); if( i_val >= 0 && i_val <= 32 ) p_sys->param.analyse.i_luma_deadzone[0] = i_val; i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "deadzone-intra" ); if( i_val >= 0 && i_val <= 32 ) p_sys->param.analyse.i_luma_deadzone[1] = i_val; if( !var_GetBool( p_enc, SOUT_CFG_PREFIX "asm" ) ) p_sys->param.cpu = 0; #ifndef X264_ANALYSE_BSUB16x16 # define X264_ANALYSE_BSUB16x16 0 #endif psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "partitions" ); if( !strcmp( psz_val, "none" ) ) { p_sys->param.analyse.inter = 0; } else if( !strcmp( psz_val, "fast" ) ) { p_sys->param.analyse.inter = X264_ANALYSE_I4x4; } else if( !strcmp( psz_val, "normal" ) ) { p_sys->param.analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16; #ifdef X264_ANALYSE_I8x8 p_sys->param.analyse.inter |= X264_ANALYSE_I8x8; #endif } else if( !strcmp( psz_val, "slow" ) ) { p_sys->param.analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16; #ifdef X264_ANALYSE_I8x8 p_sys->param.analyse.inter |= X264_ANALYSE_I8x8; #endif } else if( !strcmp( psz_val, "all" ) ) { p_sys->param.analyse.inter = ~0; } free( psz_val ); p_sys->param.analyse.b_transform_8x8 = var_GetBool( p_enc, SOUT_CFG_PREFIX "8x8dct" ); if( p_enc->fmt_in.video.i_aspect > 0 ) { int64_t i_num, i_den; unsigned int i_dst_num, i_dst_den; i_num = p_enc->fmt_in.video.i_aspect * (int64_t)p_enc->fmt_in.video.i_height; i_den = VOUT_ASPECT_FACTOR * p_enc->fmt_in.video.i_width; vlc_ureduce( &i_dst_num, &i_dst_den, i_num, i_den, 0 ); p_sys->param.vui.i_sar_width = i_dst_num; p_sys->param.vui.i_sar_height = i_dst_den; } if( p_enc->fmt_in.video.i_frame_rate_base > 0 ) { p_sys->param.i_fps_num = p_enc->fmt_in.video.i_frame_rate; p_sys->param.i_fps_den = p_enc->fmt_in.video.i_frame_rate_base; } /* x264 vbv-bufsize = 0 (default). if not provided set period in seconds for local maximum bitrate (cache/bufsize) based on average bitrate when use has told bitrate. vbv-buffer size is set to bitrate * secods between keyframes */ if( !p_sys->param.rc.i_vbv_buffer_size && p_sys->param.rc.i_rc_method == X264_RC_ABR && p_sys->param.i_fps_num ) { p_sys->param.rc.i_vbv_buffer_size = p_sys->param.rc.i_bitrate * p_sys->param.i_fps_den; p_sys->param.rc.i_vbv_buffer_size *= p_sys->param.i_keyint_max; p_sys->param.rc.i_vbv_buffer_size /= p_sys->param.i_fps_num; } /* Check if user has given some profile (baseline,main,high) to limit * settings, and apply those*/ psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "profile" ); if( psz_val ) { if( !strcasecmp( psz_val, "baseline" ) ) { msg_Dbg( p_enc, "Limiting to baseline profile"); p_sys->param.analyse.b_transform_8x8 = 0; p_sys->param.b_cabac = 0; p_sys->param.i_bframe = 0; } else if (!strcasecmp( psz_val, "main" ) ) { msg_Dbg( p_enc, "Limiting to main-profile"); p_sys->param.analyse.b_transform_8x8 = 0; } /* high profile don't restrict stuff*/ } free( psz_val ); unsigned i_cpu = vlc_CPU(); if( !(i_cpu & CPU_CAPABILITY_MMX) ) { p_sys->param.cpu &= ~X264_CPU_MMX; } if( !(i_cpu & CPU_CAPABILITY_MMXEXT) ) { p_sys->param.cpu &= ~X264_CPU_MMXEXT; } if( !(i_cpu & CPU_CAPABILITY_SSE) ) { p_sys->param.cpu &= ~X264_CPU_SSE; } if( !(i_cpu & CPU_CAPABILITY_SSE2) ) { p_sys->param.cpu &= ~X264_CPU_SSE2; } /* BUILD 29 adds support for multi-threaded encoding while BUILD 49 (r543) also adds support for threads = 0 for automatically selecting an optimal value (cores * 1.5) based on detected CPUs. Default behavior for x264 is threads = 1, however VLC usage differs and uses threads = 0 (auto) by default unless ofcourse transcode threads is explicitly specified.. */ p_sys->param.i_threads = p_enc->i_threads; psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "stats" ); if( psz_val ) { p_sys->param.rc.psz_stat_in = p_sys->param.rc.psz_stat_out = p_sys->psz_stat_name = psz_val; } i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "pass" ); if( i_val > 0 && i_val <= 3 ) { p_sys->param.rc.b_stat_write = i_val & 1; p_sys->param.rc.b_stat_read = i_val & 2; } /* We need to initialize pthreadw32 before we open the encoder, but only once for the whole application. Since pthreadw32 doesn't keep a refcount, do it ourselves. */ #ifdef PTW32_STATIC_LIB vlc_value_t lock, count; var_Create( p_enc->p_libvlc, "pthread_win32_mutex", VLC_VAR_MUTEX ); var_Get( p_enc->p_libvlc, "pthread_win32_mutex", &lock ); vlc_mutex_lock( lock.p_address ); var_Create( p_enc->p_libvlc, "pthread_win32_count", VLC_VAR_INTEGER ); var_Get( p_enc->p_libvlc, "pthread_win32_count", &count ); if( count.i_int == 0 ) { msg_Dbg( p_enc, "initializing pthread-win32" ); if( !pthread_win32_process_attach_np() || !pthread_win32_thread_attach_np() ) { msg_Warn( p_enc, "pthread Win32 Initialization failed" ); vlc_mutex_unlock( lock.p_address ); return VLC_EGENERIC; } } count.i_int++; var_Set( p_enc->p_libvlc, "pthread_win32_count", count ); vlc_mutex_unlock( lock.p_address ); #endif /* Set lookahead value to lower than default, * as rtp-output without mux doesn't handle * difference that well yet*/ p_sys->param.rc.i_lookahead=5; /* Open the encoder */ p_sys->h = x264_encoder_open( &p_sys->param ); if( p_sys->h == NULL ) { msg_Err( p_enc, "cannot open x264 encoder" ); Close( VLC_OBJECT(p_enc) ); return VLC_EGENERIC; } /* alloc mem */ p_sys->i_buffer = 4 * p_enc->fmt_in.video.i_width * p_enc->fmt_in.video.i_height + 1000; p_sys->p_buffer = malloc( p_sys->i_buffer ); if( !p_sys->p_buffer ) { Close( VLC_OBJECT(p_enc) ); return VLC_ENOMEM; } /* get the globals headers */ p_enc->fmt_out.i_extra = 0; p_enc->fmt_out.p_extra = NULL; p_enc->fmt_out.i_extra = x264_encoder_headers( p_sys->h, &nal, &i_nal ); p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra ); if( !p_enc->fmt_out.p_extra ) { Close( VLC_OBJECT(p_enc) ); return VLC_ENOMEM; } void *p_tmp = p_enc->fmt_out.p_extra; for( i = 0; i < i_nal; i++ ) { memcpy( p_tmp, nal[i].p_payload, nal[i].i_payload ); p_tmp += nal[i].i_payload; } return VLC_SUCCESS; }
int pthread_rwlock_init (pthread_rwlock_t * rwlock, const pthread_rwlockattr_t * attr) { int result; pthread_rwlock_t rwl = 0; if (rwlock == NULL) { return EINVAL; } #ifdef PTW32_STATIC_LIB // This allos for C++ static initializers to function without crashes. (air) pthread_win32_process_attach_np(); #endif if (attr != NULL && *attr != NULL) { result = EINVAL; /* Not supported */ goto DONE; } rwl = (pthread_rwlock_t) calloc (1, sizeof (*rwl)); if (rwl == NULL) { result = ENOMEM; goto DONE; } rwl->nSharedAccessCount = 0; rwl->nExclusiveAccessCount = 0; rwl->nCompletedSharedAccessCount = 0; result = pthread_mutex_init (&rwl->mtxExclusiveAccess, NULL); if (result != 0) { goto FAIL0; } result = pthread_mutex_init (&rwl->mtxSharedAccessCompleted, NULL); if (result != 0) { goto FAIL1; } result = pthread_cond_init (&rwl->cndSharedAccessCompleted, NULL); if (result != 0) { goto FAIL2; } rwl->nMagic = PTW32_RWLOCK_MAGIC; result = 0; goto DONE; FAIL2: (void) pthread_mutex_destroy (&(rwl->mtxSharedAccessCompleted)); FAIL1: (void) pthread_mutex_destroy (&(rwl->mtxExclusiveAccess)); FAIL0: (void) free (rwl); rwl = NULL; DONE: *rwlock = rwl; return result; }
static void on_process_init(void) { pthread_win32_process_attach_np (); }
static int on_process_init(void) { pthread_win32_process_attach_np (); return 0; }
int main (int argc, char **argv) { int rv = 0; inst = & _plugin; #ifdef __APPLE__ rtk_osx_api_init(); #endif #ifdef _WIN32 pthread_win32_process_attach_np(); #endif #if (defined _WIN32 && defined RTK_STATIC_INIT) glib_init_static(); gobject_init_ctor(); #endif struct { int argc; char **argv; } rtkargv; rtkargv.argc = argc; rtkargv.argv = argv; const LV2_Feature external_lv_feature = { LV2_EXTERNAL_UI_URI, &extui_host}; const LV2_Feature external_kx_feature = { LV2_EXTERNAL_UI_URI__KX__Host, &extui_host}; const LV2_Feature robtk_argv = { "http://gareus.org/oss/lv2/robtk#argv", &rtkargv}; // TODO add argv[] as feature const LV2_Feature* ui_features[] = { &external_lv_feature, &external_kx_feature, &robtk_argv, NULL }; extui_host.plugin_human_id = inst->plugin_human_id; plugin_gui = inst->lv2ui_descriptor(inst->gui_descriptor_id); if (plugin_gui) { /* init plugin GUI */ extui_host.ui_closed = on_external_ui_closed; gui_instance = plugin_gui->instantiate(plugin_gui, "URI TODO", NULL, NULL, NULL, (void **)&extui, ui_features); } if (!gui_instance || !extui) { fprintf(stderr, "Error: GUI was not initialized.\n"); rv |= 2; goto out; } #ifndef _WIN32 signal (SIGHUP, catchsig); signal (SIGINT, catchsig); #endif { LV2_EXTERNAL_UI_SHOW(extui); #ifdef __APPLE__ CFRunLoopRef runLoop = CFRunLoopGetCurrent(); CFRunLoopTimerContext context = {0, NULL, NULL, NULL, NULL}; CFRunLoopTimerRef timer = CFRunLoopTimerCreate(kCFAllocatorDefault, 0, 1.0/UI_UPDATE_FPS, 0, 0, &osx_loop, &context); CFRunLoopAddTimer(runLoop, timer, kCFRunLoopCommonModes); rtk_osx_api_run(); #else main_loop(); #endif LV2_EXTERNAL_UI_HIDE(extui); } out: cleanup(0); #ifdef _WIN32 pthread_win32_process_detach_np(); #endif #if (defined _WIN32 && defined RTK_STATIC_INIT) glib_cleanup_static(); #endif return(rv); }
int main(int argc, char **argv) { int ds, dms, ret; double mb, rmb; struct timeval t1, t2; #ifndef C_WINDOWS struct timezone tz; sigset_t sigset; #endif struct optstruct *opts; const struct optstruct *opt; #if defined(C_WINDOWS) && defined(CL_THREAD_SAFE) if(!pthread_win32_process_attach_np()) { mprintf("!Can't start the win32 pthreads layer\n"); return 72; } #endif #if !defined(C_WINDOWS) && !defined(C_BEOS) sigemptyset(&sigset); sigaddset(&sigset, SIGXFSZ); sigprocmask(SIG_SETMASK, &sigset, NULL); #endif if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMSCAN, 0, NULL)) == NULL) { mprintf("!Can't parse command line options\n"); return 40; } if(optget(opts, "verbose")->enabled) { mprintf_verbose = 1; logg_verbose = 1; } if(optget(opts, "quiet")->enabled) mprintf_quiet = 1; if(optget(opts, "stdout")->enabled) mprintf_stdout = 1; if(optget(opts, "debug")->enabled) { #if defined(C_LINUX) /* [email protected]: create a dump if needed */ struct rlimit rlim; rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; if(setrlimit(RLIMIT_CORE, &rlim) < 0) perror("setrlimit"); #endif cl_debug(); /* enable debug messages */ } if(optget(opts, "version")->enabled) { print_version(optget(opts, "database")->strarg); optfree(opts); return 0; } if(optget(opts, "help")->enabled) { optfree(opts); help(); return 0; } if(optget(opts, "recursive")->enabled) recursion = 1; if(optget(opts, "infected")->enabled) printinfected = 1; if(optget(opts, "bell")->enabled) bell = 1; /* initialize logger */ if((opt = optget(opts, "log"))->enabled) { logg_file = opt->strarg; if(logg("#\n-------------------------------------------------------------------------------\n\n")) { mprintf("!Problem with internal logger.\n"); optfree(opts); return 62; } } else logg_file = NULL; if(actsetup(opts)) { optfree(opts); logg_close(); exit(2); } memset(&info, 0, sizeof(struct s_info)); #ifdef C_WINDOWS _set_fmode(_O_BINARY); #ifdef CL_DEBUG { _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); } #endif gettimeofday(&t1, NULL); #else gettimeofday(&t1, &tz); #endif ret = scanmanager(opts); if(!optget(opts, "no-summary")->enabled) { #ifdef C_WINDOWS gettimeofday(&t2, NULL); #else gettimeofday(&t2, &tz); #endif ds = t2.tv_sec - t1.tv_sec; dms = t2.tv_usec - t1.tv_usec; ds -= (dms < 0) ? (1):(0); dms += (dms < 0) ? (1000000):(0); logg("\n----------- SCAN SUMMARY -----------\n"); logg("Known viruses: %u\n", info.sigs); logg("Engine version: %s\n", get_version()); logg("Scanned directories: %u\n", info.dirs); logg("Scanned files: %u\n", info.files); logg("Infected files: %u\n", info.ifiles); if(notremoved) { logg("Not removed: %u\n", notremoved); } if(notmoved) { logg("Not %s: %u\n", optget(opts, "copy")->enabled ? "moved" : "copied", notmoved); } mb = info.blocks * (CL_COUNT_PRECISION / 1024) / 1024.0; logg("Data scanned: %2.2lf MB\n", mb); rmb = info.rblocks * (CL_COUNT_PRECISION / 1024) / 1024.0; logg("Data read: %2.2lf MB (ratio %.2f:1)\n", rmb, info.rblocks ? (double)info.blocks/(double)info.rblocks : 0); logg("Time: %u.%3.3u sec (%u m %u s)\n", ds, dms/1000, ds/60, ds%60); } optfree(opts); #if defined(C_WINDOWS) && defined(CL_THREAD_SAFE) if(!pthread_win32_process_detach_np()) { logg("!Can't stop the win32 pthreads layer\n"); return 72; } #endif return ret; }
/** * From the pthreads readme for mingw: * Define PTW32_STATIC_LIB when building your application. Also, your * application must call a two non-portable routines to initialise the * some state on startup and cleanup before exit. One other routine needs * to be called to cleanup after any Win32 threads have called POSIX API * routines. See README.NONPORTABLE or the html reference manual pages for * details on these routines: * * BOOL pthread_win32_process_attach_np (void); * BOOL pthread_win32_process_detach_np (void); * BOOL pthread_win32_thread_attach_np (void); // Currently a no-op * BOOL pthread_win32_thread_detach_np (void); * */ void threadpool::win32_init() { pthread_win32_process_attach_np(); pthread_win32_thread_attach_np(); }
int main(int argc, char* argv[]) { char *albumdir = 0, *musicfilename, *file_path = 0; int i, area_idx; sacd_reader_t *sacd_reader; #ifdef PTW32_STATIC_LIB pthread_win32_process_attach_np(); pthread_win32_thread_attach_np(); #endif init(); if (parse_options(argc, argv)) { setlocale(LC_ALL, ""); if (fwide(stdout, 1) < 0) { fprintf(stderr, "ERROR: Output not set to wide.\n"); } // default to 2 channel if (opts.two_channel == 0 && opts.multi_channel == 0) { opts.two_channel = 1; } sacd_reader = sacd_open(opts.input_device); if (sacd_reader) { handle = scarletbook_open(sacd_reader, 0); if (handle) { if (opts.print) { scarletbook_print(handle); } if (opts.output_dsf || opts.output_iso || opts.output_dsdiff || opts.output_dsdiff_em || opts.export_cue_sheet) { output = scarletbook_output_create(handle, handle_status_update_track_callback, handle_status_update_progress_callback, safe_fwprintf); // select the channel area area_idx = ((has_multi_channel(handle) && opts.multi_channel) || !has_two_channel(handle)) ? handle->mulch_area_idx : handle->twoch_area_idx; albumdir = (strlen(opts.output_file) > 0 ? strdup(opts.output_file) : get_album_dir(handle)); if (opts.output_iso) { uint32_t total_sectors = sacd_get_total_sectors(sacd_reader); #ifdef SECTOR_LIMIT #define FAT32_SECTOR_LIMIT 2090000 uint32_t sector_size = FAT32_SECTOR_LIMIT; uint32_t sector_offset = 0; if (total_sectors > FAT32_SECTOR_LIMIT) { musicfilename = (char *) malloc(512); file_path = make_filename(0, 0, albumdir, "iso"); for (i = 1; total_sectors != 0; i++) { sector_size = min(total_sectors, FAT32_SECTOR_LIMIT); snprintf(musicfilename, 512, "%s.%03d", file_path, i); scarletbook_output_enqueue_raw_sectors(output, sector_offset, sector_size, musicfilename, "iso"); sector_offset += sector_size; total_sectors -= sector_size; } free(musicfilename); } else #endif { get_unique_filename(&albumdir, "iso"); file_path = make_filename(0, 0, albumdir, "iso"); scarletbook_output_enqueue_raw_sectors(output, 0, total_sectors, file_path, "iso"); } } else if (opts.output_dsdiff_em) { get_unique_filename(&albumdir, "dff"); file_path = make_filename(0, 0, albumdir, "dff"); scarletbook_output_enqueue_track(output, area_idx, 0, file_path, "dsdiff_edit_master", (opts.convert_dst ? 1 : handle->area[area_idx].area_toc->frame_format != FRAME_FORMAT_DST)); } else if (opts.output_dsf || opts.output_dsdiff) { // create the output folder get_unique_dir(0, &albumdir); recursive_mkdir(albumdir, 0774); // fill the queue with items to rip for (i = 0; i < handle->area[area_idx].area_toc->track_count; i++) { if (opts.select_tracks && opts.selected_tracks[i] == 0) continue; musicfilename = get_music_filename(handle, area_idx, i, opts.output_file); if (opts.output_dsf) { file_path = make_filename(0, albumdir, musicfilename, "dsf"); scarletbook_output_enqueue_track(output, area_idx, i, file_path, "dsf", 1 /* always decode to DSD */); } else if (opts.output_dsdiff) { file_path = make_filename(0, albumdir, musicfilename, "dff"); scarletbook_output_enqueue_track(output, area_idx, i, file_path, "dsdiff", (opts.convert_dst ? 1 : handle->area[area_idx].area_toc->frame_format != FRAME_FORMAT_DST)); } free(musicfilename); free(file_path); file_path = 0; } } if (opts.export_cue_sheet) { char *cue_file_path = make_filename(0, 0, albumdir, "cue"); #ifdef _WIN32 wchar_t *wide_filename = (wchar_t *) charset_convert(cue_file_path, strlen(cue_file_path), "UTF-8", sizeof(wchar_t) == 2 ? "UCS-2-INTERNAL" : "UCS-4-INTERNAL"); #else wchar_t *wide_filename = (wchar_t *) charset_convert(cue_file_path, strlen(cue_file_path), "UTF-8", "WCHAR_T"); #endif fwprintf(stdout, L"Exporting CUE sheet [%ls]\n", wide_filename); if (!file_path) file_path = make_filename(0, 0, albumdir, "dff"); write_cue_sheet(handle, file_path, area_idx, cue_file_path); free(cue_file_path); free(wide_filename); } free(file_path); started_processing = time(0); scarletbook_output_start(output); scarletbook_output_destroy(output); fprintf(stdout, "\rWe are done.. \n"); } scarletbook_close(handle); free(albumdir); } } sacd_close(sacd_reader); #ifndef _WIN32 freopen(0, "w", stdout); #endif if (fwide(stdout, -1) >= 0) { fprintf(stderr, "ERROR: Output not set to byte oriented.\n"); } } free_lock(g_fwprintf_lock); destroy_logging(); #ifdef PTW32_STATIC_LIB pthread_win32_process_detach_np(); pthread_win32_thread_detach_np(); #endif printf("\n"); return 0; }
/**************************************************************************** * Function: ThreadPoolInit * * Description: * Initializes and starts ThreadPool. Must be called first. * And only once for ThreadPool. * Parameters: * tp - must be valid, non null, pointer to ThreadPool. * minWorkerThreads - minimum number of worker threads * thread pool will never have less than this * number of threads. * maxWorkerThreads - maximum number of worker threads * thread pool will never have more than this * number of threads. * maxIdleTime - maximum time that a worker thread will spend * idle. If a worker is idle longer than this * time and there are more than the min * number of workers running, than the * worker thread exits. * jobsPerThread - ratio of jobs to thread to try and maintain * if a job is scheduled and the number of jobs per * thread is greater than this number,and * if less than the maximum number of * workers are running then a new thread is * started to help out with efficiency. * schedPolicy - scheduling policy to try and set (OS dependent) * Returns: * 0 on success, nonzero on failure. * EAGAIN if not enough system resources to create minimum threads. * INVALID_POLICY if schedPolicy can't be set * EMAXTHREADS if minimum threads is greater than maximum threads *****************************************************************************/ int ThreadPoolInit( ThreadPool *tp, ThreadPoolAttr *attr ) { int retCode = 0; int i = 0; //printf("%s, %d\n", __FUNCTION__, __LINE__); assert( tp != NULL ); if( tp == NULL ) { return EINVAL; } #ifdef WIN32 #ifdef PTW32_STATIC_LIB pthread_win32_process_attach_np(); #endif #endif //printf("%s, %d\n", __FUNCTION__, __LINE__); retCode += ithread_mutex_init( &tp->mutex, NULL ); assert( retCode == 0 ); retCode += ithread_mutex_lock( &tp->mutex ); assert( retCode == 0 ); retCode += ithread_cond_init( &tp->condition, NULL ); assert( retCode == 0 ); retCode += ithread_cond_init( &tp->start_and_shutdown, NULL ); assert( retCode == 0 ); //printf("%s, %d\n", __FUNCTION__, __LINE__); if( retCode != 0 ) { return EAGAIN; } if( attr ) { tp->attr = ( *attr ); } else { TPAttrInit( &tp->attr ); } //printf("%s, %d, minthreads: %d\n", __FUNCTION__, __LINE__, tp->attr.minThreads); if( SetPolicyType( tp->attr.schedPolicy ) != 0 ) { ithread_mutex_unlock( &tp->mutex ); ithread_mutex_destroy( &tp->mutex ); ithread_cond_destroy( &tp->condition ); ithread_cond_destroy( &tp->start_and_shutdown ); return INVALID_POLICY; } //printf("%s, %d\n", __FUNCTION__, __LINE__); retCode += FreeListInit( &tp->jobFreeList, sizeof( ThreadPoolJob ), JOBFREELISTSIZE ); assert( retCode == 0 ); StatsInit( &tp->stats ); retCode += ListInit( &tp->highJobQ, CmpThreadPoolJob, NULL ); assert( retCode == 0 ); retCode += ListInit( &tp->medJobQ, CmpThreadPoolJob, NULL ); assert( retCode == 0 ); retCode += ListInit( &tp->lowJobQ, CmpThreadPoolJob, NULL ); assert( retCode == 0 ); //printf("%s, %d, retcode is %d\n", __FUNCTION__, __LINE__, retCode); if( retCode != 0 ) { retCode = EAGAIN; //printf("%s, %d\n", __FUNCTION__, __LINE__); } else { //printf("%s, %d\n", __FUNCTION__, __LINE__); tp->persistentJob = NULL; tp->lastJobId = 0; tp->shutdown = 0; tp->totalThreads = 0; tp->persistentThreads = 0; //printf("%s, %d\n", __FUNCTION__, __LINE__); for( i = 0; i < tp->attr.minThreads; ++i ) { if( ( retCode = CreateWorker( tp ) ) != 0 ) { //printf("%s, %d\n", __FUNCTION__, __LINE__); break; } } } //printf("%s, %d\n", __FUNCTION__, __LINE__); ithread_mutex_unlock( &tp->mutex ); if( retCode != 0 ) { // clean up if the min threads could not be created ThreadPoolShutdown( tp ); } //printf("%s, %d\n", __FUNCTION__, __LINE__); return retCode; }
void avcodec_register_all(void) { static int initialized; if (initialized) return; initialized = 1; /* hardware accelerators */ REGISTER_HWACCEL (H263_VAAPI, h263_vaapi); REGISTER_HWACCEL (H264_DXVA2, h264_dxva2); REGISTER_HWACCEL (H264_VAAPI, h264_vaapi); REGISTER_HWACCEL (MPEG1_VDPAU, mpeg1_vdpau); REGISTER_HWACCEL (MPEG2_DXVA2, mpeg2_dxva2); REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi); REGISTER_HWACCEL (MPEG2_VDPAU, mpeg2_vdpau); REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi); REGISTER_HWACCEL (VC1_DXVA2, vc1_dxva2); REGISTER_HWACCEL (VC1_VAAPI, vc1_vaapi); REGISTER_HWACCEL (WMV3_DXVA2, wmv3_dxva2); REGISTER_HWACCEL (WMV3_VAAPI, wmv3_vaapi); #ifdef PTW32_STATIC_LIB pthread_win32_process_attach_np(); pthread_win32_thread_attach_np(); atexit(detach_ptw32); #endif #ifdef PTW32_STATIC_LIB pthread_win32_process_attach_np(); pthread_win32_thread_attach_np(); atexit(detach_ptw32); #endif /* video codecs */ REGISTER_ENCODER (A64MULTI, a64multi); REGISTER_ENCODER (A64MULTI5, a64multi5); REGISTER_DECODER (AASC, aasc); REGISTER_DECODER (AMV, amv); REGISTER_DECODER (ANM, anm); REGISTER_DECODER (ANSI, ansi); REGISTER_ENCDEC (ASV1, asv1); REGISTER_ENCDEC (ASV2, asv2); REGISTER_DECODER (AURA, aura); REGISTER_DECODER (AURA2, aura2); REGISTER_DECODER (AVS, avs); REGISTER_DECODER (BETHSOFTVID, bethsoftvid); REGISTER_DECODER (BFI, bfi); REGISTER_DECODER (BINK, bink); REGISTER_ENCDEC (BMP, bmp); REGISTER_DECODER (C93, c93); REGISTER_DECODER (CAVS, cavs); REGISTER_DECODER (CDGRAPHICS, cdgraphics); REGISTER_DECODER (CINEPAK, cinepak); REGISTER_DECODER (CLJR, cljr); REGISTER_DECODER (CSCD, cscd); REGISTER_DECODER (CYUV, cyuv); REGISTER_DECODER (DFA, dfa); REGISTER_ENCDEC (DNXHD, dnxhd); REGISTER_ENCDEC (DPX, dpx); REGISTER_DECODER (DSICINVIDEO, dsicinvideo); REGISTER_ENCDEC (DVVIDEO, dvvideo); REGISTER_DECODER (DXA, dxa); REGISTER_DECODER (EACMV, eacmv); REGISTER_DECODER (EAMAD, eamad); REGISTER_DECODER (EATGQ, eatgq); REGISTER_DECODER (EATGV, eatgv); REGISTER_DECODER (EATQI, eatqi); REGISTER_DECODER (EIGHTBPS, eightbps); REGISTER_DECODER (EIGHTSVX_EXP, eightsvx_exp); REGISTER_DECODER (EIGHTSVX_FIB, eightsvx_fib); REGISTER_DECODER (ESCAPE124, escape124); REGISTER_ENCDEC (FFV1, ffv1); REGISTER_ENCDEC (FFVHUFF, ffvhuff); REGISTER_ENCDEC (FLASHSV, flashsv); REGISTER_DECODER (FLIC, flic); REGISTER_ENCDEC (FLV, flv); REGISTER_DECODER (FOURXM, fourxm); REGISTER_DECODER (FRAPS, fraps); REGISTER_DECODER (FRWU, frwu); REGISTER_ENCDEC (GIF, gif); REGISTER_ENCDEC (H261, h261); REGISTER_ENCDEC (H263, h263); REGISTER_DECODER (H263I, h263i); REGISTER_ENCODER (H263P, h263p); REGISTER_DECODER (H264, h264); REGISTER_DECODER (H264_CRYSTALHD, h264_crystalhd); REGISTER_DECODER (H264_VDPAU, h264_vdpau); REGISTER_ENCDEC (HUFFYUV, huffyuv); REGISTER_DECODER (IDCIN, idcin); REGISTER_DECODER (IFF_BYTERUN1, iff_byterun1); REGISTER_DECODER (IFF_ILBM, iff_ilbm); REGISTER_DECODER (INDEO2, indeo2); REGISTER_DECODER (INDEO3, indeo3); REGISTER_DECODER (INDEO5, indeo5); REGISTER_DECODER (INTERPLAY_VIDEO, interplay_video); REGISTER_ENCDEC (JPEGLS, jpegls); REGISTER_DECODER (JV, jv); REGISTER_DECODER (KGV1, kgv1); REGISTER_DECODER (KMVC, kmvc); REGISTER_DECODER (LAGARITH, lagarith); REGISTER_ENCODER (LJPEG, ljpeg); REGISTER_DECODER (LOCO, loco); REGISTER_DECODER (MDEC, mdec); REGISTER_DECODER (MIMIC, mimic); REGISTER_ENCDEC (MJPEG, mjpeg); REGISTER_DECODER (MJPEGB, mjpegb); REGISTER_DECODER (MMVIDEO, mmvideo); REGISTER_DECODER (MOTIONPIXELS, motionpixels); REGISTER_DECODER (MPEG_XVMC, mpeg_xvmc); REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video); REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); REGISTER_ENCDEC (MPEG4, mpeg4); REGISTER_DECODER (MPEG4_CRYSTALHD, mpeg4_crystalhd); REGISTER_DECODER (MPEG4_VDPAU, mpeg4_vdpau); REGISTER_DECODER (MPEGVIDEO, mpegvideo); REGISTER_DECODER (MPEG_VDPAU, mpeg_vdpau); REGISTER_DECODER (MPEG1_VDPAU, mpeg1_vdpau); REGISTER_DECODER (MPEG2_CRYSTALHD, mpeg2_crystalhd); REGISTER_DECODER (MSMPEG4_CRYSTALHD, msmpeg4_crystalhd); REGISTER_ENCDEC (MSMPEG4V1, msmpeg4v1); REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2); REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3); REGISTER_DECODER (MSRLE, msrle); REGISTER_DECODER (MSVIDEO1, msvideo1); REGISTER_DECODER (MSZH, mszh); REGISTER_DECODER (NUV, nuv); REGISTER_ENCDEC (PAM, pam); REGISTER_ENCDEC (PBM, pbm); REGISTER_ENCDEC (PCX, pcx); REGISTER_ENCDEC (PGM, pgm); REGISTER_ENCDEC (PGMYUV, pgmyuv); REGISTER_DECODER (PICTOR, pictor); REGISTER_ENCDEC (PNG, png); REGISTER_ENCDEC (PPM, ppm); REGISTER_DECODER (PTX, ptx); REGISTER_DECODER (QDRAW, qdraw); REGISTER_DECODER (QPEG, qpeg); REGISTER_ENCDEC (QTRLE, qtrle); REGISTER_DECODER (R10K, r10k); REGISTER_DECODER (R210, r210); REGISTER_ENCDEC (RAWVIDEO, rawvideo); REGISTER_DECODER (RL2, rl2); REGISTER_ENCDEC (ROQ, roq); REGISTER_DECODER (RPZA, rpza); REGISTER_ENCDEC (RV10, rv10); REGISTER_ENCDEC (RV20, rv20); REGISTER_DECODER (RV30, rv30); REGISTER_DECODER (RV40, rv40); REGISTER_ENCDEC (SGI, sgi); REGISTER_DECODER (SMACKER, smacker); REGISTER_DECODER (SMC, smc); REGISTER_ENCDEC (SNOW, snow); REGISTER_DECODER (SP5X, sp5x); REGISTER_DECODER (SUNRAST, sunrast); REGISTER_ENCDEC (SVQ1, svq1); REGISTER_DECODER (SVQ3, svq3); REGISTER_ENCDEC (TARGA, targa); REGISTER_DECODER (THEORA, theora); REGISTER_DECODER (THP, thp); REGISTER_DECODER (TIERTEXSEQVIDEO, tiertexseqvideo); REGISTER_ENCDEC (TIFF, tiff); REGISTER_DECODER (TMV, tmv); REGISTER_DECODER (TRUEMOTION1, truemotion1); REGISTER_DECODER (TRUEMOTION2, truemotion2); REGISTER_DECODER (TSCC, tscc); REGISTER_DECODER (TXD, txd); REGISTER_DECODER (ULTI, ulti); REGISTER_ENCDEC (V210, v210); REGISTER_DECODER (V210X, v210x); REGISTER_DECODER (VB, vb); REGISTER_DECODER (VC1, vc1); REGISTER_DECODER (VC1_CRYSTALHD, vc1_crystalhd); REGISTER_DECODER (VC1_VDPAU, vc1_vdpau); REGISTER_DECODER (VCR1, vcr1); REGISTER_DECODER (VMDVIDEO, vmdvideo); REGISTER_DECODER (VMNC, vmnc); REGISTER_DECODER (VP3, vp3); REGISTER_DECODER (VP5, vp5); REGISTER_DECODER (VP6, vp6); REGISTER_DECODER (VP6A, vp6a); REGISTER_DECODER (VP6F, vp6f); REGISTER_DECODER (VP8, vp8); REGISTER_DECODER (VQA, vqa); REGISTER_ENCDEC (WMV1, wmv1); REGISTER_ENCDEC (WMV2, wmv2); REGISTER_DECODER (WMV3, wmv3); REGISTER_DECODER (WMV3_CRYSTALHD, wmv3_crystalhd); REGISTER_DECODER (WMV3_VDPAU, wmv3_vdpau); REGISTER_DECODER (WNV1, wnv1); REGISTER_DECODER (XAN_WC3, xan_wc3); REGISTER_DECODER (XAN_WC4, xan_wc4); REGISTER_DECODER (XL, xl); REGISTER_DECODER (YOP, yop); REGISTER_ENCDEC (ZLIB, zlib); REGISTER_ENCDEC (ZMBV, zmbv); /* audio codecs */ REGISTER_ENCDEC (AAC, aac); REGISTER_DECODER (AAC_LATM, aac_latm); REGISTER_ENCDEC (AC3, ac3); REGISTER_ENCODER (AC3_FIXED, ac3_fixed); //deprecated, just for libav compatibility // REGISTER_ENCODER (AC3_FLOAT, ac3_float); dont remove dont outcomment, for configure REGISTER_ENCDEC (ALAC, alac); REGISTER_DECODER (ALS, als); REGISTER_DECODER (AMRNB, amrnb); REGISTER_DECODER (AMRWB, amrwb); REGISTER_DECODER (APE, ape); REGISTER_DECODER (ATRAC1, atrac1); REGISTER_DECODER (ATRAC3, atrac3); REGISTER_DECODER (BINKAUDIO_DCT, binkaudio_dct); REGISTER_DECODER (BINKAUDIO_RDFT, binkaudio_rdft); REGISTER_DECODER (COOK, cook); REGISTER_DECODER (DCA, dca); REGISTER_DECODER (DSICINAUDIO, dsicinaudio); REGISTER_DECODER (EAC3, eac3); REGISTER_ENCDEC (FLAC, flac); REGISTER_DECODER (GSM, gsm); REGISTER_DECODER (GSM_MS, gsm_ms); REGISTER_DECODER (IMC, imc); REGISTER_DECODER (MACE3, mace3); REGISTER_DECODER (MACE6, mace6); REGISTER_DECODER (MLP, mlp); REGISTER_DECODER (MP1, mp1); REGISTER_DECODER (MP1FLOAT, mp1float); REGISTER_ENCDEC (MP2, mp2); REGISTER_DECODER (MP2FLOAT, mp2float); REGISTER_DECODER (MP3, mp3); REGISTER_DECODER (MP3FLOAT, mp3float); REGISTER_DECODER (MP3ADU, mp3adu); REGISTER_DECODER (MP3ADUFLOAT, mp3adufloat); REGISTER_DECODER (MP3ON4, mp3on4); REGISTER_DECODER (MP3ON4FLOAT, mp3on4float); REGISTER_DECODER (MPC7, mpc7); REGISTER_DECODER (MPC8, mpc8); REGISTER_ENCDEC (NELLYMOSER, nellymoser); REGISTER_DECODER (QCELP, qcelp); REGISTER_DECODER (QDM2, qdm2); REGISTER_ENCDEC (RA_144, ra_144); REGISTER_DECODER (RA_288, ra_288); REGISTER_DECODER (SHORTEN, shorten); REGISTER_DECODER (SIPR, sipr); REGISTER_DECODER (SMACKAUD, smackaud); REGISTER_ENCDEC (SONIC, sonic); REGISTER_ENCODER (SONIC_LS, sonic_ls); REGISTER_DECODER (TRUEHD, truehd); REGISTER_DECODER (TRUESPEECH, truespeech); REGISTER_DECODER (TTA, tta); REGISTER_DECODER (TWINVQ, twinvq); REGISTER_DECODER (VMDAUDIO, vmdaudio); REGISTER_ENCDEC (VORBIS, vorbis); REGISTER_DECODER (WAVPACK, wavpack); REGISTER_DECODER (WMAPRO, wmapro); REGISTER_ENCDEC (WMAV1, wmav1); REGISTER_ENCDEC (WMAV2, wmav2); REGISTER_DECODER (WMAVOICE, wmavoice); REGISTER_DECODER (WS_SND1, ws_snd1); /* PCM codecs */ REGISTER_ENCDEC (PCM_ALAW, pcm_alaw); REGISTER_DECODER (PCM_BLURAY, pcm_bluray); REGISTER_DECODER (PCM_DVD, pcm_dvd); REGISTER_ENCDEC (PCM_F32BE, pcm_f32be); REGISTER_ENCDEC (PCM_F32LE, pcm_f32le); REGISTER_ENCDEC (PCM_F64BE, pcm_f64be); REGISTER_ENCDEC (PCM_F64LE, pcm_f64le); REGISTER_DECODER (PCM_LXF, pcm_lxf); REGISTER_ENCDEC (PCM_MULAW, pcm_mulaw); REGISTER_ENCDEC (PCM_S8, pcm_s8); REGISTER_ENCDEC (PCM_S16BE, pcm_s16be); REGISTER_ENCDEC (PCM_S16LE, pcm_s16le); REGISTER_DECODER (PCM_S16LE_PLANAR, pcm_s16le_planar); REGISTER_ENCDEC (PCM_S24BE, pcm_s24be); REGISTER_ENCDEC (PCM_S24DAUD, pcm_s24daud); REGISTER_ENCDEC (PCM_S24LE, pcm_s24le); REGISTER_ENCDEC (PCM_S32BE, pcm_s32be); REGISTER_ENCDEC (PCM_S32LE, pcm_s32le); REGISTER_ENCDEC (PCM_U8, pcm_u8); REGISTER_ENCDEC (PCM_U16BE, pcm_u16be); REGISTER_ENCDEC (PCM_U16LE, pcm_u16le); REGISTER_ENCDEC (PCM_U24BE, pcm_u24be); REGISTER_ENCDEC (PCM_U24LE, pcm_u24le); REGISTER_ENCDEC (PCM_U32BE, pcm_u32be); REGISTER_ENCDEC (PCM_U32LE, pcm_u32le); REGISTER_ENCDEC (PCM_ZORK , pcm_zork); /* DPCM codecs */ REGISTER_DECODER (INTERPLAY_DPCM, interplay_dpcm); REGISTER_ENCDEC (ROQ_DPCM, roq_dpcm); REGISTER_DECODER (SOL_DPCM, sol_dpcm); REGISTER_DECODER (XAN_DPCM, xan_dpcm); /* ADPCM codecs */ REGISTER_DECODER (ADPCM_4XM, adpcm_4xm); REGISTER_ENCDEC (ADPCM_ADX, adpcm_adx); REGISTER_DECODER (ADPCM_CT, adpcm_ct); REGISTER_DECODER (ADPCM_EA, adpcm_ea); REGISTER_DECODER (ADPCM_EA_MAXIS_XA, adpcm_ea_maxis_xa); REGISTER_DECODER (ADPCM_EA_R1, adpcm_ea_r1); REGISTER_DECODER (ADPCM_EA_R2, adpcm_ea_r2); REGISTER_DECODER (ADPCM_EA_R3, adpcm_ea_r3); REGISTER_DECODER (ADPCM_EA_XAS, adpcm_ea_xas); REGISTER_ENCDEC (ADPCM_G722, adpcm_g722); REGISTER_ENCDEC (ADPCM_G726, adpcm_g726); REGISTER_DECODER (ADPCM_IMA_AMV, adpcm_ima_amv); REGISTER_DECODER (ADPCM_IMA_DK3, adpcm_ima_dk3); REGISTER_DECODER (ADPCM_IMA_DK4, adpcm_ima_dk4); REGISTER_DECODER (ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs); REGISTER_DECODER (ADPCM_IMA_EA_SEAD, adpcm_ima_ea_sead); REGISTER_DECODER (ADPCM_IMA_ISS, adpcm_ima_iss); REGISTER_ENCDEC (ADPCM_IMA_QT, adpcm_ima_qt); REGISTER_DECODER (ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg); REGISTER_ENCDEC (ADPCM_IMA_WAV, adpcm_ima_wav); REGISTER_DECODER (ADPCM_IMA_WS, adpcm_ima_ws); REGISTER_ENCDEC (ADPCM_MS, adpcm_ms); REGISTER_DECODER (ADPCM_SBPRO_2, adpcm_sbpro_2); REGISTER_DECODER (ADPCM_SBPRO_3, adpcm_sbpro_3); REGISTER_DECODER (ADPCM_SBPRO_4, adpcm_sbpro_4); REGISTER_ENCDEC (ADPCM_SWF, adpcm_swf); REGISTER_DECODER (ADPCM_THP, adpcm_thp); REGISTER_DECODER (ADPCM_XA, adpcm_xa); REGISTER_ENCDEC (ADPCM_YAMAHA, adpcm_yamaha); /* subtitles */ REGISTER_ENCDEC (ASS, ass); REGISTER_ENCDEC (DVBSUB, dvbsub); REGISTER_ENCDEC (DVDSUB, dvdsub); REGISTER_DECODER (PGSSUB, pgssub); REGISTER_ENCDEC (SRT, srt); REGISTER_ENCDEC (XSUB, xsub); /* external libraries */ REGISTER_DECODER (LIBCELT, libcelt); REGISTER_ENCDEC (LIBDIRAC, libdirac); REGISTER_ENCODER (LIBFAAC, libfaac); REGISTER_ENCDEC (LIBGSM, libgsm); REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms); REGISTER_ENCODER (LIBMP3LAME, libmp3lame); REGISTER_ENCDEC (LIBOPENCORE_AMRNB, libopencore_amrnb); REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb); REGISTER_DECODER (LIBOPENJPEG, libopenjpeg); REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger); REGISTER_DECODER (LIBSPEEX, libspeex); REGISTER_ENCODER (LIBTHEORA, libtheora); REGISTER_ENCODER (LIBVO_AACENC, libvo_aacenc); REGISTER_ENCODER (LIBVO_AMRWBENC, libvo_amrwbenc); REGISTER_ENCODER (LIBVORBIS, libvorbis); REGISTER_ENCDEC (LIBVPX, libvpx); REGISTER_ENCODER (LIBX264, libx264); REGISTER_ENCODER (LIBXAVS, libxavs); REGISTER_ENCODER (LIBXVID, libxvid); /* parsers */ REGISTER_PARSER (AAC, aac); REGISTER_PARSER (AAC_LATM, aac_latm); REGISTER_PARSER (AC3, ac3); REGISTER_PARSER (CAVSVIDEO, cavsvideo); REGISTER_PARSER (DCA, dca); REGISTER_PARSER (DIRAC, dirac); REGISTER_PARSER (DNXHD, dnxhd); REGISTER_PARSER (DVBSUB, dvbsub); REGISTER_PARSER (DVDSUB, dvdsub); REGISTER_PARSER (FLAC, flac); REGISTER_PARSER (H261, h261); REGISTER_PARSER (H263, h263); REGISTER_PARSER (H264, h264); REGISTER_PARSER (MJPEG, mjpeg); REGISTER_PARSER (MLP, mlp); REGISTER_PARSER (MPEG4VIDEO, mpeg4video); REGISTER_PARSER (MPEGAUDIO, mpegaudio); REGISTER_PARSER (MPEGVIDEO, mpegvideo); REGISTER_PARSER (PNM, pnm); REGISTER_PARSER (VC1, vc1); REGISTER_PARSER (VP3, vp3); REGISTER_PARSER (VP8, vp8); /* bitstream filters */ REGISTER_BSF (AAC_ADTSTOASC, aac_adtstoasc); REGISTER_BSF (CHOMP, chomp); REGISTER_BSF (DUMP_EXTRADATA, dump_extradata); REGISTER_BSF (H264_MP4TOANNEXB, h264_mp4toannexb); REGISTER_BSF (IMX_DUMP_HEADER, imx_dump_header); REGISTER_BSF (MJPEG2JPEG, mjpeg2jpeg); REGISTER_BSF (MJPEGA_DUMP_HEADER, mjpega_dump_header); REGISTER_BSF (MP3_HEADER_COMPRESS, mp3_header_compress); REGISTER_BSF (MP3_HEADER_DECOMPRESS, mp3_header_decompress); REGISTER_BSF (MOV2TEXTSUB, mov2textsub); REGISTER_BSF (NOISE, noise); REGISTER_BSF (REMOVE_EXTRADATA, remove_extradata); REGISTER_BSF (TEXT2MOVSUB, text2movsub); }
int main(int argc, char **argv) { int ret; atexit(&exit_handler); TEST_WRAPPER(test_sequence2); pthread_win32_process_detach_np(); // ptw32_processTerminate(); pthread_win32_process_attach_np(); // ptw32_processInitialize(); /* fails when run down below; does not fail when run at start of run - turns out to be due to the thread reuse logic kicking in and the test code not anticipating that --> introduction of test sequence2.c above to showcase the fix for this, including augmentation of pthread_win32_process_attach_np() to prevent crashes. */ TEST_WRAPPER(test_reuse1); pthread_win32_process_detach_np(); // ptw32_processTerminate(); pthread_win32_process_attach_np(); // ptw32_processInitialize(); TEST_WRAPPER(test_sequence1); /* fails when run down below; does not fail when run at start of run - same issue as test reuse1 */ pthread_win32_process_detach_np(); // ptw32_processTerminate(); pthread_win32_process_attach_np(); // ptw32_processInitialize(); TEST_WRAPPER(test_cancel7); TEST_WRAPPER(test_cancel8); TEST_WRAPPER(test_cleanup1); TEST_WRAPPER(test_condvar7); TEST_WRAPPER(test_condvar9); TEST_WRAPPER(test_exception1); TEST_WRAPPER(test_loadfree); TEST_WRAPPER(test_sequence1); TEST_WRAPPER(test_barrier1); TEST_WRAPPER(test_barrier2); TEST_WRAPPER(test_barrier3); TEST_WRAPPER(test_barrier4); TEST_WRAPPER(test_barrier5); TEST_WRAPPER(test_barrier6); TEST_WRAPPER(test_benchtest1); TEST_WRAPPER(test_benchtest2); TEST_WRAPPER(test_benchtest3); TEST_WRAPPER(test_benchtest4); TEST_WRAPPER(test_benchtest5); TEST_WRAPPER(test_cancel1); TEST_WRAPPER(test_cancel2); TEST_WRAPPER(test_cancel3); TEST_WRAPPER(test_cancel4); TEST_WRAPPER(test_cancel5); TEST_WRAPPER(test_cancel6a); TEST_WRAPPER(test_cancel6d); // TEST_WRAPPER(test_cancel7); // TEST_WRAPPER(test_cancel8); TEST_WRAPPER(test_cancel9); TEST_WRAPPER(test_cleanup0); // TEST_WRAPPER(test_cleanup1); TEST_WRAPPER(test_cleanup2); TEST_WRAPPER(test_cleanup3); TEST_WRAPPER(test_condvar1); TEST_WRAPPER(test_condvar1_1); TEST_WRAPPER(test_condvar1_2); TEST_WRAPPER(test_condvar2); TEST_WRAPPER(test_condvar2_1); TEST_WRAPPER(test_condvar3); TEST_WRAPPER(test_condvar3_1); TEST_WRAPPER(test_condvar3_2); TEST_WRAPPER(test_condvar3_3); TEST_WRAPPER(test_condvar4); TEST_WRAPPER(test_condvar5); TEST_WRAPPER(test_condvar6); // TEST_WRAPPER(test_condvar7); TEST_WRAPPER(test_condvar8); // TEST_WRAPPER(test_condvar9); TEST_WRAPPER(test_context1); TEST_WRAPPER(test_count1); TEST_WRAPPER(test_create1); TEST_WRAPPER(test_create2); TEST_WRAPPER(test_create3); TEST_WRAPPER(test_delay1); TEST_WRAPPER(test_delay2); TEST_WRAPPER(test_detach1); TEST_WRAPPER(test_equal1); TEST_WRAPPER(test_errno1); // TEST_WRAPPER(test_exception1); TEST_WRAPPER(test_exception3); TEST_WRAPPER(test_exception3_0); TEST_WRAPPER(test_exit2); TEST_WRAPPER(test_exit3); TEST_WRAPPER(test_exit4); TEST_WRAPPER(test_exit5); TEST_WRAPPER(test_eyal1); TEST_WRAPPER(test_inherit1); TEST_WRAPPER(test_join0); TEST_WRAPPER(test_join1); TEST_WRAPPER(test_join2); TEST_WRAPPER(test_join3); TEST_WRAPPER(test_join4); TEST_WRAPPER(test_kill1); // TEST_WRAPPER(test_loadfree); TEST_WRAPPER(test_mutex1); TEST_WRAPPER(test_mutex1e); TEST_WRAPPER(test_mutex1n); TEST_WRAPPER(test_mutex1r); TEST_WRAPPER(test_mutex2); TEST_WRAPPER(test_mutex2e); TEST_WRAPPER(test_mutex2r); TEST_WRAPPER(test_mutex3); TEST_WRAPPER(test_mutex3e); TEST_WRAPPER(test_mutex3r); TEST_WRAPPER(test_mutex4); TEST_WRAPPER(test_mutex5); TEST_WRAPPER(test_mutex6); TEST_WRAPPER(test_mutex6e); TEST_WRAPPER(test_mutex6es); TEST_WRAPPER(test_mutex6n); TEST_WRAPPER(test_mutex6r); TEST_WRAPPER(test_mutex6rs); TEST_WRAPPER(test_mutex6s); TEST_WRAPPER(test_mutex7); TEST_WRAPPER(test_mutex7e); TEST_WRAPPER(test_mutex7n); TEST_WRAPPER(test_mutex7r); TEST_WRAPPER(test_mutex8); TEST_WRAPPER(test_mutex8e); TEST_WRAPPER(test_mutex8n); TEST_WRAPPER(test_mutex8r); TEST_WRAPPER(test_once1); TEST_WRAPPER(test_once2); TEST_WRAPPER(test_once3); TEST_WRAPPER(test_once4); TEST_WRAPPER_W_ARGV(test_openmp1); TEST_WRAPPER(test_priority1); TEST_WRAPPER(test_priority2); /* TEST_WRAPPER(test_reuse1); -- fails when run here; does not fail when run at start of run :-S */ TEST_WRAPPER(test_reuse2); TEST_WRAPPER(test_robust1); TEST_WRAPPER(test_robust2); TEST_WRAPPER(test_robust3); TEST_WRAPPER(test_robust4); TEST_WRAPPER(test_robust5); TEST_WRAPPER(test_rwlock1); TEST_WRAPPER(test_rwlock2); TEST_WRAPPER(test_rwlock2_t); TEST_WRAPPER(test_rwlock3); TEST_WRAPPER(test_rwlock3_t); TEST_WRAPPER(test_rwlock4); TEST_WRAPPER(test_rwlock4_t); TEST_WRAPPER(test_rwlock5); TEST_WRAPPER(test_rwlock5_t); TEST_WRAPPER(test_rwlock6); TEST_WRAPPER(test_rwlock6_t); TEST_WRAPPER(test_rwlock6_t2); TEST_WRAPPER(test_rwlock7); TEST_WRAPPER(test_rwlock8); TEST_WRAPPER(test_self1); TEST_WRAPPER(test_self2); TEST_WRAPPER(test_semaphore1); TEST_WRAPPER(test_semaphore2); TEST_WRAPPER(test_semaphore3); TEST_WRAPPER(test_semaphore4); TEST_WRAPPER(test_semaphore4t); TEST_WRAPPER(test_semaphore5); // TEST_WRAPPER(test_sequence1); TEST_WRAPPER(test_sizes); TEST_WRAPPER(test_spin1); TEST_WRAPPER(test_spin2); TEST_WRAPPER(test_spin3); TEST_WRAPPER(test_spin4); TEST_WRAPPER(test_stress1); TEST_WRAPPER(test_tryentercs); TEST_WRAPPER(test_tryentercs2); TEST_WRAPPER(test_tsd1); TEST_WRAPPER(test_tsd2); TEST_WRAPPER(test_valid1); TEST_WRAPPER(test_valid2); TEST_WRAPPER_W_ARGV(test_create3a); TEST_WRAPPER_W_ARGV(test_exception2); /* test_exit1 should be the VERY LAST test of the bunch as it will exit the application before it returns! */ TEST_WRAPPER(test_exit1); printf("Should never get here!\n"); return EXIT_FAILURE; }
int pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr) /* * ------------------------------------------------------ * DOCPUBLIC * This function initializes a condition variable. * * PARAMETERS * cond * pointer to an instance of pthread_cond_t * * attr * specifies optional creation attributes. * * * DESCRIPTION * This function initializes a condition variable. * * RESULTS * 0 successfully created condition variable, * EINVAL 'attr' is invalid, * EAGAIN insufficient resources (other than * memory, * ENOMEM insufficient memory, * EBUSY 'cond' is already initialized, * * ------------------------------------------------------ */ { int result; pthread_cond_t cv = NULL; if (cond == NULL) { return EINVAL; } #ifdef PTW32_STATIC_LIB // This allos for C++ static initializers to function without crashes. (air) pthread_win32_process_attach_np(); #endif if ((attr != NULL && *attr != NULL) && ((*attr)->pshared == PTHREAD_PROCESS_SHARED)) { /* * Creating condition variable that can be shared between * processes. */ result = ENOSYS; goto DONE; } cv = (pthread_cond_t) calloc (1, sizeof (*cv)); if (cv == NULL) { result = ENOMEM; goto DONE; } cv->nWaitersBlocked = 0; cv->nWaitersToUnblock = 0; cv->nWaitersGone = 0; if (sem_init (&(cv->semBlockLock), 0, 1) != 0) { result = errno; goto FAIL0; } if (sem_init (&(cv->semBlockQueue), 0, 0) != 0) { result = errno; goto FAIL1; } if ((result = pthread_mutex_init (&(cv->mtxUnblockLock), 0)) != 0) { goto FAIL2; } result = 0; goto DONE; /* * ------------- * Failed... * ------------- */ FAIL2: (void) sem_destroy (&(cv->semBlockQueue)); FAIL1: (void) sem_destroy (&(cv->semBlockLock)); FAIL0: (void) free (cv); cv = NULL; DONE: if (0 == result) { EnterCriticalSection (&ptw32_cond_list_lock); cv->next = NULL; cv->prev = ptw32_cond_list_tail; if (ptw32_cond_list_tail != NULL) { ptw32_cond_list_tail->next = cv; } ptw32_cond_list_tail = cv; if (ptw32_cond_list_head == NULL) { ptw32_cond_list_head = cv; } LeaveCriticalSection (&ptw32_cond_list_lock); } *cond = cv; return result; } /* pthread_cond_init */
int main(int argc, char **argv) { int ds, dms, ret; double mb; struct timeval t1, t2; #ifndef C_WINDOWS struct timezone tz; sigset_t sigset; #endif struct optstruct *opt; const char *pt; #if defined(C_WINDOWS) && defined(CL_THREAD_SAFE) if(!pthread_win32_process_attach_np()) { mprintf("!Can't start the win32 pthreads layer\n"); return 72; } #endif #if !defined(C_WINDOWS) && !defined(C_BEOS) sigemptyset(&sigset); sigaddset(&sigset, SIGXFSZ); sigprocmask(SIG_SETMASK, &sigset, NULL); #endif opt = opt_parse(argc, argv, clamscan_shortopt, clamscan_longopt, NULL, clamscan_deprecated); if(!opt) { mprintf("!Can't parse the command line\n"); return 40; } if(opt_check(opt, "verbose")) { mprintf_verbose = 1; logg_verbose = 1; } if(opt_check(opt, "quiet")) mprintf_quiet = 1; if(opt_check(opt, "stdout")) mprintf_stdout = 1; if(opt_check(opt, "debug")) { #if defined(C_LINUX) /* [email protected]: create a dump if needed */ struct rlimit rlim; rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; if(setrlimit(RLIMIT_CORE, &rlim) < 0) perror("setrlimit"); #endif cl_debug(); /* enable debug messages */ } if(opt_check(opt, "version")) { print_version(opt_arg(opt, "database")); opt_free(opt); return 0; } if(opt_check(opt, "help")) { opt_free(opt); help(); return 0; } if(opt_check(opt, "recursive")) recursion = 1; if(opt_check(opt, "infected")) printinfected = 1; if(opt_check(opt, "bell")) bell = 1; if(opt_check(opt, "tempdir")) cl_settempdir(opt_arg(opt, "tempdir"), 0); if(opt_check(opt, "leave-temps")) cl_settempdir(NULL, 1); /* initialize logger */ if(opt_check(opt, "log")) { logg_file = opt_arg(opt, "log"); if(logg("#\n-------------------------------------------------------------------------------\n\n")) { mprintf("!Problem with internal logger.\n"); opt_free(opt); return 62; } } else logg_file = NULL; /* validate some numerical options */ if(opt_check(opt, "max-scansize")) { pt = opt_arg(opt, "max-scansize"); if(!strchr(pt, 'M') && !strchr(pt, 'm')) { if(!cli_isnumber(pt)) { logg("!--max-scansize requires a natural number\n"); opt_free(opt); return 40; } } } if(opt_check(opt, "max-filesize")) { pt = opt_arg(opt, "max-filesize"); if(!strchr(pt, 'M') && !strchr(pt, 'm')) { if(!cli_isnumber(pt)) { logg("!--max-filesize requires a natural number\n"); opt_free(opt); return 40; } } } if(opt_check(opt, "max-files")) { if(!cli_isnumber(opt_arg(opt, "max-files"))) { logg("!--max-files requires a natural number\n"); opt_free(opt); return 40; } } if(opt_check(opt, "max-recursion")) { if(!cli_isnumber(opt_arg(opt, "max-recursion"))) { logg("!--max-recursion requires a natural number\n"); opt_free(opt); return 40; } } if(opt_check(opt, "max-mail-recursion")) { if(!cli_isnumber(opt_arg(opt, "max-mail-recursion"))) { logg("!--max-mail-recursion requires a natural number\n"); opt_free(opt); return 40; } } if(opt_check(opt, "max-dir-recursion")) { if(!cli_isnumber(opt_arg(opt, "max-dir-recursion"))) { logg("!--max-dir-recursion requires a natural number\n"); opt_free(opt); return 40; } } if(opt_check(opt, "max-ratio")) { if(!cli_isnumber(opt_arg(opt, "max-ratio"))) { logg("!--max-ratio requires a natural number\n"); opt_free(opt); return 40; } } memset(&info, 0, sizeof(struct s_info)); #ifdef _WIN32 SetConsoleCtrlHandler((PHANDLER_ROUTINE) clamscan_ctrl_handler, TRUE); #endif #ifdef C_WINDOWS _set_fmode(_O_BINARY); #ifdef CL_DEBUG { _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); } #endif gettimeofday(&t1, NULL); #else gettimeofday(&t1, &tz); #endif ret = scanmanager(opt); if(!opt_check(opt, "disable-summary") && !opt_check(opt, "no-summary")) { #ifdef C_WINDOWS gettimeofday(&t2, NULL); #else gettimeofday(&t2, &tz); #endif ds = t2.tv_sec - t1.tv_sec; dms = t2.tv_usec - t1.tv_usec; ds -= (dms < 0) ? (1):(0); dms += (dms < 0) ? (1000000):(0); logg("\n----------- SCAN SUMMARY -----------\n"); logg("Known viruses: %u\n", info.sigs); logg("Engine version: %s\n", get_version()); logg("Scanned directories: %u\n", info.dirs); logg("Scanned files: %u\n", info.files); logg("Infected files: %u\n", info.ifiles); if(info.notremoved) { logg("Not removed: %u\n", info.notremoved); } if(info.notmoved) { logg("Not %s: %u\n", opt_check(opt, "copy") ? "moved" : "copied", info.notmoved); } mb = info.blocks * (CL_COUNT_PRECISION / 1024) / 1024.0; logg("Data scanned: %2.2lf MB\n", mb); logg("Time: %u.%3.3u sec (%u m %u s)\n", ds, dms/1000, ds/60, ds%60); } opt_free(opt); #if defined(C_WINDOWS) && defined(CL_THREAD_SAFE) if(!pthread_win32_process_detach_np()) { logg("!Can't stop the win32 pthreads layer\n"); return 72; } #endif return ret; }
int main(int argc, char **argv) { const struct optstruct *opt; #ifndef C_WINDOWS struct passwd *user = NULL; #endif time_t currtime; const char *dbdir, *cfgfile; char *pua_cats = NULL, *pt; int ret, tcpsock = 0, localsock = 0, i, min_port, max_port; unsigned int sigs = 0; int lsockets[2], nlsockets = 0; unsigned int dboptions = 0; #ifdef C_LINUX struct stat sb; #endif #ifdef C_WINDOWS if(!pthread_win32_process_attach_np()) { mprintf("!Can't start the win32 pthreads layer\n"); return 1; } #endif if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMD, 0, NULL)) == NULL) { mprintf("!Can't parse command line options\n"); return 1; } if(optget(opts, "help")->enabled) { help(); optfree(opts); return 0; } if(optget(opts, "debug")->enabled) { #if defined(C_LINUX) /* [email protected]: create a dump if needed */ struct rlimit rlim; rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; if(setrlimit(RLIMIT_CORE, &rlim) < 0) perror("setrlimit"); #endif debug_mode = 1; } /* parse the config file */ cfgfile = optget(opts, "config-file")->strarg; pt = strdup(cfgfile); if((opts = optparse(cfgfile, 0, NULL, 1, OPT_CLAMD, 0, opts)) == NULL) { fprintf(stderr, "ERROR: Can't open/parse the config file %s\n", pt); free(pt); return 1; } free(pt); if(optget(opts, "version")->enabled) { print_version(optget(opts, "DatabaseDirectory")->strarg); optfree(opts); return 0; } umask(0); /* drop privileges */ #if (!defined(C_OS2)) && (!defined(C_WINDOWS)) if(geteuid() == 0 && (opt = optget(opts, "User"))->enabled) { if((user = getpwnam(opt->strarg)) == NULL) { fprintf(stderr, "ERROR: Can't get information about user %s.\n", opt->strarg); optfree(opts); return 1; } if(optget(opts, "AllowSupplementaryGroups")->enabled) { #ifdef HAVE_INITGROUPS if(initgroups(opt->strarg, user->pw_gid)) { fprintf(stderr, "ERROR: initgroups() failed.\n"); optfree(opts); return 1; } #else mprintf("!AllowSupplementaryGroups: initgroups() is not available, please disable AllowSupplementaryGroups in %s\n", cfgfile); optfree(opts); return 1; #endif } else { #ifdef HAVE_SETGROUPS if(setgroups(1, &user->pw_gid)) { fprintf(stderr, "ERROR: setgroups() failed.\n"); optfree(opts); return 1; } #endif } if(setgid(user->pw_gid)) { fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid); optfree(opts); return 1; } if(setuid(user->pw_uid)) { fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid); optfree(opts); return 1; } } #endif /* initialize logger */ logg_lock = !optget(opts, "LogFileUnlock")->enabled; logg_time = optget(opts, "LogTime")->enabled; logok = optget(opts, "LogClean")->enabled; logg_size = optget(opts, "LogFileMaxSize")->numarg; logg_verbose = mprintf_verbose = optget(opts, "LogVerbose")->enabled; mprintf_send_timeout = optget(opts, "SendBufTimeout")->numarg; do { /* logger initialized */ if((opt = optget(opts, "LogFile"))->enabled) { char timestr[32]; logg_file = opt->strarg; if(strlen(logg_file) < 2 || (logg_file[0] != '/' && logg_file[0] != '\\' && logg_file[1] != ':')) { fprintf(stderr, "ERROR: LogFile requires full path.\n"); ret = 1; break; } time(&currtime); if(logg("#+++ Started at %s", cli_ctime(&currtime, timestr, sizeof(timestr)))) { fprintf(stderr, "ERROR: Can't initialize the internal logger\n"); ret = 1; break; } } else logg_file = NULL; if((ret = cl_init(CL_INIT_DEFAULT))) { logg("!Can't initialize libclamav: %s\n", cl_strerror(ret)); ret = 1; break; } if(optget(opts, "Debug")->enabled) /* enable debug messages in libclamav */ { cl_debug(); logg_verbose = 2; } #if defined(USE_SYSLOG) && !defined(C_AIX) if(optget(opts, "LogSyslog")->enabled) { int fac = LOG_LOCAL6; opt = optget(opts, "LogFacility"); if((fac = logg_facility(opt->strarg)) == -1) { logg("!LogFacility: %s: No such facility.\n", opt->strarg); ret = 1; break; } openlog("clamd", LOG_PID, fac); logg_syslog = 1; } #endif #ifdef C_LINUX procdev = 0; if(stat("/proc", &sb) != -1 && !sb.st_size) procdev = sb.st_dev; #endif /* check socket type */ if(optget(opts, "TCPSocket")->enabled) tcpsock = 1; if(optget(opts, "LocalSocket")->enabled) localsock = 1; if(!tcpsock && !localsock) { logg("!Please define server type (local and/or TCP).\n"); ret = 1; break; } logg("#clamd daemon %s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")\n", get_version()); #ifndef C_WINDOWS if(user) logg("#Running as user %s (UID %u, GID %u)\n", user->pw_name, user->pw_uid, user->pw_gid); #endif if(logg_size) logg("#Log file size limited to %d bytes.\n", logg_size); else logg("#Log file size limit disabled.\n"); min_port = optget(opts, "StreamMinPort")->numarg; max_port = optget(opts, "StreamMaxPort")->numarg; if (min_port < 1024 || min_port > max_port || max_port > 65535) { logg("!Invalid StreamMinPort/StreamMaxPort: %d, %d\n", min_port, max_port); ret = 1; break; } if(!(engine = cl_engine_new())) { logg("!Can't initialize antivirus engine\n"); ret = 1; break; } /* load the database(s) */ dbdir = optget(opts, "DatabaseDirectory")->strarg; logg("#Reading databases from %s\n", dbdir); if(optget(opts, "DetectPUA")->enabled) { dboptions |= CL_DB_PUA; if((opt = optget(opts, "ExcludePUA"))->enabled) { dboptions |= CL_DB_PUA_EXCLUDE; i = 0; logg("#Excluded PUA categories:"); while(opt) { if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) { logg("!Can't allocate memory for pua_cats\n"); cl_engine_free(engine); ret = 1; break; } logg("# %s", opt->strarg); sprintf(pua_cats + i, ".%s", opt->strarg); i += strlen(opt->strarg) + 1; pua_cats[i] = 0; opt = opt->nextarg; } if (ret) break; logg("#\n"); pua_cats[i] = '.'; pua_cats[i + 1] = 0; } if((opt = optget(opts, "IncludePUA"))->enabled) { if(pua_cats) { logg("!ExcludePUA and IncludePUA cannot be used at the same time\n"); free(pua_cats); ret = 1; break; } dboptions |= CL_DB_PUA_INCLUDE; i = 0; logg("#Included PUA categories:"); while(opt) { if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) { logg("!Can't allocate memory for pua_cats\n"); ret = 1; break; } logg("# %s", opt->strarg); sprintf(pua_cats + i, ".%s", opt->strarg); i += strlen(opt->strarg) + 1; pua_cats[i] = 0; opt = opt->nextarg; } if (ret) break; logg("#\n"); pua_cats[i] = '.'; pua_cats[i + 1] = 0; } if(pua_cats) { if((ret = cl_engine_set_str(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))) { logg("!cli_engine_set_str(CL_ENGINE_PUA_CATEGORIES) failed: %s\n", cl_strerror(ret)); free(pua_cats); ret = 1; break; } free(pua_cats); } } else { logg("#Not loading PUA signatures.\n"); } /* set the temporary dir */ if((opt = optget(opts, "TemporaryDirectory"))->enabled) { if((ret = cl_engine_set_str(engine, CL_ENGINE_TMPDIR, opt->strarg))) { logg("!cli_engine_set_str(CL_ENGINE_TMPDIR) failed: %s\n", cl_strerror(ret)); ret = 1; break; } } if(optget(opts, "LeaveTemporaryFiles")->enabled) cl_engine_set_num(engine, CL_ENGINE_KEEPTMP, 1); if(optget(opts, "PhishingSignatures")->enabled) dboptions |= CL_DB_PHISHING; else logg("#Not loading phishing signatures.\n"); if(optget(opts,"PhishingScanURLs")->enabled) dboptions |= CL_DB_PHISHING_URLS; else logg("#Disabling URL based phishing detection.\n"); if(optget(opts,"DevACOnly")->enabled) { logg("#Only using the A-C matcher.\n"); cl_engine_set_num(engine, CL_ENGINE_AC_ONLY, 1); } if((opt = optget(opts, "DevACDepth"))->enabled) { cl_engine_set_num(engine, CL_ENGINE_AC_MAXDEPTH, opt->numarg); logg("#Max A-C depth set to %u\n", (unsigned int) opt->numarg); } if((ret = cl_load(dbdir, engine, &sigs, dboptions))) { logg("!%s\n", cl_strerror(ret)); ret = 1; break; } logg("#Loaded %u signatures.\n", sigs); if((ret = cl_engine_compile(engine)) != 0) { logg("!Database initialization error: %s\n", cl_strerror(ret)); ret = 1; break; } if(tcpsock) { #ifdef C_WINDOWS WSADATA wsaData; if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { logg("!Error at WSAStartup(): %d\n", WSAGetLastError()); ret = 1; break; } #endif if ((lsockets[nlsockets] = tcpserver(opts)) == -1) { ret = 1; break; } nlsockets++; } if(localsock) { if ((lsockets[nlsockets] = localserver(opts)) == -1) { ret = 1; break; } nlsockets++; } /* fork into background */ if(!optget(opts, "Foreground")->enabled) { #ifdef C_BSD /* workaround for OpenBSD bug, see https://wwws.clamav.net/bugzilla/show_bug.cgi?id=885 */ for(ret=0;ret<nlsockets;ret++) { fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) | O_NONBLOCK); } #endif if(daemonize() == -1) { logg("!daemonize() failed\n"); ret = 1; break; } #ifdef C_BSD for(ret=0;ret<nlsockets;ret++) { fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) & ~O_NONBLOCK); } #endif if(!debug_mode) if(chdir("/") == -1) logg("^Can't change current working directory to root\n"); } else foreground = 1; ret = recvloop_th(lsockets, nlsockets, engine, dboptions, opts); } while (0); logg("*Closing the main socket%s.\n", (nlsockets > 1) ? "s" : ""); for (i = 0; i < nlsockets; i++) { closesocket(lsockets[i]); } #ifndef C_OS2 if(nlsockets && localsock) { opt = optget(opts, "LocalSocket"); if(unlink(opt->strarg) == -1) logg("!Can't unlink the socket file %s\n", opt->strarg); else logg("Socket file removed.\n"); } #endif #ifdef C_WINDOWS if(tcpsock) WSACleanup(); if(!pthread_win32_process_detach_np()) { logg("!Can't stop the win32 pthreads layer\n"); logg_close(); optfree(opts); return 1; } #endif logg_close(); optfree(opts); return ret; }