/** * Create the SAP handler * * \param p_announce the parent announce_handler * \return the newly created SAP handler or NULL on error */ sap_handler_t *announce_SAPHandlerCreate( announce_handler_t *p_announce ) { sap_handler_t *p_sap; p_sap = vlc_object_create( p_announce, sizeof( sap_handler_t ) ); if( !p_sap ) { msg_Err( p_announce, "out of memory" ); return NULL; } vlc_mutex_init( p_sap, &p_sap->object_lock ); p_sap->pf_add = announce_SAPAnnounceAdd; p_sap->pf_del = announce_SAPAnnounceDel; p_sap->i_sessions = 0; p_sap->i_addresses = 0; p_sap->i_current_session = 0; p_sap->b_control = config_GetInt( p_sap, "sap-flow-control"); if( vlc_thread_create( p_sap, "sap handler", RunThread, VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) ) { msg_Dbg( p_announce, "Unable to spawn SAP handler thread"); free( p_sap ); return NULL; }; msg_Dbg( p_announce, "thread created, %i sessions", p_sap->i_sessions); return p_sap; }
/***************************************************************************** * aout_New: initialize aout structure *****************************************************************************/ aout_instance_t * __aout_New( vlc_object_t * p_parent ) { aout_instance_t * p_aout; vlc_value_t val; /* Allocate descriptor. */ p_aout = vlc_object_create( p_parent, VLC_OBJECT_AOUT ); if( p_aout == NULL ) { return NULL; } /* Initialize members. */ vlc_mutex_init( p_parent, &p_aout->input_fifos_lock ); vlc_mutex_init( p_parent, &p_aout->mixer_lock ); vlc_mutex_init( p_parent, &p_aout->output_fifo_lock ); p_aout->i_nb_inputs = 0; p_aout->mixer.f_multiplier = 1.0; p_aout->mixer.b_error = 1; p_aout->output.b_error = 1; p_aout->output.b_starving = 1; var_Create( p_aout, "intf-change", VLC_VAR_BOOL ); val.b_bool = VLC_TRUE; var_Set( p_aout, "intf-change", val ); return p_aout; }
/***************************************************************************** * 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; }
static int Install( addons_storage_t *p_storage, addon_entry_t *p_entry ) { vlc_object_t *p_this = VLC_OBJECT( p_storage ); int i_ret = VLC_EGENERIC; if ( ! p_entry->psz_source_module ) return i_ret; /* Query origin module for download path */ addons_finder_t *p_finder = vlc_object_create( p_this, sizeof( addons_finder_t ) ); if( !p_finder ) return VLC_ENOMEM; module_t *p_module = module_need( p_finder, "addons finder", p_entry->psz_source_module, true ); if( p_module ) { if ( p_finder->pf_retrieve( p_finder, p_entry ) == VLC_SUCCESS ) { /* Do things while retrieved data is here */ vlc_mutex_lock( &p_entry->lock ); i_ret = InstallAllFiles( p_storage, p_entry ); vlc_mutex_unlock( &p_entry->lock ); /* !Do things while retrieved data is here */ } module_unneed( p_finder, p_module ); } vlc_object_release( p_finder ); return i_ret; }
static filter_t *CreateFilter( vlc_object_t *p_this, const es_format_t *p_fmt_in, vlc_fourcc_t fmt_out ) { filter_t *p_filter; p_filter = vlc_object_create( p_this, sizeof(filter_t) ); if (unlikely(p_filter == NULL)) return NULL; p_filter->owner.video.buffer_new = (picture_t *(*)(filter_t *))video_new_buffer; es_format_InitFromVideo( &p_filter->fmt_in, &p_fmt_in->video ); es_format_InitFromVideo( &p_filter->fmt_out, &p_fmt_in->video ); p_filter->fmt_in.i_codec = p_filter->fmt_in.video.i_chroma = VLC_CODEC_D3D11_OPAQUE; p_filter->fmt_out.i_codec = p_filter->fmt_out.video.i_chroma = fmt_out; p_filter->p_module = module_need( p_filter, "video filter2", NULL, false ); if( !p_filter->p_module ) { msg_Dbg( p_filter, "no video filter found" ); DeleteFilter( p_filter ); return NULL; } return p_filter; }
/***************************************************************************** * 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; }
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; }
/***************************************************************************** * Open: initializes demux structures *****************************************************************************/ static int Open( vlc_object_t * p_this ) { demux_t *p_demux = (demux_t*)p_this; demux_sys_t *p_sys; uint8_t *p_peek; vlc_value_t val; if( stream_Peek( p_demux->s, &p_peek, 5 ) < 5 ) return VLC_EGENERIC; if( p_peek[0] != 0x00 || p_peek[1] != 0x00 || p_peek[2] != 0x00 || p_peek[3] != 0x01 || (p_peek[4]&0x1F) != 7 ) /* SPS */ { if( !p_demux->b_force ) { msg_Warn( p_demux, "h264 module discarded (no startcode)" ); return VLC_EGENERIC; } msg_Err( p_demux, "this doesn't look like a H264 ES stream, " "continuing anyway" ); } p_demux->pf_demux = Demux; p_demux->pf_control= Control; p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) ); p_sys->p_es = NULL; p_sys->i_dts = 1; var_Create( p_demux, "h264-fps", VLC_VAR_FLOAT|VLC_VAR_DOINHERIT ); var_Get( p_demux, "h264-fps", &val ); p_sys->f_fps = val.f_float; if( val.f_float < 0.001 ) p_sys->f_fps = 0.001; msg_Dbg( p_demux, "using %.2f fps", p_sys->f_fps ); /* * Load the mpegvideo packetizer */ p_sys->p_packetizer = vlc_object_create( p_demux, VLC_OBJECT_PACKETIZER ); p_sys->p_packetizer->pf_decode_audio = NULL; p_sys->p_packetizer->pf_decode_video = NULL; p_sys->p_packetizer->pf_decode_sub = NULL; p_sys->p_packetizer->pf_packetize = NULL; es_format_Init( &p_sys->p_packetizer->fmt_in, VIDEO_ES, VLC_FOURCC( 'h', '2', '6', '4' ) ); es_format_Init( &p_sys->p_packetizer->fmt_out, UNKNOWN_ES, 0 ); p_sys->p_packetizer->p_module = module_Need( p_sys->p_packetizer, "packetizer", NULL, 0 ); if( p_sys->p_packetizer->p_module == NULL) { vlc_object_destroy( p_sys->p_packetizer ); msg_Err( p_demux, "cannot find mp4v packetizer" ); free( p_sys ); return VLC_EGENERIC; } return VLC_SUCCESS; }
/***************************************************************************** * 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; }
int playlist_MLLoad( playlist_t *p_playlist ) { input_item_t *p_input; char *psz_datadir = config_GetUserDir( VLC_DATA_DIR ); if( !psz_datadir ) /* XXX: This should never happen */ { msg_Err( p_playlist, "no data directory, cannot load media library") ; return VLC_EGENERIC; } char *psz_file; if( asprintf( &psz_file, "%s" DIR_SEP "ml.xspf", psz_datadir ) == -1 ) psz_file = NULL; free( psz_datadir ); if( psz_file == NULL ) return VLC_ENOMEM; /* lousy check for media library file */ struct stat st; if( vlc_stat( psz_file, &st ) ) { free( psz_file ); return VLC_EGENERIC; } char *psz_uri = vlc_path2uri( psz_file, "file/xspf-open" ); free( psz_file ); if( psz_uri == NULL ) return VLC_ENOMEM; p_input = input_item_New( psz_uri, _("Media Library") ); free( psz_uri ); if( p_input == NULL ) return VLC_EGENERIC; PL_LOCK; if( p_playlist->p_media_library->p_input ) vlc_gc_decref( p_playlist->p_media_library->p_input ); p_playlist->p_media_library->p_input = p_input; vlc_event_attach( &p_input->event_manager, vlc_InputItemSubItemTreeAdded, input_item_subitem_tree_added, p_playlist ); PL_UNLOCK; vlc_object_t *dummy = vlc_object_create( p_playlist, sizeof (*dummy) ); var_Create( dummy, "meta-file", VLC_VAR_VOID ); input_Read( dummy, p_input ); vlc_object_release( dummy ); vlc_event_detach( &p_input->event_manager, vlc_InputItemSubItemTreeAdded, input_item_subitem_tree_added, p_playlist ); return VLC_SUCCESS; }
/***************************************************************************** * Render: displays previously rendered output *****************************************************************************/ static picture_t *Filter( filter_t *p_filter, picture_t *p_pic ) { filter_sys_t *p_sys = p_filter->p_sys; filter_t *p_blend; if( p_sys->b_done ) return p_pic; p_blend = vlc_object_create( p_filter, sizeof(filter_t) ); if( !p_blend ) { picture_Release( p_pic ); return NULL; } p_blend->fmt_out.video = p_sys->p_base_image->format; p_blend->fmt_in.video = p_sys->p_blend_image->format; p_blend->p_module = module_need( p_blend, "video blending", NULL, false ); if( !p_blend->p_module ) { picture_Release( p_pic ); vlc_object_delete(p_blend); return NULL; } vlc_tick_t time = vlc_tick_now(); for( int i_iter = 0; i_iter < p_sys->i_loops; ++i_iter ) { p_blend->pf_video_blend( p_blend, p_sys->p_base_image, p_sys->p_blend_image, 0, 0, p_sys->i_alpha ); } time = vlc_tick_now() - time; msg_Info( p_filter, "Blended %d images in %f sec", p_sys->i_loops, secf_from_vlc_tick(time) ); msg_Info( p_filter, "Speed is: %f images/second, %f pixels/second", (float) p_sys->i_loops / time * CLOCK_FREQ, (float) p_sys->i_loops / time * CLOCK_FREQ * p_sys->p_blend_image->p[Y_PLANE].i_visible_pitch * p_sys->p_blend_image->p[Y_PLANE].i_visible_lines ); module_unneed( p_blend, p_blend->p_module ); vlc_object_delete(p_blend); p_sys->b_done = true; return p_pic; }
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 ); } }
/** * 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; }
/***************************************************************************** * Open: initialize and create window *****************************************************************************/ static int Open( vlc_object_t *p_this ) { vlc_value_t lockval; /* FIXME: put this in the module (de)initialization ASAP */ var_Create( p_this->p_libvlc, "gtk", VLC_VAR_MUTEX ); var_Get( p_this->p_libvlc, "gtk", &lockval ); vlc_mutex_lock( lockval.p_address ); if( i_refcount > 0 ) { i_refcount++; vlc_mutex_unlock( lockval.p_address ); return VLC_SUCCESS; } p_gtk_main = vlc_object_create( p_this, VLC_OBJECT_GENERIC ); /* Only initialize gthreads if it's the first time we do it */ if( !g_thread_supported() ) { g_thread_init( NULL ); } /* Launch the gtk_main() thread. It will not return until it has * called gdk_threads_enter(), which ensures us thread safety. */ if( vlc_thread_create( p_gtk_main, "gtk_main", GtkMain, VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) ) { vlc_object_destroy( p_gtk_main ); i_refcount--; vlc_mutex_unlock( lockval.p_address ); var_Destroy( p_this->p_libvlc, "gtk" ); return VLC_ETHREAD; } i_refcount++; vlc_mutex_unlock( lockval.p_address ); return VLC_SUCCESS; }
int playlist_Import( playlist_t *p_playlist, const char *psz_file ) { input_item_t *p_input; char *psz_uri = vlc_path2uri( psz_file, NULL ); if( psz_uri == NULL ) return VLC_EGENERIC; p_input = input_item_New( psz_uri, psz_file ); free( psz_uri ); playlist_AddInput( p_playlist, p_input, false, true ); vlc_object_t *dummy = vlc_object_create( p_playlist, sizeof (*dummy) ); var_Create( dummy, "meta-file", VLC_VAR_VOID ); int ret = input_Read( dummy, p_input ); vlc_object_release( dummy ); return ret; }
/** * 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; }
static int Open( vlc_object_t *p_this ) { filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys = (filter_sys_t *)vlc_object_create( p_this, sizeof( *p_sys ) ); // sunqueen modify if( unlikely( p_sys == NULL ) ) return VLC_ENOMEM; p_filter->p_sys = p_sys; p_sys->volume.format = p_filter->fmt_in.audio.i_format; p_sys->module = module_need( &p_sys->volume, "audio volume", NULL, false ); if( p_sys->module == NULL ) { msg_Warn( p_filter, "unsupported format" ); vlc_object_release( &p_sys->volume ); return VLC_EGENERIC; } p_sys->f_gain = var_InheritFloat( p_filter->p_parent, "gain-value" ); msg_Dbg( p_filter, "gain multiplier sets to %.2fx", p_sys->f_gain ); p_filter->fmt_out.audio = p_filter->fmt_in.audio; p_filter->pf_audio_filter = Process; return VLC_SUCCESS; }
/***************************************************************************** * Dummy: used by stress-test, creates objects and then do nothing. *****************************************************************************/ static void * Dummy( vlc_object_t *p_this ) { int i; vlc_object_t *pp_objects[MAXOBJ/MAXTH]; for( i = 0; i < MAXOBJ/MAXTH; i++ ) { pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC ); } vlc_thread_ready( p_this ); while( !p_this->b_die ) { msleep( 10000 ); } for( i = MAXOBJ/MAXTH; i--; ) { vlc_object_destroy( pp_objects[i] ); } return NULL; }
/** * Creates a Vulkan surface (and its underlying instance). * * @param wnd window to use as Vulkan surface * @param name module name (or NULL for auto) * @return a new context, or NULL on failure */ vlc_vk_t *vlc_vk_Create(struct vout_window_t *wnd, const char *name) { vlc_object_t *parent = (vlc_object_t *) wnd; struct vlc_vk_t *vk; vk = vlc_object_create(parent, sizeof (*vk)); if (unlikely(vk == NULL)) return NULL; vk->ctx = NULL; vk->instance = NULL; vk->surface = (VkSurfaceKHR) NULL; vk->window = wnd; vk->module = module_need(vk, "vulkan", name, true); if (vk->module == NULL) { vlc_object_delete(vk); return NULL; } vlc_atomic_rc_init(&vk->ref_count); return vk; }
static filter_t *ResamplerCreate(filter_t *p_filter) { filter_t *p_resampler = vlc_object_create( p_filter, sizeof (filter_t) ); if( unlikely( p_resampler == NULL ) ) return NULL; p_resampler->owner.sys = NULL; p_resampler->p_cfg = NULL; p_resampler->fmt_in = p_filter->fmt_in; p_resampler->fmt_out = p_filter->fmt_in; p_resampler->fmt_out.audio.i_rate = vlc_atomic_load_float( &p_filter->p_sys->rate_shift ); aout_FormatPrepare( &p_resampler->fmt_out.audio ); p_resampler->p_module = module_need( p_resampler, "audio resampler", NULL, false ); if( p_resampler->p_module == NULL ) { msg_Err( p_filter, "Could not load resampler" ); vlc_object_release( p_resampler ); return NULL; } return p_resampler; }
/***************************************************************************** * 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; }
/************************************************************************** * Create a Media Instance object. * * Refcount strategy: * - All items created by _new start with a refcount set to 1. * - Accessor _release decrease the refcount by 1, if after that * operation the refcount is 0, the object is destroyed. * - Accessor _retain increase the refcount by 1 (XXX: to implement) * * Object locking strategy: * - No lock held while in constructor. * - When accessing any member variable this lock is held. (XXX who locks?) * - When attempting to destroy the object the lock is also held. **************************************************************************/ libvlc_media_player_t * libvlc_media_player_new( libvlc_instance_t *instance ) { libvlc_media_player_t * mp; assert(instance); mp = vlc_object_create (instance->p_libvlc_int, sizeof(*mp)); if (unlikely(mp == NULL)) { libvlc_printerr("Not enough memory"); return NULL; } /* Input */ var_Create (mp, "rate", VLC_VAR_FLOAT|VLC_VAR_DOINHERIT); /* Video */ var_Create (mp, "vout", VLC_VAR_STRING|VLC_VAR_DOINHERIT); var_Create (mp, "window", VLC_VAR_STRING); var_Create (mp, "vmem-lock", VLC_VAR_ADDRESS); var_Create (mp, "vmem-unlock", VLC_VAR_ADDRESS); var_Create (mp, "vmem-display", VLC_VAR_ADDRESS); var_Create (mp, "vmem-data", VLC_VAR_ADDRESS); var_Create (mp, "vmem-setup", VLC_VAR_ADDRESS); var_Create (mp, "vmem-cleanup", VLC_VAR_ADDRESS); var_Create (mp, "vmem-chroma", VLC_VAR_STRING | VLC_VAR_DOINHERIT); var_Create (mp, "vmem-width", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "vmem-height", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "vmem-pitch", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "avcodec-hw", VLC_VAR_STRING); var_Create (mp, "drawable-xid", VLC_VAR_INTEGER); #if defined (_WIN32) || defined (__OS2__) var_Create (mp, "drawable-hwnd", VLC_VAR_INTEGER); #endif #ifdef __APPLE__ var_Create (mp, "drawable-agl", VLC_VAR_INTEGER); var_Create (mp, "drawable-nsobject", VLC_VAR_ADDRESS); #endif var_Create (mp, "keyboard-events", VLC_VAR_BOOL); var_SetBool (mp, "keyboard-events", true); var_Create (mp, "mouse-events", VLC_VAR_BOOL); var_SetBool (mp, "mouse-events", true); var_Create (mp, "fullscreen", VLC_VAR_BOOL); var_Create (mp, "autoscale", VLC_VAR_BOOL); var_SetBool (mp, "autoscale", true); var_Create (mp, "scale", VLC_VAR_FLOAT); var_SetFloat (mp, "scale", 1.); var_Create (mp, "aspect-ratio", VLC_VAR_STRING); var_Create (mp, "crop", VLC_VAR_STRING); var_Create (mp, "deinterlace", VLC_VAR_INTEGER); var_Create (mp, "deinterlace-mode", VLC_VAR_STRING); var_Create (mp, "vbi-page", VLC_VAR_INTEGER); var_Create (mp, "marq-marquee", VLC_VAR_STRING); var_Create (mp, "marq-color", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "marq-opacity", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "marq-position", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "marq-refresh", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "marq-size", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "marq-timeout", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "marq-x", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "marq-y", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "logo-file", VLC_VAR_STRING); var_Create (mp, "logo-x", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "logo-y", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "logo-delay", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "logo-repeat", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "logo-opacity", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "logo-position", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "contrast", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT); var_Create (mp, "brightness", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT); var_Create (mp, "hue", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "saturation", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT); var_Create (mp, "gamma", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT); /* Audio */ var_Create (mp, "aout", VLC_VAR_STRING | VLC_VAR_DOINHERIT); var_Create (mp, "mute", VLC_VAR_BOOL); var_Create (mp, "volume", VLC_VAR_FLOAT); var_Create (mp, "corks", VLC_VAR_INTEGER); var_Create (mp, "audio-filter", VLC_VAR_STRING); var_Create (mp, "amem-data", VLC_VAR_ADDRESS); var_Create (mp, "amem-setup", VLC_VAR_ADDRESS); var_Create (mp, "amem-cleanup", VLC_VAR_ADDRESS); var_Create (mp, "amem-play", VLC_VAR_ADDRESS); var_Create (mp, "amem-pause", VLC_VAR_ADDRESS); var_Create (mp, "amem-resume", VLC_VAR_ADDRESS); var_Create (mp, "amem-flush", VLC_VAR_ADDRESS); var_Create (mp, "amem-drain", VLC_VAR_ADDRESS); var_Create (mp, "amem-set-volume", VLC_VAR_ADDRESS); var_Create (mp, "amem-format", VLC_VAR_STRING | VLC_VAR_DOINHERIT); var_Create (mp, "amem-rate", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "amem-channels", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); /* Video Title */ var_Create (mp, "video-title-show", VLC_VAR_BOOL); var_Create (mp, "video-title-position", VLC_VAR_INTEGER); var_Create (mp, "video-title-timeout", VLC_VAR_INTEGER); /* Equalizer */ var_Create (mp, "equalizer-preamp", VLC_VAR_FLOAT); var_Create (mp, "equalizer-vlcfreqs", VLC_VAR_BOOL); var_Create (mp, "equalizer-bands", VLC_VAR_STRING); mp->p_md = NULL; mp->state = libvlc_NothingSpecial; mp->p_libvlc_instance = instance; mp->input.p_thread = NULL; mp->input.p_resource = input_resource_New(VLC_OBJECT(mp)); if (unlikely(mp->input.p_resource == NULL)) { vlc_object_release(mp); return NULL; } audio_output_t *aout = input_resource_GetAout(mp->input.p_resource); if( aout != NULL ) input_resource_PutAout(mp->input.p_resource, aout); vlc_mutex_init (&mp->input.lock); mp->i_refcount = 1; mp->p_event_manager = libvlc_event_manager_new(mp, instance); if (unlikely(mp->p_event_manager == NULL)) { input_resource_Release(mp->input.p_resource); vlc_object_release(mp); return NULL; } vlc_mutex_init(&mp->object_lock); register_event(mp, NothingSpecial); register_event(mp, Opening); register_event(mp, Buffering); register_event(mp, Playing); register_event(mp, Paused); register_event(mp, Stopped); register_event(mp, Forward); register_event(mp, Backward); register_event(mp, EndReached); register_event(mp, EncounteredError); register_event(mp, SeekableChanged); register_event(mp, PositionChanged); register_event(mp, TimeChanged); register_event(mp, LengthChanged); register_event(mp, TitleChanged); register_event(mp, PausableChanged); register_event(mp, Vout); register_event(mp, ScrambledChanged); /* Snapshot initialization */ register_event(mp, SnapshotTaken); register_event(mp, MediaChanged); /* Attach a var callback to the global object to provide the glue between * vout_thread that generates the event and media_player that re-emits it * with its own event manager * * FIXME: It's unclear why we want to put this in public API, and why we * want to expose it in such a limiting and ugly way. */ var_AddCallback(mp->p_libvlc, "snapshot-file", snapshot_was_taken, mp); libvlc_retain(instance); return mp; }
/***************************************************************************** * Open: initializes demux structures *****************************************************************************/ static int Open( vlc_object_t * p_this ) { demux_t *p_demux = (demux_t*)p_this; demux_sys_t *p_sys; vlc_bool_t b_forced = VLC_FALSE; uint8_t *p_peek; es_format_t fmt; if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) { msg_Err( p_demux, "cannot peek" ); return VLC_EGENERIC; } if( !strncmp( p_demux->psz_demux, "mpgv", 4 ) ) { b_forced = VLC_TRUE; } if( p_peek[0] != 0x00 || p_peek[1] != 0x00 || p_peek[2] != 0x01 ) { if( !b_forced ) { msg_Warn( p_demux, "ES module discarded (no startcode)" ); return VLC_EGENERIC; } msg_Err( p_demux, "this doesn't look like an MPEG ES stream, continuing" ); } if( p_peek[3] > 0xb9 ) { if( !b_forced ) { msg_Warn( p_demux, "ES module discarded (system startcode)" ); return VLC_EGENERIC; } msg_Err( p_demux, "this seems to be a system stream (PS plug-in ?), but continuing" ); } p_demux->pf_demux = Demux; p_demux->pf_control= Control; p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) ); p_sys->b_start = VLC_TRUE; p_sys->p_es = NULL; /* * Load the mpegvideo packetizer */ p_sys->p_packetizer = vlc_object_create( p_demux, VLC_OBJECT_PACKETIZER ); p_sys->p_packetizer->pf_decode_audio = NULL; p_sys->p_packetizer->pf_decode_video = NULL; p_sys->p_packetizer->pf_decode_sub = NULL; p_sys->p_packetizer->pf_packetize = NULL; es_format_Init( &p_sys->p_packetizer->fmt_in, VIDEO_ES, VLC_FOURCC( 'm', 'p', 'g', 'v' ) ); es_format_Init( &p_sys->p_packetizer->fmt_out, UNKNOWN_ES, 0 ); p_sys->p_packetizer->p_module = module_Need( p_sys->p_packetizer, "packetizer", NULL, 0 ); if( p_sys->p_packetizer->p_module == NULL) { vlc_object_destroy( p_sys->p_packetizer ); msg_Err( p_demux, "cannot find mpgv packetizer" ); free( p_sys ); return VLC_EGENERIC; } /* * create the output */ es_format_Init( &fmt, VIDEO_ES, VLC_FOURCC( 'm', 'p', 'g', 'v' ) ); p_sys->p_es = es_out_Add( p_demux->out, &fmt ); return VLC_SUCCESS; }
static sout_stream_id_sys_t * Add( sout_stream_t *p_stream, const es_format_t *p_fmt ) { sout_stream_sys_t *p_sys = p_stream->p_sys; bridge_t *p_bridge; bridged_es_t *p_es; char *psz_chain; int i; if( p_sys->b_inited || p_fmt->i_cat != VIDEO_ES ) return NULL; /* Create decoder object */ p_sys->p_decoder = vlc_object_create( p_stream, sizeof( decoder_t ) ); if( !p_sys->p_decoder ) return NULL; p_sys->p_decoder->p_module = NULL; p_sys->p_decoder->fmt_in = *p_fmt; p_sys->p_decoder->b_frame_drop_allowed = true; p_sys->p_decoder->fmt_out = p_sys->p_decoder->fmt_in; p_sys->p_decoder->fmt_out.i_extra = 0; p_sys->p_decoder->fmt_out.p_extra = 0; p_sys->p_decoder->pf_decode_video = 0; p_sys->p_decoder->pf_vout_format_update = video_update_format_decoder; p_sys->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder; p_sys->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) ); if( !p_sys->p_decoder->p_owner ) { vlc_object_release( p_sys->p_decoder ); return NULL; } p_sys->p_decoder->p_owner->video = p_fmt->video; //p_sys->p_decoder->p_cfg = p_sys->p_video_cfg; p_sys->p_decoder->p_module = module_need( p_sys->p_decoder, "decoder", "$codec", false ); if( !p_sys->p_decoder->p_module || !p_sys->p_decoder->pf_decode_video ) { if( p_sys->p_decoder->p_module ) { msg_Err( p_stream, "instanciated a non video decoder" ); module_unneed( p_sys->p_decoder, p_sys->p_decoder->p_module ); } else { msg_Err( p_stream, "cannot find decoder" ); } free( p_sys->p_decoder->p_owner ); vlc_object_release( p_sys->p_decoder ); return NULL; } p_sys->b_inited = true; vlc_global_lock( VLC_MOSAIC_MUTEX ); p_bridge = GetBridge( p_stream ); if ( p_bridge == NULL ) { vlc_object_t *p_libvlc = VLC_OBJECT( p_stream->obj.libvlc ); vlc_value_t val; p_bridge = xmalloc( sizeof( bridge_t ) ); var_Create( p_libvlc, "mosaic-struct", VLC_VAR_ADDRESS ); val.p_address = p_bridge; var_Set( p_libvlc, "mosaic-struct", val ); p_bridge->i_es_num = 0; p_bridge->pp_es = NULL; } for ( i = 0; i < p_bridge->i_es_num; i++ ) { if ( p_bridge->pp_es[i]->b_empty ) break; } if ( i == p_bridge->i_es_num ) { p_bridge->pp_es = xrealloc( p_bridge->pp_es, (p_bridge->i_es_num + 1) * sizeof(bridged_es_t *) ); p_bridge->i_es_num++; p_bridge->pp_es[i] = xmalloc( sizeof(bridged_es_t) ); } p_sys->p_es = p_es = p_bridge->pp_es[i]; p_es->i_alpha = var_GetInteger( p_stream, CFG_PREFIX "alpha" ); p_es->i_x = var_GetInteger( p_stream, CFG_PREFIX "x" ); p_es->i_y = var_GetInteger( p_stream, CFG_PREFIX "y" ); //p_es->fmt = *p_fmt; p_es->psz_id = p_sys->psz_id; p_es->p_picture = NULL; p_es->pp_last = &p_es->p_picture; p_es->b_empty = false; vlc_global_unlock( VLC_MOSAIC_MUTEX ); if ( p_sys->i_height || p_sys->i_width ) { p_sys->p_image = image_HandlerCreate( p_stream ); } else { p_sys->p_image = NULL; } msg_Dbg( p_stream, "mosaic bridge id=%s pos=%d", p_es->psz_id, i ); /* Create user specified video filters */ psz_chain = var_GetNonEmptyString( p_stream, CFG_PREFIX "vfilter" ); msg_Dbg( p_stream, "psz_chain: %s", psz_chain ); if( psz_chain ) { filter_owner_t owner = { .sys = p_sys->p_decoder->p_owner, .video = { .buffer_new = video_new_buffer_filter, }, }; p_sys->p_vf2 = filter_chain_NewVideo( p_stream, false, &owner ); es_format_t fmt; es_format_Copy( &fmt, &p_sys->p_decoder->fmt_out ); if( p_sys->i_chroma ) fmt.video.i_chroma = p_sys->i_chroma; filter_chain_Reset( p_sys->p_vf2, &fmt, &fmt ); filter_chain_AppendFromString( p_sys->p_vf2, psz_chain ); free( psz_chain ); } else {
/***************************************************************************** * Open: initializes demux structures *****************************************************************************/ static int Open( vlc_object_t * p_this ) { demux_t *p_demux = (demux_t*)p_this; demux_sys_t *p_sys; uint8_t *p_peek; module_t *p_id3; int b_forced = VLC_FALSE; if( p_demux->psz_path ) { int i_len = strlen( p_demux->psz_path ); if( i_len > 4 && !strcasecmp( &p_demux->psz_path[i_len - 4], ".aac" ) ) { b_forced = VLC_TRUE; } } if( !p_demux->b_force && !b_forced ) { return VLC_EGENERIC; } /* skip possible id3 header */ if( ( p_id3 = module_Need( p_demux, "id3", NULL, 0 ) ) ) { module_Unneed( p_demux, p_id3 ); } /* peek the begining (10 is for adts header) */ if( stream_Peek( p_demux->s, &p_peek, 10 ) < 10 ) { msg_Err( p_demux, "cannot peek" ); return VLC_EGENERIC; } if( !strncmp( p_peek, "ADIF", 4 ) ) { msg_Err( p_demux, "ADIF file. Not yet supported. (Please report)" ); return VLC_EGENERIC; } p_demux->pf_demux = Demux; p_demux->pf_control= Control; p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) ); p_sys->p_es = NULL; p_sys->b_start = VLC_TRUE; /* * Load the mpeg 4 audio packetizer */ p_sys->p_packetizer = vlc_object_create( p_demux, VLC_OBJECT_PACKETIZER ); p_sys->p_packetizer->pf_decode_audio = NULL; p_sys->p_packetizer->pf_decode_video = NULL; p_sys->p_packetizer->pf_decode_sub = NULL; p_sys->p_packetizer->pf_packetize = NULL; es_format_Init( &p_sys->p_packetizer->fmt_in, AUDIO_ES, VLC_FOURCC( 'm', 'p', '4', 'a' ) ); es_format_Init( &p_sys->p_packetizer->fmt_out, UNKNOWN_ES, 0 ); p_sys->p_packetizer->p_module = module_Need( p_sys->p_packetizer, "packetizer", NULL, 0 ); if( p_sys->p_packetizer->p_module == NULL) { vlc_object_destroy( p_sys->p_packetizer ); msg_Err( p_demux, "cannot find mp4a packetizer" ); free( p_sys ); return VLC_EGENERIC; } 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; }
/***************************************************************************** * 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; }
/** * 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; video_format_t fmt; vlc_gl_t *gl; unsigned int i_last_width = 0; unsigned int i_last_height = 0; locale_t loc; locale_t oldloc; projectM *p_projectm; #ifndef HAVE_PROJECTM2 char *psz_config; #else char *psz_preset_path; char *psz_title_font; char *psz_menu_font; projectM::Settings settings; #endif vlc_savecancel(); /* 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; /* */ 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; } /* Work-around the projectM locale bug */ loc = newlocale (LC_NUMERIC_MASK, "C", NULL); oldloc = uselocale (loc); /* Create the projectM object */ #ifndef HAVE_PROJECTM2 psz_config = var_InheritString( p_filter, "projectm-config" ); p_projectm = new projectM( psz_config ); free( psz_config ); #else psz_preset_path = var_InheritString( p_filter, "projectm-preset-path" ); #ifdef WIN32 if ( psz_preset_path == NULL ) { char *psz_data_path = config_GetDataDir( p_filter ); asprintf( &psz_preset_path, "%s" DIR_SEP "visualization", psz_data_path ); free( psz_data_path ); } #endif psz_title_font = var_InheritString( p_filter, "projectm-title-font" ); psz_menu_font = var_InheritString( p_filter, "projectm-menu-font" ); settings.meshX = var_InheritInteger( p_filter, "projectm-meshx" ); settings.meshY = var_InheritInteger( p_filter, "projectm-meshy" ); settings.fps = 35; settings.textureSize = var_InheritInteger( p_filter, "projectm-texture-size" ); settings.windowWidth = p_sys->i_width; settings.windowHeight = p_sys->i_height; settings.presetURL = psz_preset_path; settings.titleFontURL = psz_title_font; settings.menuFontURL = psz_menu_font; settings.smoothPresetDuration = 5; settings.presetDuration = 30; settings.beatSensitivity = 10; settings.aspectCorrection = 1; settings.easterEgg = 1; settings.shuffleEnabled = 1; p_projectm = new projectM( settings ); free( psz_menu_font ); free( psz_title_font ); free( psz_preset_path ); #endif /* HAVE_PROJECTM2 */ p_sys->i_buffer_size = p_projectm->pcm()->maxsamples; p_sys->p_buffer = (float*)calloc( p_sys->i_buffer_size, sizeof( float ) ); vlc_sem_post( &p_sys->ready ); /* Choose a preset randomly or projectM will always show the first one */ if ( p_projectm->getPlaylistSize() > 0 ) p_projectm->selectPreset( (unsigned)vlc_mrand48() % p_projectm->getPlaylistSize() ); /* */ 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_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_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_projectm; vout_DeleteDisplay( p_sys->p_vd, NULL ); vlc_object_release( p_sys->p_vout ); if (loc != (locale_t)0) { uselocale (oldloc); freelocale (loc); } return NULL; } vlc_mutex_unlock( &p_sys->lock ); p_projectm->renderFrame(); /* */ mwait( i_deadline ); if( !vlc_gl_Lock(gl) ) { vlc_gl_Swap( gl ); vlc_gl_Unlock( gl ); } } abort(); error: p_sys->b_error = true; vlc_sem_post( &p_sys->ready ); return NULL; }
/** * It creates an OpenGL vout display. */ static int Open(vlc_object_t *object) { vout_display_t *vd = (vout_display_t *)object; vout_display_sys_t *sys; /* Allocate structure */ vd->sys = sys = calloc(1, sizeof(*sys)); if (!sys) return VLC_ENOMEM; /* */ if (CommonInit(vd)) goto error; EventThreadUpdateTitle(sys->event, VOUT_TITLE " (OpenGL output)"); /* process selected GPU affinity */ int nVidiaAffinity = var_InheritInteger(vd, "gpu-affinity"); if (nVidiaAffinity >= 0) CreateGPUAffinityDC(vd, nVidiaAffinity); /* */ sys->hGLDC = GetDC(sys->hvideownd); /* Set the pixel format for the DC */ PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(pfd)); pfd.nSize = sizeof(pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.cDepthBits = 16; pfd.iLayerType = PFD_MAIN_PLANE; SetPixelFormat(sys->hGLDC, ChoosePixelFormat(sys->hGLDC, &pfd), &pfd); /* * Create and enable the render context * For GPU affinity, attach the window DC * to the GPU affinity DC */ sys->hGLRC = wglCreateContext((sys->affinityHDC != NULL) ? sys->affinityHDC : sys->hGLDC); wglMakeCurrent(sys->hGLDC, sys->hGLRC); const char *extensions = (const char*)glGetString(GL_EXTENSIONS); #ifdef WGL_EXT_swap_control if (HasExtension(extensions, "WGL_EXT_swap_control")) { PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); if (SwapIntervalEXT) SwapIntervalEXT(1); } #endif /* */ sys->gl = vlc_object_create(object, sizeof(*sys->gl)); if (unlikely(!sys->gl)) goto error; sys->gl->swap = Swap; sys->gl->getProcAddress = OurGetProcAddress; sys->gl->sys = vd; video_format_t fmt = vd->fmt; const vlc_fourcc_t *subpicture_chromas; sys->vgl = vout_display_opengl_New(&fmt, &subpicture_chromas, sys->gl, &vd->cfg->viewpoint); if (!sys->vgl) goto error; vout_display_info_t info = vd->info; info.has_double_click = true; info.has_hide_mouse = false; info.subpicture_chromas = subpicture_chromas; /* Setup vout_display now that everything is fine */ vd->fmt = fmt; vd->info = info; vd->pool = Pool; vd->prepare = Prepare; vd->display = Display; vd->control = Control; vd->manage = Manage; return VLC_SUCCESS; error: Close(object); return VLC_EGENERIC; }
/**************************************************************************** * EncodeVideo: the whole thing ****************************************************************************/ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict ) { encoder_sys_t *p_sys = p_enc->p_sys; AVFrame frame; int i_out, i_plane; #if LIBAVCODEC_BUILD >= 4702 if ( !p_sys->b_inited && p_enc->i_threads >= 1 ) { struct thread_context_t ** pp_contexts; int i; p_sys->b_inited = 1; pp_contexts = malloc( sizeof(struct thread_context_t *) * p_enc->i_threads ); p_sys->p_context->thread_opaque = (void *)pp_contexts; for ( i = 0; i < p_enc->i_threads; i++ ) { pp_contexts[i] = vlc_object_create( p_enc, sizeof(struct thread_context_t) ); pp_contexts[i]->p_context = p_sys->p_context; vlc_mutex_init( p_enc, &pp_contexts[i]->lock ); vlc_cond_init( p_enc, &pp_contexts[i]->cond ); pp_contexts[i]->b_work = 0; pp_contexts[i]->b_done = 0; if ( vlc_thread_create( pp_contexts[i], "encoder", FfmpegThread, VLC_THREAD_PRIORITY_VIDEO, VLC_FALSE ) ) { msg_Err( p_enc, "cannot spawn encoder thread, expect to die soon" ); return NULL; } } p_sys->p_context->execute = FfmpegExecute; } #endif memset( &frame, 0, sizeof( AVFrame ) ); for( i_plane = 0; i_plane < p_pict->i_planes; i_plane++ ) { frame.data[i_plane] = p_pict->p[i_plane].p_pixels; frame.linesize[i_plane] = p_pict->p[i_plane].i_pitch; } /* Let ffmpeg select the frame type */ frame.pict_type = 0; frame.repeat_pict = 2 - p_pict->i_nb_fields; #if LIBAVCODEC_BUILD >= 4685 frame.interlaced_frame = !p_pict->b_progressive; frame.top_field_first = !!p_pict->b_top_field_first; #endif #if LIBAVCODEC_BUILD < 4702 /* Set the pts of the frame being encoded (segfaults with mpeg4!)*/ if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', 'g', 'v' ) || p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', '1', 'v' ) || p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', '2', 'v' ) ) #else if( 1 ) #endif { frame.pts = p_pict->date ? p_pict->date : AV_NOPTS_VALUE; if ( p_sys->b_hurry_up && frame.pts != AV_NOPTS_VALUE ) { mtime_t current_date = mdate(); if ( current_date + HURRY_UP_GUARD3 > frame.pts ) { p_sys->p_context->mb_decision = FF_MB_DECISION_SIMPLE; p_sys->p_context->flags &= ~CODEC_FLAG_TRELLIS_QUANT; msg_Dbg( p_enc, "hurry up mode 3" ); } else { p_sys->p_context->mb_decision = p_sys->i_hq; if ( current_date + HURRY_UP_GUARD2 > frame.pts ) { p_sys->p_context->flags &= ~CODEC_FLAG_TRELLIS_QUANT; #if LIBAVCODEC_BUILD >= 4690 p_sys->p_context->noise_reduction = p_sys->i_noise_reduction + (HURRY_UP_GUARD2 + current_date - frame.pts) / 500; #endif msg_Dbg( p_enc, "hurry up mode 2" ); } else { if ( p_sys->b_trellis ) p_sys->p_context->flags |= CODEC_FLAG_TRELLIS_QUANT; #if LIBAVCODEC_BUILD >= 4690 p_sys->p_context->noise_reduction = p_sys->i_noise_reduction; #endif } } if ( current_date + HURRY_UP_GUARD1 > frame.pts ) { frame.pict_type = FF_P_TYPE; /* msg_Dbg( p_enc, "hurry up mode 1 %lld", current_date + HURRY_UP_GUARD1 - frame.pts ); */ } } } else { frame.pts = AV_NOPTS_VALUE; } if ( frame.pts != AV_NOPTS_VALUE && frame.pts != 0 ) { if ( p_sys->i_last_pts == frame.pts ) { msg_Warn( p_enc, "almost fed libavcodec with two frames with the " "same PTS (" I64Fd ")", frame.pts ); return NULL; } else if ( p_sys->i_last_pts > frame.pts ) { msg_Warn( p_enc, "almost fed libavcodec with a frame in the " "past (current: " I64Fd ", last: "I64Fd")", frame.pts, p_sys->i_last_pts ); return NULL; } else { p_sys->i_last_pts = frame.pts; } } frame.quality = p_sys->i_quality; /* Ugly work-around for stupid libavcodec behaviour */ #if LIBAVCODEC_BUILD >= 4722 p_sys->i_framenum++; p_sys->pi_delay_pts[p_sys->i_framenum % MAX_FRAME_DELAY] = frame.pts; frame.pts = p_sys->i_framenum * AV_TIME_BASE * p_enc->fmt_in.video.i_frame_rate_base; frame.pts += p_enc->fmt_in.video.i_frame_rate - 1; frame.pts /= p_enc->fmt_in.video.i_frame_rate; #endif /* End work-around */ i_out = avcodec_encode_video( p_sys->p_context, p_sys->p_buffer_out, AVCODEC_MAX_VIDEO_FRAME_SIZE, &frame ); if( i_out > 0 ) { block_t *p_block = block_New( p_enc, i_out ); memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out ); /* FIXME, 3-2 pulldown is not handled correctly */ p_block->i_length = I64C(1000000) * p_enc->fmt_in.video.i_frame_rate_base / p_enc->fmt_in.video.i_frame_rate; if( !p_sys->p_context->max_b_frames || !p_sys->p_context->delay ) { /* No delay -> output pts == input pts */ p_block->i_pts = p_block->i_dts = p_pict->date; } else if( p_sys->p_context->coded_frame->pts != AV_NOPTS_VALUE && p_sys->p_context->coded_frame->pts != 0 && p_sys->i_buggy_pts_detect != p_sys->p_context->coded_frame->pts ) { p_sys->i_buggy_pts_detect = p_sys->p_context->coded_frame->pts; p_block->i_pts = p_sys->p_context->coded_frame->pts; /* Ugly work-around for stupid libavcodec behaviour */ #if LIBAVCODEC_BUILD >= 4722 { int64_t i_framenum = p_block->i_pts * p_enc->fmt_in.video.i_frame_rate / p_enc->fmt_in.video.i_frame_rate_base / AV_TIME_BASE; p_block->i_pts = p_sys->pi_delay_pts[i_framenum % MAX_FRAME_DELAY]; } #endif /* End work-around */ if( p_sys->p_context->coded_frame->pict_type != FF_I_TYPE && p_sys->p_context->coded_frame->pict_type != FF_P_TYPE ) { p_block->i_dts = p_block->i_pts; } else { if( p_sys->i_last_ref_pts ) { p_block->i_dts = p_sys->i_last_ref_pts; } else { /* Let's put something sensible */ p_block->i_dts = p_block->i_pts; } p_sys->i_last_ref_pts = p_block->i_pts; } } else { /* Buggy libavcodec which doesn't update coded_frame->pts * correctly */ p_block->i_dts = p_block->i_pts = p_pict->date; } switch ( p_sys->p_context->coded_frame->pict_type ) { case FF_I_TYPE: p_block->i_flags |= BLOCK_FLAG_TYPE_I; break; case FF_P_TYPE: p_block->i_flags |= BLOCK_FLAG_TYPE_P; break; case FF_B_TYPE: p_block->i_flags |= BLOCK_FLAG_TYPE_B; break; } return p_block; } return NULL; }