static int DeinterlaceCallback(vlc_object_t *object, char const *cmd, vlc_value_t oldval, vlc_value_t newval, void *data) { VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(newval); VLC_UNUSED(data); vout_thread_t *vout = (vout_thread_t *)object; /* */ const int deinterlace_state = var_GetInteger(vout, "deinterlace"); char *mode = var_GetString(vout, "deinterlace-mode"); const bool is_needed = var_GetBool(vout, "deinterlace-needed"); if (!mode || !DeinterlaceIsModeValid(mode)) return VLC_EGENERIC; /* */ char *old = var_CreateGetString(vout, "sout-deinterlace-mode"); var_SetString(vout, "sout-deinterlace-mode", mode); msg_Dbg(vout, "deinterlace %d, mode %s, is_needed %d", deinterlace_state, mode, is_needed); if (deinterlace_state == 0 || (deinterlace_state == -1 && !is_needed)) DeinterlaceRemove(vout); else if (!DeinterlaceIsPresent(vout)) DeinterlaceAdd(vout); else if (old && strcmp(old, mode)) var_TriggerCallback(vout, "video-filter"); /* */ free(old); free(mode); return VLC_SUCCESS; }
static int DeinterlaceCallback(vlc_object_t *object, char const *cmd, vlc_value_t oldval, vlc_value_t newval, void *data) { VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(newval); VLC_UNUSED(data); vout_thread_t *vout = (vout_thread_t *)object; /* */ const int deinterlace_state = var_GetInteger(vout, "deinterlace"); char *mode = var_GetString(vout, "deinterlace-mode"); const bool is_needed = var_GetBool(vout, "deinterlace-needed"); if (!mode || !DeinterlaceIsModeValid(mode)) { free(mode); return VLC_EGENERIC; } /* */ char *old = var_CreateGetString(vout, "sout-deinterlace-mode"); var_SetString(vout, "sout-deinterlace-mode", mode); msg_Dbg(vout, "deinterlace %d, mode %s, is_needed %d", deinterlace_state, mode, is_needed); if (deinterlace_state == 0 || (deinterlace_state < 0 && !is_needed)) vout_control_PushBool(&vout->p->control, VOUT_CONTROL_CHANGE_INTERLACE, false); else vout_control_PushBool(&vout->p->control, VOUT_CONTROL_CHANGE_INTERLACE, true); /* */ free(old); free(mode); return VLC_SUCCESS; }
static void test_strings( libvlc_int_t *p_libvlc ) { int i; char *psz_tmp; for( i = 0; i < i_var_count; i++ ) var_Create( p_libvlc, psz_var_name[i], VLC_VAR_STRING ); for( i = 0; i < i_var_count; i++ ) var_SetString( p_libvlc, psz_var_name[i], psz_var_name[i] ); for( i = 0; i < i_var_count; i++ ) { psz_tmp = var_GetString( p_libvlc, psz_var_name[i] ); assert( !strcmp( psz_tmp, psz_var_name[i] ) ); free( psz_tmp ); } for( i = 0; i < i_var_count; i++ ) var_Destroy( p_libvlc, psz_var_name[i] ); /* Some more test for strings */ var_Create( p_libvlc, "bla", VLC_VAR_STRING ); assert( var_GetNonEmptyString( p_libvlc, "bla" ) == NULL ); var_SetString( p_libvlc, "bla", "" ); assert( var_GetNonEmptyString( p_libvlc, "bla" ) == NULL ); var_SetString( p_libvlc, "bla", "test" ); psz_tmp = var_GetNonEmptyString( p_libvlc, "bla" ); assert( !strcmp( psz_tmp, "test" ) ); free( psz_tmp ); var_Destroy( p_libvlc, "bla" ); }
/********************************** * Other functions **********************************/ void ExtraPanel::CheckAout() { aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf, VLC_OBJECT_AOUT, FIND_ANYWHERE); if( p_aout != NULL ) { if( p_aout != p_intf->p_sys->p_aout ) { /* We want to know if someone changes the bands */ if( var_AddCallback( p_aout, "equalizer-bands", IntfBandsCallback, this ) ) { /* The variable does not exist yet, wait */ vlc_object_release( p_aout ); return; } if( var_AddCallback( p_aout, "equalizer-preamp", IntfPreampCallback, this ) ) { vlc_object_release( p_aout ); return; } /* Ok, we have our variables, make a first update round */ p_intf->p_sys->p_aout = p_aout; f_preamp = var_GetFloat( p_aout, "equalizer-preamp" ); psz_bands = var_GetString( p_aout, "equalizer-bands" ); b_update = VLC_TRUE; } vlc_object_release( p_aout ); } }
static BOOL WINAPI DirectXOpenDDrawCallback(GUID *guid, LPTSTR desc, LPTSTR drivername, VOID *context, HMONITOR hmon) { vout_display_t *vd = context; vout_display_sys_t *sys = vd->sys; /* This callback function is called by DirectDraw once for each * available DirectDraw device. * * Returning TRUE keeps enumerating. */ if (!hmon) return TRUE; char *psz_drivername = FromT(drivername); char *psz_desc = FromT(desc); msg_Dbg(vd, "DirectXEnumCallback: %s, %s", psz_desc, psz_drivername); char *device = var_GetString(vd, "directx-device"); /* Check for forced device */ if (device && *device && !strcmp(psz_drivername, device)) { MONITORINFO monitor_info; monitor_info.cbSize = sizeof(MONITORINFO); if (GetMonitorInfoA(hmon, &monitor_info)) { RECT rect; /* Move window to the right screen */ GetWindowRect(sys->hwnd, &rect); if (!IntersectRect(&rect, &rect, &monitor_info.rcWork)) { rect.left = monitor_info.rcWork.left; rect.top = monitor_info.rcWork.top; msg_Dbg(vd, "DirectXEnumCallback: setting window " "position to %ld,%ld", rect.left, rect.top); SetWindowPos(sys->hwnd, NULL, rect.left, rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } } sys->hmonitor = hmon; } free(device); if (hmon == sys->hmonitor) { msg_Dbg(vd, "selecting %s, %s", psz_desc, psz_drivername); free(sys->display_driver); sys->display_driver = malloc(sizeof(*guid)); if (sys->display_driver) *sys->display_driver = *guid; } free(psz_drivername); free(psz_desc); return TRUE; }
/***************************************************************************** * Set the equalizer level for the specified band *****************************************************************************/ static int vlclua_equalizer_set( lua_State *L ) { int bandid = luaL_checknumber( L, 1 ); if( bandid < 0 || bandid > 9) return 0; input_thread_t *p_input = vlclua_get_input_internal( L ); if( !p_input ) return 0; audio_output_t *p_aout = input_GetAout( p_input ); vlc_object_release( p_input ); if( !p_aout ) return 0; char *psz_af = var_GetNonEmptyString( p_aout, "audio-filter" ); if( !psz_af || strstr ( psz_af, "equalizer" ) == NULL ) { free( psz_af ); vlc_object_release( p_aout ); return 0; } free( psz_af ); float level = luaL_checknumber( L, 2 ); char *bands = var_GetString( p_aout, "equalizer-bands" ); locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL); locale_t oldloc = uselocale (loc); char *b = bands; while( bandid > 0 ) { float dummy = strtof( b, &b ); (void)dummy; bandid--; } if( *b != '\0' ) *b++ = '\0'; float dummy = strtof( b, &b ); (void)dummy; char *newstr; if( asprintf( &newstr, "%s %.1f%s", bands, level, b ) != -1 ) { var_SetString( p_aout, "equalizer-bands", newstr ); free( newstr ); } if( loc != (locale_t)0 ) { uselocale (oldloc); freelocale (loc); } free( bands ); vlc_object_release( p_aout ); return 0; }
/***************************************************************************** * Open: *****************************************************************************/ static int Open( vlc_object_t *p_this ) { char* psz_tmp; sout_stream_t *p_stream = (sout_stream_t*)p_this; sout_stream_sys_t *p_sys; p_sys = calloc( 1, sizeof( sout_stream_sys_t ) ); if( !p_sys ) return VLC_ENOMEM; p_stream->p_sys = p_sys; config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options, p_stream->p_cfg ); p_sys->time_sync = var_GetBool( p_stream, SOUT_CFG_PREFIX "time-sync" ); psz_tmp = var_GetString( p_stream, SOUT_PREFIX_VIDEO "prerender-callback" ); p_sys->pf_video_prerender_callback = (void (*) (void *, uint8_t**, int))(intptr_t)atoll( psz_tmp ); free( psz_tmp ); psz_tmp = var_GetString( p_stream, SOUT_PREFIX_AUDIO "prerender-callback" ); p_sys->pf_audio_prerender_callback = (void (*) (void* , uint8_t**, unsigned int))(intptr_t)atoll( psz_tmp ); free( psz_tmp ); psz_tmp = var_GetString( p_stream, SOUT_PREFIX_VIDEO "postrender-callback" ); p_sys->pf_video_postrender_callback = (void (*) (void*, uint8_t*, int, int, int, int, mtime_t))(intptr_t)atoll( psz_tmp ); free( psz_tmp ); psz_tmp = var_GetString( p_stream, SOUT_PREFIX_AUDIO "postrender-callback" ); p_sys->pf_audio_postrender_callback = (void (*) (void*, uint8_t*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, mtime_t))(intptr_t)atoll( psz_tmp ); free( psz_tmp ); /* Setting stream out module callbacks */ p_stream->pf_add = Add; p_stream->pf_del = Del; p_stream->pf_send = Send; /* Does the module need out_pace_control? */ if ( p_sys->time_sync ) p_stream->p_sout->i_out_pace_nocontrol++; return VLC_SUCCESS; }
void VlcProc::init_equalizer() { playlist_t* pPlaylist = getIntf()->p_sys->p_playlist; audio_output_t* pAout = playlist_GetAout( pPlaylist ); if( pAout ) { if( !var_Type( pAout, "equalizer-bands" ) ) var_Create( pAout, "equalizer-bands", VLC_VAR_STRING | VLC_VAR_DOINHERIT); if( !var_Type( pAout, "equalizer-preamp" ) ) var_Create( pAout, "equalizer-preamp", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT); // New Aout (addCallbacks) var_AddCallback( pAout, "audio-filter", onGenericCallback, this ); var_AddCallback( pAout, "equalizer-bands", onEqBandsChange, this ); var_AddCallback( pAout, "equalizer-preamp", onEqPreampChange, this ); } // is equalizer enabled ? char *pFilters = pAout ? var_GetNonEmptyString( pAout, "audio-filter" ) : var_InheritString( getIntf(), "audio-filter" ); bool b_equalizer = pFilters && strstr( pFilters, "equalizer" ); free( pFilters ); SET_BOOL( m_cVarEqualizer, b_equalizer ); // retrieve initial bands char* bands = pAout ? var_GetString( pAout, "equalizer-bands" ) : var_InheritString( getIntf(), "equalizer-bands" ); if( bands ) { m_varEqBands.set( bands ); free( bands ); } // retrieve initial preamp float preamp = pAout ? var_GetFloat( pAout, "equalizer-preamp" ) : var_InheritFloat( getIntf(), "equalizer-preamp" ); EqualizerPreamp *pVarPreamp = (EqualizerPreamp*)m_cVarEqPreamp.get(); pVarPreamp->set( (preamp + 20.0) / 40.0 ); if( pAout ) vlc_object_release( pAout); }
static sout_stream_id_t *AddAudio( sout_stream_t *p_stream, es_format_t *p_fmt ) { char* psz_tmp; sout_stream_id_t* id; int i_bits_per_sample; switch( p_fmt->i_codec ) { case VLC_CODEC_U8: case VLC_CODEC_S8: i_bits_per_sample = 8; break; case VLC_CODEC_U16L: case VLC_CODEC_S16L: case VLC_CODEC_U16B: case VLC_CODEC_S16B: i_bits_per_sample = 16; break; case VLC_CODEC_U24L: case VLC_CODEC_S24L: case VLC_CODEC_U24B: case VLC_CODEC_S24B: i_bits_per_sample = 24; break; case VLC_CODEC_S32L: case VLC_CODEC_S32B: case VLC_CODEC_FL32: case VLC_CODEC_FI32: i_bits_per_sample = 32; break; case VLC_CODEC_FL64: i_bits_per_sample = 64; break; default: msg_Err( p_stream, "Smem does only support raw audio format" ); return NULL; } id = calloc( 1, sizeof( sout_stream_id_t ) ); if( !id ) return NULL; psz_tmp = var_GetString( p_stream, SOUT_PREFIX_AUDIO "data" ); id->p_data = (void *)( intptr_t )atoll( psz_tmp ); free( psz_tmp ); id->format = p_fmt; id->format->audio.i_bitspersample = i_bits_per_sample; return id; }
static sout_stream_id_t *AddVideo( sout_stream_t *p_stream, es_format_t *p_fmt ) { char* psz_tmp; sout_stream_id_t *id; int i_bits_per_pixel; switch( p_fmt->i_codec ) { case VLC_CODEC_RGB32: case VLC_CODEC_RGBA: i_bits_per_pixel = 32; break; case VLC_CODEC_I444: case VLC_CODEC_RGB24: i_bits_per_pixel = 24; break; case VLC_CODEC_RGB16: case VLC_CODEC_RGB15: case VLC_CODEC_RGB8: case VLC_CODEC_I422: i_bits_per_pixel = 16; break; case VLC_CODEC_YV12: case VLC_CODEC_I420: i_bits_per_pixel = 12; break; case VLC_CODEC_RGBP: i_bits_per_pixel = 8; break; default: i_bits_per_pixel = 0; msg_Dbg( p_stream, "non raw video format detected (%4.4s), buffers will contain compressed video", (char *)&p_fmt->i_codec ); break; } id = calloc( 1, sizeof( sout_stream_id_t ) ); if( !id ) return NULL; psz_tmp = var_GetString( p_stream, SOUT_PREFIX_VIDEO "data" ); id->p_data = (void *)( intptr_t )atoll( psz_tmp ); free( psz_tmp ); id->format = p_fmt; id->format->video.i_bits_per_pixel = i_bits_per_pixel; return id; }
/***************************************************************************** * Set the equalizer level for the specified band *****************************************************************************/ static int vlclua_equalizer_set( lua_State *L ) { int bandid = luaL_checknumber( L, 1 ); if( bandid < 0 || bandid > 9) return 0; input_thread_t *p_input = vlclua_get_input_internal( L ); if( !p_input ) return 0; int i_pos = 0 , j = 0; audio_output_t *p_aout = input_GetAout( p_input ); vlc_object_release( p_input ); if( !p_aout ) return 0; char *psz_af = var_GetNonEmptyString( p_aout, "audio-filter" ); if( !psz_af || strstr ( psz_af, "equalizer" ) == NULL ) { free( psz_af ); vlc_object_release( p_aout ); return 0; } free( psz_af ); float level = luaL_checknumber( L, 2 ); char *bands = var_GetString( p_aout, "equalizer-bands" ); char newstr[7]; while( j != bandid ) { i_pos++; if( bands[i_pos] == '.' ) { i_pos++; j++; } } if( bandid != 0 ) i_pos++; snprintf( newstr, sizeof ( newstr ) , "%6.1f", level); for( int i = 0 ; i < 6 ; i++ ) bands[i_pos+i] = newstr[i]; var_SetString( p_aout, "equalizer-bands", bands ); vlc_object_release( p_aout ); return 1; }
static sout_stream_id_t *AddVideo( sout_stream_t *p_stream, es_format_t *p_fmt ) { char* psz_tmp; sout_stream_id_t *id; int i_bits_per_pixel; switch( p_fmt->i_codec ) { case VLC_CODEC_RGB32: i_bits_per_pixel = 32; break; case VLC_CODEC_I444: case VLC_CODEC_RGB24: i_bits_per_pixel = 24; break; case VLC_CODEC_RGB16: case VLC_CODEC_RGB15: case VLC_CODEC_RGB8: case VLC_CODEC_I422: i_bits_per_pixel = 16; break; case VLC_CODEC_YV12: case VLC_CODEC_I420: i_bits_per_pixel = 12; break; case VLC_CODEC_RGBP: i_bits_per_pixel = 8; break; default: msg_Err( p_stream, "Smem does only support raw video format" ); return NULL; } id = calloc( 1, sizeof( sout_stream_id_t ) ); if( !id ) return NULL; psz_tmp = var_GetString( p_stream, SOUT_PREFIX_VIDEO "data" ); id->p_data = (void *)( intptr_t )atoll( psz_tmp ); free( psz_tmp ); id->format = p_fmt; id->format->video.i_bits_per_pixel = i_bits_per_pixel; return id; }
static sout_stream_id_t *AddAudio( sout_stream_t *p_stream, es_format_t *p_fmt ) { char* psz_tmp; sout_stream_id_t* id; int i_bits_per_sample = aout_BitsPerSample( p_fmt->i_codec ); if( !i_bits_per_sample ) { msg_Err( p_stream, "Smem does only support raw audio format" ); return NULL; } id = (sout_stream_id_t *)calloc( 1, sizeof( sout_stream_id_t ) ); // sunqueen modify if( !id ) return NULL; psz_tmp = var_GetString( p_stream, SOUT_PREFIX_AUDIO "data" ); id->p_data = (void *)( intptr_t )atoll( psz_tmp ); free( psz_tmp ); id->format = p_fmt; id->format->audio.i_bitspersample = i_bits_per_sample; return id; }
/***************************************************************************** * aout_InputDelete : delete an input ***************************************************************************** * This function must be entered with the mixer lock. *****************************************************************************/ int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input ) { AOUT_ASSERT_MIXER_LOCKED; if ( p_input->b_error ) return 0; /* XXX We need to update b_recycle_vout before calling aout_FiltersDestroyPipeline. * FIXME They can be a race condition if audio-visual is updated between * aout_InputDelete and aout_InputNew. */ char *psz_visual = var_GetString( p_aout, "audio-visual"); p_input->b_recycle_vout = psz_visual && *psz_visual; free( psz_visual ); aout_FiltersDestroyPipeline( p_aout, p_input->pp_filters, p_input->i_nb_filters ); p_input->i_nb_filters = 0; aout_FiltersDestroyPipeline( p_aout, p_input->pp_resamplers, p_input->i_nb_resamplers ); p_input->i_nb_resamplers = 0; aout_FifoDestroy( p_aout, &p_input->mixer.fifo ); return 0; }
/***************************************************************************** * HTTPOpen: Start the internal HTTP server *****************************************************************************/ int E_(HTTPOpen)( access_t *p_access ) { #define FREE( x ) \ if ( (x) != NULL ) \ free( x ); access_sys_t *p_sys = p_access->p_sys; char *psz_address, *psz_cert = NULL, *psz_key = NULL, *psz_ca = NULL, *psz_crl = NULL, *psz_user = NULL, *psz_password = NULL, *psz_acl = NULL; int i_port = 0; char psz_tmp[10]; vlc_acl_t *p_acl = NULL; httpd_file_sys_t *f; vlc_mutex_init( p_access, &p_sys->httpd_mutex ); vlc_cond_init( p_access, &p_sys->httpd_cond ); p_sys->b_request_frontend_info = p_sys->b_request_mmi_info = VLC_FALSE; p_sys->i_httpd_timeout = 0; psz_address = var_GetString( p_access, "dvb-http-host" ); if( psz_address != NULL && *psz_address ) { char *psz_parser = strchr( psz_address, ':' ); if( psz_parser ) { *psz_parser++ = '\0'; i_port = atoi( psz_parser ); } } else { if ( psz_address != NULL ) free( psz_address ); return VLC_SUCCESS; } /* determine SSL configuration */ psz_cert = var_GetString( p_access, "dvb-http-intf-cert" ); if ( psz_cert != NULL && *psz_cert ) { msg_Dbg( p_access, "enabling TLS for HTTP interface (cert file: %s)", psz_cert ); psz_key = config_GetPsz( p_access, "dvb-http-intf-key" ); psz_ca = config_GetPsz( p_access, "dvb-http-intf-ca" ); psz_crl = config_GetPsz( p_access, "dvb-http-intf-crl" ); if ( i_port <= 0 ) i_port = 8443; } else { if ( !*psz_cert ) { free( psz_cert ); psz_cert = NULL; } if ( i_port <= 0 ) i_port= 8082; } /* Ugly hack to allow to run several HTTP servers on different ports. */ sprintf( psz_tmp, ":%d", i_port + 1 ); config_PutPsz( p_access, "dvb-http-host", psz_tmp ); msg_Dbg( p_access, "base %s:%d", psz_address, i_port ); p_sys->p_httpd_host = httpd_TLSHostNew( VLC_OBJECT(p_access), psz_address, i_port, psz_cert, psz_key, psz_ca, psz_crl ); FREE( psz_cert ); FREE( psz_key ); FREE( psz_ca ); FREE( psz_crl ); if ( p_sys->p_httpd_host == NULL ) { msg_Err( p_access, "cannot listen on %s:%d", psz_address, i_port ); free( psz_address ); return VLC_EGENERIC; } free( psz_address ); psz_user = var_GetString( p_access, "dvb-http-user" ); psz_password = var_GetString( p_access, "dvb-http-password" ); psz_acl = var_GetString( p_access, "dvb-http-acl" ); if ( psz_acl != NULL ) { p_acl = ACL_Create( p_access, VLC_FALSE ); if( ACL_LoadFile( p_acl, psz_acl ) ) { ACL_Destroy( p_acl ); p_acl = NULL; } } /* Declare an index.html file. */ f = malloc( sizeof(httpd_file_sys_t) ); f->p_access = p_access; f->p_file = httpd_FileNew( p_sys->p_httpd_host, "/index.html", "text/html; charset=UTF-8", psz_user, psz_password, p_acl, HttpCallback, f ); FREE( psz_user ); FREE( psz_password ); FREE( psz_acl ); if ( p_acl != NULL ) ACL_Destroy( p_acl ); if ( f->p_file == NULL ) { free( f ); p_sys->p_httpd_file = NULL; return VLC_EGENERIC; } p_sys->p_httpd_file = f; p_sys->p_httpd_redir = httpd_RedirectNew( p_sys->p_httpd_host, "/index.html", "/" ); #undef FREE return VLC_SUCCESS; }
/***************************************************************************** * OpenEncoder: probe the encoder and return score *****************************************************************************/ static int OpenEncoder( vlc_object_t *p_this ) { encoder_t *p_enc = (encoder_t *)p_this; encoder_sys_t *p_sys = p_enc->p_sys; int i_tmp; float f_tmp; char *psz_tmp; if( p_enc->fmt_out.i_codec != VLC_CODEC_DIRAC && !p_enc->b_force ) { return VLC_EGENERIC; } if( !p_enc->fmt_in.video.i_frame_rate || !p_enc->fmt_in.video.i_frame_rate_base || !p_enc->fmt_in.video.i_height || !p_enc->fmt_in.video.i_width ) { msg_Err( p_enc, "Framerate and picture dimensions must be non-zero" ); return VLC_EGENERIC; } /* Allocate the memory needed to store the decoder's structure */ if( ( p_sys = calloc( 1, sizeof(*p_sys) ) ) == NULL ) return VLC_ENOMEM; p_enc->p_sys = p_sys; p_enc->pf_encode_video = Encode; p_enc->fmt_out.i_codec = VLC_CODEC_DIRAC; p_enc->fmt_out.i_cat = VIDEO_ES; if( ( p_sys->p_dts_fifo = block_FifoNew() ) == NULL ) { CloseEncoder( p_this ); return VLC_ENOMEM; } ResetPTStlb( p_enc ); /* guess the video format based upon number of lines and picture height */ int i = 0; VideoFormat guessed_video_fmt = VIDEO_FORMAT_CUSTOM; /* Pick the dirac_video_format in this order of preference: * 1. an exact match in frame height and an approximate fps match * 2. the previous preset with a smaller number of lines. */ do { if( dirac_format_guess[i].i_height > p_enc->fmt_in.video.i_height ) { guessed_video_fmt = dirac_format_guess[i-1].i_vf; break; } if( dirac_format_guess[i].i_height != p_enc->fmt_in.video.i_height ) continue; int src_fps = p_enc->fmt_in.video.i_frame_rate / p_enc->fmt_in.video.i_frame_rate_base; int delta_fps = abs( dirac_format_guess[i].i_approx_fps - src_fps ); if( delta_fps > 2 ) continue; guessed_video_fmt = dirac_format_guess[i].i_vf; break; } while( dirac_format_guess[++i].i_height ); dirac_encoder_context_init( &p_sys->ctx, guessed_video_fmt ); /* constants set from the input video format */ p_sys->ctx.src_params.width = p_enc->fmt_in.video.i_width; p_sys->ctx.src_params.height = p_enc->fmt_in.video.i_height; p_sys->ctx.src_params.frame_rate.numerator = p_enc->fmt_in.video.i_frame_rate; p_sys->ctx.src_params.frame_rate.denominator = p_enc->fmt_in.video.i_frame_rate_base; unsigned u_asr_num, u_asr_den; vlc_ureduce( &u_asr_num, &u_asr_den, p_enc->fmt_in.video.i_sar_num, p_enc->fmt_in.video.i_sar_den, 0 ); p_sys->ctx.src_params.pix_asr.numerator = u_asr_num; p_sys->ctx.src_params.pix_asr.denominator = u_asr_den; config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg ); psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_CHROMAFMT ); if( !psz_tmp ) goto error; else if( !strcmp( psz_tmp, "420" ) ) { p_enc->fmt_in.i_codec = VLC_CODEC_I420; p_enc->fmt_in.video.i_bits_per_pixel = 12; p_sys->ctx.src_params.chroma = format420; p_sys->i_buffer_in = p_enc->fmt_in.video.i_width * p_enc->fmt_in.video.i_height * 3 / 2; } else if( !strcmp( psz_tmp, "422" ) ) { p_enc->fmt_in.i_codec = VLC_CODEC_I422; p_enc->fmt_in.video.i_bits_per_pixel = 16; p_sys->ctx.src_params.chroma = format422; p_sys->i_buffer_in = p_enc->fmt_in.video.i_width * p_enc->fmt_in.video.i_height * 2; } else if( !strcmp( psz_tmp, "444" ) ) { p_enc->fmt_in.i_codec = VLC_CODEC_I444; p_enc->fmt_in.video.i_bits_per_pixel = 24; p_sys->ctx.src_params.chroma = format444; p_sys->i_buffer_in = p_enc->fmt_in.video.i_width * p_enc->fmt_in.video.i_height * 3; } else { msg_Err( p_enc, "Invalid chroma format: %s", psz_tmp ); free( psz_tmp ); goto error; } free( psz_tmp ); p_sys->ctx.enc_params.qf = var_GetFloat( p_enc, ENC_CFG_PREFIX ENC_QUALITY_FACTOR ); /* use bitrate from sout-transcode-vb in kbps */ p_sys->ctx.enc_params.trate = p_enc->fmt_out.i_bitrate / 1000; i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_TARGETRATE ); if( i_tmp > -1 ) p_sys->ctx.enc_params.trate = i_tmp; p_enc->fmt_out.i_bitrate = p_sys->ctx.enc_params.trate * 1000; p_sys->ctx.enc_params.lossless = var_GetBool( p_enc, ENC_CFG_PREFIX ENC_LOSSLESS ); psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_PREFILTER ); if( !psz_tmp ) goto error; else if( !strcmp( psz_tmp, "none" ) ) { p_sys->ctx.enc_params.prefilter = NO_PF; } else if( !strcmp( psz_tmp, "cwm" ) ) { p_sys->ctx.enc_params.prefilter = CWM; } else if( !strcmp( psz_tmp, "rectlp" ) ) { p_sys->ctx.enc_params.prefilter = RECTLP; } else if( !strcmp( psz_tmp, "diaglp" ) ) { p_sys->ctx.enc_params.prefilter = DIAGLP; } else { msg_Err( p_enc, "Invalid prefilter: %s", psz_tmp ); free( psz_tmp ); goto error; } free( psz_tmp ); p_sys->ctx.enc_params.prefilter_strength = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_PREFILTER_STRENGTH ); i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_L1SEP ); if( i_tmp > -1 ) p_sys->ctx.enc_params.L1_sep = i_tmp; i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_L1NUM ); if( i_tmp > -1 ) p_sys->ctx.enc_params.num_L1 = i_tmp; psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_CODINGMODE ); if( !psz_tmp ) goto error; else if( !strcmp( psz_tmp, "auto" ) ) { p_sys->b_auto_field_coding = true; } else if( !strcmp( psz_tmp, "progressive" ) ) { p_sys->b_auto_field_coding = false; p_sys->ctx.enc_params.picture_coding_mode = 0; } else if( !strcmp( psz_tmp, "field" ) ) { p_sys->b_auto_field_coding = false; p_sys->ctx.enc_params.picture_coding_mode = 1; } else { msg_Err( p_enc, "Invalid codingmode: %s", psz_tmp ); free( psz_tmp ); goto error; } free( psz_tmp ); psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_MVPREC ); if( !psz_tmp ) goto error; else if( !strcmp( psz_tmp, "1" ) ) { p_sys->ctx.enc_params.mv_precision = MV_PRECISION_PIXEL; } else if( !strcmp( psz_tmp, "1/2" ) ) { p_sys->ctx.enc_params.mv_precision = MV_PRECISION_HALF_PIXEL; } else if( !strcmp( psz_tmp, "1/4" ) ) { p_sys->ctx.enc_params.mv_precision = MV_PRECISION_QUARTER_PIXEL; } else if( !strcmp( psz_tmp, "1/8" ) ) { p_sys->ctx.enc_params.mv_precision = MV_PRECISION_EIGHTH_PIXEL; } else { msg_Err( p_enc, "Invalid mv-prec: %s", psz_tmp ); free( psz_tmp ); goto error; } free( psz_tmp ); /* * {x,y}b{len,sep} must be multiples of 4 */ i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MCBLK_WIDTH ); if( i_tmp > -1 ) p_sys->ctx.enc_params.xbsep = i_tmp / 4 * 4; i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MCBLK_HEIGHT ); if( i_tmp > -1 ) p_sys->ctx.enc_params.ybsep = i_tmp / 4 * 4; i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MCBLK_OVERLAP ); if( i_tmp > -1 ) { p_sys->ctx.enc_params.xblen = p_sys->ctx.enc_params.xbsep * (100 + i_tmp) / 400 * 4; p_sys->ctx.enc_params.yblen = p_sys->ctx.enc_params.ybsep * (100 + i_tmp) / 400 * 4; } /* * {x,y}blen >= {x,y}bsep * {x,y}blen <= 2* {x,y}bsep */ i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MCBLK_XBLEN ); if( i_tmp > -1 ) { int xblen = __MAX( i_tmp, p_sys->ctx.enc_params.xbsep ); xblen = __MIN( xblen, 2 * p_sys->ctx.enc_params.xbsep ); p_sys->ctx.enc_params.xblen = xblen; } i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MCBLK_YBLEN ); if( i_tmp > -1 ) { int yblen = __MAX( i_tmp, p_sys->ctx.enc_params.ybsep ); yblen = __MIN( yblen, 2 * p_sys->ctx.enc_params.ybsep ); p_sys->ctx.enc_params.yblen = yblen; } psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_ME_SIMPLESEARCH ); if( !psz_tmp ) goto error; if( *psz_tmp != '\0' ) { /* of the form [0-9]+:[0-9]+ */ char *psz_start = psz_tmp; char *psz_end = psz_tmp; p_sys->ctx.enc_params.x_range_me = strtol(psz_start, &psz_end, 10); if( *psz_end != ':' || psz_end == psz_start ) { msg_Err( p_enc, "Invalid simple search range: %s", psz_tmp ); free( psz_tmp ); goto error; } psz_start = ++psz_end; p_sys->ctx.enc_params.y_range_me = strtol(psz_start, &psz_end, 10); if( *psz_end != '\0' || psz_end == psz_start ) { msg_Err( p_enc, "Invalid simple search range: %s", psz_tmp ); free( psz_tmp ); goto error; } if( p_sys->ctx.enc_params.x_range_me < 0 || p_sys->ctx.enc_params.y_range_me < 0 ) { msg_Err( p_enc, "Invalid negative simple search range: %s", psz_tmp ); free( psz_tmp ); goto error; } p_sys->ctx.enc_params.full_search = 1; } free( psz_tmp ); #if DIRAC_RESEARCH_VERSION_ATLEAST(1,0,1) p_sys->ctx.enc_params.combined_me = var_GetBool( p_enc, ENC_CFG_PREFIX ENC_ME_COMBINED ); #endif i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_DWTINTRA ); if( i_tmp > -1 ) p_sys->ctx.enc_params.intra_wlt_filter = i_tmp; i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_DWTINTER ); if( i_tmp > -1 ) p_sys->ctx.enc_params.inter_wlt_filter = i_tmp; i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_DWTDEPTH ); if( i_tmp > -1 ) p_sys->ctx.enc_params.wlt_depth = i_tmp; i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MULTIQUANT ); if( i_tmp > -1 ) p_sys->ctx.enc_params.multi_quants = i_tmp; i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_SPARTITION ); if( i_tmp > -1 ) p_sys->ctx.enc_params.spatial_partition = i_tmp; p_sys->ctx.enc_params.using_ac = !var_GetBool( p_enc, ENC_CFG_PREFIX ENC_NOAC ); f_tmp = var_GetFloat( p_enc, ENC_CFG_PREFIX ENC_CPD ); if( f_tmp > -1 ) p_sys->ctx.enc_params.cpd = f_tmp; /* Allocate the buffer for inputing frames into the encoder */ if( ( p_sys->p_buffer_in = malloc( p_sys->i_buffer_in ) ) == NULL ) { CloseEncoder( p_this ); return VLC_ENOMEM; } /* Set up output buffer */ /* Unfortunately it isn't possible to determine if the buffer * is too small (and then reallocate it) */ p_sys->i_buffer_out = 4096 + p_sys->i_buffer_in; if( ( p_sys->p_buffer_out = malloc( p_sys->i_buffer_out ) ) == NULL ) { CloseEncoder( p_this ); return VLC_ENOMEM; } return VLC_SUCCESS; error: CloseEncoder( p_this ); return VLC_EGENERIC; }
static int DirectXOpenDDraw(vout_display_t *vd) { vout_display_sys_t *sys = vd->sys; HRESULT hr; /* */ HRESULT (WINAPI *OurDirectDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *); OurDirectDrawCreate = (void *)GetProcAddress(sys->hddraw_dll, _T("DirectDrawCreate")); if (!OurDirectDrawCreate) { msg_Err(vd, "DirectXInitDDraw failed GetProcAddress"); return VLC_EGENERIC; } /* */ HRESULT (WINAPI *OurDirectDrawEnumerateEx)(LPDDENUMCALLBACKEXA, LPVOID, DWORD); OurDirectDrawEnumerateEx = (void *)GetProcAddress(sys->hddraw_dll, _T("DirectDrawEnumerateExA")); if (OurDirectDrawEnumerateEx) { char *device = var_GetString(vd, "directx-device"); if (device) { msg_Dbg(vd, "directx-device: %s", device); free(device); } sys->hmonitor = MonitorFromWindow(sys->hwnd, MONITOR_DEFAULTTONEAREST); /* Enumerate displays */ OurDirectDrawEnumerateEx(DirectXOpenDDrawCallback, vd, DDENUM_ATTACHEDSECONDARYDEVICES); } /* Initialize DirectDraw now */ LPDIRECTDRAW ddobject; hr = OurDirectDrawCreate(sys->display_driver, &ddobject, NULL); if (hr != DD_OK) { msg_Err(vd, "DirectXInitDDraw cannot initialize DDraw"); return VLC_EGENERIC; } /* Get the IDirectDraw2 interface */ hr = IDirectDraw_QueryInterface(ddobject, &IID_IDirectDraw2, &sys->ddobject); /* Release the unused interface */ IDirectDraw_Release(ddobject); if (hr != DD_OK) { msg_Err(vd, "cannot get IDirectDraw2 interface"); sys->ddobject = NULL; return VLC_EGENERIC; } /* Set DirectDraw Cooperative level, ie what control we want over Windows * display */ hr = IDirectDraw2_SetCooperativeLevel(sys->ddobject, NULL, DDSCL_NORMAL); if (hr != DD_OK) { msg_Err(vd, "cannot set direct draw cooperative level"); return VLC_EGENERIC; } /* Get the size of the current display device */ if (sys->hmonitor) { MONITORINFO monitor_info; monitor_info.cbSize = sizeof(MONITORINFO); GetMonitorInfoA(vd->sys->hmonitor, &monitor_info); sys->rect_display = monitor_info.rcMonitor; } else { sys->rect_display.left = 0; sys->rect_display.top = 0; sys->rect_display.right = GetSystemMetrics(SM_CXSCREEN); sys->rect_display.bottom = GetSystemMetrics(SM_CYSCREEN); } msg_Dbg(vd, "screen dimensions (%lix%li,%lix%li)", sys->rect_display.left, sys->rect_display.top, sys->rect_display.right, sys->rect_display.bottom); /* Probe the capabilities of the hardware */ DirectXGetDDrawCaps(vd); return VLC_SUCCESS; }
/***************************************************************************** * 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; }
static int OpenEncoder( vlc_object_t *p_this ) { encoder_t *p_enc = (encoder_t *)p_this; encoder_sys_t *p_sys; ogg_packet header; int status; if( p_enc->fmt_out.i_codec != VLC_CODEC_DAALA && !p_enc->b_force ) { return VLC_EGENERIC; } /* Allocate the memory needed to store the encoder's structure */ p_sys = malloc( sizeof( encoder_sys_t ) ); if( !p_sys ) return VLC_ENOMEM; p_enc->p_sys = p_sys; p_enc->pf_encode_video = Encode; p_enc->fmt_in.i_codec = VLC_CODEC_I420; p_enc->fmt_out.i_codec = VLC_CODEC_DAALA; config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg ); char *psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX "chroma-fmt" ); uint32_t i_codec; if( !psz_tmp ) { free(p_sys); return VLC_ENOMEM; } else { if( !strcmp( psz_tmp, "420" ) ) { i_codec = VLC_CODEC_I420; } else if( !strcmp( psz_tmp, "444" ) ) { i_codec = VLC_CODEC_I444; } else { msg_Err( p_enc, "Invalid chroma format: %s", psz_tmp ); free( psz_tmp ); free( p_sys ); return VLC_EGENERIC; } free( psz_tmp ); p_enc->fmt_in.i_codec = i_codec; /* update bits_per_pixel */ video_format_Setup(&p_enc->fmt_in.video, i_codec, p_enc->fmt_in.video.i_width, p_enc->fmt_in.video.i_height, p_enc->fmt_in.video.i_visible_width, p_enc->fmt_in.video.i_visible_height, p_enc->fmt_in.video.i_sar_num, p_enc->fmt_in.video.i_sar_den); } daala_info_init( &p_sys->di ); p_sys->di.pic_width = p_enc->fmt_in.video.i_visible_width; p_sys->di.pic_height = p_enc->fmt_in.video.i_visible_height; p_sys->di.nplanes = 3; for (int i = 0; i < p_sys->di.nplanes; i++) { p_sys->di.plane_info[i].xdec = i > 0 && i_codec != VLC_CODEC_I444; p_sys->di.plane_info[i].ydec = i_codec == VLC_CODEC_I420 ? p_sys->di.plane_info[i].xdec : 0; } p_sys->di.frame_duration = 1; if( !p_enc->fmt_in.video.i_frame_rate || !p_enc->fmt_in.video.i_frame_rate_base ) { p_sys->di.timebase_numerator = 25; p_sys->di.timebase_denominator = 1; } else { p_sys->di.timebase_numerator = p_enc->fmt_in.video.i_frame_rate; p_sys->di.timebase_denominator = p_enc->fmt_in.video.i_frame_rate_base; } if( p_enc->fmt_in.video.i_sar_num > 0 && p_enc->fmt_in.video.i_sar_den > 0 ) { unsigned i_dst_num, i_dst_den; vlc_ureduce( &i_dst_num, &i_dst_den, p_enc->fmt_in.video.i_sar_num, p_enc->fmt_in.video.i_sar_den, 0 ); p_sys->di.pixel_aspect_numerator = i_dst_num; p_sys->di.pixel_aspect_denominator = i_dst_den; } else { p_sys->di.pixel_aspect_numerator = 4; p_sys->di.pixel_aspect_denominator = 3; } p_sys->di.keyframe_rate = var_GetInteger( p_enc, ENC_CFG_PREFIX "keyint" ); daala_enc_ctx *dcx; p_sys->dcx = dcx = daala_encode_create( &p_sys->di ); if( !dcx ) { free( p_sys ); return VLC_ENOMEM; } daala_comment_init( &p_sys->dc ); int i_quality = var_GetInteger( p_enc, ENC_CFG_PREFIX "quality" ); daala_encode_ctl( dcx, OD_SET_QUANT, &i_quality, sizeof(i_quality) ); /* Create and store headers */ while( ( status = daala_encode_flush_header( dcx, &p_sys->dc, &header ) ) ) { if ( status < 0 ) { CloseEncoder( p_this ); return VLC_EGENERIC; } if( xiph_AppendHeaders( &p_enc->fmt_out.i_extra, &p_enc->fmt_out.p_extra, header.bytes, header.packet ) ) { p_enc->fmt_out.i_extra = 0; p_enc->fmt_out.p_extra = NULL; } } return VLC_SUCCESS; }
/* This function will add or remove a a module from a string list (colon * separated). It will return true if there is a modification * In case p_aout is NULL, we will use configuration instead of variable */ bool aout_ChangeFilterString( vlc_object_t *p_obj, aout_instance_t *p_aout, const char *psz_variable, const char *psz_name, bool b_add ) { if( *psz_name == '\0' ) return false; char *psz_list; if( p_aout ) { psz_list = var_GetString( p_aout, psz_variable ); } else { psz_list = var_CreateGetString( p_obj->p_libvlc, psz_variable ); var_Destroy( p_obj->p_libvlc, psz_variable ); } /* Split the string into an array of filters */ int i_count = 1; for( char *p = psz_list; p && *p; p++ ) i_count += *p == ':'; i_count += b_add; const char **ppsz_filter = calloc( i_count, sizeof(*ppsz_filter) ); if( !ppsz_filter ) { free( psz_list ); return false; } bool b_present = false; i_count = 0; for( char *p = psz_list; p && *p; ) { char *psz_end = strchr(p, ':'); if( psz_end ) *psz_end++ = '\0'; else psz_end = p + strlen(p); if( *p ) { b_present |= !strcmp( p, psz_name ); ppsz_filter[i_count++] = p; } p = psz_end; } if( b_present == b_add ) { free( ppsz_filter ); free( psz_list ); return false; } if( b_add ) { int i_order = FilterOrder( psz_name ); int i; for( i = 0; i < i_count; i++ ) { if( FilterOrder( ppsz_filter[i] ) > i_order ) break; } if( i < i_count ) memmove( &ppsz_filter[i+1], &ppsz_filter[i], (i_count - i) * sizeof(*ppsz_filter) ); ppsz_filter[i] = psz_name; i_count++; } else { for( int i = 0; i < i_count; i++ ) { if( !strcmp( ppsz_filter[i], psz_name ) ) ppsz_filter[i] = ""; } } size_t i_length = 0; for( int i = 0; i < i_count; i++ ) i_length += 1 + strlen( ppsz_filter[i] ); char *psz_new = malloc( i_length + 1 ); *psz_new = '\0'; for( int i = 0; i < i_count; i++ ) { if( *ppsz_filter[i] == '\0' ) continue; if( *psz_new ) strcat( psz_new, ":" ); strcat( psz_new, ppsz_filter[i] ); } free( ppsz_filter ); free( psz_list ); if( p_aout ) var_SetString( p_aout, psz_variable, psz_new ); else config_PutPsz( p_obj, psz_variable, psz_new ); free( psz_new ); return true; }
/***************************************************************************** * Open: initialize and create stuff *****************************************************************************/ int Open_LuaSD( vlc_object_t *p_this ) { services_discovery_t *p_sd = ( services_discovery_t * )p_this; services_discovery_sys_t *p_sys; lua_State *L = NULL; char *psz_name; if( !( p_sys = malloc( sizeof( services_discovery_sys_t ) ) ) ) return VLC_ENOMEM; if( !strcmp( p_sd->psz_name, "lua" ) || !strcmp( p_sd->psz_name, "luasd" ) ) { // We want to load the module name "lua" // This module can be used to load lua script not registered // as builtin lua SD modules. config_ChainParse( p_sd, "lua-", ppsz_sd_options, p_sd->p_cfg ); psz_name = var_GetString( p_sd, "lua-sd" ); } else { // We are loading a builtin lua sd module. psz_name = strdup(p_sd->psz_name); } p_sd->p_sys = p_sys; p_sd->pf_control = Control; p_sys->psz_filename = vlclua_find_file( "sd", psz_name ); if( !p_sys->psz_filename ) { msg_Err( p_sd, "Couldn't find lua services discovery script \"%s\".", psz_name ); free( psz_name ); goto error; } free( psz_name ); L = luaL_newstate(); if( !L ) { msg_Err( p_sd, "Could not create new Lua State" ); goto error; } vlclua_set_this( L, p_sd ); luaL_openlibs( L ); luaL_register_namespace( L, "vlc", p_reg ); luaopen_input( L ); luaopen_msg( L ); luaopen_object( L ); luaopen_sd_sd( L ); luaopen_strings( L ); luaopen_variables( L ); luaopen_stream( L ); luaopen_gettext( L ); luaopen_xml( L ); lua_pop( L, 1 ); if( vlclua_add_modules_path( L, p_sys->psz_filename ) ) { msg_Warn( p_sd, "Error while setting the module search path for %s", p_sys->psz_filename ); goto error; } if( vlclua_dofile( VLC_OBJECT(p_sd), L, p_sys->psz_filename ) ) { msg_Err( p_sd, "Error loading script %s: %s", p_sys->psz_filename, lua_tostring( L, lua_gettop( L ) ) ); lua_pop( L, 1 ); goto error; } // No strdup(), just don't remove the string from the lua stack p_sd->description = vlclua_sd_description( VLC_OBJECT(p_sd), L, p_sys->psz_filename ); if( p_sd->description == NULL ) p_sd->description = p_sd->psz_name; p_sys->L = L; vlc_mutex_init( &p_sys->lock ); vlc_cond_init( &p_sys->cond ); TAB_INIT( p_sys->i_query, p_sys->ppsz_query ); if( vlc_clone( &p_sys->thread, Run, p_sd, VLC_THREAD_PRIORITY_LOW ) ) { TAB_CLEAN( p_sys->i_query, p_sys->ppsz_query ); vlc_cond_destroy( &p_sys->cond ); vlc_mutex_destroy( &p_sys->lock ); goto error; } return VLC_SUCCESS; error: if( L ) lua_close( L ); free( p_sys->psz_filename ); free( p_sys ); return VLC_EGENERIC; }
/***************************************************************************** * aout_InputNew : allocate a new input and rework the filter pipeline *****************************************************************************/ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input, const aout_request_vout_t *p_request_vout ) { audio_sample_format_t chain_input_format; audio_sample_format_t chain_output_format; vlc_value_t val, text; char *psz_filters, *psz_visual, *psz_scaletempo; int i_visual; aout_FormatPrint( p_aout, "input", &p_input->input ); p_input->i_nb_resamplers = p_input->i_nb_filters = 0; /* Prepare FIFO. */ aout_FifoInit( p_aout, &p_input->mixer.fifo, p_aout->mixer_format.i_rate ); p_input->mixer.begin = NULL; /* */ if( p_request_vout ) { p_input->request_vout = *p_request_vout; } else { p_input->request_vout.pf_request_vout = RequestVout; p_input->request_vout.p_private = p_aout; } /* Prepare format structure */ chain_input_format = p_input->input; chain_output_format = p_aout->mixer_format; chain_output_format.i_rate = p_input->input.i_rate; aout_FormatPrepare( &chain_output_format ); /* Now add user filters */ if( var_Type( p_aout, "visual" ) == 0 ) { var_Create( p_aout, "visual", VLC_VAR_STRING | VLC_VAR_HASCHOICE ); text.psz_string = _("Visualizations"); var_Change( p_aout, "visual", VLC_VAR_SETTEXT, &text, NULL ); val.psz_string = (char*)""; text.psz_string = _("Disable"); var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = (char*)"spectrometer"; text.psz_string = _("Spectrometer"); var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = (char*)"scope"; text.psz_string = _("Scope"); var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = (char*)"spectrum"; text.psz_string = _("Spectrum"); var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = (char*)"vuMeter"; text.psz_string = _("Vu meter"); var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text ); /* Look for goom plugin */ if( module_exists( "goom" ) ) { val.psz_string = (char*)"goom"; text.psz_string = (char*)"Goom"; var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text ); } /* Look for libprojectM plugin */ if( module_exists( "projectm" ) ) { val.psz_string = (char*)"projectm"; text.psz_string = (char*)"projectM"; var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text ); } if( var_Get( p_aout, "effect-list", &val ) == VLC_SUCCESS ) { var_SetString( p_aout, "visual", val.psz_string ); free( val.psz_string ); } var_AddCallback( p_aout, "visual", VisualizationCallback, NULL ); } if( var_Type( p_aout, "equalizer" ) == 0 ) { module_config_t *p_config; int i; p_config = config_FindConfig( VLC_OBJECT(p_aout), "equalizer-preset" ); if( p_config && p_config->i_list ) { var_Create( p_aout, "equalizer", VLC_VAR_STRING | VLC_VAR_HASCHOICE ); text.psz_string = _("Equalizer"); var_Change( p_aout, "equalizer", VLC_VAR_SETTEXT, &text, NULL ); val.psz_string = (char*)""; text.psz_string = _("Disable"); var_Change( p_aout, "equalizer", VLC_VAR_ADDCHOICE, &val, &text ); for( i = 0; i < p_config->i_list; i++ ) { val.psz_string = (char *)p_config->ppsz_list[i]; text.psz_string = (char *)p_config->ppsz_list_text[i]; var_Change( p_aout, "equalizer", VLC_VAR_ADDCHOICE, &val, &text ); } var_AddCallback( p_aout, "equalizer", EqualizerCallback, NULL ); } } if( var_Type( p_aout, "audio-filter" ) == 0 ) { var_Create( p_aout, "audio-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); text.psz_string = _("Audio filters"); var_Change( p_aout, "audio-filter", VLC_VAR_SETTEXT, &text, NULL ); } if( var_Type( p_aout, "audio-visual" ) == 0 ) { var_Create( p_aout, "audio-visual", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); text.psz_string = _("Audio visualizations"); var_Change( p_aout, "audio-visual", VLC_VAR_SETTEXT, &text, NULL ); } if( var_Type( p_aout, "audio-replay-gain-mode" ) == 0 ) { module_config_t *p_config; int i; p_config = config_FindConfig( VLC_OBJECT(p_aout), "audio-replay-gain-mode" ); if( p_config && p_config->i_list ) { var_Create( p_aout, "audio-replay-gain-mode", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); text.psz_string = _("Replay gain"); var_Change( p_aout, "audio-replay-gain-mode", VLC_VAR_SETTEXT, &text, NULL ); for( i = 0; i < p_config->i_list; i++ ) { val.psz_string = (char *)p_config->ppsz_list[i]; text.psz_string = (char *)p_config->ppsz_list_text[i]; var_Change( p_aout, "audio-replay-gain-mode", VLC_VAR_ADDCHOICE, &val, &text ); } var_AddCallback( p_aout, "audio-replay-gain-mode", ReplayGainCallback, NULL ); } } if( var_Type( p_aout, "audio-replay-gain-preamp" ) == 0 ) { var_Create( p_aout, "audio-replay-gain-preamp", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); } if( var_Type( p_aout, "audio-replay-gain-default" ) == 0 ) { var_Create( p_aout, "audio-replay-gain-default", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); } if( var_Type( p_aout, "audio-replay-gain-peak-protection" ) == 0 ) { var_Create( p_aout, "audio-replay-gain-peak-protection", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); } if( var_Type( p_aout, "audio-time-stretch" ) == 0 ) { var_Create( p_aout, "audio-time-stretch", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); } psz_filters = var_GetString( p_aout, "audio-filter" ); psz_visual = var_GetString( p_aout, "audio-visual"); psz_scaletempo = var_GetBool( p_aout, "audio-time-stretch" ) ? strdup( "scaletempo" ) : NULL; p_input->b_recycle_vout = psz_visual && *psz_visual; /* parse user filter lists */ char *const ppsz_array[] = { psz_scaletempo, psz_filters, psz_visual }; p_input->p_playback_rate_filter = NULL; for( i_visual = 0; i_visual < 3 && !AOUT_FMT_NON_LINEAR(&chain_output_format); i_visual++ ) { char *psz_next = NULL; char *psz_parser = ppsz_array[i_visual]; if( psz_parser == NULL || !*psz_parser ) continue; while( psz_parser && *psz_parser ) { filter_t * p_filter = NULL; if( p_input->i_nb_filters >= AOUT_MAX_FILTERS ) { msg_Dbg( p_aout, "max filters reached (%d)", AOUT_MAX_FILTERS ); break; } while( *psz_parser == ' ' && *psz_parser == ':' ) { psz_parser++; } if( ( psz_next = strchr( psz_parser , ':' ) ) ) { *psz_next++ = '\0'; } if( *psz_parser =='\0' ) { break; } /* Create a VLC object */ static const char typename[] = "audio filter"; p_filter = vlc_custom_create( p_aout, sizeof(*p_filter), VLC_OBJECT_GENERIC, typename ); if( p_filter == NULL ) { msg_Err( p_aout, "cannot add user filter %s (skipped)", psz_parser ); psz_parser = psz_next; continue; } vlc_object_attach( p_filter , p_aout ); p_filter->p_owner = malloc( sizeof(*p_filter->p_owner) ); p_filter->p_owner->p_aout = p_aout; p_filter->p_owner->p_input = p_input; /* request format */ memcpy( &p_filter->fmt_in.audio, &chain_output_format, sizeof(audio_sample_format_t) ); p_filter->fmt_in.i_codec = chain_output_format.i_format; memcpy( &p_filter->fmt_out.audio, &chain_output_format, sizeof(audio_sample_format_t) ); p_filter->fmt_out.i_codec = chain_output_format.i_format; p_filter->pf_audio_buffer_new = aout_FilterBufferNew; /* try to find the requested filter */ if( i_visual == 2 ) /* this can only be a visualization module */ { p_filter->p_module = module_need( p_filter, "visualization2", psz_parser, true ); } else /* this can be a audio filter module as well as a visualization module */ { p_filter->p_module = module_need( p_filter, "audio filter", psz_parser, true ); if ( p_filter->p_module == NULL ) { /* if the filter requested a special format, retry */ if ( !( AOUT_FMTS_IDENTICAL( &p_filter->fmt_in.audio, &chain_input_format ) && AOUT_FMTS_IDENTICAL( &p_filter->fmt_out.audio, &chain_output_format ) ) ) { aout_FormatPrepare( &p_filter->fmt_in.audio ); aout_FormatPrepare( &p_filter->fmt_out.audio ); p_filter->p_module = module_need( p_filter, "audio filter", psz_parser, true ); } /* try visual filters */ else { memcpy( &p_filter->fmt_in.audio, &chain_output_format, sizeof(audio_sample_format_t) ); memcpy( &p_filter->fmt_out.audio, &chain_output_format, sizeof(audio_sample_format_t) ); p_filter->p_module = module_need( p_filter, "visualization2", psz_parser, true ); } } } /* failure */ if ( p_filter->p_module == NULL ) { msg_Err( p_aout, "cannot add user filter %s (skipped)", psz_parser ); free( p_filter->p_owner ); vlc_object_release( p_filter ); psz_parser = psz_next; continue; } /* complete the filter chain if necessary */ if ( !AOUT_FMTS_IDENTICAL( &chain_input_format, &p_filter->fmt_in.audio ) ) { if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters, &p_input->i_nb_filters, &chain_input_format, &p_filter->fmt_in.audio ) < 0 ) { msg_Err( p_aout, "cannot add user filter %s (skipped)", psz_parser ); module_unneed( p_filter, p_filter->p_module ); free( p_filter->p_owner ); vlc_object_release( p_filter ); psz_parser = psz_next; continue; } } /* success */ p_input->pp_filters[p_input->i_nb_filters++] = p_filter; memcpy( &chain_input_format, &p_filter->fmt_out.audio, sizeof( audio_sample_format_t ) ); if( i_visual == 0 ) /* scaletempo */ p_input->p_playback_rate_filter = p_filter; /* next filter if any */ psz_parser = psz_next; } } free( psz_visual ); free( psz_filters ); free( psz_scaletempo ); /* complete the filter chain if necessary */ if ( !AOUT_FMTS_IDENTICAL( &chain_input_format, &chain_output_format ) ) { if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters, &p_input->i_nb_filters, &chain_input_format, &chain_output_format ) < 0 ) { inputFailure( p_aout, p_input, "couldn't set an input pipeline" ); return -1; } } /* Prepare hints for the buffer allocator. */ p_input->input_alloc.b_alloc = true; p_input->input_alloc.i_bytes_per_sec = -1; /* Create resamplers. */ if ( !AOUT_FMT_NON_LINEAR( &p_aout->mixer_format ) ) { chain_output_format.i_rate = (__MAX(p_input->input.i_rate, p_aout->mixer_format.i_rate) * (100 + AOUT_MAX_RESAMPLING)) / 100; if ( chain_output_format.i_rate == p_aout->mixer_format.i_rate ) { /* Just in case... */ chain_output_format.i_rate++; } if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_resamplers, &p_input->i_nb_resamplers, &chain_output_format, &p_aout->mixer_format ) < 0 ) { inputFailure( p_aout, p_input, "couldn't set a resampler pipeline"); return -1; } aout_FiltersHintBuffers( p_aout, p_input->pp_resamplers, p_input->i_nb_resamplers, &p_input->input_alloc ); p_input->input_alloc.b_alloc = true; /* Setup the initial rate of the resampler */ p_input->pp_resamplers[0]->fmt_in.audio.i_rate = p_input->input.i_rate; } p_input->i_resampling_type = AOUT_RESAMPLING_NONE; if( ! p_input->p_playback_rate_filter && p_input->i_nb_resamplers > 0 ) { p_input->p_playback_rate_filter = p_input->pp_resamplers[0]; } aout_FiltersHintBuffers( p_aout, p_input->pp_filters, p_input->i_nb_filters, &p_input->input_alloc ); p_input->input_alloc.b_alloc = true; /* i_bytes_per_sec is still == -1 if no filters */ p_input->input_alloc.i_bytes_per_sec = __MAX( p_input->input_alloc.i_bytes_per_sec, (int)(p_input->input.i_bytes_per_frame * p_input->input.i_rate / p_input->input.i_frame_length) ); ReplayGainSelect( p_aout, p_input ); /* Success */ p_input->b_error = false; p_input->i_last_input_rate = INPUT_RATE_DEFAULT; return 0; }
void vout_EnableFilter( vout_thread_t *p_vout, char *psz_name, bool b_add, bool b_setconfig ) { char *psz_parser; char *psz_string; const char *psz_filter_type; /* FIXME temporary hack */ const char *psz_module_name = psz_name; if( !strcmp( psz_name, "magnify" ) || !strcmp( psz_name, "puzzle" ) || !strcmp( psz_name, "logo" ) || !strcmp( psz_name, "wall" ) || !strcmp( psz_name, "clone" ) ) psz_module_name = "video_filter_wrapper"; module_t *p_obj = module_find( psz_module_name ); if( !p_obj ) { msg_Err( p_vout, "Unable to find filter module \"%s\".", psz_name ); return; } if( module_provides( p_obj, "video filter" ) ) { psz_filter_type = "vout-filter"; } else if( module_provides( p_obj, "video filter2" ) ) { psz_filter_type = "video-filter"; } else if( module_provides( p_obj, "sub filter" ) ) { psz_filter_type = "sub-filter"; } else { module_release( p_obj ); msg_Err( p_vout, "Unknown video filter type." ); return; } module_release( p_obj ); if( !strcmp( psz_filter_type, "sub-filter") ) psz_string = var_GetString( vout_GetSpu( p_vout ), psz_filter_type ); else psz_string = var_GetString( p_vout, psz_filter_type ); /* Todo : Use some generic chain manipulation functions */ if( !psz_string ) psz_string = strdup(""); psz_parser = strstr( psz_string, psz_name ); if( b_add ) { if( !psz_parser ) { psz_parser = psz_string; if( asprintf( &psz_string, (*psz_string) ? "%s:%s" : "%s%s", psz_string, psz_name ) == -1 ) { free( psz_parser ); return; } free( psz_parser ); } else return; } else { if( psz_parser ) { memmove( psz_parser, psz_parser + strlen(psz_name) + (*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ), strlen(psz_parser + strlen(psz_name)) + 1 ); /* Remove trailing : : */ if( *(psz_string+strlen(psz_string ) -1 ) == ':' ) { *(psz_string+strlen(psz_string ) -1 ) = '\0'; } } else { free( psz_string ); return; } } if( b_setconfig ) { if( !strcmp( psz_filter_type, "sub-filter") ) config_PutPsz( vout_GetSpu( p_vout ), psz_filter_type, psz_string ); else config_PutPsz( p_vout, psz_filter_type, psz_string ); } if( !strcmp( psz_filter_type, "sub-filter") ) var_SetString( vout_GetSpu( p_vout ), psz_filter_type, psz_string ); else var_SetString( p_vout, psz_filter_type, psz_string ); free( psz_string ); }
/***************************************************************************** * Open: *****************************************************************************/ static int Open( vlc_object_t *p_this ) { sout_stream_t *p_stream = (sout_stream_t*)p_this; sout_stream_sys_t *p_sys; char *psz_string; if( !p_stream->p_next ) { msg_Err( p_stream, "cannot create chain" ); return VLC_EGENERIC; } p_sys = calloc( 1, sizeof( *p_sys ) ); p_sys->i_master_drift = 0; config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options, p_stream->p_cfg ); /* Audio transcoding parameters */ psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "aenc" ); p_sys->psz_aenc = NULL; p_sys->p_audio_cfg = NULL; if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg, psz_string ); free( psz_next ); } free( psz_string ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "acodec" ); p_sys->i_acodec = 0; if( psz_string && *psz_string ) { char fcc[5] = " \0"; memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) ); p_sys->i_acodec = vlc_fourcc_GetCodecFromString( AUDIO_ES, fcc ); msg_Dbg( p_stream, "Checking codec mapping for %s got %4.4s ", fcc, (char*)&p_sys->i_acodec); } free( psz_string ); p_sys->psz_alang = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "alang" ); p_sys->i_abitrate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "ab" ); if( p_sys->i_abitrate < 4000 ) p_sys->i_abitrate *= 1000; p_sys->i_sample_rate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "samplerate" ); p_sys->i_channels = var_GetInteger( p_stream, SOUT_CFG_PREFIX "channels" ); if( p_sys->i_acodec ) { if( ( p_sys->i_acodec == VLC_CODEC_MP3 || p_sys->i_acodec == VLC_CODEC_MP2 || p_sys->i_acodec == VLC_CODEC_MPGA ) && p_sys->i_channels > 2 ) { msg_Warn( p_stream, "%d channels invalid for mp2/mp3, forcing to 2", p_sys->i_channels ); p_sys->i_channels = 2; } msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s", (char *)&p_sys->i_acodec, p_sys->i_sample_rate, p_sys->i_channels, p_sys->i_abitrate / 1000 ); } psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "afilter" ); if( psz_string && *psz_string ) p_sys->psz_af = strdup( psz_string ); else p_sys->psz_af = NULL; free( psz_string ); /* Video transcoding parameters */ psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "venc" ); p_sys->psz_venc = NULL; p_sys->p_video_cfg = NULL; if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_venc, &p_sys->p_video_cfg, psz_string ); free( psz_next ); } free( psz_string ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "vcodec" ); p_sys->i_vcodec = 0; if( psz_string && *psz_string ) { char fcc[5] = " \0"; memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) ); p_sys->i_vcodec = vlc_fourcc_GetCodecFromString( VIDEO_ES, fcc ); msg_Dbg( p_stream, "Checking video codec mapping for %s got %4.4s ", fcc, (char*)&p_sys->i_vcodec); } free( psz_string ); p_sys->i_vbitrate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "vb" ); if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000; p_sys->f_scale = var_GetFloat( p_stream, SOUT_CFG_PREFIX "scale" ); p_sys->b_master_sync = var_InheritURational( p_stream, &p_sys->fps_num, &p_sys->fps_den, SOUT_CFG_PREFIX "fps" ) == VLC_SUCCESS; p_sys->i_width = var_GetInteger( p_stream, SOUT_CFG_PREFIX "width" ); p_sys->i_height = var_GetInteger( p_stream, SOUT_CFG_PREFIX "height" ); p_sys->i_maxwidth = var_GetInteger( p_stream, SOUT_CFG_PREFIX "maxwidth" ); p_sys->i_maxheight = var_GetInteger( p_stream, SOUT_CFG_PREFIX "maxheight" ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "vfilter" ); if( psz_string && *psz_string ) p_sys->psz_vf2 = strdup(psz_string ); else p_sys->psz_vf2 = NULL; free( psz_string ); p_sys->b_deinterlace = var_GetBool( p_stream, SOUT_CFG_PREFIX "deinterlace" ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "deinterlace-module" ); p_sys->psz_deinterlace = NULL; p_sys->p_deinterlace_cfg = NULL; if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_deinterlace, &p_sys->p_deinterlace_cfg, psz_string ); free( psz_next ); } free( psz_string ); p_sys->i_threads = var_GetInteger( p_stream, SOUT_CFG_PREFIX "threads" ); p_sys->b_high_priority = var_GetBool( p_stream, SOUT_CFG_PREFIX "high-priority" ); if( p_sys->i_vcodec ) { msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s", (char *)&p_sys->i_vcodec, p_sys->i_width, p_sys->i_height, p_sys->f_scale, p_sys->i_vbitrate / 1000 ); } /* Disable hardware decoding by default (unlike normal playback) */ psz_string = var_CreateGetString( p_stream, "avcodec-hw" ); if( !strcasecmp( "any", psz_string ) ) var_SetString( p_stream, "avcodec-hw", "none" ); free( psz_string ); /* Subpictures transcoding parameters */ p_sys->p_spu = NULL; p_sys->p_spu_blend = NULL; p_sys->psz_senc = NULL; p_sys->p_spu_cfg = NULL; p_sys->i_scodec = 0; psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "senc" ); if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg, psz_string ); free( psz_next ); } free( psz_string ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "scodec" ); if( psz_string && *psz_string ) { char fcc[5] = " \0"; memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) ); p_sys->i_scodec = vlc_fourcc_GetCodecFromString( SPU_ES, fcc ); msg_Dbg( p_stream, "Checking spu codec mapping for %s got %4.4s ", fcc, (char*)&p_sys->i_scodec); } free( psz_string ); if( p_sys->i_scodec ) { msg_Dbg( p_stream, "codec spu=%4.4s", (char *)&p_sys->i_scodec ); } p_sys->b_soverlay = var_GetBool( p_stream, SOUT_CFG_PREFIX "soverlay" ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "sfilter" ); if( psz_string && *psz_string ) { p_sys->p_spu = spu_Create( p_stream ); if( p_sys->p_spu ) spu_ChangeSources( p_sys->p_spu, psz_string ); } free( psz_string ); /* OSD menu transcoding parameters */ p_sys->psz_osdenc = NULL; p_sys->p_osd_cfg = NULL; p_sys->i_osdcodec = 0; p_sys->b_osd = var_GetBool( p_stream, SOUT_CFG_PREFIX "osd" ); if( p_sys->b_osd ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_osdenc, &p_sys->p_osd_cfg, "dvbsub" ); free( psz_next ); p_sys->i_osdcodec = VLC_CODEC_YUVP; msg_Dbg( p_stream, "codec osd=%4.4s", (char *)&p_sys->i_osdcodec ); if( !p_sys->p_spu ) { p_sys->p_spu = spu_Create( p_stream ); if( p_sys->p_spu ) spu_ChangeSources( p_sys->p_spu, "osdmenu" ); } else { spu_ChangeSources( p_sys->p_spu, "osdmenu" ); } } p_stream->pf_add = Add; p_stream->pf_del = Del; p_stream->pf_send = Send; p_stream->p_sys = p_sys; return VLC_SUCCESS; }
void vout_EnableFilter( vout_thread_t *p_vout, const char *psz_name, bool b_add, bool b_setconfig ) { char *psz_parser; char *psz_string; const char *psz_filter_type; module_t *p_obj = module_find( psz_name ); if( !p_obj ) { msg_Err( p_vout, "Unable to find filter module \"%s\".", psz_name ); return; } if( module_provides( p_obj, "video filter2" ) ) { psz_filter_type = "video-filter"; } else if( module_provides( p_obj, "sub source" ) ) { psz_filter_type = "sub-source"; } else if( module_provides( p_obj, "sub filter" ) ) { psz_filter_type = "sub-filter"; } else { msg_Err( p_vout, "Unknown video filter type." ); return; } psz_string = var_GetString( p_vout, psz_filter_type ); /* Todo : Use some generic chain manipulation functions */ if( !psz_string ) psz_string = strdup(""); psz_parser = strstr( psz_string, psz_name ); if( b_add ) { if( !psz_parser ) { psz_parser = psz_string; if( asprintf( &psz_string, (*psz_string) ? "%s:%s" : "%s%s", psz_string, psz_name ) == -1 ) { free( psz_parser ); return; } free( psz_parser ); } else return; } else { if( psz_parser ) { memmove( psz_parser, psz_parser + strlen(psz_name) + (*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ), strlen(psz_parser + strlen(psz_name)) + 1 ); /* Remove trailing : : */ if( *(psz_string+strlen(psz_string ) -1 ) == ':' ) { *(psz_string+strlen(psz_string ) -1 ) = '\0'; } } else { free( psz_string ); return; } } if( b_setconfig ) { config_PutPsz( p_vout, psz_filter_type, psz_string ); } var_SetString( p_vout, psz_filter_type, psz_string ); free( psz_string ); }
/***************************************************************************** * Open: *****************************************************************************/ static int Open( vlc_object_t *p_this ) { sout_stream_t *p_stream = (sout_stream_t*)p_this; sout_stream_sys_t *p_sys; char *psz_string; if( !p_stream->p_next ) { msg_Err( p_stream, "cannot create chain" ); return VLC_EGENERIC; } p_sys = calloc( 1, sizeof( *p_sys ) ); p_sys->i_master_drift = 0; config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options, p_stream->p_cfg ); /* Audio transcoding parameters */ psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "aenc" ); p_sys->psz_aenc = NULL; p_sys->p_audio_cfg = NULL; if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg, psz_string ); free( psz_next ); } free( psz_string ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "acodec" ); p_sys->i_acodec = 0; if( psz_string && *psz_string ) { char fcc[4] = " "; memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) ); p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] ); } free( psz_string ); p_sys->psz_alang = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "alang" ); p_sys->i_abitrate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "ab" ); if( p_sys->i_abitrate < 4000 ) p_sys->i_abitrate *= 1000; p_sys->i_sample_rate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "samplerate" ); p_sys->i_channels = var_GetInteger( p_stream, SOUT_CFG_PREFIX "channels" ); if( p_sys->i_acodec ) { if( ( p_sys->i_acodec == VLC_CODEC_MP3 || p_sys->i_acodec == VLC_CODEC_MP2 || p_sys->i_acodec == VLC_CODEC_MPGA ) && p_sys->i_channels > 2 ) { msg_Warn( p_stream, "%d channels invalid for mp2/mp3, forcing to 2", p_sys->i_channels ); p_sys->i_channels = 2; } msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s", (char *)&p_sys->i_acodec, p_sys->i_sample_rate, p_sys->i_channels, p_sys->i_abitrate / 1000 ); } psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "afilter" ); if( psz_string && *psz_string ) p_sys->psz_af = strdup( psz_string ); else p_sys->psz_af = NULL; free( psz_string ); /* Video transcoding parameters */ psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "venc" ); p_sys->psz_venc = NULL; p_sys->p_video_cfg = NULL; if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_venc, &p_sys->p_video_cfg, psz_string ); free( psz_next ); } free( psz_string ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "vcodec" ); p_sys->i_vcodec = 0; if( psz_string && *psz_string ) { char fcc[4] = " "; memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) ); p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] ); } free( psz_string ); p_sys->i_vbitrate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "vb" ); if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000; p_sys->f_scale = var_GetFloat( p_stream, SOUT_CFG_PREFIX "scale" ); p_sys->f_fps = var_GetFloat( p_stream, SOUT_CFG_PREFIX "fps" ); p_sys->b_hurry_up = var_GetBool( p_stream, SOUT_CFG_PREFIX "hurry-up" ); p_sys->i_width = var_GetInteger( p_stream, SOUT_CFG_PREFIX "width" ); p_sys->i_height = var_GetInteger( p_stream, SOUT_CFG_PREFIX "height" ); p_sys->i_maxwidth = var_GetInteger( p_stream, SOUT_CFG_PREFIX "maxwidth" ); p_sys->i_maxheight = var_GetInteger( p_stream, SOUT_CFG_PREFIX "maxheight" ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "vfilter" ); if( psz_string && *psz_string ) p_sys->psz_vf2 = strdup(psz_string ); else p_sys->psz_vf2 = NULL; free( psz_string ); p_sys->b_deinterlace = var_GetBool( p_stream, SOUT_CFG_PREFIX "deinterlace" ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "deinterlace-module" ); p_sys->psz_deinterlace = NULL; p_sys->p_deinterlace_cfg = NULL; if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_deinterlace, &p_sys->p_deinterlace_cfg, psz_string ); free( psz_next ); } free( psz_string ); p_sys->i_threads = var_GetInteger( p_stream, SOUT_CFG_PREFIX "threads" ); p_sys->b_high_priority = var_GetBool( p_stream, SOUT_CFG_PREFIX "high-priority" ); if( p_sys->i_vcodec ) { msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s", (char *)&p_sys->i_vcodec, p_sys->i_width, p_sys->i_height, p_sys->f_scale, p_sys->i_vbitrate / 1000 ); } /* Subpictures transcoding parameters */ p_sys->p_spu = NULL; p_sys->p_spu_blend = NULL; p_sys->psz_senc = NULL; p_sys->p_spu_cfg = NULL; p_sys->i_scodec = 0; psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "senc" ); if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg, psz_string ); free( psz_next ); } free( psz_string ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "scodec" ); if( psz_string && *psz_string ) { char fcc[4] = " "; memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) ); p_sys->i_scodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] ); } free( psz_string ); if( p_sys->i_scodec ) { msg_Dbg( p_stream, "codec spu=%4.4s", (char *)&p_sys->i_scodec ); } p_sys->b_soverlay = var_GetBool( p_stream, SOUT_CFG_PREFIX "soverlay" ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "sfilter" ); if( psz_string && *psz_string ) { p_sys->p_spu = spu_Create( p_stream ); if( p_sys->p_spu ) spu_ChangeSources( p_sys->p_spu, psz_string ); } free( psz_string ); /* OSD menu transcoding parameters */ p_sys->psz_osdenc = NULL; p_sys->p_osd_cfg = NULL; p_sys->i_osdcodec = 0; p_sys->b_osd = var_GetBool( p_stream, SOUT_CFG_PREFIX "osd" ); if( p_sys->b_osd ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_osdenc, &p_sys->p_osd_cfg, strdup( "dvbsub") ); free( psz_next ); p_sys->i_osdcodec = VLC_CODEC_YUVP; msg_Dbg( p_stream, "codec osd=%4.4s", (char *)&p_sys->i_osdcodec ); if( !p_sys->p_spu ) { p_sys->p_spu = spu_Create( p_stream ); if( p_sys->p_spu ) spu_ChangeSources( p_sys->p_spu, "osdmenu" ); } else { spu_ChangeSources( p_sys->p_spu, "osdmenu" ); } } /* Audio settings */ p_sys->b_master_sync = var_GetBool( p_stream, SOUT_CFG_PREFIX "audio-sync" ); if( p_sys->f_fps > 0 ) p_sys->b_master_sync = true; p_stream->pf_add = Add; p_stream->pf_del = Del; p_stream->pf_send = Send; p_stream->p_sys = p_sys; return VLC_SUCCESS; }
/***************************************************************************** * Open: create a handle and open an alsa device ***************************************************************************** * This function opens an alsa device, through the alsa API. * * Note: the only heap-allocated string is psz_device. All the other pointers * are references to psz_device or to stack-allocated data. *****************************************************************************/ static int Open (vlc_object_t *obj) { aout_instance_t * p_aout = (aout_instance_t *)obj; /* Get device name */ char *psz_device; if (var_Type (p_aout, "audio-device")) psz_device = var_GetString (p_aout, "audio-device"); else psz_device = var_InheritString( p_aout, "alsa-audio-device" ); if (unlikely(psz_device == NULL)) return VLC_ENOMEM; snd_pcm_format_t pcm_format; /* ALSA sample format */ vlc_fourcc_t fourcc = p_aout->output.output.i_format; bool spdif = false; switch (fourcc) { case VLC_CODEC_F64B: pcm_format = SND_PCM_FORMAT_FLOAT64_BE; break; case VLC_CODEC_F64L: pcm_format = SND_PCM_FORMAT_FLOAT64_LE; break; case VLC_CODEC_F32B: pcm_format = SND_PCM_FORMAT_FLOAT_BE; break; case VLC_CODEC_F32L: pcm_format = SND_PCM_FORMAT_FLOAT_LE; break; case VLC_CODEC_FI32: fourcc = VLC_CODEC_FL32; pcm_format = SND_PCM_FORMAT_FLOAT; break; case VLC_CODEC_S32B: pcm_format = SND_PCM_FORMAT_S32_BE; break; case VLC_CODEC_S32L: pcm_format = SND_PCM_FORMAT_S32_LE; break; case VLC_CODEC_S24B: pcm_format = SND_PCM_FORMAT_S24_3BE; break; case VLC_CODEC_S24L: pcm_format = SND_PCM_FORMAT_S24_3LE; break; case VLC_CODEC_U24B: pcm_format = SND_PCM_FORMAT_U24_3BE; break; case VLC_CODEC_U24L: pcm_format = SND_PCM_FORMAT_U24_3LE; break; case VLC_CODEC_S16B: pcm_format = SND_PCM_FORMAT_S16_BE; break; case VLC_CODEC_S16L: pcm_format = SND_PCM_FORMAT_S16_LE; break; case VLC_CODEC_U16B: pcm_format = SND_PCM_FORMAT_U16_BE; break; case VLC_CODEC_U16L: pcm_format = SND_PCM_FORMAT_U16_LE; break; case VLC_CODEC_S8: pcm_format = SND_PCM_FORMAT_S8; break; case VLC_CODEC_U8: pcm_format = SND_PCM_FORMAT_U8; break; default: if (AOUT_FMT_NON_LINEAR(&p_aout->output.output)) spdif = var_InheritBool (p_aout, "spdif"); if (HAVE_FPU) { fourcc = VLC_CODEC_FL32; pcm_format = SND_PCM_FORMAT_FLOAT; } else { fourcc = VLC_CODEC_S16N; pcm_format = SND_PCM_FORMAT_S16; } } /* Choose the IEC device for S/PDIF output: if the device is overridden by the user then it will be the one otherwise we compute the default device based on the output format. */ if (spdif && !strcmp (psz_device, DEFAULT_ALSA_DEVICE)) { unsigned aes3; switch (p_aout->output.output.i_rate) { #define FS(freq) \ case freq: aes3 = IEC958_AES3_CON_FS_ ## freq; break; FS( 44100) /* def. */ FS( 48000) FS( 32000) FS( 22050) FS( 24000) FS( 88200) FS(768000) FS( 96000) FS(176400) FS(192000) #undef FS default: aes3 = IEC958_AES3_CON_FS_NOTID; break; } free (psz_device); if (asprintf (&psz_device, "iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x", IEC958_AES0_CON_EMPHASIS_NONE | IEC958_AES0_NONAUDIO, IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER, 0, aes3) == -1) return VLC_ENOMEM; }
static void ChangeFiltersString( intf_thread_t *p_intf, aout_instance_t * p_aout, char *psz_name, vlc_bool_t b_add ) { char *psz_parser, *psz_string; if( p_aout ) { psz_string = var_GetString( p_aout, "audio-filter" ); } else { psz_string = config_GetPsz( p_intf, "audio-filter" ); } if( !psz_string ) psz_string = strdup(""); psz_parser = strstr( psz_string, psz_name ); if( b_add ) { if( !psz_parser ) { psz_parser = psz_string; asprintf( &psz_string, (*psz_string) ? "%s,%s" : "%s%s", psz_string, psz_name ); free( psz_parser ); } else { return; } } else { if( psz_parser ) { memmove( psz_parser, psz_parser + strlen(psz_name) + (*(psz_parser + strlen(psz_name)) == ',' ? 1 : 0 ), strlen(psz_parser + strlen(psz_name)) + 1 ); if( *(psz_string+strlen(psz_string ) -1 ) == ',' ) { *(psz_string+strlen(psz_string ) -1 ) = '\0'; } } else { free( psz_string ); return; } } if( p_aout == NULL ) { config_PutPsz( p_intf, "audio-filter", psz_string ); } else { var_SetString( p_aout, "audio-filter", psz_string ); for( int i = 0; i < p_aout->i_nb_inputs; i++ ) { p_aout->pp_inputs[i]->b_restart = VLC_TRUE; } } free( psz_string ); }