static void Run( fingerprinter_thread_t *p_fingerprinter ) { fingerprinter_sys_t *p_sys = p_fingerprinter->p_sys; /* main loop */ for (;;) { vlc_mutex_lock( &p_sys->processing.lock ); mutex_cleanup_push( &p_sys->processing.lock ); vlc_cond_timedwait( &p_sys->incoming_queue_filled, &p_sys->processing.lock, mdate() + 1000000 ); vlc_cleanup_run(); QueueIncomingRequests( p_sys ); vlc_mutex_lock( &p_sys->processing.lock ); // L0 mutex_cleanup_push( &p_sys->processing.lock ); vlc_cleanup_push( cancelRun, p_sys ); // C1 //** for ( p_sys->i = 0 ; p_sys->i < vlc_array_count( p_sys->processing.queue ); p_sys->i++ ) { fingerprint_request_t *p_data = vlc_array_item_at_index( p_sys->processing.queue, p_sys->i ); acoustid_fingerprint_t acoustid_print; memset( &acoustid_print , 0, sizeof(acoustid_fingerprint_t) ); vlc_cleanup_push( clearPrint, &acoustid_print ); // C2 p_sys->psz_uri = input_item_GetURI( p_data->p_item ); if ( p_sys->psz_uri ) { /* overwrite with hint, as in this case, fingerprint's session will be truncated */ if ( p_data->i_duration ) acoustid_print.i_duration = p_data->i_duration; DoFingerprint( VLC_OBJECT(p_fingerprinter), p_sys, &acoustid_print ); DoAcoustIdWebRequest( VLC_OBJECT(p_fingerprinter), &acoustid_print ); fill_metas_with_results( p_data, &acoustid_print ); FREENULL( p_sys->psz_uri ); } vlc_cleanup_run( ); // C2 /* copy results */ vlc_mutex_lock( &p_sys->results.lock ); vlc_array_append( p_sys->results.queue, p_data ); vlc_mutex_unlock( &p_sys->results.lock ); vlc_testcancel(); } if ( vlc_array_count( p_sys->processing.queue ) ) { var_TriggerCallback( p_fingerprinter, "results-available" ); vlc_array_clear( p_sys->processing.queue ); } vlc_cleanup_pop( ); // C1 //** vlc_cleanup_run(); // L0 } }
static void* Raw1394EventThread( void *obj ) { event_thread_t *p_ev = (event_thread_t *)obj; access_t *p_access = (access_t *) p_ev->p_access; access_sys_t *p_sys = (access_sys_t *) p_access->p_sys; int result = 0; int canc = vlc_savecancel(); AVCPlay( p_access, p_sys->i_node ); vlc_cleanup_push( Raw1394EventThreadCleanup, p_ev ); vlc_restorecancel( canc ); for( ;; ) { while( ( result = poll( &p_sys->raw1394_poll, 1, -1 ) ) < 0 ) { if( errno != EINTR ) msg_Err( p_access, "poll error: %m" ); } if( result > 0 && ( ( p_sys->raw1394_poll.revents & POLLIN ) || ( p_sys->raw1394_poll.revents & POLLPRI ) ) ) { canc = vlc_savecancel(); result = raw1394_loop_iterate( p_sys->p_raw1394 ); vlc_restorecancel( canc ); } } vlc_cleanup_run(); return NULL; }
/***************************************************************************** * Run: Thread entry-point ****************************************************************************/ static void* Run( void *data ) { services_discovery_t *p_sd = ( services_discovery_t * )data; services_discovery_sys_t *p_sys = p_sd->p_sys; lua_State *L = p_sys->L; int cancel = vlc_savecancel(); lua_getglobal( L, "main" ); if( !lua_isfunction( L, lua_gettop( L ) ) || lua_pcall( L, 0, 1, 0 ) ) { msg_Err( p_sd, "Error while running script %s, " "function main(): %s", p_sys->psz_filename, lua_tostring( L, lua_gettop( L ) ) ); lua_pop( L, 1 ); vlc_restorecancel( cancel ); return NULL; } msg_Dbg( p_sd, "LuaSD script loaded: %s", p_sys->psz_filename ); /* Force garbage collection, because the core will keep the SD * open, but lua will never gc until lua_close(). */ lua_gc( L, LUA_GCCOLLECT, 0 ); vlc_restorecancel( cancel ); /* Main loop to handle search requests */ vlc_mutex_lock( &p_sys->lock ); mutex_cleanup_push( &p_sys->lock ); while( !p_sys->b_exiting ) { /* Wait for a request */ while( !p_sys->i_query ) vlc_cond_wait( &p_sys->cond, &p_sys->lock ); /* Execute every query each one protected against cancelation */ cancel = vlc_savecancel(); while( !p_sys->b_exiting && p_sys->i_query ) { char *psz_query = p_sys->ppsz_query[p_sys->i_query - 1]; REMOVE_ELEM( (char **), p_sys->ppsz_query, p_sys->i_query, p_sys->i_query - 1 ); // sunqueen modify vlc_mutex_unlock( &p_sys->lock ); DoSearch( p_sd, psz_query ); free( psz_query ); vlc_mutex_lock( &p_sys->lock ); } /* Force garbage collection, because the core will keep the SD * open, but lua will never gc until lua_close(). */ lua_gc( L, LUA_GCCOLLECT, 0 ); vlc_restorecancel( cancel ); } vlc_cleanup_run(); return NULL; }
static void *Thread (void *data) { stream_t *stream = data; stream_sys_t *p_sys = stream->p_sys; #ifdef HAVE_VMSPLICE ssize_t page_mask = sysconf (_SC_PAGE_SIZE) - 1; #endif int fd = p_sys->write_fd; bool error = false; do { ssize_t len; int canc = vlc_savecancel (); #ifdef HAVE_VMSPLICE unsigned char *buf = mmap (NULL, bufsize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); vlc_cleanup_push (cleanup_mmap, buf); #else unsigned char buf[bufsize]; #endif len = stream_Read (stream->p_source, buf, bufsize); vlc_restorecancel (canc); error = len <= 0; for (ssize_t i = 0, j; i < len; i += j) { #ifdef HAVE_VMSPLICE if ((len - i) <= page_mask) /* incomplete last page */ j = write (fd, buf + i, len - i); else { struct iovec iov = { buf + i, (len - i) & ~page_mask, }; j = vmsplice (fd, &iov, 1, SPLICE_F_GIFT); } if (j == -1 && errno == ENOSYS) /* vmsplice() not supported */ #endif j = write (fd, buf + i, len - i); if (j <= 0) { if (j == 0) errno = EPIPE; msg_Err (stream, "cannot write data (%m)"); error = true; break; } } #ifdef HAVE_VMSPLICE vlc_cleanup_run (); /* munmap (buf, bufsize) */ #endif } while (!error); msg_Dbg (stream, "compressed stream at EOF"); return NULL; }
static void* update_request_thread( void *obj ) { filter_t* p_filter = (filter_t*)obj; filter_sys_t *p_sys = p_filter->p_sys; msg_Dbg( p_filter, "VNC update request thread started" ); rfbFramebufferUpdateRequestMsg udr; udr.type = rfbFramebufferUpdateRequest; udr.incremental = 0; udr.x = 0; udr.y = 0; udr.w = htons(p_sys->i_vnc_width); udr.h = htons(p_sys->i_vnc_height); int w; vlc_cleanup_push( update_request_thread_cleanup, p_filter ); w = write_exact(p_filter, p_sys->i_socket, (char*)&udr, sz_rfbFramebufferUpdateRequestMsg); vlc_cleanup_pop(); if( !w ) { msg_Err( p_filter, "Could not write rfbFramebufferUpdateRequestMsg." ); update_request_thread_cleanup( p_filter ); return NULL; } udr.incremental = 1; mtime_t i_poll_interval_microsec = p_sys->i_vnc_poll_interval * 1000; if( p_sys->b_vnc_poll) { vlc_cleanup_push( update_request_thread_cleanup, p_filter ); for( ;; ) { msleep( i_poll_interval_microsec ); if( !write_exact(p_filter, p_sys->i_socket, (char*)&udr, sz_rfbFramebufferUpdateRequestMsg)) { msg_Err( p_filter, "Could not write rfbFramebufferUpdateRequestMsg." ); break; } } vlc_cleanup_run(); } else { msg_Dbg( p_filter, "VNC polling disabled." ); } msg_Dbg( p_filter, "VNC update request thread ended" ); return NULL; }
static void *joinable_thread(void *data) { vlc_thread_t th = data; void *ret; vlc_cleanup_push(finish_joinable_thread, th); thread = th; ret = th->entry(th->data); vlc_cleanup_run(); return ret; }
static void *detached_thread(void *data) { vlc_thread_t th = data; thread = th; vlc_cleanup_push(clean_detached_thread, data); th->entry(th->data); vlc_cleanup_run(); return NULL; }
void mwait (mtime_t deadline) { vlc_mutex_t lock; vlc_cond_t wait; vlc_mutex_init (&lock); vlc_cond_init (&wait); vlc_mutex_lock (&lock); mutex_cleanup_push (&lock); while (!vlc_cond_timedwait (&wait, &lock, deadline)); vlc_cleanup_run (); vlc_cond_destroy (&wait); vlc_mutex_destroy (&lock); }
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; }
/***************************************************************************** * 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; }
/***************************************************************************** * Run : call Handshake() then submit songs *****************************************************************************/ static void Run( intf_thread_t *p_intf ) { char *psz_submit, *psz_submit_song, *psz_submit_tmp; int i_net_ret; int i_song; uint8_t p_buffer[1024]; char *p_buffer_pos; int i_post_socket; int canc = vlc_savecancel(); intf_sys_t *p_sys = p_intf->p_sys; /* main loop */ for( ;; ) { bool b_wait = false; vlc_restorecancel( canc ); vlc_mutex_lock( &p_sys->lock ); mutex_cleanup_push( &p_sys->lock ); if( mdate() < p_sys->next_exchange ) /* wait until we can resubmit, i.e. */ b_wait = vlc_cond_timedwait( &p_sys->wait, &p_sys->lock, p_sys->next_exchange ) == 0; else /* wait for data to submit */ /* we are signaled each time there is a song to submit */ vlc_cond_wait( &p_sys->wait, &p_sys->lock ); vlc_cleanup_run(); canc = vlc_savecancel(); if( b_wait ) continue; /* holding on until next_exchange */ /* handshake if needed */ if( !p_sys->b_handshaked ) { msg_Dbg( p_intf, "Handshaking with last.fm ..." ); switch( Handshake( p_intf ) ) { case VLC_ENOMEM: return; 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.") ); return; case VLC_SUCCESS: msg_Dbg( p_intf, "Handshake successfull :)" ); p_sys->b_handshaked = true; p_sys->i_interval = 0; p_sys->next_exchange = mdate(); break; case VLC_AUDIOSCROBBLER_EFATAL: msg_Warn( p_intf, "Exiting..." ); return; case VLC_EGENERIC: default: /* protocol error : we'll try later */ HandleInterval( &p_sys->next_exchange, &p_sys->i_interval ); break; } /* if handshake failed let's restart the loop */ if( !p_sys->b_handshaked ) continue; } msg_Dbg( p_intf, "Going to submit some data..." ); /* The session may be invalid if there is a trailing \n */ char *psz_ln = strrchr( p_sys->psz_auth_token, '\n' ); if( psz_ln ) *psz_ln = '\0'; if( !asprintf( &psz_submit, "s=%s", p_sys->psz_auth_token ) ) { /* Out of memory */ return; } /* forge the HTTP POST request */ vlc_mutex_lock( &p_sys->lock ); audioscrobbler_song_t *p_song; for( i_song = 0 ; i_song < p_sys->i_songs ; i_song++ ) { 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 ) ) { /* Out of memory */ vlc_mutex_unlock( &p_sys->lock ); return; } psz_submit_tmp = psz_submit; if( !asprintf( &psz_submit, "%s%s", psz_submit_tmp, psz_submit_song ) ) { /* Out of memory */ free( psz_submit_tmp ); free( psz_submit_song ); vlc_mutex_unlock( &p_sys->lock ); return; } free( psz_submit_song ); free( psz_submit_tmp ); } vlc_mutex_unlock( &p_sys->lock ); i_post_socket = net_ConnectTCP( p_intf, p_sys->psz_submit_host, p_sys->i_submit_port ); if ( i_post_socket == -1 ) { /* If connection fails, we assume we must handshake again */ HandleInterval( &p_sys->next_exchange, &p_sys->i_interval ); p_sys->b_handshaked = false; free( psz_submit ); continue; } /* we transmit the data */ i_net_ret = net_Printf( p_intf, i_post_socket, NULL, POST_REQUEST, p_sys->psz_submit_file, (unsigned)strlen( psz_submit ), p_sys->psz_submit_host, VERSION, psz_submit ); free( psz_submit ); if ( i_net_ret == -1 ) { /* If connection fails, we assume we must handshake again */ HandleInterval( &p_sys->next_exchange, &p_sys->i_interval ); p_sys->b_handshaked = false; continue; } i_net_ret = net_Read( p_intf, i_post_socket, NULL, p_buffer, 1023, 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'; p_buffer_pos = strstr( ( char * ) p_buffer, "FAILED" ); if ( p_buffer_pos ) { msg_Warn( p_intf, "%s", p_buffer_pos ); HandleInterval( &p_sys->next_exchange, &p_sys->i_interval ); continue; } p_buffer_pos = strstr( ( char * ) p_buffer, "BADSESSION" ); if ( p_buffer_pos ) { msg_Err( p_intf, "Authentication failed (BADSESSION), are you connected to last.fm with another program ?" ); p_sys->b_handshaked = false; HandleInterval( &p_sys->next_exchange, &p_sys->i_interval ); continue; } p_buffer_pos = strstr( ( char * ) p_buffer, "OK" ); if ( p_buffer_pos ) { int i; for( i = 0; i < p_sys->i_songs; i++ ) DeleteSong( &p_sys->p_queue[i] ); p_sys->i_songs = 0; p_sys->i_interval = 0; p_sys->next_exchange = mdate(); msg_Dbg( p_intf, "Submission successful!" ); } else { msg_Err( p_intf, "Authentication failed, handshaking again (%s)", p_buffer ); p_sys->b_handshaked = false; HandleInterval( &p_sys->next_exchange, &p_sys->i_interval ); continue; } } vlc_restorecancel( canc ); }
static void *Thread (void *data) { stream_t *stream = data; stream_sys_t *p_sys = stream->p_sys; #ifdef HAVE_VMSPLICE const ssize_t page_mask = sysconf (_SC_PAGE_SIZE) - 1; #endif int fd = p_sys->write_fd; bool error = false; do { ssize_t len; int canc = vlc_savecancel (); #ifdef HAVE_VMSPLICE unsigned char *buf = mmap (NULL, bufsize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (unlikely(buf == MAP_FAILED)) break; vlc_cleanup_push (cleanup_mmap, buf); #else unsigned char *buf = malloc (bufsize); if (unlikely(buf == NULL)) break; vlc_cleanup_push (free, buf); #endif vlc_mutex_lock (&p_sys->lock); while (p_sys->paused) /* practically always false, but... */ vlc_cond_wait (&p_sys->wait, &p_sys->lock); len = stream_Read (stream->p_source, buf, bufsize); vlc_mutex_unlock (&p_sys->lock); vlc_restorecancel (canc); error = len <= 0; for (ssize_t i = 0, j; i < len; i += j) { #ifdef HAVE_VMSPLICE if ((len - i) <= page_mask) /* incomplete last page */ j = write (fd, buf + i, len - i); else { struct iovec iov = { buf + i, (len - i) & ~page_mask, }; j = vmsplice (fd, &iov, 1, SPLICE_F_GIFT); } if (j == -1 && errno == ENOSYS) /* vmsplice() not supported */ #endif j = write (fd, buf + i, len - i); if (j <= 0) { if (j == 0) errno = EPIPE; msg_Err (stream, "cannot write data: %s", vlc_strerror_c(errno)); error = true; break; } } vlc_cleanup_run (); /* free (buf) */ } while (!error); msg_Dbg (stream, "compressed stream at EOF"); /* Let child process know about EOF */ p_sys->write_fd = -1; close (fd); return NULL; }
/***************************************************************************** * Run : call Handshake() then submit items *****************************************************************************/ static void Run(intf_thread_t *p_intf) { msg_Dbg(p_intf, "Entering Run()"); uint8_t p_buffer[1024]; int parse_url_ret; int canc = vlc_savecancel(); char *psz_scrobbler_url; mtime_t next_exchange; /**< when can we send data */ unsigned int i_interval; /**< waiting interval (secs)*/ intf_sys_t *p_sys = p_intf->p_sys; psz_scrobbler_url = var_InheritString(p_intf, "mediascrobbler-url"); if(!psz_scrobbler_url) return; msg_Dbg(p_intf, "Scrobbler URL: %s", psz_scrobbler_url); /* main loop */ for (;;) { vlc_restorecancel(canc); vlc_mutex_lock(&p_sys->lock); mutex_cleanup_push(&p_sys->lock); msg_Dbg(p_intf, "Next exchange %lld (current: %lld)", next_exchange, mdate()); do { vlc_cond_wait(&p_sys->wait, &p_sys->lock); } while (mdate() < next_exchange); vlc_cleanup_run(); canc = vlc_savecancel(); msg_Dbg(p_intf, "Going to submit some data..."); char *psz_submit; if (asprintf(&psz_submit, "s=%s", psz_scrobbler_url) == -1) return; msg_Dbg(p_intf, "Going to parse URL (%s)", psz_scrobbler_url); parse_url_ret = ParseURL(psz_scrobbler_url, &p_sys->psz_submit_host, &p_sys->psz_submit_file, &p_sys->i_submit_port); if(parse_url_ret != VLC_SUCCESS) { msg_Err(p_intf, "Couldn't process URL, can't continue"); return; } msg_Dbg(p_intf, "Submit Host: %s", p_sys->psz_submit_host); msg_Dbg(p_intf, "Preparing to submit %d items", p_sys->i_items); /* forge the HTTP POST request */ vlc_mutex_lock(&p_sys->lock); mediascrobbler_item_t *p_item; for (int i_item = 0 ; i_item < p_sys->i_items ; i_item++) { char *psz_submit_item, *psz_submit_tmp; p_item = &p_sys->p_queue[i_item]; if (asprintf(&psz_submit_item, "&n%%5B%d%%5D=%s" "&u%%5B%d%%5D=%s" "&d%%5B%d%%5D=%ju" "&l%%5B%d%%5D=%d", i_item, p_item->psz_n, i_item, p_item->psz_u, i_item, p_item->date, i_item, p_item->i_l ) == -1) { /* Out of memory */ vlc_mutex_unlock(&p_sys->lock); return; } psz_submit_tmp = psz_submit; if (asprintf(&psz_submit, "%s%s", psz_submit_tmp, psz_submit_item) == -1) { /* Out of memory */ free(psz_submit_tmp); free(psz_submit_item); vlc_mutex_unlock(&p_sys->lock); return; } free(psz_submit_item); free(psz_submit_tmp); } vlc_mutex_unlock(&p_sys->lock); int i_post_socket = net_ConnectTCP(p_intf, p_sys->psz_submit_host, p_sys->i_submit_port); if (i_post_socket == -1) { msg_Warn(p_intf, "Couldn't talk to the API, waiting to try again. (%d)", i_interval); HandleInterval(&next_exchange, &i_interval); 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\r\n" "Accept-Encoding: identity\r\n" "Content-length: %zu\r\n" "Connection: close\r\n" "Content-type: application/x-www-form-urlencoded\r\n" "Host: %s\r\n" "User-agent: VLC media player/"VERSION"\r\n" "\r\n" "%s\r\n" "\r\n", p_sys->psz_submit_file, strlen(psz_submit), p_sys->psz_submit_host, psz_submit ); free(psz_submit); if (i_net_ret == -1) { /* If connection fails, back off the timer, and try again */ HandleInterval(&next_exchange, &i_interval); 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, "BADAPIKEY")) { msg_Err(p_intf, "Authentication failed (BADAPIKEY), are you sure your API key is valid?"); HandleInterval(&next_exchange, &i_interval); continue; } if (strstr((char *) p_buffer, "OK")) { for (int i = 0; i < p_sys->i_items; i++) DeleteItem(&p_sys->p_queue[i]); p_sys->i_items = 0; i_interval = 0; next_exchange = mdate(); msg_Dbg(p_intf, "Submission successful!"); } else { msg_Err(p_intf, "Authentication failed, trying again (%s)", p_buffer); HandleInterval(&next_exchange, &i_interval); } } vlc_restorecancel(canc); }
static void DoFingerprint( vlc_object_t *p_this, fingerprinter_sys_t *p_sys, acoustid_fingerprint_t *fp ) { p_sys->p_input = NULL; p_sys->p_item = NULL; p_sys->chroma_fingerprint.psz_fingerprint = NULL; vlc_cleanup_push( cancelDoFingerprint, p_sys ); p_sys->p_item = input_item_New( NULL, NULL ); if ( ! p_sys->p_item ) goto end; char *psz_sout_option; /* Note: need at -max- 2 channels, but we can't guess it before playing */ /* the stereo upmix could make the mono tracks fingerprint to differ :/ */ if ( asprintf( &psz_sout_option, "sout=#transcode{acodec=%s,channels=2}:chromaprint", ( VLC_CODEC_S16L == VLC_CODEC_S16N ) ? "s16l" : "s16b" ) == -1 ) goto end; input_item_AddOption( p_sys->p_item, psz_sout_option, VLC_INPUT_OPTION_TRUSTED ); free( psz_sout_option ); input_item_AddOption( p_sys->p_item, "vout=dummy", VLC_INPUT_OPTION_TRUSTED ); input_item_AddOption( p_sys->p_item, "aout=dummy", VLC_INPUT_OPTION_TRUSTED ); if ( fp->i_duration ) { if ( asprintf( &psz_sout_option, "stop-time=%u", fp->i_duration ) == -1 ) goto end; input_item_AddOption( p_sys->p_item, psz_sout_option, VLC_INPUT_OPTION_TRUSTED ); free( psz_sout_option ); } input_item_SetURI( p_sys->p_item, p_sys->psz_uri ) ; p_sys->p_input = input_Create( p_this, p_sys->p_item, "fingerprinter", NULL ); if ( p_sys->p_input ) { p_sys->chroma_fingerprint.i_duration = fp->i_duration; var_Create( p_sys->p_input, "fingerprint-data", VLC_VAR_ADDRESS ); var_SetAddress( p_sys->p_input, "fingerprint-data", & p_sys->chroma_fingerprint ); input_Start( p_sys->p_input ); /* Wait for input to start && end */ p_sys->condwait.i_input_state = var_GetInteger( p_sys->p_input, "state" ); if ( likely( var_AddCallback( p_sys->p_input, "intf-event", inputStateCallback, p_sys ) == VLC_SUCCESS ) ) { while( p_sys->condwait.i_input_state <= PAUSE_S ) { vlc_mutex_lock( &p_sys->condwait.lock ); mutex_cleanup_push( &p_sys->condwait.lock ); vlc_cond_wait( &p_sys->condwait.wait, &p_sys->condwait.lock ); vlc_cleanup_run(); } var_DelCallback( p_sys->p_input, "intf-event", inputStateCallback, p_sys ); } input_Stop( p_sys->p_input, true ); input_Close( p_sys->p_input ); p_sys->p_input = NULL; if ( p_sys->chroma_fingerprint.psz_fingerprint ) { fp->psz_fingerprint = strdup( p_sys->chroma_fingerprint.psz_fingerprint ); if ( ! fp->i_duration ) /* had not given hint */ fp->i_duration = p_sys->chroma_fingerprint.i_duration; } } end: vlc_cleanup_run( ); }
/***************************************************************************** * 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 ); } }
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; }
/***************************************************************************** * OSSThread: asynchronous thread used to DMA the data to the device *****************************************************************************/ static void* OSSThread( void *obj ) { audio_output_t * p_aout = (audio_output_t*)obj; struct aout_sys_t * p_sys = p_aout->sys; mtime_t next_date = 0; for( ;; ) { aout_buffer_t * p_buffer = NULL; int canc = vlc_savecancel (); if ( p_aout->format.i_format != VLC_CODEC_SPDIFL ) { mtime_t buffered = BufferDuration( p_aout ); /* Next buffer will be played at mdate() + buffered */ p_buffer = aout_PacketNext( p_aout, mdate() + buffered ); if( p_buffer == NULL && buffered > ( p_aout->sys->max_buffer_duration / p_aout->sys->i_fragstotal ) ) { vlc_restorecancel (canc); /* If we have at least a fragment full, then we can wait a * little and retry to get a new audio buffer instead of * playing a blank sample */ msleep( ( p_aout->sys->max_buffer_duration / p_aout->sys->i_fragstotal / 2 ) ); continue; } } else { vlc_restorecancel (canc); /* emu10k1 driver does not report Buffer Duration correctly in * passthrough mode so we have to cheat */ if( !next_date ) { next_date = mdate(); } else { mtime_t delay = next_date - mdate(); if( delay > AOUT_MAX_PTS_ADVANCE ) { msleep( delay / 2 ); } } for( ;; ) { canc = vlc_savecancel (); p_buffer = aout_PacketNext( p_aout, next_date ); if ( p_buffer ) break; vlc_restorecancel (canc); msleep( VLC_HARD_MIN_SLEEP ); next_date = mdate(); } } uint8_t * p_bytes; int i_size; if ( p_buffer != NULL ) { p_bytes = p_buffer->p_buffer; i_size = p_buffer->i_buffer; /* This is theoretical ... we'll see next iteration whether * we're drifting */ next_date += p_buffer->i_length; } else { i_size = FRAME_SIZE / p_aout->format.i_frame_length * p_aout->format.i_bytes_per_frame; p_bytes = malloc( i_size ); memset( p_bytes, 0, i_size ); next_date = 0; } oss_thread_ctx_t ctx = { .p_buffer = p_buffer, .p_bytes = p_bytes, }; vlc_cleanup_push( OSSThreadCleanup, &ctx ); vlc_restorecancel( canc ); int i_tmp = write( p_sys->i_fd, p_bytes, i_size ); if( i_tmp < 0 ) { msg_Err( p_aout, "write failed (%m)" ); } vlc_cleanup_run(); } return NULL; }