Esempio n. 1
0
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
    }
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
File: dv.c Progetto: 0xheart0/vlc
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: %s", vlc_strerror_c(errno) );
        }

        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_pop();
    vlc_assert_unreachable();
}
Esempio n. 4
0
/** Background thread for Wayland shell events handling */
static void *Thread(void *data)
{
    vout_window_t *wnd = data;
    struct wl_display *display = wnd->display.wl;
    struct pollfd ufd[1];

    int canc = vlc_savecancel();
    vlc_cleanup_push(cleanup_wl_display_read, display);

    ufd[0].fd = wl_display_get_fd(display);
    ufd[0].events = POLLIN;

    for (;;)
    {
        while (wl_display_prepare_read(display) != 0)
            wl_display_dispatch_pending(display);

        wl_display_flush(display);
        vlc_restorecancel(canc);

        while (poll(ufd, 1, -1) < 0);

        canc = vlc_savecancel();
        wl_display_read_events(display);
        wl_display_dispatch_pending(display);
    }
    vlc_assert_unreachable();
    vlc_cleanup_pop();
    //vlc_restorecancel(canc);
    //return NULL;
}
Esempio n. 5
0
int vlc_mwait_i11e(mtime_t deadline)
{
    vlc_interrupt_t *ctx = vlc_threadvar_get(vlc_interrupt_var);
    if (ctx == NULL)
        return mwait(deadline), 0;

    vlc_cond_t wait;
    vlc_cond_init(&wait);

    int ret = vlc_interrupt_prepare(ctx, vlc_mwait_i11e_wake, &wait);
    if (ret)
    {
        vlc_cond_destroy(&wait);
        vlc_testcancel();
        return ret;
    }

    vlc_mutex_lock(&ctx->lock);
    vlc_cleanup_push(vlc_mwait_i11e_cleanup, ctx);
    while (!ctx->interrupted
        && vlc_cond_timedwait(&wait, &ctx->lock, deadline) == 0);
    vlc_cleanup_pop();
    vlc_mutex_unlock(&ctx->lock);

    ret = vlc_interrupt_finish(ctx);
    vlc_cond_destroy(&wait);
    return ret;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
/**
 * Sends one HTTP/2 frame through TLS.
 *
 * This function sends a whole HTTP/2 frame through a TLS session, then
 * releases the memory used by the frame.
 *
 * The caller must "own" the write side of the TLS session.
 *
 * @note This is a blocking function and may be a thread cancellation point.
 *
 * @return 0 on success, -1 if the connection failed
 */
static int vlc_h2_frame_send(struct vlc_tls *tls, struct vlc_h2_frame *f)
{
    size_t len = vlc_h2_frame_size(f);
    ssize_t val;

    vlc_cleanup_push(free, f);
    val = vlc_https_send(tls, f->data, len);
    vlc_cleanup_pop();
    free(f);

    return ((size_t)val == len) ? 0 : -1;
}
Esempio n. 8
0
vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd,
                                        const char *host, const char *service,
                                        const char *const *alpn, char **alp)
{
    vlc_tls_t *session;
    int canc, val;

    canc = vlc_savecancel();
    session = vlc_tls_SessionCreate (crd, fd, host, alpn);
    if (session == NULL)
    {
        vlc_restorecancel(canc);
        return NULL;
    }

    mtime_t deadline = mdate ();
    deadline += var_InheritInteger (crd, "ipv4-timeout") * 1000;

    struct pollfd ufd[1];
    ufd[0].fd = fd;

    vlc_cleanup_push (cleanup_tls, session);
    while ((val = crd->handshake(crd, session, host, service, alp)) != 0)
    {
        if (val < 0)
        {
            msg_Err(crd, "TLS session handshake error");
error:
            vlc_tls_SessionDelete (session);
            session = NULL;
            break;
        }

        mtime_t now = mdate ();
        if (now > deadline)
           now = deadline;

        assert (val <= 2);
        ufd[0] .events = (val == 1) ? POLLIN : POLLOUT;

        vlc_restorecancel(canc);
        val = poll (ufd, 1, (deadline - now) / 1000);
        canc = vlc_savecancel();
        if (val == 0)
        {
            msg_Err(crd, "TLS session handshake timeout");
            goto error;
        }
    }
    vlc_cleanup_pop();
    vlc_restorecancel(canc);
    return session;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
static void *detached_thread(void *data)
{
    vlc_thread_t th = data;

    thread = th;

    vlc_cleanup_push(clean_detached_thread, th);
    th->entry(th->data);
    vlc_cleanup_pop();
    clean_detached_thread(th);
    return NULL;
}
Esempio n. 11
0
int vlc_sem_wait_i11e(vlc_sem_t *sem)
{
    vlc_interrupt_t *ctx = vlc_interrupt_get();
    if (ctx == NULL)
        return vlc_sem_wait(sem), 0;

    vlc_interrupt_prepare(ctx, vlc_interrupt_sem, sem);

    vlc_cleanup_push(vlc_interrupt_cleanup, ctx);
    vlc_sem_wait(sem);
    vlc_cleanup_pop();

    return vlc_interrupt_finish(ctx);
}
Esempio n. 12
0
/*****************************************************************************
 * ALSAThread: asynchronous thread used to DMA the data to the device
 *****************************************************************************/
static void* ALSAThread( void *data )
{
    aout_instance_t * p_aout = data;
    struct aout_sys_t * p_sys = p_aout->output.p_sys;

    /* Wait for the exact time to start playing (avoids resampling) */
    vlc_sem_wait( &p_sys->wait );
    mwait( p_sys->start_date - AOUT_PTS_TOLERANCE / 4 );

    vlc_cleanup_push( pcm_drop, p_sys->p_snd_pcm );
    for(;;)
        ALSAFill( p_aout );

    assert(0);
    vlc_cleanup_pop();
}
Esempio n. 13
0
int vlc_sem_wait_i11e(vlc_sem_t *sem)
{
    vlc_interrupt_t *ctx = vlc_threadvar_get(vlc_interrupt_var);
    if (ctx == NULL)
        return vlc_sem_wait(sem), 0;

    int ret = vlc_interrupt_prepare(ctx, vlc_interrupt_sem, sem);
    if (ret)
    {
        vlc_testcancel();
        return ret;
    }

    vlc_cleanup_push(vlc_interrupt_cleanup, ctx);
    vlc_sem_wait(sem);
    vlc_cleanup_pop();

    return vlc_interrupt_finish(ctx);
}
Esempio n. 14
0
static void *Thread(void *data)
{
    demux_t *demux = data;
    demux_sys_t *sys = demux->p_sys;
    struct wl_display *display = sys->display;
    struct pollfd ufd[1];
    unsigned interval = lroundf(CLOCK_FREQ / (sys->rate * 1000.f));

    int canc = vlc_savecancel();
    vlc_cleanup_push(cleanup_wl_display_read, display);

    ufd[0].fd = wl_display_get_fd(display);
    ufd[0].events = POLLIN;

    for (;;)
    {
        if (DisplayError(demux, display))
            break;

        if (sys->es != NULL)
        {
            block_t *block = Shoot(demux);

            block->i_pts = block->i_dts = vlc_tick_now();
            es_out_SetPCR(demux->out, block->i_pts);
            es_out_Send(demux->out, sys->es, block);
        }

        while (wl_display_prepare_read(display) != 0)
            wl_display_dispatch_pending(display);
        wl_display_flush(display);
        vlc_restorecancel(canc);

        while (poll(ufd, 1, interval) < 0);

        canc = vlc_savecancel();
        wl_display_read_events(display);
        wl_display_dispatch_pending(display);
    }
    vlc_cleanup_pop();
    vlc_restorecancel(canc);
    return NULL;
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
File: oss.c Progetto: CSRedRat/vlc
/*****************************************************************************
 * 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;
}
Esempio n. 17
0
static void* vnc_worker_thread( void *obj )
{
    filter_t* p_filter = (filter_t*)obj;
    filter_sys_t *p_sys = p_filter->p_sys;
    vlc_thread_t update_thread;
    int canc = vlc_savecancel ();

    msg_Dbg( p_filter, "VNC worker thread started" );

    int fd = vnc_connect( p_filter );
    if( fd == -1 )
    {
        msg_Err( p_filter, "Error occurred while handshaking VNC host" );
        return NULL;
    }

    /* Create an empty picture for VNC the data */
    picture_t *pic =  picture_New( VLC_CODEC_YUVA, p_sys->i_vnc_width,
                                   p_sys->i_vnc_height, 1, 1 );
    if( likely(pic != NULL) )
    {
        vlc_mutex_lock( &p_sys->lock );
        p_sys->i_socket = fd;
        p_sys->p_pic = pic;
        vlc_mutex_unlock( &p_sys->lock );
    }
    else
    {
        net_Close( fd );
        return NULL;
    }

    write_update_request( p_filter, false );

    /* create the update request thread */
    bool polling = var_InheritBool( p_filter, RMTOSD_CFG "vnc-polling" );
    if( polling
     && vlc_clone( &update_thread, update_request_thread,
                   p_filter, VLC_THREAD_PRIORITY_LOW ) )
    {
        msg_Err( p_filter, "cannot spawn VNC update request thread" );
        polling = false;
    }

    vlc_cleanup_push( polling ? update_thread_cleanup : dummy_cleanup,
                      &update_thread );

    /* connection is initialized, now read and handle server messages */
    for( ;; )
    {
        rfbServerToClientMsg msg;
        int i_msgSize;

        memset( &msg, 0, sizeof(msg) );
        vlc_restorecancel (canc);

        if( !read_exact(p_filter, fd, &msg, 1 ) )
        {
            msg_Err( p_filter, "Error while waiting for next server message");
            break;
        }
        switch (msg.type)
        {
        case rfbFramebufferUpdate:
            i_msgSize = sz_rfbFramebufferUpdateMsg;
            break;
        case rfbSetColourMapEntries:
            i_msgSize = sz_rfbSetColourMapEntriesMsg;
            break;
        case rfbBell:
            i_msgSize = sz_rfbBellMsg;
            break;
        case rfbServerCutText:
            i_msgSize = sz_rfbServerCutTextMsg;
            break;
        case rfbReSizeFrameBuffer:
            i_msgSize = sz_rfbReSizeFrameBufferMsg;
            break;
        default:
            i_msgSize = 0;
            msg_Err( p_filter, "Invalid message %u received", msg.type );
            break;
        }

        if( i_msgSize <= 0 )
            break;

        if( --i_msgSize > 0 )
        {
            if ( !read_exact( p_filter, fd, ((char *)&msg) + 1, i_msgSize ) )
            {
                msg_Err( p_filter, "Error while reading message of type %u",
                         msg.type );
                break;
            }
        }

        canc = vlc_savecancel ();
        process_server_message( p_filter, &msg);
    }

    vlc_cleanup_pop();
    if( polling )
        update_thread_cleanup( &update_thread );

    msg_Dbg( p_filter, "VNC message reader thread ended" );
    vlc_restorecancel (canc);
    return NULL;
}
Esempio n. 18
0
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;
}
Esempio n. 19
0
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;
}
Esempio n. 20
0
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( );
}