static void *proxy_thread(void *data) { int lfd = (intptr_t)data; for (;;) { int cfd = accept4(lfd, NULL, NULL, SOCK_CLOEXEC); if (cfd == -1) continue; int canc = vlc_savecancel(); proxy_client_process(cfd); vlc_close(cfd); connection_count++; vlc_restorecancel(canc); } vlc_assert_unreachable(); }
static block_t *rtp_recv (demux_t *demux) { demux_sys_t *p_sys = demux->p_sys; for (block_t *block;; block_Release (block)) { block = p_sys->framed_rtp ? rtp_stream_recv (VLC_OBJECT (demux), p_sys->fd) : rtp_dgram_recv (VLC_OBJECT (demux), p_sys->fd); if (block == NULL) { msg_Err (demux, "RTP flow stopped"); break; /* fatal error */ } if (block->i_buffer < 2) continue; /* FIXME */ const uint8_t ptype = rtp_ptype (block); if (ptype >= 72 && ptype <= 76) continue; /* Muxed RTCP, ignore for now */ #ifdef HAVE_SRTP if (p_sys->srtp) { size_t len = block->i_buffer; int canc, err; canc = vlc_savecancel (); err = srtp_recv (p_sys->srtp, block->p_buffer, &len); vlc_restorecancel (canc); if (err) { msg_Dbg (demux, "SRTP authentication/decryption failed"); continue; } block->i_buffer = len; } #endif return block; /* success! */ } return NULL; }
void* update_CheckReal( vlc_object_t* p_this ) { update_check_thread_t *p_uct = (update_check_thread_t *)p_this; bool b_ret; int canc; canc = vlc_savecancel (); vlc_mutex_lock( &p_uct->p_update->lock ); EmptyRelease( p_uct->p_update ); b_ret = GetUpdateFile( p_uct->p_update ); vlc_mutex_unlock( &p_uct->p_update->lock ); if( p_uct->pf_callback ) (p_uct->pf_callback)( p_uct->p_data, b_ret ); vlc_restorecancel (canc); return NULL; }
static char *vlc_https_proxy_find(const char *hostname, unsigned port) { const char *fmt; char *url, *proxy = NULL; int canc = vlc_savecancel(); if (strchr(hostname, ':') != NULL) fmt = port ? "https://[%s]:%u" : "https://[%s]"; else fmt = port ? "https://%s:%u" : "https://%s"; if (likely(asprintf(&url, fmt, hostname, port) >= 0)) { proxy = vlc_getProxyUrl(url); free(url); } vlc_restorecancel(canc); return proxy; }
/***************************************************************************** * Thread: thread used to DMA the data to the device *****************************************************************************/ static void* Thread( vlc_object_t *p_this ) { aout_instance_t * p_aout = (aout_instance_t*)p_this; aout_buffer_t * p_buffer; struct aout_sys_t * p_sys = p_aout->output.p_sys; PCMAudioPlayer * pPlayer = p_sys->pPlayer; int canc = vlc_savecancel (); while( vlc_object_alive (p_aout) ) { pPlayer->WaitForBuffer(); vlc_mutex_lock( &p_aout->output_fifo_lock ); p_buffer = aout_FifoPop( p_aout, &p_aout->output.fifo ); vlc_mutex_unlock( &p_aout->output_fifo_lock ); #define i p_sys->nNextBufferIndex if( p_buffer == NULL ) { vlc_memset( p_aout, p_sys->ppBuffers[ i ], 0, p_sys->nBufferSize ); } else { InterleaveS16( (int16_t *)p_buffer->p_buffer, (int16_t *)p_sys->ppBuffers[ i ] ); aout_BufferFree( p_buffer ); } if( !pPlayer->QueueBuffer( (s16 *)p_sys->ppBuffers[ i ], p_sys->nBufferSize / 2 ) ) { msg_Err( p_aout, "QueueBuffer failed" ); } i = (i + 1) % p_sys->nBuffers; #undef i } vlc_restorecancel (canc); return NULL; }
/** * Log a message */ static void Overflow (msg_cb_data_t *p_sys, msg_item_t *p_item, unsigned overruns) { VLC_UNUSED(overruns); int verbosity = var_InheritInteger( p_sys->p_intf, "log-verbose" ); if (verbosity == -1) verbosity = var_InheritInteger( p_sys->p_intf, "verbose" ); switch( p_item->i_type ) { case VLC_MSG_INFO: case VLC_MSG_ERR: if( verbosity < 0 ) return; break; case VLC_MSG_WARN: if( verbosity < 1 ) return; break; case VLC_MSG_DBG: if( verbosity < 2 ) return; break; } int canc = vlc_savecancel(); switch( p_sys->i_mode ) { case MODE_HTML: HtmlPrint( p_item, p_sys->p_file ); break; #ifdef HAVE_SYSLOG_H case MODE_SYSLOG: SyslogPrint( p_item ); break; #endif case MODE_TEXT: default: TextPrint( p_item, p_sys->p_file ); break; } vlc_restorecancel( canc ); }
void MessagesDialog::MsgCallback( void *self, int type, const vlc_log_t *item, const char *format, va_list ap ) { MessagesDialog *dialog = (MessagesDialog *)self; char *str; #if HAS_QT5 int verbosity = dialog->verbosity.load(); #else int verbosity = dialog->verbosity; #endif if( verbosity < 0 || verbosity < (type - VLC_MSG_ERR) || unlikely(vasprintf( &str, format, ap ) == -1) ) return; int canc = vlc_savecancel(); QApplication::postEvent( dialog, new MsgEvent( type, item, str ) ); vlc_restorecancel( canc ); free( str ); }
static void* CommandThread( void *obj ) { vod_t *p_vod = (vod_t*)obj; vod_sys_t *p_sys = p_vod->p_sys; for( ;; ) { block_t *p_block_cmd = block_FifoGet( p_sys->p_fifo_cmd ); rtsp_cmd_t cmd; if( !p_block_cmd ) break; int canc = vlc_savecancel (); memcpy( &cmd, p_block_cmd->p_buffer, sizeof(cmd) ); block_Release( p_block_cmd ); /* */ switch( cmd.i_type ) { case RTSP_CMD_TYPE_ADD: MediaSetup(p_vod, cmd.p_media, cmd.psz_arg); break; case RTSP_CMD_TYPE_DEL: MediaDel(p_vod, cmd.p_media); break; case RTSP_CMD_TYPE_STOP: vod_MediaControl( p_vod, cmd.p_media, cmd.psz_arg, VOD_MEDIA_STOP ); break; default: break; } free( cmd.psz_arg ); vlc_restorecancel (canc); } return NULL; }
/** * RTP/RTCP session thread for stream sockets (framed RTP) */ void *rtp_stream_thread (void *opaque) { #ifndef WIN32 demux_t *demux = opaque; demux_sys_t *sys = demux->p_sys; int fd = sys->fd; for (;;) { /* There is no reordering on stream sockets, so no timeout. */ ssize_t val; uint16_t frame_len; if (recv (fd, &frame_len, 2, MSG_WAITALL) != 2) break; block_t *block = block_Alloc (ntohs (frame_len)); if (unlikely(block == NULL)) break; block_cleanup_push (block); val = recv (fd, block->p_buffer, block->i_buffer, MSG_WAITALL); vlc_cleanup_pop (); if (val != (ssize_t)block->i_buffer) { block_Release (block); break; } int canc = vlc_savecancel (); rtp_process (demux, block); rtp_dequeue_force (demux, sys->session); vlc_restorecancel (canc); } #else (void) opaque; #endif return NULL; }
void vlc_mutex_lock (vlc_mutex_t *p_mutex) { if (!p_mutex->dynamic) { /* static mutexes */ int canc = vlc_savecancel (); assert (p_mutex != &super_mutex); /* this one cannot be static */ vlc_mutex_lock (&super_mutex); while (p_mutex->locked) { p_mutex->contention++; vlc_cond_wait (&super_variable, &super_mutex); p_mutex->contention--; } p_mutex->locked = true; vlc_mutex_unlock (&super_mutex); vlc_restorecancel (canc); return; } DosRequestMutexSem(p_mutex->hmtx, SEM_INDEFINITE_WAIT); }
/***************************************************************************** * Run: interface thread *****************************************************************************/ static void Run( intf_thread_t *p_intf ) { intf_sys_t sys; SERVICE_TABLE_ENTRY dispatchTable[] = { { (LPTSTR)VLCSERVICENAME, &ServiceDispatch }, { NULL, NULL } }; int canc = vlc_savecancel(); p_global_intf = p_intf; p_intf->p_sys = &sys; p_intf->p_sys->psz_service = var_InheritString( p_intf, "ntservice-name" ); p_intf->p_sys->psz_service = p_intf->p_sys->psz_service ? p_intf->p_sys->psz_service : strdup(VLCSERVICENAME); if( var_InheritBool( p_intf, "ntservice-install" ) ) { NTServiceInstall( p_intf ); return; } if( var_InheritBool( p_intf, "ntservice-uninstall" ) ) { NTServiceUninstall( p_intf ); return; } if( StartServiceCtrlDispatcher( dispatchTable ) == 0 ) { msg_Err( p_intf, "StartServiceCtrlDispatcher failed" ); /* str review */ } free( p_intf->p_sys->psz_service ); /* Make sure we exit (In case other interfaces have been spawned) */ libvlc_Quit( p_intf->p_libvlc ); vlc_restorecancel( canc ); }
void vlc_mutex_lock (vlc_mutex_t *p_mutex) { if (!p_mutex->dynamic) { /* static mutexes */ int canc = vlc_savecancel (); assert (p_mutex != &super_mutex); /* this one cannot be static */ vlc_mutex_lock (&super_mutex); while (p_mutex->locked) { p_mutex->contention++; vlc_cond_wait (&super_variable, &super_mutex); p_mutex->contention--; } p_mutex->locked = true; vlc_mutex_unlock (&super_mutex); vlc_restorecancel (canc); return; } EnterCriticalSection (&p_mutex->mutex); }
/***************************************************************************** * vlc_thread_fatal: Report an error from the threading layer ***************************************************************************** * This is mostly meant for debugging. *****************************************************************************/ static void vlc_thread_fatal (const char *action, int error, const char *function, const char *file, unsigned line) { int canc = vlc_savecancel (); fprintf (stderr, "LibVLC fatal error %s (%d) in thread %lu ", action, error, vlc_threadid ()); vlc_trace (function, file, line); /* Sometimes strerror_r() crashes too, so make sure we print an error * message before we invoke it */ #ifdef __GLIBC__ /* Avoid the strerror_r() prototype brain damage in glibc */ errno = error; fprintf (stderr, " Error message: %m\n"); #else char buf[1000]; const char *msg; switch (strerror_r (error, buf, sizeof (buf))) { case 0: msg = buf; break; case ERANGE: /* should never happen */ msg = "unknwon (too big to display)"; break; default: msg = "unknown (invalid error number)"; break; } fprintf (stderr, " Error message: %s\n", msg); #endif fflush (stderr); vlc_restorecancel (canc); abort (); }
void *rtp_thread (void *data) { demux_t *demux = data; demux_sys_t *p_sys = demux->p_sys; bool autodetect = true; if (vlc_timer_create (&p_sys->timer, rtp_process, data)) return NULL; vlc_cleanup_push (timer_cleanup, (void *)p_sys->timer); for (;;) { block_t *block = rtp_recv (demux); if (block == NULL) break; if (autodetect) { /* Autodetect payload type, _before_ rtp_queue() */ /* No need for lock - the queue is empty. */ if (rtp_autodetect (demux, p_sys->session, block)) { block_Release (block); continue; } autodetect = false; } int canc = vlc_savecancel (); vlc_mutex_lock (&p_sys->lock); rtp_queue (demux, p_sys->session, block); vlc_mutex_unlock (&p_sys->lock); vlc_restorecancel (canc); rtp_process (demux); } vlc_cleanup_run (); return NULL; }
static void *playlist_thread(void *data) { libvlc_media_list_player_t *mlp = data; vlc_mutex_lock(&mlp->mp_callback_lock); mutex_cleanup_push(&mlp->mp_callback_lock); for (;;) { int canc; while (mlp->seek_offset == 0) vlc_cond_wait(&mlp->seek_pending, &mlp->mp_callback_lock); canc = vlc_savecancel(); set_relative_playlist_position_and_play(mlp, mlp->seek_offset); mlp->seek_offset = 0; vlc_restorecancel(canc); } vlc_cleanup_pop(); vlc_assert_unreachable(); }
static void HtmlPrint( void *opaque, int type, const vlc_log_t *item, const char *fmt, va_list ap ) { static const unsigned color[4] = { 0xffffff, 0xff6666, 0xffff66, 0xaaaaaa, }; intf_thread_t *p_intf = opaque; FILE *stream = p_intf->p_sys->p_file; if( IgnoreMessage( p_intf, type ) ) return; int canc = vlc_savecancel(); flockfile( stream ); fprintf( stream, "%s%s: <span style=\"color: #%06x\">", item->psz_module, ppsz_type[type], color[type] ); /* FIXME: encode special ASCII characters */ vfprintf( stream, fmt, ap ); fputs( "</span>\n", stream ); funlockfile( stream ); vlc_restorecancel( canc ); }
static void SyslogPrint( void *opaque, int type, const vlc_log_t *item, const char *fmt, va_list ap ) { static const int i_prio[4] = { LOG_INFO, LOG_ERR, LOG_WARNING, LOG_DEBUG }; intf_thread_t *p_intf = opaque; char *str; int i_priority = i_prio[type]; if( IgnoreMessage( p_intf, type ) || unlikely(vasprintf( &str, fmt, ap ) == -1) ) return; int canc = vlc_savecancel(); if( item->psz_header != NULL ) syslog( i_priority, "[%s] %s%s: %s", item->psz_header, item->psz_module, ppsz_type[type], str ); else syslog( i_priority, "%s%s: %s", item->psz_module, ppsz_type[type], str ); vlc_restorecancel( canc ); free( str ); }
/** * Sends bytes to a connection. * @note This may be a cancellation point. * The caller is responsible for serializing writes on a given connection. */ static ssize_t vlc_https_send(vlc_tls_t *tls, const void *buf, size_t len) { struct pollfd ufd; struct iovec iov; size_t count = 0; ufd.fd = vlc_tls_GetFD(tls); ufd.events = POLLOUT; iov.iov_base = (void *)buf; iov.iov_len = len; while (count < len) { int canc = vlc_savecancel(); ssize_t val = tls->writev(tls, &iov, 1); vlc_restorecancel(canc); if (val > 0) { iov.iov_base = (char *)iov.iov_base + val; iov.iov_len -= val; count += val; continue; } if (val == 0) break; if (errno != EINTR && errno != EAGAIN) return count ? (ssize_t)count : -1; poll(&ufd, 1, -1); } return count; }
static void* EncoderThread( void *obj ) { sout_stream_sys_t *p_sys = (sout_stream_sys_t*)obj; sout_stream_id_t *id = p_sys->id_video; picture_t *p_pic; int canc = vlc_savecancel (); for( ;; ) { block_t *p_block; vlc_mutex_lock( &p_sys->lock_out ); while( !p_sys->b_abort && (p_pic = picture_fifo_Pop( p_sys->pp_pics )) == NULL ) vlc_cond_wait( &p_sys->cond, &p_sys->lock_out ); if( p_sys->b_abort ) { vlc_mutex_unlock( &p_sys->lock_out ); break; } vlc_mutex_unlock( &p_sys->lock_out ); p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic ); vlc_mutex_lock( &p_sys->lock_out ); block_ChainAppend( &p_sys->p_buffers, p_block ); vlc_mutex_unlock( &p_sys->lock_out ); picture_Release( p_pic ); } block_ChainRelease( p_sys->p_buffers ); vlc_restorecancel (canc); return NULL; }
static void PrintObject( vlc_object_internals_t *priv, const char *psz_prefix ) { char psz_refcount[20], psz_thread[30], psz_name[50], psz_parent[20]; int canc = vlc_savecancel (); memset( &psz_name, 0, sizeof(psz_name) ); vlc_mutex_lock (&name_lock); if (priv->psz_name != NULL) { snprintf( psz_name, 49, " \"%s\"", priv->psz_name ); if( psz_name[48] ) psz_name[48] = '\"'; } vlc_mutex_unlock (&name_lock); psz_refcount[0] = '\0'; if( priv->i_refcount > 0 ) snprintf( psz_refcount, 19, ", %u refs", priv->i_refcount ); psz_thread[0] = '\0'; if( priv->b_thread ) snprintf( psz_thread, 29, " (thread %lu)", (unsigned long)priv->thread_id ); psz_parent[0] = '\0'; /* FIXME: need structure lock!!! */ if( vlc_externals(priv)->p_parent ) snprintf( psz_parent, 19, ", parent %p", vlc_externals(priv)->p_parent ); printf( " %so %p %s%s%s%s%s\n", psz_prefix, vlc_externals(priv), vlc_externals(priv)->psz_object_type, psz_name, psz_thread, psz_refcount, psz_parent ); vlc_restorecancel (canc); }
int DoAcoustIdWebRequest( vlc_object_t *p_obj, acoustid_fingerprint_t *p_data ) { int i_ret; int i_status; struct webrequest_t request = { NULL, NULL, NULL }; if ( !p_data->psz_fingerprint ) return VLC_SUCCESS; i_ret = asprintf( & request.psz_url, "http://fingerprint.videolan.org/acoustid.php?meta=recordings+tracks+usermeta+releases&duration=%d&fingerprint=%s", p_data->i_duration, p_data->psz_fingerprint ); if ( i_ret < 1 ) return VLC_EGENERIC; vlc_cleanup_push( cancelDoAcoustIdWebRequest, &request ); msg_Dbg( p_obj, "Querying AcoustID from %s", request.psz_url ); request.p_stream = stream_UrlNew( p_obj, request.psz_url ); if ( !request.p_stream ) { i_status = VLC_EGENERIC; goto cleanup; } /* read answer */ i_ret = 0; for( ;; ) { int i_read = 65536; if( i_ret >= INT_MAX - i_read ) break; request.p_buffer = realloc_or_free( request.p_buffer, 1 + i_ret + i_read ); if( !request.p_buffer ) { i_status = VLC_ENOMEM; goto cleanup; } i_read = stream_Read( request.p_stream, &request.p_buffer[i_ret], i_read ); if( i_read <= 0 ) break; i_ret += i_read; } stream_Delete( request.p_stream ); request.p_stream = NULL; request.p_buffer[ i_ret ] = 0; int i_canc = vlc_savecancel(); if ( ParseJson( p_obj, request.p_buffer, & p_data->results ) ) { msg_Dbg( p_obj, "results count == %d", p_data->results.count ); } else { msg_Dbg( p_obj, "No results" ); } vlc_restorecancel( i_canc ); i_status = VLC_SUCCESS; cleanup: vlc_cleanup_run( ); return i_status; }
/***************************************************************************** * EventThread: Create video window & handle its messages ***************************************************************************** * This function creates a video window and then enters an infinite loop * that handles the messages sent to that window. * The main goal of this thread is to isolate the Win32 PeekMessage function * because this one can block for a long time. *****************************************************************************/ static void *EventThread( void *p_this ) { event_thread_t *p_event = (event_thread_t *)p_this; vout_display_t *vd = p_event->vd; MSG msg; POINT old_mouse_pos = {0,0}, mouse_pos; int canc = vlc_savecancel (); bool b_mouse_support = var_InheritBool( p_event->vd, "mouse-events" ); bool b_key_support = var_InheritBool( p_event->vd, "keyboard-events" ); vlc_mutex_lock( &p_event->lock ); /* Create a window for the video */ /* Creating a window under Windows also initializes the thread's event * message queue */ if( DirectXCreateWindow( p_event ) ) p_event->b_error = true; p_event->b_ready = true; vlc_cond_signal( &p_event->wait ); const bool b_error = p_event->b_error; vlc_mutex_unlock( &p_event->lock ); if( b_error ) { vlc_restorecancel( canc ); return NULL; } #ifndef UNDER_CE /* Prevent monitor from powering off */ SetThreadExecutionState( ES_DISPLAY_REQUIRED | ES_CONTINUOUS ); #endif /* Main loop */ /* GetMessage will sleep if there's no message in the queue */ for( ;; ) { vout_display_place_t place; video_format_t source; if( !GetMessage( &msg, 0, 0, 0 ) ) { vlc_mutex_lock( &p_event->lock ); p_event->b_done = true; vlc_mutex_unlock( &p_event->lock ); break; } /* Check if we are asked to exit */ vlc_mutex_lock( &p_event->lock ); const bool b_done = p_event->b_done; vlc_mutex_unlock( &p_event->lock ); if( b_done ) break; if( !b_mouse_support && isMouseEvent( msg.message ) ) continue; if( !b_key_support && isKeyEvent( msg.message ) ) continue; /* Handle mouse state */ if( msg.message == WM_MOUSEMOVE || msg.message == WM_NCMOUSEMOVE ) { GetCursorPos( &mouse_pos ); /* FIXME, why this >2 limits ? */ if( (abs(mouse_pos.x - old_mouse_pos.x) > 2 || (abs(mouse_pos.y - old_mouse_pos.y)) > 2 ) ) { old_mouse_pos = mouse_pos; UpdateCursor( p_event, true ); } } else if( isMouseEvent( msg.message ) ) { UpdateCursor( p_event, true ); } else if( msg.message == WM_VLC_HIDE_MOUSE ) { UpdateCursor( p_event, false ); } /* */ switch( msg.message ) { case WM_MOUSEMOVE: vlc_mutex_lock( &p_event->lock ); place = p_event->place; source = p_event->source; vlc_mutex_unlock( &p_event->lock ); if( place.width > 0 && place.height > 0 ) { if( msg.hwnd == p_event->hvideownd ) { /* Child window */ place.x = 0; place.y = 0; } const int x = source.i_x_offset + (int64_t)(GET_X_LPARAM(msg.lParam) - place.x) * source.i_width / place.width; const int y = source.i_y_offset + (int64_t)(GET_Y_LPARAM(msg.lParam) - place.y) * source.i_height / place.height; vout_display_SendEventMouseMoved(vd, x, y); } break; case WM_NCMOUSEMOVE: break; case WM_VLC_HIDE_MOUSE: break; case WM_LBUTTONDOWN: MousePressed( p_event, msg.hwnd, MOUSE_BUTTON_LEFT ); break; case WM_LBUTTONUP: MouseReleased( p_event, MOUSE_BUTTON_LEFT ); break; case WM_LBUTTONDBLCLK: vout_display_SendEventMouseDoubleClick(vd); break; case WM_MBUTTONDOWN: MousePressed( p_event, msg.hwnd, MOUSE_BUTTON_CENTER ); break; case WM_MBUTTONUP: MouseReleased( p_event, MOUSE_BUTTON_CENTER ); break; case WM_RBUTTONDOWN: MousePressed( p_event, msg.hwnd, MOUSE_BUTTON_RIGHT ); break; case WM_RBUTTONUP: MouseReleased( p_event, MOUSE_BUTTON_RIGHT ); break; case WM_KEYDOWN: case WM_SYSKEYDOWN: { /* The key events are first processed here and not translated * into WM_CHAR events because we need to know the status of the * modifier keys. */ int i_key = DirectXConvertKey( msg.wParam ); if( !i_key ) { /* This appears to be a "normal" (ascii) key */ i_key = tolower( MapVirtualKey( msg.wParam, 2 ) ); } if( i_key ) { if( GetKeyState(VK_CONTROL) & 0x8000 ) { i_key |= KEY_MODIFIER_CTRL; } if( GetKeyState(VK_SHIFT) & 0x8000 ) { i_key |= KEY_MODIFIER_SHIFT; } if( GetKeyState(VK_MENU) & 0x8000 ) { i_key |= KEY_MODIFIER_ALT; } vout_display_SendEventKey(vd, i_key); } break; } case WM_MOUSEWHEEL: { int i_key; if( GET_WHEEL_DELTA_WPARAM( msg.wParam ) > 0 ) { i_key = KEY_MOUSEWHEELUP; } else { i_key = KEY_MOUSEWHEELDOWN; } if( i_key ) { if( GetKeyState(VK_CONTROL) & 0x8000 ) { i_key |= KEY_MODIFIER_CTRL; } if( GetKeyState(VK_SHIFT) & 0x8000 ) { i_key |= KEY_MODIFIER_SHIFT; } if( GetKeyState(VK_MENU) & 0x8000 ) { i_key |= KEY_MODIFIER_ALT; } vout_display_SendEventKey(vd, i_key); } break; } case WM_VLC_CHANGE_TEXT: { vlc_mutex_lock( &p_event->lock ); wchar_t *pwz_title = NULL; if( p_event->psz_title ) { const size_t i_length = strlen(p_event->psz_title); pwz_title = malloc( 2 * (i_length + 1) ); if( pwz_title ) { mbstowcs( pwz_title, p_event->psz_title, 2 * i_length ); pwz_title[i_length] = 0; } } vlc_mutex_unlock( &p_event->lock ); if( pwz_title ) { SetWindowTextW( p_event->hwnd, pwz_title ); if( p_event->hfswnd ) SetWindowTextW( p_event->hfswnd, pwz_title ); free( pwz_title ); } break; } default: /* Messages we don't handle directly are dispatched to the * window procedure */ TranslateMessage(&msg); DispatchMessage(&msg); break; } /* End Switch */ } /* End Main loop */ /* Check for WM_QUIT if we created the window */ if( !p_event->hparent && msg.message == WM_QUIT ) { msg_Warn( vd, "WM_QUIT... should not happen!!" ); p_event->hwnd = NULL; /* Window already destroyed */ } msg_Dbg( vd, "DirectXEventThread terminating" ); DirectXCloseWindow( p_event ); vlc_restorecancel(canc); return NULL; }
static void *Thread (void *data) { demux_t *demux = data; demux_sys_t *sys = demux->p_sys; snd_pcm_t *pcm = sys->pcm; size_t bytes; int canc, val; canc = vlc_savecancel (); bytes = snd_pcm_frames_to_bytes (pcm, sys->period_size); val = snd_pcm_start (pcm); if (val) { msg_Err (demux, "cannot prepare device: %s", snd_strerror (val)); return NULL; } for (;;) { block_t *block = block_Alloc (bytes); if (unlikely(block == NULL)) break; /* Wait for data */ Poll (pcm, canc); /* Read data */ snd_pcm_sframes_t frames, delay; mtime_t pts; frames = snd_pcm_readi (pcm, block->p_buffer, sys->period_size); pts = mdate (); if (frames < 0) { block_Release (block); if (frames == -EAGAIN) continue; val = snd_pcm_recover (pcm, frames, 1); if (val == 0) { msg_Warn (demux, "cannot read samples: %s", snd_strerror (frames)); snd_pcm_state_t state = snd_pcm_state (pcm); switch (state) { case SND_PCM_STATE_PREPARED: val = snd_pcm_start (pcm); if (val < 0) { msg_Err (demux, "cannot prepare device: %s", snd_strerror (val)); return NULL; } continue; case SND_PCM_STATE_RUNNING: continue; default: break; } } msg_Err (demux, "cannot recover record stream: %s", snd_strerror (val)); DumpDeviceStatus (demux, pcm); break; } /* Compute time stamp */ if (snd_pcm_delay (pcm, &delay)) delay = 0; delay += frames; pts -= (CLOCK_FREQ * delay) / sys->rate; block->i_buffer = snd_pcm_frames_to_bytes (pcm, frames); block->i_nb_samples = frames; block->i_pts = pts; block->i_length = (CLOCK_FREQ * frames) / sys->rate; es_out_SetPCR(demux->out, block->i_pts); es_out_Send (demux->out, sys->es, block); } return NULL; }
/***************************************************************************** * Run: xosd thread ***************************************************************************** * This part of the interface runs in a separate thread *****************************************************************************/ static void Run( intf_thread_t *p_intf ) { playlist_t *p_playlist; playlist_item_t *p_item = NULL; char *psz_display = NULL; int cancel = vlc_savecancel(); while( true ) { // Wait for a signal vlc_restorecancel( cancel ); vlc_mutex_lock( &p_intf->p_sys->lock ); mutex_cleanup_push( &p_intf->p_sys->lock ); while( !p_intf->p_sys->b_need_update ) vlc_cond_wait( &p_intf->p_sys->cond, &p_intf->p_sys->lock ); p_intf->p_sys->b_need_update = false; vlc_cleanup_run(); // Compute the signal cancel = vlc_savecancel(); p_playlist = pl_Hold( p_intf ); PL_LOCK; // If the playlist is empty don't do anything if( playlist_IsEmpty( p_playlist ) ) { PL_UNLOCK; pl_Release( p_intf ); continue; } free( psz_display ); int i_status = playlist_Status( p_playlist ); if( i_status == PLAYLIST_STOPPED ) { psz_display = strdup(_("Stop")); } else if( i_status == PLAYLIST_PAUSED ) { psz_display = strdup(_("Pause")); } else { p_item = playlist_CurrentPlayingItem( p_playlist ); if( !p_item ) { psz_display = NULL; PL_UNLOCK; pl_Release( p_intf ); continue; } input_item_t *p_input = p_item->p_input; mtime_t i_duration = input_item_GetDuration( p_input ); if( i_duration != -1 ) { char psz_durationstr[MSTRTIME_MAX_SIZE]; secstotimestr( psz_durationstr, i_duration / 1000000 ); if( asprintf( &psz_display, "%s (%s)", p_input->psz_name, psz_durationstr ) == -1 ) psz_display = NULL; } else psz_display = strdup( p_input->psz_name ); } PL_UNLOCK; pl_Release( p_intf ); /* Display */ xosd_display( p_intf->p_sys->p_osd, 0, /* first line */ XOSD_string, psz_display ); } }
/***************************************************************************** * Demux: *****************************************************************************/ static void *DemuxThread( void *p_data ) { demux_t *p_demux = (demux_t *) p_data; demux_sys_t *p_sys = p_demux->p_sys; p_sys->i_starttime = vlc_tick_now(); vlc_tick_t i_next_frame_date = vlc_tick_now() + p_sys->i_frame_interval; int i_ret; for(;;) { i_ret = 0; p_sys->i_cancel_state = vlc_savecancel(); if ( freerdp_shall_disconnect( p_sys->p_instance ) ) { vlc_restorecancel( p_sys->i_cancel_state ); msg_Warn( p_demux, "RDP server closed session" ); es_out_Del( p_demux->out, p_sys->es ); p_sys->es = NULL; return NULL; } struct { void* pp_rfds[RDP_MAX_FD]; /* Declared by rdp */ void* pp_wfds[RDP_MAX_FD]; int i_nbr; int i_nbw; struct pollfd ufds[RDP_MAX_FD]; } fds; fds.i_nbr = fds.i_nbw = 0; if ( freerdp_get_fds( p_sys->p_instance, fds.pp_rfds, &fds.i_nbr, fds.pp_wfds, &fds.i_nbw ) != true ) { vlc_restorecancel( p_sys->i_cancel_state ); msg_Err( p_demux, "cannot get FDS" ); } else if ( (fds.i_nbr + fds.i_nbw) > 0 && p_sys->es ) { vlc_restorecancel( p_sys->i_cancel_state ); int i_count = 0; for( int i = 0; i < fds.i_nbr; i++ ) { fds.ufds[ i_count ].fd = (long) fds.pp_rfds[ i ]; fds.ufds[ i_count ].events = POLLIN ; fds.ufds[ i_count++ ].revents = 0; } for( int i = 0; i < fds.i_nbw && i_count < RDP_MAX_FD; i++ ) { /* may be useless */ fds.ufds[ i_count ].fd = (long) fds.pp_wfds[ i ]; fds.ufds[ i_count ].events = POLLOUT; fds.ufds[ i_count++ ].revents = 0; } i_ret = poll( fds.ufds, i_count, p_sys->i_frame_interval * 1000/2 ); } else { vlc_restorecancel( p_sys->i_cancel_state ); } vlc_tick_wait( i_next_frame_date ); i_next_frame_date += p_sys->i_frame_interval; if ( i_ret >= 0 ) { /* Do the rendering */ p_sys->i_cancel_state = vlc_savecancel(); freerdp_check_fds( p_sys->p_instance ); vlc_restorecancel( p_sys->i_cancel_state ); block_t *p_block = block_Duplicate( p_sys->p_block ); if (likely( p_block && p_sys->p_block )) { p_sys->p_block->i_dts = p_sys->p_block->i_pts = vlc_tick_now() - p_sys->i_starttime; es_out_SetPCR( p_demux->out, p_sys->p_block->i_pts ); es_out_Send( p_demux->out, p_sys->es, p_sys->p_block ); p_sys->p_block = p_block; } } } return NULL; }
/** * 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; }
/***************************************************************************** * Run : call Handshake() then submit songs *****************************************************************************/ static void *Run(void *data) { intf_thread_t *p_intf = data; uint8_t p_buffer[1024]; int canc = vlc_savecancel(); bool b_handshaked = false; /* data about audioscrobbler session */ mtime_t next_exchange = -1; /**< when can we send data */ unsigned int i_interval = 0; /**< waiting interval (secs)*/ intf_sys_t *p_sys = p_intf->p_sys; /* main loop */ for (;;) { vlc_restorecancel(canc); vlc_mutex_lock(&p_sys->lock); mutex_cleanup_push(&p_sys->lock); do vlc_cond_wait(&p_sys->wait, &p_sys->lock); while (mdate() < next_exchange); vlc_cleanup_run(); canc = vlc_savecancel(); /* handshake if needed */ if (!b_handshaked) { msg_Dbg(p_intf, "Handshaking with last.fm ..."); switch(Handshake(p_intf)) { case VLC_ENOMEM: goto out; case VLC_ENOVAR: /* username not set */ dialog_Fatal(p_intf, _("Last.fm username not set"), "%s", _("Please set a username or disable the " "audioscrobbler plugin, and restart VLC.\n" "Visit http://www.last.fm/join/ to get an account.")); goto out; case VLC_SUCCESS: msg_Dbg(p_intf, "Handshake successful :)"); b_handshaked = true; i_interval = 0; next_exchange = mdate(); break; case VLC_AUDIOSCROBBLER_EFATAL: msg_Warn(p_intf, "Exiting..."); goto out; case VLC_EGENERIC: default: /* protocol error : we'll try later */ HandleInterval(&next_exchange, &i_interval); break; } /* if handshake failed let's restart the loop */ if (!b_handshaked) continue; } msg_Dbg(p_intf, "Going to submit some data..."); char *psz_submit; if (asprintf(&psz_submit, "s=%s", p_sys->psz_auth_token) == -1) break; /* forge the HTTP POST request */ vlc_mutex_lock(&p_sys->lock); audioscrobbler_song_t *p_song; for (int i_song = 0 ; i_song < p_sys->i_songs ; i_song++) { char *psz_submit_song, *psz_submit_tmp; p_song = &p_sys->p_queue[i_song]; if (asprintf(&psz_submit_song, "&a%%5B%d%%5D=%s" "&t%%5B%d%%5D=%s" "&i%%5B%d%%5D=%u" "&o%%5B%d%%5D=P" "&r%%5B%d%%5D=" "&l%%5B%d%%5D=%d" "&b%%5B%d%%5D=%s" "&n%%5B%d%%5D=%s" "&m%%5B%d%%5D=%s", i_song, p_song->psz_a, i_song, p_song->psz_t, i_song, (unsigned)p_song->date, /* HACK: %ju (uintmax_t) unsupported on Windows */ i_song, i_song, i_song, p_song->i_l, i_song, p_song->psz_b, i_song, p_song->psz_n, i_song, p_song->psz_m ) == -1) { /* Out of memory */ vlc_mutex_unlock(&p_sys->lock); goto out; } psz_submit_tmp = psz_submit; if (asprintf(&psz_submit, "%s%s", psz_submit_tmp, psz_submit_song) == -1) { /* Out of memory */ free(psz_submit_tmp); free(psz_submit_song); vlc_mutex_unlock(&p_sys->lock); goto out; } free(psz_submit_song); free(psz_submit_tmp); } vlc_mutex_unlock(&p_sys->lock); int i_post_socket = net_ConnectTCP(p_intf, p_sys->p_submit_url.psz_host, p_sys->p_submit_url.i_port); if (i_post_socket == -1) { /* If connection fails, we assume we must handshake again */ HandleInterval(&next_exchange, &i_interval); b_handshaked = false; free(psz_submit); continue; } /* we transmit the data */ int i_net_ret = net_Printf(p_intf, i_post_socket, NULL, "POST %s HTTP/1.1\n" "Accept-Encoding: identity\n" "Content-length: %zu\n" "Connection: close\n" "Content-type: application/x-www-form-urlencoded\n" "Host: %s\n" "User-agent: VLC media player/"VERSION"\r\n" "\r\n" "%s\r\n" "\r\n", p_sys->p_submit_url.psz_path, strlen(psz_submit), p_sys->p_submit_url.psz_host, psz_submit ); free(psz_submit); if (i_net_ret == -1) { /* If connection fails, we assume we must handshake again */ HandleInterval(&next_exchange, &i_interval); b_handshaked = false; continue; } i_net_ret = net_Read(p_intf, i_post_socket, NULL, p_buffer, sizeof(p_buffer) - 1, false); if (i_net_ret <= 0) { /* if we get no answer, something went wrong : try again */ continue; } net_Close(i_post_socket); p_buffer[i_net_ret] = '\0'; char *failed = strstr((char *) p_buffer, "FAILED"); if (failed) { msg_Warn(p_intf, "%s", failed); HandleInterval(&next_exchange, &i_interval); continue; } if (strstr((char *) p_buffer, "BADSESSION")) { msg_Err(p_intf, "Authentication failed (BADSESSION), are you connected to last.fm with another program ?"); b_handshaked = false; HandleInterval(&next_exchange, &i_interval); continue; } if (strstr((char *) p_buffer, "OK")) { for (int i = 0; i < p_sys->i_songs; i++) DeleteSong(&p_sys->p_queue[i]); p_sys->i_songs = 0; i_interval = 0; next_exchange = mdate(); msg_Dbg(p_intf, "Submission successful!"); } else { msg_Err(p_intf, "Authentication failed, handshaking again (%s)", p_buffer); b_handshaked = false; HandleInterval(&next_exchange, &i_interval); } } out: vlc_restorecancel(canc); return NULL; }
static void *Master(void *handle) { intf_thread_t *intf = handle; intf_sys_t *sys = intf->p_sys; for (;;) { struct pollfd ufd = { .fd = sys->fd, .events = POLLIN, }; uint64_t data[2]; if (poll(&ufd, 1, -1) < 0) continue; /* We received something */ struct sockaddr_storage from; unsigned struct_size = sizeof(from); recvfrom(sys->fd, data, sizeof(data), 0, (struct sockaddr*)&from, &struct_size); mtime_t master_system = GetPcrSystem(sys->input); if (master_system < 0) continue; data[0] = hton64(mdate()); data[1] = hton64(master_system); /* Reply to the sender */ sendto(sys->fd, data, sizeof(data), 0, (struct sockaddr *)&from, struct_size); #if 0 /* not sure we need the client information to sync, since we are the master anyway */ mtime_t client_system = ntoh64(data[0]); msg_Dbg(intf, "Master clockref: %"PRId64" -> %"PRId64", from %s " "(date: %"PRId64")", client_system, master_system, (from.ss_family == AF_INET) ? inet_ntoa(((struct sockaddr_in *)&from)->sin_addr) : "non-IPv4", /*date*/ 0); #endif } return NULL; } static void *Slave(void *handle) { intf_thread_t *intf = handle; intf_sys_t *sys = intf->p_sys; for (;;) { struct pollfd ufd = { .fd = sys->fd, .events = POLLIN, }; uint64_t data[2]; mtime_t system = GetPcrSystem(sys->input); if (system < 0) goto wait; /* Send clock request to the master */ data[0] = hton64(system); const mtime_t send_date = mdate(); if (send(sys->fd, data, sizeof(data[0]), 0) <= 0) goto wait; /* Don't block */ if (poll(&ufd, 1, sys->timeout) <= 0) continue; const mtime_t receive_date = mdate(); if (recv(sys->fd, data, sizeof(data), 0) <= 0) goto wait; const mtime_t master_date = ntoh64(data[0]); const mtime_t master_system = ntoh64(data[1]); const mtime_t diff_date = receive_date - ((receive_date - send_date) / 2 + master_date); if (master_system > 0) { int canc = vlc_savecancel(); mtime_t client_system; if (!input_GetPcrSystem(sys->input, &client_system, NULL)) { const mtime_t diff_system = client_system - master_system - diff_date; if (diff_system != 0) { input_ModifyPcrSystem(sys->input, true, master_system - diff_date); #if 0 msg_Dbg(intf, "Slave clockref: %"PRId64" -> %"PRId64" -> %"PRId64"," " clock diff: %"PRId64", diff: %"PRId64"", system, master_system, client_system, diff_system, diff_date); #endif } } vlc_restorecancel(canc); } wait: msleep(INTF_IDLE_SLEEP); } return NULL; } static int InputEvent(vlc_object_t *object, char const *cmd, vlc_value_t oldval, vlc_value_t newval, void *data) { VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(object); intf_thread_t *intf = data; intf_sys_t *sys = intf->p_sys; if (newval.i_int == INPUT_EVENT_DEAD && sys->input) { msg_Err(intf, "InputEvent DEAD"); vlc_cancel(sys->thread); vlc_join(sys->thread, NULL); vlc_object_release(sys->input); sys->input = NULL; } return VLC_SUCCESS; }
//--------------------------------------------------------------------------- // Run: main loop //--------------------------------------------------------------------------- static void *Run( void * p_obj ) { int canc = vlc_savecancel(); intf_thread_t *p_intf = (intf_thread_t *)p_obj; bool b_error = false; char *skin_last = NULL; ThemeLoader *pLoader = NULL; OSLoop *loop = NULL; vlc_mutex_lock( &p_intf->p_sys->init_lock ); // Initialize singletons if( OSFactory::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot initialize OSFactory" ); b_error = true; goto end; } if( AsyncQueue::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot initialize AsyncQueue" ); b_error = true; goto end; } if( Interpreter::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instantiate Interpreter" ); b_error = true; goto end; } if( VarManager::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instantiate VarManager" ); b_error = true; goto end; } if( VlcProc::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot initialize VLCProc" ); b_error = true; goto end; } if( VoutManager::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instantiate VoutManager" ); b_error = true; goto end; } if( ArtManager::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instantiate ArtManager" ); b_error = true; goto end; } if( ThemeRepository::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instantiate ThemeRepository" ); b_error = true; goto end; } if( Dialogs::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instantiate qt4 dialogs provider" ); b_error = true; goto end; } // Load a theme skin_last = config_GetPsz( p_intf, "skins2-last" ); pLoader = new ThemeLoader( p_intf ); if( !skin_last || !pLoader->load( skin_last ) ) { // No skins (not even the default one). let's quit CmdQuit *pCmd = new CmdQuit( p_intf ); AsyncQueue *pQueue = AsyncQueue::instance( p_intf ); pQueue->push( CmdGenericPtr( pCmd ) ); msg_Err( p_intf, "no skins found : exiting"); } delete pLoader; free( skin_last ); // Get the instance of OSLoop loop = OSFactory::instance( p_intf )->getOSLoop(); // Signal the main thread this thread is now ready p_intf->p_sys->b_error = false; p_intf->p_sys->b_ready = true; vlc_cond_signal( &p_intf->p_sys->init_wait ); vlc_mutex_unlock( &p_intf->p_sys->init_lock ); // Enter the main event loop loop->run(); // Destroy OSLoop OSFactory::instance( p_intf )->destroyOSLoop(); // save and delete the theme if( p_intf->p_sys->p_theme ) { p_intf->p_sys->p_theme->saveConfig(); delete p_intf->p_sys->p_theme; p_intf->p_sys->p_theme = NULL; msg_Dbg( p_intf, "current theme deleted" ); } // save config file config_SaveConfigFile( p_intf ); end: // Destroy "singleton" objects Dialogs::destroy( p_intf ); ThemeRepository::destroy( p_intf ); ArtManager::destroy( p_intf ); VoutManager::destroy( p_intf ); VlcProc::destroy( p_intf ); VarManager::destroy( p_intf ); Interpreter::destroy( p_intf ); AsyncQueue::destroy( p_intf ); OSFactory::destroy( p_intf ); if( b_error ) { p_intf->p_sys->b_error = true; p_intf->p_sys->b_ready = true; vlc_cond_signal( &p_intf->p_sys->init_wait ); vlc_mutex_unlock( &p_intf->p_sys->init_lock ); } vlc_restorecancel(canc); return NULL; }
void *vlc_custom_create( vlc_object_t *p_this, size_t i_size, int i_type, const char *psz_type ) { vlc_object_t *p_new; vlc_object_internals_t *p_priv; /* NOTE: * VLC objects are laid out as follow: * - first the LibVLC-private per-object data, * - then VLC_COMMON members from vlc_object_t, * - finally, the type-specific data (if any). * * This function initializes the LibVLC and common data, * and zeroes the rest. */ p_priv = calloc( 1, sizeof( *p_priv ) + i_size ); if( p_priv == NULL ) return NULL; assert (i_size >= sizeof (vlc_object_t)); p_new = (vlc_object_t *)(p_priv + 1); p_priv->i_object_type = i_type; p_new->psz_object_type = psz_type; p_priv->psz_name = NULL; p_new->b_die = false; p_new->b_force = false; p_new->psz_header = NULL; if (p_this) p_new->i_flags = p_this->i_flags & (OBJECT_FLAGS_NODBG|OBJECT_FLAGS_QUIET|OBJECT_FLAGS_NOINTERACT); p_priv->var_root = NULL; if( p_this == NULL ) { libvlc_int_t *self = (libvlc_int_t*)p_new; p_new->p_libvlc = self; vlc_mutex_init (&(libvlc_priv (self)->structure_lock)); p_this = p_new; } else p_new->p_libvlc = p_this->p_libvlc; vlc_spin_init( &p_priv->ref_spin ); p_priv->i_refcount = 1; p_priv->pf_destructor = NULL; p_priv->b_thread = false; p_new->p_parent = NULL; p_priv->first = NULL; #ifndef NDEBUG p_priv->old_parent = NULL; #endif /* Initialize mutexes and condvars */ vlc_mutex_init( &p_priv->var_lock ); vlc_cond_init( &p_priv->var_wait ); p_priv->pipes[0] = p_priv->pipes[1] = -1; if (p_new == VLC_OBJECT(p_new->p_libvlc)) { /* TODO: should be in src/libvlc.c */ int canc = vlc_savecancel (); var_Create( p_new, "tree", VLC_VAR_STRING | VLC_VAR_ISCOMMAND ); var_AddCallback( p_new, "tree", DumpCommand, NULL ); var_Create( p_new, "vars", VLC_VAR_STRING | VLC_VAR_ISCOMMAND ); var_AddCallback( p_new, "vars", DumpCommand, NULL ); vlc_restorecancel (canc); } return p_new; }