aout_input_t * __aout_DecNew( vlc_object_t * p_this, aout_instance_t ** pp_aout, audio_sample_format_t * p_format ) { if ( *pp_aout == NULL ) { /* Create an audio output if there is none. */ *pp_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE ); if( *pp_aout == NULL ) { msg_Dbg( p_this, "no aout present, spawning one" ); *pp_aout = aout_New( p_this ); /* Everything failed, I'm a loser, I just wanna die */ if( *pp_aout == NULL ) { return NULL; } vlc_object_attach( *pp_aout, p_this->p_vlc ); } else { vlc_object_release( *pp_aout ); } } return DecNew( p_this, *pp_aout, p_format ); }
/***************************************************************************** * Open: open a scope effect plugin *****************************************************************************/ static int Open( vlc_object_t *p_this ) { aout_filter_t *p_filter = (aout_filter_t *)p_this; aout_filter_sys_t *p_sys; galaktos_thread_t *p_thread; if ( p_filter->input.i_format != VLC_FOURCC('f','l','3','2' ) || p_filter->output.i_format != VLC_FOURCC('f','l','3','2') ) { msg_Warn( p_filter, "bad input or output format" ); return VLC_EGENERIC; } if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) ) { msg_Warn( p_filter, "input and output formats are not similar" ); return VLC_EGENERIC; } p_filter->pf_do_work = DoWork; p_filter->b_in_place = 1; /* Allocate structure */ p_sys = p_filter->p_sys = malloc( sizeof( aout_filter_sys_t ) ); /* Create galaktos thread */ p_sys->p_thread = p_thread = vlc_object_create( p_filter, sizeof( galaktos_thread_t ) ); vlc_object_attach( p_thread, p_this ); /* var_Create( p_thread, "galaktos-width", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); var_Get( p_thread, "galaktos-width", &width ); var_Create( p_thread, "galaktos-height", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); var_Get( p_thread, "galaktos-height", &height ); */ p_thread->i_cur_sample = 0; bzero( p_thread->p_data, 2*2*512 ); p_thread->i_width = 600; p_thread->i_height = 600; p_thread->b_fullscreen = 0; galaktos_init( p_thread ); p_thread->i_channels = aout_FormatNbChannels( &p_filter->input ); p_thread->psz_title = TitleGet( VLC_OBJECT( p_filter ) ); if( vlc_thread_create( p_thread, "galaktos update thread", Thread, VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) ) { msg_Err( p_filter, "cannot lauch galaktos thread" ); if( p_thread->psz_title ) free( p_thread->psz_title ); vlc_object_detach( p_thread ); vlc_object_destroy( p_thread ); free( p_sys ); return VLC_EGENERIC; } return VLC_SUCCESS; }
/***************************************************************************** * FindFilter: find an audio filter for a specific transformation *****************************************************************************/ static aout_filter_t * FindFilter( aout_instance_t * p_aout, const audio_sample_format_t * p_input_format, const audio_sample_format_t * p_output_format ) { aout_filter_t * p_filter = vlc_object_create( p_aout, sizeof(aout_filter_t) ); if ( p_filter == NULL ) return NULL; vlc_object_attach( p_filter, p_aout ); memcpy( &p_filter->input, p_input_format, sizeof(audio_sample_format_t) ); memcpy( &p_filter->output, p_output_format, sizeof(audio_sample_format_t) ); p_filter->p_module = module_Need( p_filter, "audio filter", NULL, 0 ); if ( p_filter->p_module == NULL ) { vlc_object_detach( p_filter ); vlc_object_destroy( p_filter ); return NULL; } p_filter->b_continuity = VLC_FALSE; return p_filter; }
bool Dialogs::init() { // Allocate descriptor m_pProvider = (intf_thread_t *)vlc_object_create( getIntf(), sizeof( intf_thread_t ) ); if( m_pProvider == NULL ) return false; // Attach the dialogs provider to its parent interface vlc_object_attach( m_pProvider, getIntf() ); m_pModule = module_need( m_pProvider, "dialogs provider", NULL, false ); if( m_pModule == NULL ) { msg_Err( getIntf(), "no suitable dialogs provider found (hint: compile the qt4 plugin, and make sure it is loaded properly)" ); vlc_object_release( m_pProvider ); m_pProvider = NULL; return false; } /* Register callback for the intf-popupmenu variable */ var_AddCallback( getIntf()->p_libvlc, "intf-popupmenu", PopupMenuCB, this ); return true; }
sql_t *sql_Create( vlc_object_t *p_this, const char *psz_name, const char* psz_host, int i_port, const char* psz_user, const char* psz_pass ) { sql_t *p_sql; p_sql = ( sql_t * ) vlc_custom_create( p_this, sizeof( sql_t ), VLC_OBJECT_GENERIC, "sql" ); if( !p_sql ) { msg_Err( p_this, "unable to create sql object" ); return NULL; } vlc_object_attach( p_sql, p_this ); p_sql->psz_host = strdup( psz_host ); p_sql->psz_user = strdup( psz_user ); p_sql->psz_pass = strdup( psz_pass ); p_sql->i_port = i_port; p_sql->p_module = module_need( p_sql, "sql", psz_name, psz_name && *psz_name ); if( !p_sql->p_module ) { free( p_sql->psz_host ); free( p_sql->psz_user ); free( p_sql->psz_pass ); vlc_object_release( p_sql ); msg_Err( p_this, "SQL provider not found" ); return NULL; } return p_sql; }
/***************************************************************************** * aout_New: initialize aout structure *****************************************************************************/ aout_instance_t * __aout_New( vlc_object_t * p_parent ) { aout_instance_t * p_aout; /* Allocate descriptor. */ p_aout = vlc_custom_create( p_parent, sizeof( *p_aout ), VLC_OBJECT_AOUT, "audio output" ); if( p_aout == NULL ) { return NULL; } /* Initialize members. */ vlc_mutex_init( &p_aout->input_fifos_lock ); vlc_mutex_init( &p_aout->mixer_lock ); vlc_mutex_init( &p_aout->volume_vars_lock ); vlc_mutex_init( &p_aout->output_fifo_lock ); p_aout->i_nb_inputs = 0; p_aout->mixer_multiplier = 1.0; p_aout->p_mixer = NULL; p_aout->output.b_error = 1; p_aout->output.b_starving = 1; var_Create( p_aout, "intf-change", VLC_VAR_VOID ); vlc_object_set_destructor( p_aout, aout_Destructor ); vlc_object_attach( p_aout, p_parent ); return p_aout; }
filter_t *filter_NewBlend( vlc_object_t *p_this, const video_format_t *p_dst_chroma ) { filter_t *p_blend = vlc_custom_create( p_this, sizeof(*p_blend), VLC_OBJECT_GENERIC, "blend" ); if( !p_blend ) return NULL; es_format_Init( &p_blend->fmt_in, VIDEO_ES, 0 ); es_format_Init( &p_blend->fmt_out, VIDEO_ES, 0 ); p_blend->fmt_out.i_codec = p_blend->fmt_out.video.i_chroma = p_dst_chroma->i_chroma; p_blend->fmt_out.video.i_rmask = p_dst_chroma->i_rmask; p_blend->fmt_out.video.i_gmask = p_dst_chroma->i_gmask; p_blend->fmt_out.video.i_bmask = p_dst_chroma->i_bmask; p_blend->fmt_out.video.i_rrshift= p_dst_chroma->i_rrshift; p_blend->fmt_out.video.i_rgshift= p_dst_chroma->i_rgshift; p_blend->fmt_out.video.i_rbshift= p_dst_chroma->i_rbshift; p_blend->fmt_out.video.i_lrshift= p_dst_chroma->i_lrshift; p_blend->fmt_out.video.i_lgshift= p_dst_chroma->i_lgshift; p_blend->fmt_out.video.i_lbshift= p_dst_chroma->i_lbshift; /* The blend module will be loaded when needed with the real * input format */ p_blend->p_module = NULL; /* */ vlc_object_attach( p_blend, p_this ); return p_blend; }
/***************************************************************************** * OpenDisplay: create qte applicaton / window ***************************************************************************** * Create a window according to video output given size, and set other * properties according to the display properties. *****************************************************************************/ static int OpenDisplay( vout_thread_t *p_vout ) { /* for displaying the vout in a qt window we need the QtApplication */ p_vout->p_sys->p_QApplication = NULL; p_vout->p_sys->p_VideoWidget = NULL; p_vout->p_sys->p_event = (event_thread_t*) vlc_object_create( p_vout, sizeof(event_thread_t) ); p_vout->p_sys->p_event->p_vout = p_vout; /* Initializations */ #if 1 /* FIXME: I need an event queue to handle video output size changes. */ p_vout->b_fullscreen = true; #endif /* Set main window's size */ QWidget *desktop = p_vout->p_sys->p_QApplication->desktop(); p_vout->p_sys->i_width = p_vout->b_fullscreen ? desktop->height() : p_vout->i_window_width; p_vout->p_sys->i_height = p_vout->b_fullscreen ? desktop->width() : p_vout->i_window_height; #if 0 /* FIXME: I need an event queue to handle video output size changes. */ /* Update dimensions */ p_vout->i_changes |= VOUT_SIZE_CHANGE; p_vout->i_window_width = p_vout->p_sys->i_width; p_vout->i_window_height = p_vout->p_sys->i_height; #endif msg_Dbg( p_vout, "opening display (h=%d,w=%d)",p_vout->p_sys->i_height,p_vout->p_sys->i_width); /* create thread to exec the qpe application */ if ( vlc_thread_create( p_vout->p_sys->p_event, "QT Embedded Thread", RunQtThread, VLC_THREAD_PRIORITY_OUTPUT, true) ) { msg_Err( p_vout, "cannot create QT Embedded Thread" ); vlc_object_release( p_vout->p_sys->p_event ); p_vout->p_sys->p_event = NULL; return -1; } if( p_vout->p_sys->p_event->b_error ) { msg_Err( p_vout, "RunQtThread failed" ); return -1; } vlc_object_attach( p_vout->p_sys->p_event, p_vout ); msg_Dbg( p_vout, "RunQtThread running" ); // just wait until the crew is complete... while(p_vout->p_sys->p_VideoWidget == NULL) { msleep(1); } return VLC_SUCCESS; }
tls_session_t *tls_ServerSessionPrepare (tls_server_t *srv) { tls_session_t *ses; ses = srv->pf_open (srv); if (ses == NULL) return NULL; vlc_object_attach (ses, srv); return ses; }
/** * Create the SAP handler * * \param p_announce a VLC object * \return the newly created SAP handler or NULL on error */ sap_handler_t *SAP_Create (vlc_object_t *p_announce) { sap_handler_t *p_sap; p_sap = vlc_custom_create (p_announce, sizeof (*p_sap), VLC_OBJECT_GENERIC, "sap sender"); if (p_sap == NULL) return NULL; vlc_object_attach( p_sap, p_announce ); vlc_mutex_init (&p_sap->lock); p_sap->first = NULL; return p_sap; }
CThread::CThread(vlc_object_t *pOwner) { m_bTerminated = ATMO_FALSE; m_pAtmoThread = (atmo_thread_t *)vlc_object_create( pOwner, sizeof(atmo_thread_t) ); if(m_pAtmoThread) { m_pAtmoThread->p_thread = this; this->m_pOwner = pOwner; vlc_object_attach( m_pAtmoThread, m_pOwner); vlc_mutex_init( &m_TerminateLock ); vlc_cond_init( &m_TerminateCond ); } }
/** * Allocates a client's TLS credentials and shakes hands through the network. * This is a blocking network operation. * * @param fd stream socket through which to establish the secure communication * layer. * @param psz_hostname Server Name Indication to pass to the server, or NULL. * * @return NULL on error. **/ tls_session_t * tls_ClientCreate (vlc_object_t *obj, int fd, const char *psz_hostname) { tls_session_t *cl; int val; cl = (tls_session_t *)vlc_custom_create (obj, sizeof (*cl), VLC_OBJECT_GENERIC, "tls client"); if (cl == NULL) return NULL; var_Create (cl, "tls-server-name", VLC_VAR_STRING); if (psz_hostname != NULL) { msg_Dbg (cl, "requested server name: %s", psz_hostname); var_SetString (cl, "tls-server-name", psz_hostname); } else msg_Dbg (cl, "requested anonymous server"); vlc_object_attach (cl, obj); cl->p_module = module_need (cl, "tls client", NULL, false ); if (cl->p_module == NULL) { msg_Err (cl, "TLS client plugin not available"); vlc_object_release (cl); return NULL; } cl->pf_set_fd (cl, fd); do val = cl->pf_handshake (cl); while (val > 0); if (val == 0) { msg_Dbg (cl, "TLS client session initialized"); return cl; } msg_Err (cl, "TLS client session handshake error"); module_unneed (cl, cl->p_module); vlc_object_release (cl); return NULL; }
vout_window_t *vout_window_New(vlc_object_t *obj, const char *module, const vout_window_cfg_t *cfg) { static char const name[] = "window"; window_t *w = vlc_custom_create(obj, sizeof(*w), VLC_OBJECT_GENERIC, name); vout_window_t *window = &w->wnd; window->cfg = cfg; memset(&window->handle, 0, sizeof(window->handle)); window->control = NULL; window->sys = NULL; vlc_object_attach(window, obj); const char *type; switch (cfg->type) { case VOUT_WINDOW_TYPE_HWND: type = "vout window hwnd"; break; case VOUT_WINDOW_TYPE_XID: type = "vout window xid"; break; default: assert(0); } w->module = module_need(window, type, module, module && *module != '\0'); if (!w->module) { vlc_object_detach(window); vlc_object_release(window); return NULL; } /* Hook for screensaver inhibition */ if (cfg->type == VOUT_WINDOW_TYPE_XID) { w->inhibit = vlc_inhibit_Create (VLC_OBJECT (window), window->handle.xid); if (w->inhibit != NULL) vlc_inhibit_Set (w->inhibit, true); /* FIXME: ^ wait for vout activation, pause */ } else w->inhibit = NULL; return window; }
int playlist_Export( playlist_t * p_playlist, const char *psz_filename, playlist_item_t *p_export_root, const char *psz_type ) { if( p_export_root == NULL ) return VLC_EGENERIC; playlist_export_t *p_export = vlc_custom_create( p_playlist, sizeof( *p_export ), VLC_OBJECT_GENERIC, "playlist export" ); if( !p_export ) return VLC_ENOMEM; vlc_object_attach( p_export, p_playlist ); msg_Dbg( p_export, "saving %s to file %s", p_export_root->p_input->psz_name, psz_filename ); int ret = VLC_EGENERIC; /* Prepare the playlist_export_t structure */ p_export->p_root = p_export_root; p_export->psz_filename = psz_filename; p_export->p_file = vlc_fopen( psz_filename, "wt" ); if( p_export->p_file == NULL ) msg_Err( p_export, "could not create playlist file %s (%m)", psz_filename ); else { module_t *p_module; /* And call the module ! All work is done now */ playlist_Lock( p_playlist ); p_module = module_need( p_export, "playlist export", psz_type, true ); playlist_Unlock( p_playlist ); if( p_module == NULL ) msg_Err( p_playlist, "could not export playlist" ); else { module_unneed( p_export, p_module ); ret = VLC_SUCCESS; } fclose( p_export->p_file ); } vlc_object_release( p_export ); return ret; }
/***************************************************************************** * vout_RequestWindow: Create/Get a video window if possible. ***************************************************************************** * This function looks for the main interface and tries to request * a new video window. If it fails then the vout will still need to create the * window by itself. *****************************************************************************/ void *vout_RequestWindow( vout_thread_t *p_vout, int *pi_x_hint, int *pi_y_hint, unsigned int *pi_width_hint, unsigned int *pi_height_hint ) { /* Small kludge */ if( !var_Type( p_vout, "aspect-ratio" ) ) vout_IntfInit( p_vout ); /* Get requested coordinates */ *pi_x_hint = var_GetInteger( p_vout, "video-x" ); *pi_y_hint = var_GetInteger( p_vout, "video-y" ); *pi_width_hint = p_vout->i_window_width; *pi_height_hint = p_vout->i_window_height; /* Check whether someone provided us with a window ID */ int drawable = var_CreateGetInteger( p_vout, "drawable" ); if( drawable ) return (void *)(intptr_t)drawable; vout_window_t *wnd = vlc_custom_create (VLC_OBJECT(p_vout), sizeof (*wnd), VLC_OBJECT_GENERIC, "window"); if (wnd == NULL) return NULL; wnd->vout = p_vout; wnd->width = *pi_width_hint; wnd->height = *pi_height_hint; wnd->pos_x = *pi_x_hint; wnd->pos_y = *pi_y_hint; vlc_object_attach (wnd, p_vout); wnd->module = module_Need (wnd, "vout window", 0, 0); if (wnd->module == NULL) { msg_Dbg (wnd, "no window provider available"); vlc_object_release (wnd); return NULL; } p_vout->p_window = wnd; *pi_width_hint = wnd->width; *pi_height_hint = wnd->height; *pi_x_hint = wnd->pos_x; *pi_y_hint = wnd->pos_y; return wnd->handle; }
/** * Create the announce handler object * * \param p_this a vlc_object structure * \return the new announce handler or NULL on error */ announce_handler_t *__announce_HandlerCreate( vlc_object_t *p_this ) { announce_handler_t *p_announce; p_announce = vlc_object_create( p_this, VLC_OBJECT_ANNOUNCE ); if( !p_announce ) { msg_Err( p_this, "out of memory" ); return NULL; } p_announce->p_sap = NULL; vlc_object_attach( p_announce, p_this->p_vlc); return p_announce; }
/** * Create the interface, and prepare it for main loop. * * \param p_this the calling vlc_object_t * \param psz_module a preferred interface module * \return a pointer to the created interface thread, NULL on error */ intf_thread_t* __intf_Create( vlc_object_t *p_this, const char *psz_module ) { intf_thread_t * p_intf; /* Allocate structure */ p_intf = vlc_object_create( p_this, VLC_OBJECT_INTF ); if( !p_intf ) return NULL; p_intf->b_interaction = false; #if defined( __APPLE__ ) || defined( WIN32 ) p_intf->b_should_run_on_first_thread = false; #endif /* Choose the best module */ p_intf->psz_intf = strdup( psz_module ); p_intf->p_module = module_Need( p_intf, "interface", psz_module, false ); if( p_intf->p_module == NULL ) { msg_Err( p_intf, "no suitable interface module" ); free( p_intf->psz_intf ); vlc_object_release( p_intf ); return NULL; } /* Initialize structure */ p_intf->b_menu = false; p_intf->b_menu_change = false; /* Initialize mutexes */ vlc_mutex_init( &p_intf->change_lock ); /* Attach interface to its parent object */ vlc_object_attach( p_intf, p_this ); vlc_object_set_destructor( p_intf, intf_Destroy ); return p_intf; }
video_splitter_t *video_splitter_New( vlc_object_t *p_this, const char *psz_name, const video_format_t *p_fmt ) { video_splitter_t *p_splitter = vlc_custom_create( p_this, sizeof(*p_splitter), VLC_OBJECT_GENERIC, "video splitter" ); if( !p_splitter ) return NULL; video_format_Copy( &p_splitter->fmt, p_fmt ); /* */ vlc_object_attach( p_splitter, p_this ); p_splitter->p_module = module_need( p_splitter, "video splitter", psz_name, true ); if( ! p_splitter->p_module ) { video_splitter_Delete( p_splitter ); return NULL; } return p_splitter; }
/** * Creates a video output window. * On Unix systems, this is an X11 drawable (handle). * On Windows, this is a Win32 window (handle). * Video output plugins are supposed to called this function and display the * video within the resulting window, while in windowed mode. * * @param p_vout video output thread to create a window for * @param psz_cap VLC module capability (window system type) * @param pi_x_hint pointer to store the recommended horizontal position [OUT] * @param pi_y_hint pointer to store the recommended vertical position [OUT] * @param pi_width_hint pointer to store the recommended width [OUT] * @param pi_height_hint pointer to store the recommended height [OUT] * * @return a vout_window_t object, or NULL in case of failure. * The window is released with vout_ReleaseWindow(). */ vout_window_t *vout_RequestWindow( vout_thread_t *p_vout, const char *psz_cap, int *pi_x_hint, int *pi_y_hint, unsigned int *pi_width_hint, unsigned int *pi_height_hint ) { /* Get requested coordinates */ *pi_x_hint = var_GetInteger( p_vout, "video-x" ); *pi_y_hint = var_GetInteger( p_vout, "video-y" ); *pi_width_hint = p_vout->i_window_width; *pi_height_hint = p_vout->i_window_height; vout_window_t *wnd = vlc_custom_create (VLC_OBJECT(p_vout), sizeof (*wnd), VLC_OBJECT_GENERIC, "window"); if (wnd == NULL) return NULL; wnd->vout = p_vout; wnd->width = *pi_width_hint; wnd->height = *pi_height_hint; wnd->pos_x = *pi_x_hint; wnd->pos_y = *pi_y_hint; vlc_object_attach (wnd, p_vout); wnd->module = module_need (wnd, psz_cap, NULL, false); if (wnd->module == NULL) { msg_Dbg (wnd, "no \"%s\" window provider available", psz_cap); vlc_object_release (wnd); return NULL; } *pi_width_hint = wnd->width; *pi_height_hint = wnd->height; *pi_x_hint = wnd->pos_x; *pi_y_hint = wnd->pos_y; return wnd; }
/** * Allocates a whole server's TLS credentials. * * @param cert_path required (Unicode) path to an x509 certificate, * if NULL, anonymous key exchange will be used. * @param key_path (UTF-8) path to the PKCS private key for the certificate, * if NULL; cert_path will be used. * * @return NULL on error. */ tls_server_t * tls_ServerCreate (vlc_object_t *obj, const char *cert_path, const char *key_path) { tls_server_t *srv; srv = (tls_server_t *)vlc_custom_create (obj, sizeof (*srv), VLC_OBJECT_GENERIC, "tls server"); if (srv == NULL) return NULL; var_Create (srv, "tls-x509-cert", VLC_VAR_STRING); var_Create (srv, "tls-x509-key", VLC_VAR_STRING); if (cert_path != NULL) { var_SetString (srv, "tls-x509-cert", cert_path); if (key_path == NULL) key_path = cert_path; var_SetString (srv, "tls-x509-key", key_path); } vlc_object_attach (srv, obj); srv->p_module = module_need (srv, "tls server", NULL, false ); if (srv->p_module == NULL) { msg_Err (srv, "TLS server plugin not available"); vlc_object_release (srv); return NULL; } msg_Dbg (srv, "TLS server plugin initialized"); return srv; }
/*********************************************************************** * Create ***********************************************************************/ services_discovery_t * services_discovery_Create ( vlc_object_t * p_super, const char * psz_module_name ) { services_discovery_t *p_sd; p_sd = vlc_custom_create( p_super, sizeof( *p_sd ), VLC_OBJECT_GENERIC, "services discovery" ); if( !p_sd ) return NULL; p_sd->pf_run = NULL; p_sd->psz_localized_name = NULL; vlc_event_manager_init( &p_sd->event_manager, p_sd, (vlc_object_t *)p_sd ); vlc_event_manager_register_event_type( &p_sd->event_manager, vlc_ServicesDiscoveryItemAdded ); vlc_event_manager_register_event_type( &p_sd->event_manager, vlc_ServicesDiscoveryItemRemoved ); vlc_event_manager_register_event_type( &p_sd->event_manager, vlc_ServicesDiscoveryStarted ); vlc_event_manager_register_event_type( &p_sd->event_manager, vlc_ServicesDiscoveryEnded ); p_sd->p_module = module_Need( p_sd, "services_discovery", psz_module_name, true ); if( p_sd->p_module == NULL ) { msg_Err( p_super, "no suitable services discovery module" ); vlc_object_release( p_sd ); return NULL; } p_sd->psz_module = strdup( psz_module_name ); p_sd->b_die = false; /* FIXME */ vlc_object_attach( p_sd, p_super ); return p_sd; }
/***************************************************************************** * Thread: *****************************************************************************/ static void Thread( vlc_object_t *p_this ) { galaktos_thread_t *p_thread = (galaktos_thread_t*)p_this; int count=0; double realfps=0,fpsstart=0; int timed=0; int timestart=0; int mspf=0; /* Get on OpenGL provider */ p_thread->p_opengl = (vout_thread_t *)vlc_object_create( p_this, VLC_OBJECT_OPENGL ); if( p_thread->p_opengl == NULL ) { msg_Err( p_thread, "out of memory" ); return; } vlc_object_attach( p_thread->p_opengl, p_this ); /* Initialize vout parameters */ vout_InitFormat( &p_thread->p_opengl->fmt_in, VLC_FOURCC('R','V','3','2'), p_thread->i_width, p_thread->i_height, 1 ); p_thread->p_opengl->i_window_width = p_thread->i_width; p_thread->p_opengl->i_window_height = p_thread->i_height; p_thread->p_opengl->render.i_width = p_thread->i_width; p_thread->p_opengl->render.i_height = p_thread->i_width; p_thread->p_opengl->render.i_aspect = VOUT_ASPECT_FACTOR; p_thread->p_opengl->b_scale = VLC_TRUE; p_thread->p_opengl->b_fullscreen = VLC_FALSE; p_thread->p_opengl->i_alignment = 0; p_thread->p_opengl->fmt_in.i_sar_num = 1; p_thread->p_opengl->fmt_in.i_sar_den = 1; p_thread->p_opengl->fmt_render = p_thread->p_opengl->fmt_in; p_thread->p_module = module_Need( p_thread->p_opengl, "opengl provider", NULL, 0 ); if( p_thread->p_module == NULL ) { msg_Err( p_thread, "unable to initialize OpenGL" ); vlc_object_detach( p_thread->p_opengl ); vlc_object_destroy( p_thread->p_opengl ); return; } p_thread->p_opengl->pf_init( p_thread->p_opengl ); setup_opengl( p_thread->i_width, p_thread->i_height ); CreateRenderTarget(512, &RenderTargetTextureID, NULL); timestart=mdate()/1000; while( !p_thread->b_die ) { mspf = 1000 / 60; if( galaktos_update( p_thread ) == 1 ) { p_thread->b_die = 1; } if( p_thread->psz_title ) { free( p_thread->psz_title ); p_thread->psz_title = NULL; } if (++count%100==0) { realfps=100/((mdate()/1000-fpsstart)/1000); // printf("%f\n",realfps); fpsstart=mdate()/1000; } //framerate limiter timed=mspf-(mdate()/1000-timestart); // printf("%d,%d\n",time,mspf); if (timed>0) msleep(1000*timed); // printf("Limiter %d\n",(mdate()/1000-timestart)); timestart=mdate()/1000; } /* Free the openGL provider */ module_Unneed( p_thread->p_opengl, p_thread->p_module ); vlc_object_detach( p_thread->p_opengl ); vlc_object_destroy( p_thread->p_opengl ); }
static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt ) { sout_stream_sys_t *p_sys = p_stream->p_sys; sout_stream_id_t *id; id = calloc( 1, sizeof( sout_stream_id_t ) ); if( !id ) goto error; id->id = NULL; id->p_decoder = NULL; id->p_encoder = NULL; /* Create decoder object */ id->p_decoder = vlc_object_create( p_stream, sizeof( decoder_t ) ); if( !id->p_decoder ) goto error; vlc_object_attach( id->p_decoder, p_stream ); id->p_decoder->p_module = NULL; id->p_decoder->fmt_in = *p_fmt; id->p_decoder->b_pace_control = true; /* Create encoder object */ id->p_encoder = sout_EncoderCreate( p_stream ); if( !id->p_encoder ) goto error; vlc_object_attach( id->p_encoder, p_stream ); id->p_encoder->p_module = NULL; /* Create destination format */ es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 ); id->p_encoder->fmt_out.i_id = p_fmt->i_id; id->p_encoder->fmt_out.i_group = p_fmt->i_group; if( p_sys->psz_alang ) id->p_encoder->fmt_out.psz_language = strdup( p_sys->psz_alang ); else if( p_fmt->psz_language ) id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language ); bool success; if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) ) success = transcode_audio_add(p_stream, p_fmt, id); else if( p_fmt->i_cat == VIDEO_ES && (p_sys->i_vcodec || p_sys->psz_venc) ) success = transcode_video_add(p_stream, p_fmt, id); else if( ( p_fmt->i_cat == SPU_ES ) && ( p_sys->i_scodec || p_sys->psz_senc || p_sys->b_soverlay ) ) success = transcode_spu_add(p_stream, p_fmt, id); else if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) ) success = transcode_osd_add(p_stream, p_fmt, id); else { msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')", (char*)&p_fmt->i_codec ); id->id = sout_StreamIdAdd( p_stream->p_next, p_fmt ); id->b_transcode = false; success = id->id; } if(!success) goto error; return id; error: if( id ) { if( id->p_decoder ) { vlc_object_release( id->p_decoder ); id->p_decoder = NULL; } if( id->p_encoder ) { es_format_Clean( &id->p_encoder->fmt_out ); vlc_object_release( id->p_encoder ); id->p_encoder = NULL; } free( id ); } return NULL; }
/***************************************************************************** * Init: initialize logo video thread output method *****************************************************************************/ static int Init( vout_thread_t *p_vout ) { vout_sys_t *p_sys = p_vout->p_sys; picture_t *p_pic; int i_index; I_OUTPUTPICTURES = 0; /* Initialize the output structure */ p_vout->output.i_chroma = p_vout->render.i_chroma; p_vout->output.i_width = p_vout->render.i_width; p_vout->output.i_height = p_vout->render.i_height; p_vout->output.i_aspect = p_vout->render.i_aspect; /* Load the video blending filter */ p_sys->p_blend = vlc_object_create( p_vout, sizeof(filter_t) ); vlc_object_attach( p_sys->p_blend, p_vout ); p_sys->p_blend->fmt_out.video.i_x_offset = p_sys->p_blend->fmt_out.video.i_y_offset = 0; p_sys->p_blend->fmt_in.video.i_x_offset = p_sys->p_blend->fmt_in.video.i_y_offset = 0; p_sys->p_blend->fmt_out.video.i_aspect = p_vout->render.i_aspect; p_sys->p_blend->fmt_out.video.i_chroma = p_vout->output.i_chroma; p_sys->p_blend->fmt_in.video.i_chroma = VLC_FOURCC('Y','U','V','A'); p_sys->p_blend->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR; p_sys->p_blend->fmt_in.video.i_width = p_sys->p_blend->fmt_in.video.i_visible_width = p_sys->p_pic->p[Y_PLANE].i_visible_pitch; p_sys->p_blend->fmt_in.video.i_height = p_sys->p_blend->fmt_in.video.i_visible_height = p_sys->p_pic->p[Y_PLANE].i_visible_lines; p_sys->p_blend->fmt_out.video.i_width = p_sys->p_blend->fmt_out.video.i_visible_width = p_vout->output.i_width; p_sys->p_blend->fmt_out.video.i_height = p_sys->p_blend->fmt_out.video.i_visible_height = p_vout->output.i_height; p_sys->p_blend->p_module = module_Need( p_sys->p_blend, "video blending", 0, 0 ); if( !p_sys->p_blend->p_module ) { msg_Err( p_vout, "can't open blending filter, aborting" ); vlc_object_detach( p_sys->p_blend ); vlc_object_destroy( p_sys->p_blend ); return VLC_EGENERIC; } if( p_sys->posx < 0 || p_sys->posy < 0 ) { p_sys->posx = 0; p_sys->posy = 0; if( p_sys->pos & SUBPICTURE_ALIGN_BOTTOM ) { p_sys->posy = p_vout->render.i_height - p_sys->i_height; } else if ( !(p_sys->pos & SUBPICTURE_ALIGN_TOP) ) { p_sys->posy = p_vout->render.i_height / 2 - p_sys->i_height / 2; } if( p_sys->pos & SUBPICTURE_ALIGN_RIGHT ) { p_sys->posx = p_vout->render.i_width - p_sys->i_width; } else if ( !(p_sys->pos & SUBPICTURE_ALIGN_LEFT) ) { p_sys->posx = p_vout->render.i_width / 2 - p_sys->i_width / 2; } } /* Try to open the real video output */ msg_Dbg( p_vout, "spawning the real video output" ); p_sys->p_vout = vout_Create( p_vout, p_vout->render.i_width, p_vout->render.i_height, p_vout->render.i_chroma, p_vout->render.i_aspect ); /* Everything failed */ if( p_sys->p_vout == NULL ) { msg_Err( p_vout, "can't open vout, aborting" ); return VLC_EGENERIC; } var_AddCallback( p_sys->p_vout, "mouse-x", MouseEvent, p_vout); var_AddCallback( p_sys->p_vout, "mouse-y", MouseEvent, p_vout); ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); ADD_CALLBACKS( p_sys->p_vout, SendEvents ); ADD_PARENT_CALLBACKS( SendEventsToChild ); return VLC_SUCCESS; }
/** * Create playlist * * Create a playlist structure. * \param p_parent the vlc object that is to be the parent of this playlist * \return a pointer to the created playlist, or NULL on error */ playlist_t * __playlist_Create ( vlc_object_t *p_parent ) { playlist_t *p_playlist; vlc_value_t val; /* Allocate structure */ p_playlist = vlc_object_create( p_parent, VLC_OBJECT_PLAYLIST ); if( !p_playlist ) { msg_Err( p_parent, "out of memory" ); return NULL; } var_Create( p_playlist, "intf-change", VLC_VAR_BOOL ); val.b_bool = VLC_TRUE; var_Set( p_playlist, "intf-change", val ); var_Create( p_playlist, "item-change", VLC_VAR_INTEGER ); val.i_int = -1; var_Set( p_playlist, "item-change", val ); var_Create( p_playlist, "playlist-current", VLC_VAR_INTEGER ); val.i_int = -1; var_Set( p_playlist, "playlist-current", val ); var_Create( p_playlist, "intf-popupmenu", VLC_VAR_BOOL ); var_Create( p_playlist, "intf-show", VLC_VAR_BOOL ); val.b_bool = VLC_TRUE; var_Set( p_playlist, "intf-show", val ); var_Create( p_playlist, "prevent-skip", VLC_VAR_BOOL ); val.b_bool = VLC_FALSE; var_Set( p_playlist, "prevent-skip", val ); var_Create( p_playlist, "play-and-stop", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_playlist, "random", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_playlist, "repeat", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_playlist, "loop", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); p_playlist->p_input = NULL; p_playlist->i_status = PLAYLIST_STOPPED; p_playlist->i_index = -1; p_playlist->i_size = 0; p_playlist->pp_items = NULL; p_playlist->i_groups = 0; p_playlist->pp_groups = NULL; p_playlist->i_last_group = 0; p_playlist->i_last_id = 0; p_playlist->i_sort = SORT_ID; p_playlist->i_order = ORDER_NORMAL; playlist_CreateGroup( p_playlist, _("Normal") ); if( vlc_thread_create( p_playlist, "playlist", RunThread, VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) ) { msg_Err( p_playlist, "cannot spawn playlist thread" ); vlc_object_destroy( p_playlist ); return NULL; } /* The object has been initialized, now attach it */ vlc_object_attach( p_playlist, p_parent ); return p_playlist; }
/***************************************************************************** * Open: open the rtmp connection *****************************************************************************/ static int Open( vlc_object_t *p_this ) { sout_access_out_t *p_access = (sout_access_out_t *) p_this; sout_access_out_sys_t *p_sys; char *psz, *p; int length_path, length_media_name; int i; if( !( p_sys = calloc ( 1, sizeof( sout_access_out_sys_t ) ) ) ) return VLC_ENOMEM; p_access->p_sys = p_sys; p_sys->p_thread = vlc_object_create( p_access, sizeof( rtmp_control_thread_t ) ); if( !p_sys->p_thread ) { free( p_sys ); return VLC_ENOMEM; } vlc_object_attach( p_sys->p_thread, p_access ); /* Parse URI - remove spaces */ p = psz = strdup( p_access->psz_path ); while( ( p = strchr( p, ' ' ) ) != NULL ) *p = '+'; vlc_UrlParse( &p_sys->p_thread->url, psz, 0 ); free( psz ); if( p_sys->p_thread->url.psz_host == NULL || *p_sys->p_thread->url.psz_host == '\0' ) { msg_Warn( p_access, "invalid host" ); goto error; } if( p_sys->p_thread->url.i_port <= 0 ) p_sys->p_thread->url.i_port = 1935; if ( p_sys->p_thread->url.psz_path == NULL ) { msg_Warn( p_access, "invalid path" ); goto error; } length_path = strlen( p_sys->p_thread->url.psz_path ); char* psz_tmp = strrchr( p_sys->p_thread->url.psz_path, '/' ); if( !psz_tmp ) goto error; length_media_name = strlen( psz_tmp ) - 1; p_sys->p_thread->psz_application = strndup( p_sys->p_thread->url.psz_path + 1, length_path - length_media_name - 2 ); p_sys->p_thread->psz_media = strdup( p_sys->p_thread->url.psz_path + ( length_path - length_media_name ) ); msg_Dbg( p_access, "rtmp: host='%s' port=%d path='%s'", p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port, p_sys->p_thread->url.psz_path ); if( p_sys->p_thread->url.psz_username && *p_sys->p_thread->url.psz_username ) { msg_Dbg( p_access, " user='******'", p_sys->p_thread->url.psz_username ); } /* Initialize thread variables */ p_sys->p_thread->b_error= 0; p_sys->p_thread->p_fifo_input = block_FifoNew(); p_sys->p_thread->p_empty_blocks = block_FifoNew(); p_sys->p_thread->has_audio = 0; p_sys->p_thread->has_video = 0; p_sys->p_thread->metadata_received = 0; p_sys->p_thread->first_media_packet = 1; p_sys->p_thread->flv_tag_previous_tag_size = 0x00000000; /* FLV_TAG_FIRST_PREVIOUS_TAG_SIZE */ p_sys->p_thread->flv_body = rtmp_body_new( -1 ); p_sys->p_thread->flv_length_body = 0; p_sys->p_thread->chunk_size_recv = 128; /* RTMP_DEFAULT_CHUNK_SIZE */ p_sys->p_thread->chunk_size_send = 128; /* RTMP_DEFAULT_CHUNK_SIZE */ for(i = 0; i < 64; i++) { memset( &p_sys->p_thread->rtmp_headers_recv[i], 0, sizeof( rtmp_packet_t ) ); p_sys->p_thread->rtmp_headers_send[i].length_header = -1; p_sys->p_thread->rtmp_headers_send[i].stream_index = -1; p_sys->p_thread->rtmp_headers_send[i].timestamp = -1; p_sys->p_thread->rtmp_headers_send[i].timestamp_relative = -1; p_sys->p_thread->rtmp_headers_send[i].length_encoded = -1; p_sys->p_thread->rtmp_headers_send[i].length_body = -1; p_sys->p_thread->rtmp_headers_send[i].content_type = -1; p_sys->p_thread->rtmp_headers_send[i].src_dst = -1; p_sys->p_thread->rtmp_headers_send[i].body = NULL; } vlc_cond_init( &p_sys->p_thread->wait ); vlc_mutex_init( &p_sys->p_thread->lock ); p_sys->p_thread->result_connect = 1; /* p_sys->p_thread->result_publish = only used on access */ p_sys->p_thread->result_play = 1; p_sys->p_thread->result_stop = 0; p_sys->p_thread->fd = -1; /* Open connection */ if( var_CreateGetBool( p_access, "rtmp-connect" ) > 0 ) { #if 0 p_sys->p_thread->fd = net_ConnectTCP( p_access, p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port ); #endif msg_Err( p_access, "to be implemented" ); goto error2; } else { int *p_fd_listen; p_sys->active = 0; p_fd_listen = net_ListenTCP( p_access, p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port ); if( p_fd_listen == NULL ) { msg_Warn( p_access, "cannot listen to %s port %i", p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port ); goto error2; } do p_sys->p_thread->fd = net_Accept( p_access, p_fd_listen ); while( p_sys->p_thread->fd == -1 ); net_ListenClose( p_fd_listen ); if( rtmp_handshake_passive( p_this, p_sys->p_thread->fd ) < 0 ) { msg_Err( p_access, "handshake passive failed"); goto error2; } } if( vlc_clone( &p_sys->p_thread->thread, ThreadControl, p_sys->p_thread, VLC_THREAD_PRIORITY_INPUT ) ) { msg_Err( p_access, "cannot spawn rtmp control thread" ); goto error2; } if( !p_sys->active ) { if( rtmp_connect_passive( p_sys->p_thread ) < 0 ) { msg_Err( p_access, "connect passive failed"); vlc_cancel( p_sys->p_thread->thread ); vlc_join( p_sys->p_thread->thread, NULL ); goto error2; } } p_access->pf_write = Write; p_access->pf_seek = Seek; return VLC_SUCCESS; error2: vlc_cond_destroy( &p_sys->p_thread->wait ); vlc_mutex_destroy( &p_sys->p_thread->lock ); free( p_sys->p_thread->psz_application ); free( p_sys->p_thread->psz_media ); if( p_sys->p_thread->fd != -1 ) net_Close( p_sys->p_thread->fd ); error: vlc_UrlClean( &p_sys->p_thread->url ); vlc_object_release( p_sys->p_thread ); free( p_sys ); return VLC_EGENERIC; }
/***************************************************************************** * CreateVout: This function allocates and initializes the OpenGL vout method. *****************************************************************************/ static int CreateVout( vlc_object_t *p_this ) { vout_thread_t *p_vout = (vout_thread_t *)p_this; vout_sys_t *p_sys; char * psz; /* Allocate structure */ p_vout->p_sys = p_sys = malloc( sizeof( vout_sys_t ) ); if( p_sys == NULL ) return VLC_ENOMEM; /* Get window */ p_sys->p_vout = (vout_thread_t *)vlc_object_create( p_this, sizeof( vout_thread_t ) ); if( p_sys->p_vout == NULL ) { free( p_sys ); return VLC_ENOMEM; } vlc_object_attach( p_sys->p_vout, p_this ); p_sys->p_vout->i_window_width = p_vout->i_window_width; p_sys->p_vout->i_window_height = p_vout->i_window_height; p_sys->p_vout->b_fullscreen = p_vout->b_fullscreen; p_sys->p_vout->render.i_width = p_vout->render.i_width; p_sys->p_vout->render.i_height = p_vout->render.i_height; p_sys->p_vout->render.i_aspect = p_vout->render.i_aspect; p_sys->p_vout->fmt_render = p_vout->fmt_render; p_sys->p_vout->fmt_in = p_vout->fmt_in; p_sys->p_vout->b_autoscale = p_vout->b_autoscale; p_sys->p_vout->i_zoom = p_vout->i_zoom; p_sys->p_vout->i_alignment = p_vout->i_alignment; var_Create( p_sys->p_vout, "video-deco", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); /* Forward events from the opengl provider */ var_Create( p_sys->p_vout, "mouse-moved", VLC_VAR_COORDS ); var_Create( p_sys->p_vout, "mouse-clicked", VLC_VAR_COORDS ); var_Create( p_sys->p_vout, "mouse-button-down", VLC_VAR_INTEGER ); var_Create( p_sys->p_vout, "video-on-top", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_sys->p_vout, "autoscale", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_sys->p_vout, "scale", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); var_AddCallback( p_sys->p_vout, "mouse-moved", SendEvents, p_vout ); var_AddCallback( p_sys->p_vout, "mouse-clicked", SendEvents, p_vout ); var_AddCallback( p_sys->p_vout, "mouse-button-down", SendEvents, p_vout ); var_AddCallback( p_sys->p_vout, "video-on-top", SendEvents, p_vout ); var_AddCallback( p_vout, "autoscale", SendEvents, p_sys->p_vout ); var_AddCallback( p_vout, "scale", SendEvents, p_sys->p_vout ); psz = var_CreateGetString( p_vout, "opengl-provider" ); p_sys->p_vout->p_module = module_need( p_sys->p_vout, "opengl provider", psz, false ); free( psz ); if( p_sys->p_vout->p_module == NULL ) { msg_Warn( p_vout, "No OpenGL provider found" ); /* no need for var_DelCallback here :-) */ vlc_object_release( p_sys->p_vout ); free( p_sys ); return VLC_ENOOBJ; } p_vout->pf_init = Init; p_vout->pf_end = End; p_vout->pf_manage = Manage; p_vout->pf_render = Render; p_vout->pf_display = DisplayVideo; p_vout->pf_control = Control; return VLC_SUCCESS; }
/***************************************************************************** * OSD menu Funtions *****************************************************************************/ osd_menu_t *osd_MenuCreate( vlc_object_t *p_this, const char *psz_file ) { osd_menu_t *p_osd = NULL; vlc_value_t val; vlc_mutex_t *p_lock; int i_volume = 0; int i_steps = 0; /* to be sure to avoid multiple creation */ p_lock = osd_GetMutex( p_this ); vlc_mutex_lock( p_lock ); var_Create( p_this->p_libvlc, "osd", VLC_VAR_ADDRESS ); var_Get( p_this->p_libvlc, "osd", &val ); if( val.p_address == NULL ) { static const char osdmenu_name[] = "osd menu"; p_osd = vlc_custom_create( p_this, sizeof( *p_osd ), VLC_OBJECT_GENERIC, osdmenu_name ); if( !p_osd ) return NULL; p_osd->p_parser = NULL; vlc_object_attach( p_osd, p_this->p_libvlc ); /* Parse configuration file */ if ( !osd_ParserLoad( p_osd, psz_file ) ) goto error; if( !p_osd->p_state ) goto error; /* Setup default button (first button) */ p_osd->p_state->p_visible = p_osd->p_button; p_osd->p_state->p_visible->p_current_state = osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT ); p_osd->i_width = p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch; p_osd->i_height = p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines; if( p_osd->p_state->p_volume ) { /* Update the volume state images to match the current volume */ i_volume = config_GetInt( p_this, "volume" ); i_steps = osd_VolumeStep( p_this, i_volume, p_osd->p_state->p_volume->i_ranges ); p_osd->p_state->p_volume->p_current_state = osd_VolumeStateChange( p_osd->p_state->p_volume->p_states, i_steps ); } /* Initialize OSD state */ osd_UpdateState( p_osd->p_state, p_osd->i_x, p_osd->i_y, p_osd->i_width, p_osd->i_height, NULL ); /* Signal when an update of OSD menu is needed */ var_Create( p_osd, "osd-menu-update", VLC_VAR_BOOL ); var_Create( p_osd, "osd-menu-visible", VLC_VAR_BOOL ); var_SetBool( p_osd, "osd-menu-update", false ); var_SetBool( p_osd, "osd-menu-visible", false ); val.p_address = p_osd; var_Set( p_this->p_libvlc, "osd", val ); } else p_osd = val.p_address; vlc_object_hold( p_osd ); vlc_mutex_unlock( p_lock ); return p_osd; error: vlc_mutex_unlock( p_lock ); osd_MenuDelete( p_this, p_osd ); return NULL; }
/***************************************************************************** * 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; }
/** * ProjectM update thread which do the rendering * @param p_this: the p_thread object */ static void *Thread( void *p_data ) { filter_t *p_filter = (filter_t*)p_data; filter_sys_t *p_sys = p_filter->p_sys; int cancel = vlc_savecancel(); video_format_t fmt; vout_opengl_t *gl; int i_last_width = 0; int i_last_height = 0; #ifdef HAVE_PROJECTM2 projectM::Settings settings; #endif /* Create the openGL provider */ p_sys->p_vout = (vout_thread_t *)vlc_object_create( p_filter, sizeof(vout_thread_t) ); if( !p_sys->p_vout ) goto error; vlc_object_attach( p_sys->p_vout, p_filter ); /* */ video_format_Init( &fmt, 0 ); video_format_Setup( &fmt, VLC_CODEC_RGB32, p_sys->i_width, p_sys->i_height, 0, 1 ); fmt.i_sar_num = 1; fmt.i_sar_den = 1; vout_display_state_t state; memset( &state, 0, sizeof(state) ); state.cfg.display.sar.num = 1; state.cfg.display.sar.den = 1; state.cfg.is_display_filled = true; state.cfg.zoom.num = 1; state.cfg.zoom.den = 1; state.sar.num = 1; state.sar.den = 1; p_sys->p_vd = vout_NewDisplay( p_sys->p_vout, &fmt, &state, "opengl", 300000, 1000000 ); if( !p_sys->p_vd ) { vlc_object_release( p_sys->p_vout ); goto error; } var_Create( p_sys->p_vout, "fullscreen", VLC_VAR_BOOL ); var_AddCallback( p_sys->p_vout, "fullscreen", VoutCallback, p_sys->p_vd ); gl = vout_GetDisplayOpengl( p_sys->p_vd ); if( !gl ) { vout_DeleteDisplay( p_sys->p_vd, NULL ); vlc_object_release( p_sys->p_vout ); goto error; } /* Create the projectM object */ #ifndef HAVE_PROJECTM2 p_sys->p_projectm = new projectM( p_sys->psz_config ); #else settings.meshX = 32; settings.meshY = 24; settings.fps = 35; settings.textureSize = 1024; settings.windowWidth = p_sys->i_width; settings.windowHeight = p_sys->i_height; settings.presetURL = p_sys->psz_preset_path; settings.titleFontURL = p_sys->psz_title_font; settings.menuFontURL = p_sys->psz_menu_font; settings.smoothPresetDuration = 5; settings.presetDuration = 30; settings.beatSensitivity = 10; settings.aspectCorrection = 1; settings.easterEgg = 1; settings.shuffleEnabled = 1; p_sys->p_projectm = new projectM( settings ); #endif p_sys->i_buffer_size = p_sys->p_projectm->pcm()->maxsamples; p_sys->p_buffer = (float*)calloc( p_sys->i_buffer_size, sizeof( float ) ); vlc_sem_post( &p_sys->ready ); /* TODO: Give to projectm the name of the input p_sys->p_projectm->projectM_setTitle( "" ); */ /* */ for( ;; ) { const mtime_t i_deadline = mdate() + CLOCK_FREQ / 50; /* 50 fps max */ /* Manage the events */ vout_ManageDisplay( p_sys->p_vd, true ); if( p_sys->p_vd->cfg->display.width != i_last_width || p_sys->p_vd->cfg->display.height != i_last_height ) { /* FIXME it is not perfect as we will have black bands */ vout_display_place_t place; vout_display_PlacePicture( &place, &p_sys->p_vd->source, p_sys->p_vd->cfg, false ); p_sys->p_projectm->projectM_resetGL( place.width, place.height ); i_last_width = p_sys->p_vd->cfg->display.width; i_last_height = p_sys->p_vd->cfg->display.height; } /* Render the image and swap the buffers */ vlc_mutex_lock( &p_sys->lock ); if( p_sys->i_nb_samples > 0 ) { p_sys->p_projectm->pcm()->addPCMfloat( p_sys->p_buffer, p_sys->i_nb_samples ); p_sys->i_nb_samples = 0; } if( p_sys->b_quit ) { vlc_mutex_unlock( &p_sys->lock ); delete p_sys->p_projectm; vout_DeleteDisplay( p_sys->p_vd, NULL ); vlc_object_release( p_sys->p_vout ); return NULL; } vlc_mutex_unlock( &p_sys->lock ); p_sys->p_projectm->renderFrame(); /* */ mwait( i_deadline ); if( !vout_opengl_Lock(gl) ) { vout_opengl_Swap( gl ); vout_opengl_Unlock( gl ); } } abort(); error: p_sys->b_error = true; vlc_sem_post( &p_sys->ready ); return NULL; }