Ejemplo n.º 1
0
/**
 * Add a SAP announce
 */
int SAP_Add (sap_handler_t *p_sap, session_descriptor_t *p_session)
{
    int i;
    char psz_addr[NI_MAXNUMERICHOST];
    sap_session_t *p_sap_session;
    mtime_t i_hash;
    union
    {
        struct sockaddr     a;
        struct sockaddr_in  in;
        struct sockaddr_in6 in6;
    } addr;
    socklen_t addrlen;

    addrlen = p_session->addrlen;
    if ((addrlen == 0) || (addrlen > sizeof (addr)))
    {
        msg_Err( p_sap, "No/invalid address specified for SAP announce" );
        return VLC_EGENERIC;
    }

    /* Determine SAP multicast address automatically */
    memcpy (&addr, &p_session->addr, addrlen);

    switch (addr.a.sa_family)
    {
#if defined (HAVE_INET_PTON) || defined (WIN32)
        case AF_INET6:
        {
            /* See RFC3513 for list of valid IPv6 scopes */
            struct in6_addr *a6 = &addr.in6.sin6_addr;

            memcpy( a6->s6_addr + 2, "\x00\x00\x00\x00\x00\x00"
                   "\x00\x00\x00\x00\x00\x02\x7f\xfe", 14 );
            if( IN6_IS_ADDR_MULTICAST( a6 ) )
                /* force flags to zero, preserve scope */
                a6->s6_addr[1] &= 0xf;
            else
                /* Unicast IPv6 - assume global scope */
                memcpy( a6->s6_addr, "\xff\x0e", 2 );
            break;
        }
#endif

        case AF_INET:
        {
            /* See RFC2365 for IPv4 scopes */
            uint32_t ipv4 = addr.in.sin_addr.s_addr;

            /* 224.0.0.0/24 => 224.0.0.255 */
            if ((ipv4 & htonl (0xffffff00)) == htonl (0xe0000000))
                ipv4 =  htonl (0xe00000ff);
            else
            /* 239.255.0.0/16 => 239.255.255.255 */
            if ((ipv4 & htonl (0xffff0000)) == htonl (0xefff0000))
                ipv4 =  htonl (0xefffffff);
            else
            /* 239.192.0.0/14 => 239.195.255.255 */
            if ((ipv4 & htonl (0xfffc0000)) == htonl (0xefc00000))
                ipv4 =  htonl (0xefc3ffff);
            else
            if ((ipv4 & htonl (0xff000000)) == htonl (0xef000000))
                ipv4 = 0;
            else
            /* other addresses => 224.2.127.254 */
                ipv4 = htonl (0xe0027ffe);

            if( ipv4 == 0 )
            {
                msg_Err( p_sap, "Out-of-scope multicast address "
                         "not supported by SAP" );
                return VLC_EGENERIC;
            }

            addr.in.sin_addr.s_addr = ipv4;
            break;
        }

        default:
            msg_Err( p_sap, "Address family %d not supported by SAP",
                     addr.a.sa_family );
            return VLC_EGENERIC;
    }

    i = vlc_getnameinfo( &addr.a, addrlen,
                         psz_addr, sizeof( psz_addr ), NULL, NI_NUMERICHOST );

    if( i )
    {
        msg_Err( p_sap, "%s", gai_strerror( i ) );
        return VLC_EGENERIC;
    }

    /* Find/create SAP address thread */
    msg_Dbg( p_sap, "using SAP address: %s", psz_addr);

    vlc_mutex_lock (&p_sap->lock);
    sap_address_t *sap_addr;
    for (sap_addr = p_sap->first; sap_addr; sap_addr = sap_addr->next)
        if (!strcmp (psz_addr, sap_addr->group))
            break;

    if (sap_addr == NULL)
    {
        sap_addr = AddressCreate (VLC_OBJECT(p_sap), psz_addr);
        if (sap_addr == NULL)
        {
            vlc_mutex_unlock (&p_sap->lock);
            return VLC_EGENERIC;
        }
        sap_addr->next = p_sap->first;
        p_sap->first = sap_addr;
    }
    /* Switch locks.
     * NEVER take the global SAP lock when holding a SAP thread lock! */
    vlc_mutex_lock (&sap_addr->lock);
    vlc_mutex_unlock (&p_sap->lock);

    memcpy (&p_session->orig, &sap_addr->orig, sap_addr->origlen);
    p_session->origlen = sap_addr->origlen;

    size_t headsize = 20, length;
    switch (p_session->orig.ss_family)
    {
#ifdef AF_INET6
        case AF_INET6:
            headsize += 16;
            break;
#endif
        case AF_INET:
            headsize += 4;
            break;
        default:
            assert (0);
    }

    /* XXX: Check for dupes */
    length = headsize + strlen (p_session->psz_sdp);
    p_sap_session = malloc (sizeof (*p_sap_session) + length + 1);
    if (p_sap_session == NULL)
    {
        vlc_mutex_unlock (&sap_addr->lock);
        return VLC_EGENERIC; /* NOTE: we should destroy the thread if left unused */
    }
    p_sap_session->next = sap_addr->first;
    sap_addr->first = p_sap_session;
    p_sap_session->p_sd = p_session;
    p_sap_session->length = length;

    /* Build the SAP Headers */
    uint8_t *psz_head = p_sap_session->data;

    /* SAPv1, not encrypted, not compressed */
    psz_head[0] = 0x20;
    psz_head[1] = 0x00; /* No authentication length */

    i_hash = mdate();
    psz_head[2] = i_hash >> 8; /* Msg id hash */
    psz_head[3] = i_hash;      /* Msg id hash 2 */

    headsize = 4;
    switch (p_session->orig.ss_family)
    {
#ifdef AF_INET6
        case AF_INET6:
        {
            struct in6_addr *a6 =
                &((struct sockaddr_in6 *)&p_session->orig)->sin6_addr;
            memcpy (psz_head + headsize, a6, 16);
            psz_head[0] |= 0x10; /* IPv6 flag */
            headsize += 16;
            break;
        }
#endif
        case AF_INET:
        {
            uint32_t ipv4 =
                (((struct sockaddr_in *)&p_session->orig)->sin_addr.s_addr);
            memcpy (psz_head + headsize, &ipv4, 4);
            headsize += 4;
            break;
        }

    }

    memcpy (psz_head + headsize, "application/sdp", 16);
    headsize += 16;

    /* Build the final message */
    strcpy( (char *)psz_head + headsize, p_session->psz_sdp);

    sap_addr->session_count++;
    vlc_cond_signal (&sap_addr->wait);
    vlc_mutex_unlock (&sap_addr->lock);
    return VLC_SUCCESS;
}
Ejemplo n.º 2
0
static void DecSysHold( decoder_sys_t *p_sys )
{
    vlc_mutex_lock( &p_sys->lock );
    p_sys->i_refcount++;
    vlc_mutex_unlock( &p_sys->lock );
}
Ejemplo n.º 3
0
void CommonManage( vout_thread_t *p_vout )
{
    /* If we do not control our window, we check for geometry changes
     * ourselves because the parent might not send us its events. */
    vlc_mutex_lock( &p_vout->p_sys->lock );
    if( p_vout->p_sys->hparent && !p_vout->b_fullscreen )
    {
        RECT rect_parent;
        POINT point;

        vlc_mutex_unlock( &p_vout->p_sys->lock );

        GetClientRect( p_vout->p_sys->hparent, &rect_parent );
        point.x = point.y = 0;
        ClientToScreen( p_vout->p_sys->hparent, &point );
        OffsetRect( &rect_parent, point.x, point.y );

        if( !EqualRect( &rect_parent, &p_vout->p_sys->rect_parent ) )
        {
            p_vout->p_sys->rect_parent = rect_parent;

            /* FIXME I find such #ifdef quite weirds. Are they really needed ? */

#if defined(MODULE_NAME_IS_direct3d)
            SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,
                          rect_parent.right - rect_parent.left,
                          rect_parent.bottom - rect_parent.top,
                          SWP_NOZORDER );
            UpdateRects( p_vout, true );
#else
            /* This one is to force the update even if only
             * the position has changed */
            SetWindowPos( p_vout->p_sys->hwnd, 0, 1, 1,
                          rect_parent.right - rect_parent.left,
                          rect_parent.bottom - rect_parent.top, 0 );

            SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,
                          rect_parent.right - rect_parent.left,
                          rect_parent.bottom - rect_parent.top, 0 );

#if defined(MODULE_NAME_IS_wingdi) || defined(MODULE_NAME_IS_wingapi)
            unsigned int i_x, i_y, i_width, i_height;
            vout_PlacePicture( p_vout, rect_parent.right - rect_parent.left,
                               rect_parent.bottom - rect_parent.top,
                               &i_x, &i_y, &i_width, &i_height );

            SetWindowPos( p_vout->p_sys->hvideownd, HWND_TOP,
                          i_x, i_y, i_width, i_height, 0 );
#endif
#endif
        }
    }
    else
    {
        vlc_mutex_unlock( &p_vout->p_sys->lock );
    }

    /* autoscale toggle */
    if( p_vout->i_changes & VOUT_SCALE_CHANGE )
    {
        p_vout->i_changes &= ~VOUT_SCALE_CHANGE;

        p_vout->b_autoscale = var_GetBool( p_vout, "autoscale" );
        p_vout->i_zoom = (int) ZOOM_FP_FACTOR;

        UpdateRects( p_vout, true );
    }

    /* scaling factor */
    if( p_vout->i_changes & VOUT_ZOOM_CHANGE )
    {
        p_vout->i_changes &= ~VOUT_ZOOM_CHANGE;

        p_vout->b_autoscale = false;
        p_vout->i_zoom =
            (int)( ZOOM_FP_FACTOR * var_GetFloat( p_vout, "scale" ) );
        UpdateRects( p_vout, true );
    }

    /* Check for cropping / aspect changes */
    if( p_vout->i_changes & VOUT_CROP_CHANGE ||
        p_vout->i_changes & VOUT_ASPECT_CHANGE )
    {
        p_vout->i_changes &= ~VOUT_CROP_CHANGE;
        p_vout->i_changes &= ~VOUT_ASPECT_CHANGE;

        p_vout->fmt_out.i_x_offset = p_vout->fmt_in.i_x_offset;
        p_vout->fmt_out.i_y_offset = p_vout->fmt_in.i_y_offset;
        p_vout->fmt_out.i_visible_width = p_vout->fmt_in.i_visible_width;
        p_vout->fmt_out.i_visible_height = p_vout->fmt_in.i_visible_height;
        p_vout->fmt_out.i_aspect = p_vout->fmt_in.i_aspect;
        p_vout->fmt_out.i_sar_num = p_vout->fmt_in.i_sar_num;
        p_vout->fmt_out.i_sar_den = p_vout->fmt_in.i_sar_den;
        p_vout->output.i_aspect = p_vout->fmt_in.i_aspect;
        UpdateRects( p_vout, true );
    }

    /* We used to call the Win32 PeekMessage function here to read the window
     * messages. But since window can stay blocked into this function for a
     * long time (for example when you move your window on the screen), I
     * decided to isolate PeekMessage in another thread. */

    /*
     * Fullscreen change
     */
    if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE
        || p_vout->p_sys->i_changes & VOUT_FULLSCREEN_CHANGE )
    {
        Win32ToggleFullscreen( p_vout );

        p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
        p_vout->p_sys->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
    }

    /*
     * Pointer change
     */
    EventThreadMouseAutoHide( p_vout->p_sys->p_event );

    /*
     * "Always on top" status change
     */
    if( p_vout->p_sys->b_on_top_change )
    {
        HMENU hMenu = GetSystemMenu( p_vout->p_sys->hwnd, FALSE );
        bool b = var_GetBool( p_vout, "video-on-top" );

        /* Set the window on top if necessary */
        if( b && !( GetWindowLong( p_vout->p_sys->hwnd, GWL_EXSTYLE )
                           & WS_EX_TOPMOST ) )
        {
            CheckMenuItem( hMenu, IDM_TOGGLE_ON_TOP,
                           MF_BYCOMMAND | MFS_CHECKED );
            SetWindowPos( p_vout->p_sys->hwnd, HWND_TOPMOST, 0, 0, 0, 0,
                          SWP_NOSIZE | SWP_NOMOVE );
        }
        else
        /* The window shouldn't be on top */
        if( !b && ( GetWindowLong( p_vout->p_sys->hwnd, GWL_EXSTYLE )
                           & WS_EX_TOPMOST ) )
        {
            CheckMenuItem( hMenu, IDM_TOGGLE_ON_TOP,
                           MF_BYCOMMAND | MFS_UNCHECKED );
            SetWindowPos( p_vout->p_sys->hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
                          SWP_NOSIZE | SWP_NOMOVE );
        }

        p_vout->p_sys->b_on_top_change = false;
    }
}
Ejemplo n.º 4
0
static picture_t *decode(decoder_t *dec, block_t **pblock)
{
    decoder_sys_t *sys = dec->p_sys;
    block_t *block;
    MMAL_BUFFER_HEADER_T *buffer;
    bool need_flush = false;
    uint32_t len;
    uint32_t flags = 0;
    MMAL_STATUS_T status;
    picture_t *ret = NULL;

    /*
     * Configure output port if necessary
     */
    if (sys->output_format) {
        if (change_output_format(dec) < 0)
            msg_Err(dec, "Failed to change output port format");
    }

    if (!pblock)
        goto out;

    block = *pblock;

    /*
     * Check whether full flush is required
     */
    if (block && block->i_flags & BLOCK_FLAG_DISCONTINUITY) {
        flush_decoder(dec);
        block_Release(*pblock);
        return NULL;
    }

    /*
     * Send output buffers
     */
    if (atomic_load(&sys->started)) {
        buffer = mmal_queue_get(sys->decoded_pictures);
        if (buffer) {
            ret = (picture_t *)buffer->user_data;
            ret->date = buffer->pts;
            ret->b_progressive = sys->b_progressive;
            ret->b_top_field_first = sys->b_top_field_first;

            if (sys->output_pool) {
                buffer->data = NULL;
                mmal_buffer_header_reset(buffer);
                mmal_buffer_header_release(buffer);
            }
        }

        fill_output_port(dec);
    }

    if (ret)
        goto out;

    /*
     * Process input
     */
    if (!block)
        goto out;

    *pblock = NULL;

    if (block->i_flags & BLOCK_FLAG_CORRUPTED)
        flags |= MMAL_BUFFER_HEADER_FLAG_CORRUPTED;

    vlc_mutex_lock(&sys->mutex);
    while (block->i_buffer > 0) {
        buffer = mmal_queue_timedwait(sys->input_pool->queue, 2);
        if (!buffer) {
            msg_Err(dec, "Failed to retrieve buffer header for input data");
            need_flush = true;
            break;
        }
        mmal_buffer_header_reset(buffer);
        buffer->cmd = 0;
        buffer->pts = block->i_pts != 0 ? block->i_pts : block->i_dts;
        buffer->dts = block->i_dts;
        buffer->alloc_size = sys->input->buffer_size;

        len = block->i_buffer;
        if (len > buffer->alloc_size)
            len = buffer->alloc_size;

        buffer->data = block->p_buffer;
        block->p_buffer += len;
        block->i_buffer -= len;
        buffer->length = len;
        if (block->i_buffer == 0)
            buffer->user_data = block;
        buffer->flags = flags;

        status = mmal_port_send_buffer(sys->input, buffer);
        if (status != MMAL_SUCCESS) {
            msg_Err(dec, "Failed to send buffer to input port (status=%"PRIx32" %s)",
                    status, mmal_status_to_string(status));
            break;
        }
        atomic_fetch_add(&sys->input_in_transit, 1);
    }
    vlc_mutex_unlock(&sys->mutex);

out:
    if (need_flush)
        flush_decoder(dec);

    return ret;
}
Ejemplo n.º 5
0
/**************************************************************************
 *       libvlc_media_list_retain (Public)
 *
 * Increase an object refcount.
 **************************************************************************/
void libvlc_media_list_retain( libvlc_media_list_t * p_mlist )
{
    vlc_mutex_lock( &p_mlist->refcount_lock );
    p_mlist->i_refcount++;
    vlc_mutex_unlock( &p_mlist->refcount_lock );
}
Ejemplo n.º 6
0
Archivo: xosd.c Proyecto: CSRedRat/vlc
/*****************************************************************************
 * 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_Get( p_intf );
        PL_LOCK;

        // If the playlist is empty don't do anything
        if( playlist_IsEmpty( p_playlist ) )
        {
            PL_UNLOCK;
            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;
                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;

        /* Display */
        xosd_display( p_intf->p_sys->p_osd, 0, /* first line */
                      XOSD_string, psz_display );
    }
}
Ejemplo n.º 7
0
Archivo: logo.c Proyecto: CSRedRat/vlc
/**
 * Video filter
 */
static picture_t *FilterVideo( filter_t *p_filter, picture_t *p_src )
{
    filter_sys_t *p_sys = p_filter->p_sys;
    logo_list_t *p_list = &p_sys->list;

    picture_t *p_dst = filter_NewPicture( p_filter );
    if( !p_dst )
        goto exit;

    picture_Copy( p_dst, p_src );

    /* */
    vlc_mutex_lock( &p_sys->lock );

    logo_t *p_logo;
    if( p_list->i_next_pic < p_src->date )
        p_logo = LogoListNext( p_list, p_src->date );
    else
        p_logo = LogoListCurrent( p_list );

    /* */
    const picture_t *p_pic = p_logo->p_pic;
    if( p_pic )
    {
        const video_format_t *p_fmt = &p_pic->format;
        const int i_dst_w = p_filter->fmt_out.video.i_visible_width;
        const int i_dst_h = p_filter->fmt_out.video.i_visible_height;

        if( p_sys->i_pos )
        {
            if( p_sys->i_pos & SUBPICTURE_ALIGN_BOTTOM )
            {
                p_sys->i_pos_y = i_dst_h - p_fmt->i_visible_height;
            }
            else if ( !(p_sys->i_pos & SUBPICTURE_ALIGN_TOP) )
            {
                p_sys->i_pos_y = ( i_dst_h - p_fmt->i_visible_height ) / 2;
            }
            else
            {
                p_sys->i_pos_y = 0;
            }

            if( p_sys->i_pos & SUBPICTURE_ALIGN_RIGHT )
            {
                p_sys->i_pos_x = i_dst_w - p_fmt->i_visible_width;
            }
            else if ( !(p_sys->i_pos & SUBPICTURE_ALIGN_LEFT) )
            {
                p_sys->i_pos_x = ( i_dst_w - p_fmt->i_visible_width ) / 2;
            }
            else
            {
                p_sys->i_pos_x = 0;
            }
        }

        /* */
        const int i_alpha = p_logo->i_alpha != -1 ? p_logo->i_alpha : p_list->i_alpha;
        if( filter_ConfigureBlend( p_sys->p_blend, i_dst_w, i_dst_h, p_fmt ) ||
            filter_Blend( p_sys->p_blend, p_dst, p_sys->i_pos_x, p_sys->i_pos_y,
                          p_pic, i_alpha ) )
        {
            msg_Err( p_filter, "failed to blend a picture" );
        }
    }
    vlc_mutex_unlock( &p_sys->lock );

exit:
    picture_Release( p_src );
    return p_dst;
}
Ejemplo n.º 8
0
/*****************************************************************************
 * Manage: manage main thread messages
 *****************************************************************************
 * In this function, called approx. 10 times a second, we check what the
 * main program wanted to tell us.
 *****************************************************************************/
static int Manage( intf_thread_t *p_intf )
{
    GtkListStore *p_liststore;
    vlc_mutex_lock( &p_intf->change_lock );

    /* Update the input */
    if( p_intf->p_sys->p_input == NULL )
    {
        p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
                                                          FIND_ANYWHERE );
    }
    else if( p_intf->p_sys->p_input->b_dead )
    {
        vlc_object_release( p_intf->p_sys->p_input );
        p_intf->p_sys->p_input = NULL;
    }

    if( p_intf->p_sys->p_input )
    {
        input_thread_t *p_input = p_intf->p_sys->p_input;
        int64_t i_time = 0, i_length = 0;

        vlc_mutex_lock( &p_input->object_lock );
        if( !p_input->b_die )
        {
            playlist_t *p_playlist;

            E_(GtkModeManage)( p_intf );
            p_intf->p_sys->b_playing = 1;

            /* update playlist interface */
            p_playlist = (playlist_t *) vlc_object_find(
                    p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
            if (p_playlist != NULL)
            {
                p_liststore = gtk_list_store_new (3,
                                            G_TYPE_STRING,
                                            G_TYPE_STRING,
                                            G_TYPE_UINT);  /* Hidden index */
                PlaylistRebuildListStore(p_liststore, p_playlist);
                gtk_tree_view_set_model(p_intf->p_sys->p_tvplaylist, (GtkTreeModel*) p_liststore);
                g_object_unref(p_liststore);
                vlc_object_release( p_playlist );
            }

            /* Manage the slider */
            i_time = var_GetTime( p_intf->p_sys->p_input, "time" );
            i_length = var_GetTime( p_intf->p_sys->p_input, "length" );

            if (p_intf->p_libvlc->i_cpu & CPU_CAPABILITY_FPU)
            {
                /* Manage the slider for CPU_CAPABILITY_FPU hardware */
                if( p_intf->p_sys->b_playing )
                {
                    float newvalue = p_intf->p_sys->p_adj->value;

                    /* If the user hasn't touched the slider since the last time,
                     * then the input can safely change it */
                    if( newvalue == p_intf->p_sys->f_adj_oldvalue )
                    {
                        /* Update the value */
                        p_intf->p_sys->p_adj->value =
                        p_intf->p_sys->f_adj_oldvalue =
                            ( 100 * i_time ) / i_length;
                        g_signal_emit_by_name( GTK_OBJECT( p_intf->p_sys->p_adj ),
                                                 "value_changed" );
                    }
                    /* Otherwise, send message to the input if the user has
                     * finished dragging the slider */
                    else if( p_intf->p_sys->b_slider_free )
                    {
                        double f_pos = (double)newvalue / 100.0;

                        /* release the lock to be able to seek */
                        vlc_mutex_unlock( &p_input->object_lock );
                        var_SetFloat( p_input, "position", f_pos );
                        vlc_mutex_lock( &p_input->object_lock );

                        /* Update the old value */
                        p_intf->p_sys->f_adj_oldvalue = newvalue;
                    }
                }
            }
            else
            {
                /* Manage the slider without CPU_CAPABILITY_FPU hardware */
                if( p_intf->p_sys->b_playing )
                {
                    off_t newvalue = p_intf->p_sys->p_adj->value;

                    /* If the user hasn't touched the slider since the last time,
                     * then the input can safely change it */
                    if( newvalue == p_intf->p_sys->i_adj_oldvalue )
                    {
                        /* Update the value */
                        p_intf->p_sys->p_adj->value =
                        p_intf->p_sys->i_adj_oldvalue =
                            ( 100 * i_time ) / i_length;
                        g_signal_emit_by_name( GTK_OBJECT( p_intf->p_sys->p_adj ),
                                                 "value_changed" );
                    }
                    /* Otherwise, send message to the input if the user has
                     * finished dragging the slider */
                    else if( p_intf->p_sys->b_slider_free )
                    {
                        double f_pos = (double)newvalue / 100.0;

                        /* release the lock to be able to seek */
                        vlc_mutex_unlock( &p_input->object_lock );
                        var_SetFloat( p_input, "position", f_pos );
                        vlc_mutex_lock( &p_input->object_lock );

                        /* Update the old value */
                        p_intf->p_sys->i_adj_oldvalue = newvalue;
                    }
                }
            }
        }
        vlc_mutex_unlock( &p_input->object_lock );
    }
    else if( p_intf->p_sys->b_playing && !p_intf->b_die )
    {
        E_(GtkModeManage)( p_intf );
        p_intf->p_sys->b_playing = 0;
    }

#ifndef NEED_GTK2_MAIN
    if( p_intf->b_die )
    {
        vlc_mutex_unlock( &p_intf->change_lock );

        /* Prepare to die, young Skywalker */
        gtk_main_quit();

        return FALSE;
    }
#endif

    vlc_mutex_unlock( &p_intf->change_lock );

    return TRUE;
}
Ejemplo n.º 9
0
Archivo: mosaic.c Proyecto: Kafay/vlc
/*****************************************************************************
 * CreateFiler: allocate mosaic video filter
 *****************************************************************************/
static int CreateFilter( vlc_object_t *p_this )
{
    filter_t *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys;
    vlc_object_t *p_libvlc = VLC_OBJECT( p_filter->p_libvlc );
    char *psz_order, *_psz_order;
    char *psz_offsets;
    int i_index;
    vlc_value_t val;
    int i_command;

    /* The mosaic thread is more important than the decoder threads */
    vlc_thread_set_priority( p_this, VLC_THREAD_PRIORITY_OUTPUT );

    /* Allocate structure */
    p_sys = p_filter->p_sys = malloc( sizeof( filter_sys_t ) );
    if( p_sys == NULL )
        return VLC_ENOMEM;

    p_filter->pf_sub_filter = Filter;

    vlc_mutex_init( &p_sys->lock );
    vlc_mutex_lock( &p_sys->lock );

    var_Create( p_libvlc, "mosaic-lock", VLC_VAR_MUTEX );
    var_Get( p_libvlc, "mosaic-lock", &val );
    p_sys->p_lock = val.p_address;

    config_ChainParse( p_filter, CFG_PREFIX, ppsz_filter_options,
                       p_filter->p_cfg );

#define GET_VAR( name, min, max )                                           \
    i_command = var_CreateGetIntegerCommand( p_filter, CFG_PREFIX #name );  \
    p_sys->i_##name = __MIN( max, __MAX( min, i_command ) );                \
    var_AddCallback( p_filter, CFG_PREFIX #name, MosaicCallback, p_sys );

    GET_VAR( width, 0, INT_MAX );
    GET_VAR( height, 0, INT_MAX );
    GET_VAR( xoffset, 0, INT_MAX );
    GET_VAR( yoffset, 0, INT_MAX );

    GET_VAR( align, 0, 10 );
    if( p_sys->i_align == 3 || p_sys->i_align == 7 )
        p_sys->i_align = 5; /* FIXME: NOT THREAD SAFE w.r.t. callback */

    GET_VAR( borderw, 0, INT_MAX );
    GET_VAR( borderh, 0, INT_MAX );
    GET_VAR( rows, 1, INT_MAX );
    GET_VAR( cols, 1, INT_MAX );
    GET_VAR( alpha, 0, 255 );
    GET_VAR( position, 0, 2 );
    GET_VAR( delay, 100, INT_MAX );
#undef GET_VAR
    p_sys->i_delay *= 1000; /* FIXME: NOT THREAD SAFE w.r.t. callback */

    p_sys->b_ar = var_CreateGetBoolCommand( p_filter,
                                            CFG_PREFIX "keep-aspect-ratio" );
    var_AddCallback( p_filter, CFG_PREFIX "keep-aspect-ratio", MosaicCallback,
                     p_sys );

    p_sys->b_keep = var_CreateGetBoolCommand( p_filter,
                                              CFG_PREFIX "keep-picture" );
    if ( !p_sys->b_keep )
    {
        p_sys->p_image = image_HandlerCreate( p_filter );
    }

    p_sys->i_order_length = 0;
    p_sys->ppsz_order = NULL;
    psz_order = var_CreateGetStringCommand( p_filter, CFG_PREFIX "order" );
    _psz_order = psz_order;
    var_AddCallback( p_filter, CFG_PREFIX "order", MosaicCallback, p_sys );

    if( *psz_order )
    {
        char *psz_end = NULL;
        i_index = 0;
        do
        {
            psz_end = strchr( psz_order, ',' );
            i_index++;
            p_sys->ppsz_order = realloc( p_sys->ppsz_order,
                                         i_index * sizeof(char *) );
            p_sys->ppsz_order[i_index - 1] = strndup( psz_order,
                                           psz_end - psz_order );
            psz_order = psz_end+1;
        } while( psz_end );
        p_sys->i_order_length = i_index;
    }

    free( _psz_order );

    /* Manage specific offsets for substreams */
    psz_offsets = var_CreateGetStringCommand( p_filter, CFG_PREFIX "offsets" );
    p_sys->i_offsets_length = 0;
    p_sys->pi_x_offsets = NULL;
    p_sys->pi_y_offsets = NULL;
    mosaic_ParseSetOffsets( p_filter, p_sys, psz_offsets );
    free( psz_offsets );
    var_AddCallback( p_filter, CFG_PREFIX "offsets", MosaicCallback, p_sys );

    vlc_mutex_unlock( &p_sys->lock );

    return VLC_SUCCESS;
}
Ejemplo n.º 10
0
void input_item_SetURI( input_item_t *p_i, const char *psz_uri )
{
    assert( psz_uri );
#ifndef NDEBUG
    if( !strstr( psz_uri, "://" )
     || strchr( psz_uri, ' ' ) || strchr( psz_uri, '"' ) )
        fprintf( stderr, "Warning: %s(\"%s\"): file path instead of URL.\n",
                 __func__, psz_uri );
#endif
    vlc_mutex_lock( &p_i->lock );
    free( p_i->psz_uri );
    p_i->psz_uri = strdup( psz_uri );

    p_i->i_type = GuessType( p_i );

    if( p_i->psz_name )
        ;
    else
    if( p_i->i_type == ITEM_TYPE_FILE || p_i->i_type == ITEM_TYPE_DIRECTORY )
    {
        const char *psz_filename = strrchr( p_i->psz_uri, '/' );

        if( psz_filename && *psz_filename == '/' )
            psz_filename++;
        if( psz_filename && *psz_filename )
            p_i->psz_name = strdup( psz_filename );

        /* Make the name more readable */
        if( p_i->psz_name )
        {
            decode_URI( p_i->psz_name );
            EnsureUTF8( p_i->psz_name );
        }
    }
    else
    {   /* Strip login and password from title */
        int r;
        vlc_url_t url;

        vlc_UrlParse( &url, psz_uri, 0 );
        if( url.psz_protocol )
        {
            if( url.i_port > 0 )
                r=asprintf( &p_i->psz_name, "%s://%s:%d%s", url.psz_protocol,
                          url.psz_host, url.i_port,
                          url.psz_path ? url.psz_path : "" );
            else
                r=asprintf( &p_i->psz_name, "%s://%s%s", url.psz_protocol,
                          url.psz_host ? url.psz_host : "",
                          url.psz_path ? url.psz_path : "" );
        }
        else
        {
            if( url.i_port > 0 )
                r=asprintf( &p_i->psz_name, "%s:%d%s", url.psz_host, url.i_port,
                          url.psz_path ? url.psz_path : "" );
            else
                r=asprintf( &p_i->psz_name, "%s%s", url.psz_host,
                          url.psz_path ? url.psz_path : "" );
        }
        vlc_UrlClean( &url );
        if( -1==r )
            p_i->psz_name=NULL; /* recover from undefined value */
    }

    vlc_mutex_unlock( &p_i->lock );
}
Ejemplo n.º 11
0
void input_item_SetEpg( input_item_t *p_item, const vlc_epg_t *p_update )
{
    vlc_mutex_lock( &p_item->lock );

    /* */
    vlc_epg_t *p_epg = NULL;
    for( int i = 0; i < p_item->i_epg; i++ )
    {
        vlc_epg_t *p_tmp = p_item->pp_epg[i];

        if( (p_tmp->psz_name == NULL) != (p_update->psz_name == NULL) )
            continue;
        if( p_tmp->psz_name && p_update->psz_name && strcmp(p_tmp->psz_name, p_update->psz_name) )
            continue;

        p_epg = p_tmp;
        break;
    }

    /* */
    if( !p_epg )
    {
        p_epg = vlc_epg_New( p_update->psz_name );
        if( p_epg )
            TAB_APPEND( p_item->i_epg, p_item->pp_epg, p_epg );
    }
    if( p_epg )
        vlc_epg_Merge( p_epg, p_update );

    vlc_mutex_unlock( &p_item->lock );

    if( !p_epg )
        return;

#ifdef EPG_DEBUG
    char *psz_epg;
    if( asprintf( &psz_epg, "EPG %s", p_epg->psz_name ? p_epg->psz_name : "unknown" ) < 0 )
        goto signal;

    input_item_DelInfo( p_item, psz_epg, NULL );

    vlc_mutex_lock( &p_item->lock );
    for( int i = 0; i < p_epg->i_event; i++ )
    {
        const vlc_epg_event_t *p_evt = p_epg->pp_event[i];
        time_t t_start = (time_t)p_evt->i_start;
        struct tm tm_start;
        char psz_start[128];

        localtime_r( &t_start, &tm_start );

        snprintf( psz_start, sizeof(psz_start), "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d",
                  1900 + tm_start.tm_year, 1 + tm_start.tm_mon, tm_start.tm_mday,
                  tm_start.tm_hour, tm_start.tm_min, tm_start.tm_sec );
        if( p_evt->psz_short_description || p_evt->psz_description )
            InputItemAddInfo( p_item, psz_epg, psz_start, "%s (%2.2d:%2.2d) - %s %s",
                              p_evt->psz_name,
                              p_evt->i_duration/60/60, (p_evt->i_duration/60)%60,
                              p_evt->psz_short_description ? p_evt->psz_short_description : "" ,
                              p_evt->psz_description ? p_evt->psz_description : "" );
        else
            InputItemAddInfo( p_item, psz_epg, psz_start, "%s (%2.2d:%2.2d)",
                              p_evt->psz_name,
                              p_evt->i_duration/60/60, (p_evt->i_duration/60)%60 );
    }
    vlc_mutex_unlock( &p_item->lock );
    free( psz_epg );
signal:
#endif

    if( p_epg->i_event > 0 )
    {
        vlc_event_t event = { .type = vlc_InputItemInfoChanged, };
        vlc_event_send( &p_item->event_manager, &event );
    }
Ejemplo n.º 12
0
/*****************************************************************************
 * PORTAUDIOThread: all interactions with libportaudio.a are handled
 * in this single thread.  Otherwise libportaudio.a is _not_ happy :-(
 *****************************************************************************/
static void* PORTAUDIOThread( vlc_object_t *p_this )
{
    pa_thread_t *pa_thread = (pa_thread_t*)p_this;
    aout_instance_t *p_aout;
    aout_sys_t *p_sys;
    int i_err;
    int canc = vlc_savecancel ();

    while( vlc_object_alive (pa_thread) )
    {
        /* Wait for start of stream */
        vlc_mutex_lock( &pa_thread->lock_signal );
        if( !pa_thread->b_signal )
            vlc_cond_wait( &pa_thread->signal, &pa_thread->lock_signal );
        vlc_mutex_unlock( &pa_thread->lock_signal );
        pa_thread->b_signal = false;

        p_aout = pa_thread->p_aout;
        p_sys = p_aout->output.p_sys;

        if( PAOpenDevice( p_aout ) != VLC_SUCCESS )
        {
            msg_Err( p_aout, "cannot open portaudio device" );
            pa_thread->b_error = true;
        }

        if( !pa_thread->b_error && PAOpenStream( p_aout ) != VLC_SUCCESS )
        {
            msg_Err( p_aout, "cannot open portaudio device" );
            pa_thread->b_error = true;

            i_err = Pa_Terminate();
            if( i_err != paNoError )
            {
                msg_Err( p_aout, "Pa_Terminate: %d (%s)", i_err,
                         Pa_GetErrorText( i_err ) );
            }
        }

        /* Tell the main thread that we are ready */
        vlc_mutex_lock( &pa_thread->lock_wait );
        pa_thread->b_wait = true;
        vlc_cond_signal( &pa_thread->wait );
        vlc_mutex_unlock( &pa_thread->lock_wait );

        /* Wait for end of stream */
        vlc_mutex_lock( &pa_thread->lock_signal );
        if( !pa_thread->b_signal )
            vlc_cond_wait( &pa_thread->signal, &pa_thread->lock_signal );
        vlc_mutex_unlock( &pa_thread->lock_signal );
        pa_thread->b_signal = false;

        if( pa_thread->b_error ) continue;

        i_err = Pa_StopStream( p_sys->p_stream );
        if( i_err != paNoError )
        {
            msg_Err( p_aout, "Pa_StopStream: %d (%s)", i_err,
                     Pa_GetErrorText( i_err ) );
        }
        i_err = Pa_CloseStream( p_sys->p_stream );
        if( i_err != paNoError )
        {
            msg_Err( p_aout, "Pa_CloseStream: %d (%s)", i_err,
                     Pa_GetErrorText( i_err ) );
        }
        i_err = Pa_Terminate();
        if( i_err != paNoError )
        {
            msg_Err( p_aout, "Pa_Terminate: %d (%s)", i_err,
                     Pa_GetErrorText( i_err ) );
        }

        /* Tell the main thread that we are ready */
        vlc_mutex_lock( &pa_thread->lock_wait );
        pa_thread->b_wait = true;
        vlc_cond_signal( &pa_thread->wait );
        vlc_mutex_unlock( &pa_thread->lock_wait );
    }
    vlc_restorecancel (canc);
    return NULL;
}
Ejemplo n.º 13
0
/*****************************************************************************
 * Open: open the audio device
 *****************************************************************************/
static int Open( vlc_object_t * p_this )
{
    aout_instance_t *p_aout = (aout_instance_t *)p_this;
    struct aout_sys_t * p_sys;
    int i_err;

    msg_Dbg( p_aout, "entering Open()");

    /* Allocate p_sys structure */
    p_sys = malloc( sizeof(aout_sys_t) );
    if( p_sys == NULL )
        return VLC_ENOMEM;
    p_sys->p_aout = p_aout;
    p_sys->p_stream = 0;
    p_aout->output.p_sys = p_sys;
    p_aout->output.pf_play = Play;

    /* Retrieve output device id from config */
    p_sys->i_device_id = var_CreateGetInteger( p_aout, "portaudio-audio-device" );

#ifdef PORTAUDIO_IS_SERIOUSLY_BROKEN
    if( !b_init )
    {
        /* Test device */
        if( PAOpenDevice( p_aout ) != VLC_SUCCESS )
        {
            msg_Err( p_aout, "cannot open portaudio device" );
            free( p_sys );
            return VLC_EGENERIC;
        }

        /* Close device for now. We'll re-open it later on */
        if( ( i_err = Pa_Terminate() ) != paNoError )
        {
            msg_Err( p_aout, "closing the device returned %d", i_err );
        }

        b_init = true;

        /* Now we need to setup our DirectSound play notification structure */
        pa_thread = vlc_object_create( p_aout, sizeof(pa_thread_t) );
        pa_thread->p_aout = p_aout;
        pa_thread->b_error = false;
        vlc_mutex_init( &pa_thread->lock_wait );
        vlc_cond_init( &pa_thread->wait );
        pa_thread->b_wait = false;
        vlc_mutex_init( &pa_thread->lock_signal );
        vlc_cond_init( &pa_thread->signal );
        pa_thread->b_signal = false;

        /* Create PORTAUDIOThread */
        if( vlc_thread_create( pa_thread, "aout", PORTAUDIOThread,
                               VLC_THREAD_PRIORITY_OUTPUT ) )
        {
            msg_Err( p_aout, "cannot create PORTAUDIO thread" );
            return VLC_EGENERIC;
        }
    }
    else
    {
        pa_thread->p_aout = p_aout;
        pa_thread->b_wait = false;
        pa_thread->b_signal = false;
        pa_thread->b_error = false;
    }

    /* Signal start of stream */
    vlc_mutex_lock( &pa_thread->lock_signal );
    pa_thread->b_signal = true;
    vlc_cond_signal( &pa_thread->signal );
    vlc_mutex_unlock( &pa_thread->lock_signal );

    /* Wait until thread is ready */
    vlc_mutex_lock( &pa_thread->lock_wait );
    if( !pa_thread->b_wait )
        vlc_cond_wait( &pa_thread->wait, &pa_thread->lock_wait );
    vlc_mutex_unlock( &pa_thread->lock_wait );
    pa_thread->b_wait = false;

    if( pa_thread->b_error )
    {
        msg_Err( p_aout, "PORTAUDIO thread failed" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;

#else

    if( PAOpenDevice( p_aout ) != VLC_SUCCESS )
    {
        msg_Err( p_aout, "cannot open portaudio device" );
        free( p_sys );
        return VLC_EGENERIC;
    }

    if( PAOpenStream( p_aout ) != VLC_SUCCESS )
    {
        msg_Err( p_aout, "cannot open portaudio device" );
    }

    return VLC_SUCCESS;

#endif
}
Ejemplo n.º 14
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( );
}
Ejemplo n.º 15
0
Archivo: dbus.c Proyecto: etix/vlc
/* Flls a callback_info_t data structure in response
 * to an "intf-event" input event.
 *
 * @warning This function executes in the input thread.
 *
 * @return VLC_SUCCESS on success, VLC_E* on error.
 */
static int InputCallback( vlc_object_t *p_this, const char *psz_var,
                          vlc_value_t oldval, vlc_value_t newval, void *data )
{
    input_thread_t *p_input = (input_thread_t *)p_this;
    intf_thread_t *p_intf = data;
    intf_sys_t *p_sys = p_intf->p_sys;

    dbus_int32_t i_state = PLAYBACK_STATE_INVALID;

    callback_info_t *p_info = calloc( 1, sizeof( callback_info_t ) );
    if( unlikely(p_info == NULL) )
        return VLC_ENOMEM;

    switch( newval.i_int )
    {
        case INPUT_EVENT_DEAD:
            i_state = PLAYBACK_STATE_STOPPED;
            break;
        case INPUT_EVENT_STATE:
            switch( var_GetInteger( p_input, "state" ) )
            {
                case OPENING_S:
                case PLAYING_S:
                    i_state = PLAYBACK_STATE_PLAYING;
                    break;
                case PAUSE_S:
                    i_state = PLAYBACK_STATE_PAUSED;
                    break;
                default:
                    i_state = PLAYBACK_STATE_STOPPED;
            }
            break;
        case INPUT_EVENT_ITEM_META:
            p_info->signal = SIGNAL_INPUT_METADATA;
            break;
        case INPUT_EVENT_RATE:
            p_info->signal = SIGNAL_RATE;
            break;
        case INPUT_EVENT_POSITION:
        {
            mtime_t i_now = mdate(), i_pos, i_projected_pos, i_interval;
            float f_current_rate;

            /* Detect seeks
             * XXX: This is way more convoluted than it should be... */
            i_pos = var_GetInteger( p_input, "time" );

            if( !p_intf->p_sys->i_last_input_pos_event ||
                !( var_GetInteger( p_input, "state" ) == PLAYING_S ) )
            {
                p_intf->p_sys->i_last_input_pos_event = i_now;
                p_intf->p_sys->i_last_input_pos = i_pos;
                break;
            }

            f_current_rate = var_GetFloat( p_input, "rate" );
            i_interval = ( i_now - p_intf->p_sys->i_last_input_pos_event );

            i_projected_pos = p_intf->p_sys->i_last_input_pos +
                ( i_interval * f_current_rate );

            p_intf->p_sys->i_last_input_pos_event = i_now;
            p_intf->p_sys->i_last_input_pos = i_pos;

            if( llabs( i_pos - i_projected_pos ) < SEEK_THRESHOLD )
                break;

            p_info->signal = SIGNAL_SEEK;
            break;
        }
        default:
            free( p_info );
            return VLC_SUCCESS; /* don't care */
    }

    vlc_mutex_lock( &p_sys->lock );
    if( i_state != PLAYBACK_STATE_INVALID &&
        i_state != p_sys->i_playing_state )
    {
        p_sys->i_playing_state = i_state;
        p_info->signal = SIGNAL_STATE;
    }
    if( p_info->signal )
        vlc_array_append( p_intf->p_sys->p_events, p_info );
    else
        free( p_info );
    vlc_mutex_unlock( &p_intf->p_sys->lock );

    wakeup_main_loop( p_intf );

    (void)psz_var;
    (void)oldval;
    return VLC_SUCCESS;
}
Ejemplo n.º 16
0
Archivo: mosaic.c Proyecto: Kafay/vlc
/*****************************************************************************
 * Filter
 *****************************************************************************/
static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
{
    filter_sys_t *p_sys = p_filter->p_sys;
    bridge_t *p_bridge;

    subpicture_t *p_spu;

    int i_index, i_real_index, i_row, i_col;
    int i_greatest_real_index_used = p_sys->i_order_length - 1;

    unsigned int col_inner_width, row_inner_height;

    subpicture_region_t *p_region;
    subpicture_region_t *p_region_prev = NULL;

    /* Allocate the subpicture internal data. */
    p_spu = filter_NewSubpicture( p_filter );
    if( !p_spu )
        return NULL;

    /* Initialize subpicture */
    p_spu->i_channel = 0;
    p_spu->i_start  = date;
    p_spu->i_stop = 0;
    p_spu->b_ephemer = true;
    p_spu->i_alpha = p_sys->i_alpha;
    p_spu->b_absolute = false;

    vlc_mutex_lock( &p_sys->lock );
    vlc_mutex_lock( p_sys->p_lock );

    p_bridge = GetBridge( p_filter );
    if ( p_bridge == NULL )
    {
        vlc_mutex_unlock( p_sys->p_lock );
        vlc_mutex_unlock( &p_sys->lock );
        return p_spu;
    }

    if ( p_sys->i_position == position_offsets )
    {
        /* If we have either too much or not enough offsets, fall-back
         * to automatic positioning. */
        if ( p_sys->i_offsets_length != p_sys->i_order_length )
        {
            msg_Err( p_filter,
                     "Number of specified offsets (%d) does not match number "
                     "of input substreams in mosaic-order (%d), falling back "
                     "to mosaic-position=0",
                     p_sys->i_offsets_length, p_sys->i_order_length );
            p_sys->i_position = position_auto;
        }
    }

    if ( p_sys->i_position == position_auto )
    {
        int i_numpics = p_sys->i_order_length; /* keep slots and all */
        for ( i_index = 0; i_index < p_bridge->i_es_num; i_index++ )
        {
            bridged_es_t *p_es = p_bridge->pp_es[i_index];
            if ( !p_es->b_empty )
            {
                i_numpics ++;
                if( p_sys->i_order_length && p_es->psz_id != NULL )
                {
                    /* We also want to leave slots for images given in
                     * mosaic-order that are not available in p_vout_picture */
                    int i;
                    for( i = 0; i < p_sys->i_order_length ; i++ )
                    {
                        if( !strcmp( p_sys->ppsz_order[i], p_es->psz_id ) )
                        {
                            i_numpics--;
                            break;
                        }
                    }

                }
            }
        }
        p_sys->i_rows = ceil(sqrt( (double)i_numpics ));
        p_sys->i_cols = ( i_numpics % p_sys->i_rows == 0 ?
                            i_numpics / p_sys->i_rows :
                            i_numpics / p_sys->i_rows + 1 );
    }

    col_inner_width  = ( ( p_sys->i_width - ( p_sys->i_cols - 1 )
                       * p_sys->i_borderw ) / p_sys->i_cols );
    row_inner_height = ( ( p_sys->i_height - ( p_sys->i_rows - 1 )
                       * p_sys->i_borderh ) / p_sys->i_rows );

    i_real_index = 0;

    for ( i_index = 0; i_index < p_bridge->i_es_num; i_index++ )
    {
        bridged_es_t *p_es = p_bridge->pp_es[i_index];
        video_format_t fmt_in, fmt_out;
        picture_t *p_converted;

        memset( &fmt_in, 0, sizeof( video_format_t ) );
        memset( &fmt_out, 0, sizeof( video_format_t ) );

        if ( p_es->b_empty )
            continue;

        while ( p_es->p_picture != NULL
                 && p_es->p_picture->date + p_sys->i_delay < date )
        {
            if ( p_es->p_picture->p_next != NULL )
            {
                picture_t *p_next = p_es->p_picture->p_next;
                picture_Release( p_es->p_picture );
                p_es->p_picture = p_next;
            }
            else if ( p_es->p_picture->date + p_sys->i_delay + BLANK_DELAY <
                        date )
            {
                /* Display blank */
                picture_Release( p_es->p_picture );
                p_es->p_picture = NULL;
                p_es->pp_last = &p_es->p_picture;
                break;
            }
            else
            {
                msg_Dbg( p_filter, "too late picture for %s (%"PRId64 ")",
                         p_es->psz_id,
                         date - p_es->p_picture->date - p_sys->i_delay );
                break;
            }
        }

        if ( p_es->p_picture == NULL )
            continue;

        if ( p_sys->i_order_length == 0 )
        {
            i_real_index++;
        }
        else
        {
            int i;
            for ( i = 0; i <= p_sys->i_order_length; i++ )
            {
                if ( i == p_sys->i_order_length ) break;
                if ( strcmp( p_es->psz_id, p_sys->ppsz_order[i] ) == 0 )
                {
                    i_real_index = i;
                    break;
                }
            }
            if ( i == p_sys->i_order_length )
                i_real_index = ++i_greatest_real_index_used;
        }
        i_row = ( i_real_index / p_sys->i_cols ) % p_sys->i_rows;
        i_col = i_real_index % p_sys->i_cols ;

        if ( !p_sys->b_keep )
        {
            /* Convert the images */
            fmt_in.i_chroma = p_es->p_picture->format.i_chroma;
            fmt_in.i_height = p_es->p_picture->format.i_height;
            fmt_in.i_width = p_es->p_picture->format.i_width;

            if( fmt_in.i_chroma == VLC_CODEC_YUVA ||
                fmt_in.i_chroma == VLC_CODEC_RGBA )
                fmt_out.i_chroma = VLC_CODEC_YUVA;
            else
                fmt_out.i_chroma = VLC_CODEC_I420;
            fmt_out.i_width = col_inner_width;
            fmt_out.i_height = row_inner_height;

            if( p_sys->b_ar ) /* keep aspect ratio */
            {
                if( (float)fmt_out.i_width / (float)fmt_out.i_height
                      > (float)fmt_in.i_width / (float)fmt_in.i_height )
                {
                    fmt_out.i_width = ( fmt_out.i_height * fmt_in.i_width )
                                         / fmt_in.i_height;
                }
                else
                {
                    fmt_out.i_height = ( fmt_out.i_width * fmt_in.i_height )
                                        / fmt_in.i_width;
                }
             }

            fmt_out.i_visible_width = fmt_out.i_width;
            fmt_out.i_visible_height = fmt_out.i_height;

            p_converted = image_Convert( p_sys->p_image, p_es->p_picture,
                                         &fmt_in, &fmt_out );
            if( !p_converted )
            {
                msg_Warn( p_filter,
                           "image resizing and chroma conversion failed" );
                continue;
            }
        }
        else
        {
            p_converted = p_es->p_picture;
            fmt_in.i_width = fmt_out.i_width = p_converted->format.i_width;
            fmt_in.i_height = fmt_out.i_height = p_converted->format.i_height;
            fmt_in.i_chroma = fmt_out.i_chroma = p_converted->format.i_chroma;
            fmt_out.i_visible_width = fmt_out.i_width;
            fmt_out.i_visible_height = fmt_out.i_height;
        }

        p_region = subpicture_region_New( &fmt_out );
        /* FIXME the copy is probably not needed anymore */
        if( p_region )
            picture_Copy( p_region->p_picture, p_converted );
        if( !p_sys->b_keep )
            picture_Release( p_converted );

        if( !p_region )
        {
            msg_Err( p_filter, "cannot allocate SPU region" );
            p_filter->pf_sub_buffer_del( p_filter, p_spu );
            vlc_mutex_unlock( &p_sys->lock );
            vlc_mutex_unlock( p_sys->p_lock );
            return p_spu;
        }

        if( p_es->i_x >= 0 && p_es->i_y >= 0 )
        {
            p_region->i_x = p_es->i_x;
            p_region->i_y = p_es->i_y;
        }
        else if( p_sys->i_position == position_offsets )
        {
            p_region->i_x = p_sys->pi_x_offsets[i_real_index];
            p_region->i_y = p_sys->pi_y_offsets[i_real_index];
        }
        else
        {
            if( fmt_out.i_width > col_inner_width ||
                p_sys->b_ar || p_sys->b_keep )
            {
                /* we don't have to center the video since it takes the
                whole rectangle area or it's larger than the rectangle */
                p_region->i_x = p_sys->i_xoffset
                            + i_col * ( p_sys->i_width / p_sys->i_cols )
                            + ( i_col * p_sys->i_borderw ) / p_sys->i_cols;
            }
            else
            {
                /* center the video in the dedicated rectangle */
                p_region->i_x = p_sys->i_xoffset
                        + i_col * ( p_sys->i_width / p_sys->i_cols )
                        + ( i_col * p_sys->i_borderw ) / p_sys->i_cols
                        + ( col_inner_width - fmt_out.i_width ) / 2;
            }

            if( fmt_out.i_height > row_inner_height
                || p_sys->b_ar || p_sys->b_keep )
            {
                /* we don't have to center the video since it takes the
                whole rectangle area or it's taller than the rectangle */
                p_region->i_y = p_sys->i_yoffset
                        + i_row * ( p_sys->i_height / p_sys->i_rows )
                        + ( i_row * p_sys->i_borderh ) / p_sys->i_rows;
            }
            else
            {
                /* center the video in the dedicated rectangle */
                p_region->i_y = p_sys->i_yoffset
                        + i_row * ( p_sys->i_height / p_sys->i_rows )
                        + ( i_row * p_sys->i_borderh ) / p_sys->i_rows
                        + ( row_inner_height - fmt_out.i_height ) / 2;
            }
        }
        p_region->i_align = p_sys->i_align;
        p_region->i_alpha = p_es->i_alpha;

        if( p_region_prev == NULL )
        {
            p_spu->p_region = p_region;
        }
        else
        {
            p_region_prev->p_next = p_region;
        }

        p_region_prev = p_region;
    }

    vlc_mutex_unlock( p_sys->p_lock );
    vlc_mutex_unlock( &p_sys->lock );

    return p_spu;
}
Ejemplo n.º 17
0
/*****************************************************************************
 * config_SaveConfigFile: Save a module's config options.
 *****************************************************************************
 * It's no use to save the config options that kept their default values, so
 * we'll try to be a bit clever here.
 *
 * When we save we mustn't delete the config options of the modules that
 * haven't been loaded. So we cannot just create a new config file with the
 * config structures we've got in memory.
 * I don't really know how to deal with this nicely, so I will use a completly
 * dumb method ;-)
 * I will load the config file in memory, but skipping all the sections of the
 * modules we want to save. Then I will create a brand new file, dump the file
 * loaded in memory and then append the sections of the modules we want to
 * save.
 * Really stupid no ?
 *****************************************************************************/
static int SaveConfigFile (vlc_object_t *p_this)
{
    module_t *p_parser;
    char *permanent = NULL, *temporary = NULL;

    if( config_PrepareDir( p_this ) )
    {
        msg_Err( p_this, "no configuration directory" );
        return -1;
    }

    /* List all available modules */
    module_t **list = module_list_get (NULL);

    char *bigbuf = NULL;
    size_t bigsize = 0;
    FILE *file = config_OpenConfigFile (p_this);
    if (file != NULL)
    {
        struct stat st;

        /* Some users make vlcrc read-only to prevent changes.
         * The atomic replacement scheme breaks this "feature",
         * so we check for read-only by hand. */
        if (fstat (fileno (file), &st)
         || !(st.st_mode & S_IWUSR))
        {
            msg_Err (p_this, "configuration file is read-only");
            goto error;
        }

        bigsize = (st.st_size < LONG_MAX) ? st.st_size : 0;
        bigbuf = malloc (bigsize + 1);
        if (bigbuf == NULL)
            goto error;

        /* backup file into memory, we only need to backup the sections we
         * won't save later on */
        char *p_index = bigbuf;
        char *line = NULL;
        size_t bufsize;
        ssize_t linelen;
        bool backup = false;

        while ((linelen = getline (&line, &bufsize, file)) != -1)
        {
            char *p_index2;

            if ((line[0] == '[') && (p_index2 = strchr(line,']')))
            {
                /* we found a new section, check if we need to do a backup */
                backup = true;
                for (int i = 0; (p_parser = list[i]) != NULL; i++)
                {
                    if (!strncmp (line + 1, p_parser->psz_object_name,
                                  strlen (p_parser->psz_object_name)))
                    {
                        backup = false; /* no, we will rewrite it! */
                        break;
                    }
                }
            }

            /* save line if requested and line is valid (doesn't begin with a
             * space, tab, or eol) */
            if (backup && !memchr ("\n\t ", line[0], 3))
            {
                memcpy (p_index, line, linelen);
                p_index += linelen;
            }
        }
        fclose (file);
        file = NULL;
        free (line);
        *p_index = '\0';
        bigsize = p_index - bigbuf;
    }

    /*
     * Save module config in file
     */
    permanent = config_GetConfigFile (p_this);
    if (!permanent)
    {
        module_list_free (list);
        goto error;
    }

    if (asprintf (&temporary, "%s.%u", permanent, getpid ()) == -1)
    {
        temporary = NULL;
        module_list_free (list);
        goto error;
    }

    /* Configuration lock must be taken before vlcrc serializer below. */
    vlc_rwlock_rdlock (&config_lock);

    /* The temporary configuration file is per-PID. Therefore SaveConfigFile()
     * should be serialized against itself within a given process. */
    static vlc_mutex_t lock = VLC_STATIC_MUTEX;
    vlc_mutex_lock (&lock);

    int fd = vlc_open (temporary, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR);
    if (fd == -1)
    {
        vlc_rwlock_unlock (&config_lock);
        vlc_mutex_unlock (&lock);
        module_list_free (list);
        goto error;
    }
    file = fdopen (fd, "wt");
    if (file == NULL)
    {
        msg_Err (p_this, "cannot create configuration file: %m");
        vlc_rwlock_unlock (&config_lock);
        close (fd);
        vlc_mutex_unlock (&lock);
        module_list_free (list);
        goto error;
    }

    fprintf( file,
        "\xEF\xBB\xBF###\n"
        "###  "PACKAGE_NAME" "PACKAGE_VERSION"\n"
        "###\n"
        "\n"
        "###\n"
        "### lines beginning with a '#' character are comments\n"
        "###\n"
        "\n" );

    /* Ensure consistent number formatting... */
    locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
    locale_t baseloc = uselocale (loc);

    /* We would take the config lock here. But this would cause a lock
     * inversion with the serializer above and config_AutoSaveConfigFile().
    vlc_rwlock_rdlock (&config_lock);*/

    /* Look for the selected module, if NULL then save everything */
    for (int i = 0; (p_parser = list[i]) != NULL; i++)
    {
        module_config_t *p_item, *p_end;

        if( !p_parser->i_config_items )
            continue;

        fprintf( file, "[%s]", p_parser->psz_object_name );
        if( p_parser->psz_longname )
            fprintf( file, " # %s\n\n", p_parser->psz_longname );
        else
            fprintf( file, "\n\n" );

        for( p_item = p_parser->p_config, p_end = p_item + p_parser->confsize;
             p_item < p_end;
             p_item++ )
        {
            if ((p_item->i_type & CONFIG_HINT) /* ignore hint */
             || p_item->b_removed              /* ignore deprecated option */
             || p_item->b_unsaveable)          /* ignore volatile option */
                continue;

            if (IsConfigIntegerType (p_item->i_type))
            {
                int64_t val = p_item->value.i;
                config_Write (file, p_item->psz_text,
                              (p_item->i_type == CONFIG_ITEM_BOOL)
                                  ? N_("boolean") : N_("integer"),
                              val == p_item->orig.i,
                              p_item->psz_name, "%"PRId64, val);
            }
            else
            if (IsConfigFloatType (p_item->i_type))
            {
                float val = p_item->value.f;
                config_Write (file, p_item->psz_text, N_("float"),
                              val == p_item->orig.f,
                              p_item->psz_name, "%f", val);
            }
            else
            {
                const char *psz_value = p_item->value.psz;
                bool modified;

                assert (IsConfigStringType (p_item->i_type));

                modified = !!strcmp (psz_value ? psz_value : "",
                                     p_item->orig.psz ? p_item->orig.psz : "");
                config_Write (file, p_item->psz_text, N_("string"),
                              !modified, p_item->psz_name, "%s",
                              psz_value ? psz_value : "");
            }
            p_item->b_dirty = false;
        }
    }
    vlc_rwlock_unlock (&config_lock);

    module_list_free (list);
    if (loc != (locale_t)0)
    {
        uselocale (baseloc);
        freelocale (loc);
    }

    /*
     * Restore old settings from the config in file
     */
    if (bigsize)
        fwrite (bigbuf, 1, bigsize, file);

    /*
     * Flush to disk and replace atomically
     */
    fflush (file); /* Flush from run-time */
    if (ferror (file))
    {
        vlc_unlink (temporary);
        vlc_mutex_unlock (&lock);
        msg_Err (p_this, "cannot write configuration file");
        clearerr (file);
        goto error;
    }
#if defined(__APPLE__) || defined(__ANDROID__)
    fsync (fd); /* Flush from OS */
#else
    fdatasync (fd); /* Flush from OS */
#endif
#if defined (WIN32) || defined (__OS2__)
    /* Windows cannot (re)move open files nor overwrite existing ones */
    fclose (file);
    vlc_unlink (permanent);
#endif
    /* Atomically replace the file... */
    if (vlc_rename (temporary, permanent))
        vlc_unlink (temporary);
    /* (...then synchronize the directory, err, TODO...) */
    /* ...and finally close the file */
    vlc_mutex_unlock (&lock);
#if !defined (WIN32) && !defined (__OS2__)
    fclose (file);
#endif

    free (temporary);
    free (permanent);
    free (bigbuf);
    return 0;

error:
    if( file )
        fclose( file );
    free (temporary);
    free (permanent);
    free (bigbuf);
    return -1;
}
Ejemplo n.º 18
0
Archivo: mosaic.c Proyecto: Kafay/vlc
/*****************************************************************************
* Callback to update params on the fly
*****************************************************************************/
static int MosaicCallback( vlc_object_t *p_this, char const *psz_var,
                            vlc_value_t oldval, vlc_value_t newval,
                            void *p_data )
{
    VLC_UNUSED(oldval);
    filter_sys_t *p_sys = (filter_sys_t *) p_data;

#define VAR_IS( a ) !strcmp( psz_var, CFG_PREFIX a )
    if( VAR_IS( "alpha" ) )
    {
        vlc_mutex_lock( &p_sys->lock );
        msg_Dbg( p_this, "changing alpha from %d/255 to %d/255",
                         p_sys->i_alpha, newval.i_int);
        p_sys->i_alpha = __MIN( __MAX( newval.i_int, 0 ), 255 );
        vlc_mutex_unlock( &p_sys->lock );
    }
    else if( VAR_IS( "height" ) )
    {
        vlc_mutex_lock( &p_sys->lock );
        msg_Dbg( p_this, "changing height from %dpx to %dpx",
                          p_sys->i_height, newval.i_int );
        p_sys->i_height = __MAX( newval.i_int, 0 );
        vlc_mutex_unlock( &p_sys->lock );
    }
    else if( VAR_IS( "width" ) )
    {
        vlc_mutex_lock( &p_sys->lock );
        msg_Dbg( p_this, "changing width from %dpx to %dpx",
                         p_sys->i_width, newval.i_int );
        p_sys->i_width = __MAX( newval.i_int, 0 );
        vlc_mutex_unlock( &p_sys->lock );
    }
    else if( VAR_IS( "xoffset" ) )
    {
        vlc_mutex_lock( &p_sys->lock );
        msg_Dbg( p_this, "changing x offset from %dpx to %dpx",
                         p_sys->i_xoffset, newval.i_int );
        p_sys->i_xoffset = __MAX( newval.i_int, 0 );
        vlc_mutex_unlock( &p_sys->lock );
    }
    else if( VAR_IS( "yoffset" ) )
    {
        vlc_mutex_lock( &p_sys->lock );
        msg_Dbg( p_this, "changing y offset from %dpx to %dpx",
                         p_sys->i_yoffset, newval.i_int );
        p_sys->i_yoffset = __MAX( newval.i_int, 0 );
        vlc_mutex_unlock( &p_sys->lock );
    }
    else if( VAR_IS( "align" ) )
    {
        int i_old = 0, i_new = 0;
        vlc_mutex_lock( &p_sys->lock );
        newval.i_int = __MIN( __MAX( newval.i_int, 0 ), 10 );
        if( newval.i_int == 3 || newval.i_int == 7 )
            newval.i_int = 5;
        while( pi_align_values[i_old] != p_sys->i_align ) i_old++;
        while( pi_align_values[i_new] != newval.i_int ) i_new++;
        msg_Dbg( p_this, "changing alignment from %d (%s) to %d (%s)",
                     p_sys->i_align, ppsz_align_descriptions[i_old],
                     newval.i_int, ppsz_align_descriptions[i_new] );
        p_sys->i_align = newval.i_int;
        vlc_mutex_unlock( &p_sys->lock );
    }
    else if( VAR_IS( "borderw" ) )
    {
        vlc_mutex_lock( &p_sys->lock );
        msg_Dbg( p_this, "changing border width from %dpx to %dpx",
                         p_sys->i_borderw, newval.i_int );
        p_sys->i_borderw = __MAX( newval.i_int, 0 );
        vlc_mutex_unlock( &p_sys->lock );
    }
    else if( VAR_IS( "borderh" ) )
    {
        vlc_mutex_lock( &p_sys->lock );
        msg_Dbg( p_this, "changing border height from %dpx to %dpx",
                         p_sys->i_borderh, newval.i_int );
        p_sys->i_borderh = __MAX( newval.i_int, 0 );
        vlc_mutex_unlock( &p_sys->lock );
    }
    else if( VAR_IS( "position" ) )
    {
        if( newval.i_int > 2 || newval.i_int < 0 )
        {
            msg_Err( p_this,
                     "Position is either 0 (%s), 1 (%s) or 2 (%s)",
                     ppsz_pos_descriptions[0],
                     ppsz_pos_descriptions[1],
                     ppsz_pos_descriptions[2] );
        }
        else
        {
            vlc_mutex_lock( &p_sys->lock );
            msg_Dbg( p_this, "changing position method from %d (%s) to %d (%s)",
                    p_sys->i_position, ppsz_pos_descriptions[p_sys->i_position],
                    newval.i_int, ppsz_pos_descriptions[newval.i_int]);
            p_sys->i_position = newval.i_int;
            vlc_mutex_unlock( &p_sys->lock );
        }
    }
    else if( VAR_IS( "rows" ) )
    {
        vlc_mutex_lock( &p_sys->lock );
        msg_Dbg( p_this, "changing number of rows from %d to %d",
                         p_sys->i_rows, newval.i_int );
        p_sys->i_rows = __MAX( newval.i_int, 1 );
        vlc_mutex_unlock( &p_sys->lock );
    }
    else if( VAR_IS( "cols" ) )
    {
        vlc_mutex_lock( &p_sys->lock );
        msg_Dbg( p_this, "changing number of columns from %d to %d",
                         p_sys->i_cols, newval.i_int );
        p_sys->i_cols = __MAX( newval.i_int, 1 );
        vlc_mutex_unlock( &p_sys->lock );
    }
    else if( VAR_IS( "order" ) )
    {
        char *psz_order;
        int i_index;
        vlc_mutex_lock( &p_sys->lock );
        msg_Dbg( p_this, "Changing mosaic order to %s", newval.psz_string );

        psz_order = newval.psz_string;

        while( p_sys->i_order_length-- )
        {
            free( p_sys->ppsz_order[p_sys->i_order_length] );
        }
        free( p_sys->ppsz_order );
        p_sys->ppsz_order = NULL;

        if( *psz_order )
        {
            char *psz_end = NULL;
            i_index = 0;
            do
            {
                psz_end = strchr( psz_order, ',' );
                i_index++;
                p_sys->ppsz_order = realloc( p_sys->ppsz_order,
                                    i_index * sizeof(char *) );
                p_sys->ppsz_order[i_index - 1] = strndup( psz_order,
                                           psz_end - psz_order );
                psz_order = psz_end+1;
            } while( psz_end );
            p_sys->i_order_length = i_index;
        }

        vlc_mutex_unlock( &p_sys->lock );
    }
    else if( VAR_IS( "offsets" ) )
    {
        vlc_mutex_lock( &p_sys->lock );
        msg_Info( p_this, "Changing mosaic-offsets to %s", newval.psz_string );

        if( p_sys->i_offsets_length != 0 )
        {
            p_sys->i_offsets_length = 0;
            free( p_sys->pi_x_offsets );
            free( p_sys->pi_y_offsets );
            p_sys->pi_x_offsets = NULL;
            p_sys->pi_y_offsets = NULL;
        }

        mosaic_ParseSetOffsets( p_this, p_sys, newval.psz_string );

        vlc_mutex_unlock( &p_sys->lock );
    }
    else if( VAR_IS( "keep-aspect-ratio" ) )
    {
        vlc_mutex_lock( &p_sys->lock );
        if( newval.i_int )
        {
            msg_Dbg( p_this, "keeping aspect ratio" );
            p_sys->b_ar = 1;
        }
        else
        {
            msg_Dbg( p_this, "won't keep aspect ratio" );
            p_sys->b_ar = 0;
        }
        vlc_mutex_unlock( &p_sys->lock );
    }
    else if( VAR_IS( "keep-picture" ) )
    {
        vlc_mutex_lock( &p_sys->lock );
        p_sys->b_keep = newval.b_bool;
        if ( !p_sys->b_keep && !p_sys->p_image )
        {
            p_sys->p_image = image_HandlerCreate( p_this );
        }
        vlc_mutex_unlock( &p_sys->lock );
    }

    return VLC_SUCCESS;
}
Ejemplo n.º 19
0
Archivo: logo.c Proyecto: CSRedRat/vlc
/**
 * Sub source
 */
static subpicture_t *FilterSub( filter_t *p_filter, mtime_t date )
{
    filter_sys_t *p_sys = p_filter->p_sys;
    logo_list_t *p_list = &p_sys->list;

    subpicture_t *p_spu;
    subpicture_region_t *p_region;
    video_format_t fmt;
    picture_t *p_pic;
    logo_t *p_logo;

    vlc_mutex_lock( &p_sys->lock );
    /* Basic test:  b_spu_update occurs on a dynamic change,
                    & i_next_pic is the general timer, when to
                    look at updating the logo image */

    if( ( !p_sys->b_spu_update && p_list->i_next_pic > date ) ||
        !p_list->i_repeat )
    {
        vlc_mutex_unlock( &p_sys->lock );
        return NULL;
    }

    /* adjust index to the next logo */
    p_logo = LogoListNext( p_list, date );
    p_sys->b_spu_update = false;

    p_pic = p_logo->p_pic;

    /* Allocate the subpicture internal data. */
    p_spu = filter_NewSubpicture( p_filter );
    if( !p_spu )
        goto exit;

    p_spu->b_absolute = p_sys->b_absolute;
    p_spu->i_start = date;
    p_spu->i_stop = 0;
    p_spu->b_ephemer = true;

    /* Send an empty subpicture to clear the display when needed */
    if( p_list->i_repeat != -1 && p_list->i_counter == 0 )
    {
        p_list->i_repeat--;
        if( p_list->i_repeat < 0 )
            goto exit;
    }
    if( !p_pic || !p_logo->i_alpha ||
        ( p_logo->i_alpha == -1 && !p_list->i_alpha ) )
        goto exit;

    /* Create new SPU region */
    memset( &fmt, 0, sizeof(video_format_t) );
    fmt.i_chroma = VLC_CODEC_YUVA;
    fmt.i_sar_num = fmt.i_sar_den = 1;
    fmt.i_width = fmt.i_visible_width = p_pic->p[Y_PLANE].i_visible_pitch;
    fmt.i_height = fmt.i_visible_height = p_pic->p[Y_PLANE].i_visible_lines;
    fmt.i_x_offset = fmt.i_y_offset = 0;
    p_region = subpicture_region_New( &fmt );
    if( !p_region )
    {
        msg_Err( p_filter, "cannot allocate SPU region" );
        p_filter->pf_sub_buffer_del( p_filter, p_spu );
        p_spu = NULL;
        goto exit;
    }

    /* */
    picture_Copy( p_region->p_picture, p_pic );

    /*  where to locate the logo: */
    if( p_sys->i_pos < 0 )
    {   /*  set to an absolute xy */
        p_region->i_align = SUBPICTURE_ALIGN_RIGHT | SUBPICTURE_ALIGN_TOP;
        p_spu->b_absolute = true;
    }
    else
    {   /* set to one of the 9 relative locations */
        p_region->i_align = p_sys->i_pos;
        p_spu->b_absolute = false;
    }

    p_region->i_x = p_sys->i_pos_x;
    p_region->i_y = p_sys->i_pos_y;

    p_spu->p_region = p_region;

    p_spu->i_alpha = ( p_logo->i_alpha != -1 ?
                       p_logo->i_alpha : p_list->i_alpha );

exit:
    vlc_mutex_unlock( &p_sys->lock );

    return p_spu;
}
Ejemplo n.º 20
0
/*****************************************************************************
 * RunIntf: main loop
 *****************************************************************************/
static void RunIntf( intf_thread_t *p_intf )
{
    p_intf->p_sys->p_vout = NULL;

    if( InitThread( p_intf ) < 0 )
    {
        msg_Err( p_intf, "cannot initialize intf" );
        return;
    }

    /* Main loop */
    while( !p_intf->b_die )
    {
        vlc_mutex_lock( &p_intf->change_lock );

        /* Notify the interfaces */
        if( p_intf->p_sys->b_triggered )
        {
            playlist_t *p_playlist =
                (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                               FIND_ANYWHERE );

            if( p_playlist != NULL )
            {
                vlc_value_t val;
                val.b_bool = VLC_TRUE;
                var_Set( p_playlist, "intf-show", val );
                vlc_object_release( p_playlist );
            }
            p_intf->p_sys->b_triggered = VLC_FALSE;
        }

        vlc_mutex_unlock( &p_intf->change_lock );


        /* Take care of the video output */
        if( p_intf->p_sys->p_vout && p_intf->p_sys->p_vout->b_die )
        {
            var_DelCallback( p_intf->p_sys->p_vout, "mouse-moved",
                             MouseEvent, p_intf );
            var_DelCallback( p_intf->p_sys->p_vout, "mouse-button-down",
                             MouseEvent, p_intf );
            vlc_object_release( p_intf->p_sys->p_vout );
            p_intf->p_sys->p_vout = NULL;
        }

        if( p_intf->p_sys->p_vout == NULL )
        {
            p_intf->p_sys->p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
                                                     FIND_ANYWHERE );
            if( p_intf->p_sys->p_vout )
            {
                var_AddCallback( p_intf->p_sys->p_vout, "mouse-moved",
                                 MouseEvent, p_intf );
                var_AddCallback( p_intf->p_sys->p_vout, "mouse-button-down",
                                 MouseEvent, p_intf );
            }
        }

        /* Wait a bit */
        msleep( INTF_IDLE_SLEEP );
    }

    if( p_intf->p_sys->p_vout )
    {
        var_DelCallback( p_intf->p_sys->p_vout, "mouse-moved",
                         MouseEvent, p_intf );
        var_DelCallback( p_intf->p_sys->p_vout, "mouse-button-down",
                         MouseEvent, p_intf );
        vlc_object_release( p_intf->p_sys->p_vout );
    }
}
Ejemplo n.º 21
0
/**
 * Sub source
 */
static subpicture_t *FilterSub(filter_t *p_filter, mtime_t date)
{
    filter_sys_t *p_sys = p_filter->p_sys;
    BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);

    subpicture_t *p_spu;
    subpicture_region_t *p_region;
    video_format_t fmt;
    picture_t *p_pic;

    vlc_mutex_lock(&p_sys->lock);
    /* Basic test:  b_spu_update occurs on a dynamic change */
    if (!p_sys->b_spu_update) {
        vlc_mutex_unlock(&p_sys->lock);
        return NULL;
    }

    p_pic = p_BarGraph->p_pic;

    /* Allocate the subpicture internal data. */
    p_spu = filter_NewSubpicture(p_filter);
    if (!p_spu)
        goto exit;

    p_spu->b_absolute = p_sys->b_absolute;
    p_spu->i_start = date;
    p_spu->i_stop = 0;
    p_spu->b_ephemer = true;

    /* Send an empty subpicture to clear the display when needed */
    if (!p_pic || !p_BarGraph->i_alpha)
        goto exit;

    /* Create new SPU region */
    memset(&fmt, 0, sizeof(video_format_t));
    fmt.i_chroma = VLC_CODEC_YUVA;
    fmt.i_sar_num = fmt.i_sar_den = 1;
    fmt.i_width = fmt.i_visible_width = p_pic->p[Y_PLANE].i_visible_pitch;
    fmt.i_height = fmt.i_visible_height = p_pic->p[Y_PLANE].i_visible_lines;
    fmt.i_x_offset = fmt.i_y_offset = 0;
    p_region = subpicture_region_New(&fmt);
    if (!p_region) {
        msg_Err(p_filter, "cannot allocate SPU region");
        subpicture_Delete(p_spu);
        p_spu = NULL;
        goto exit;
    }

    /* */
    picture_Copy(p_region->p_picture, p_pic);

    /*  where to locate the bar graph: */
    if (p_sys->i_pos < 0) {   /*  set to an absolute xy */
        p_region->i_align = SUBPICTURE_ALIGN_RIGHT | SUBPICTURE_ALIGN_TOP;
        p_spu->b_absolute = true;
    } else {   /* set to one of the 9 relative locations */
        p_region->i_align = p_sys->i_pos;
        p_spu->b_absolute = false;
    }

    p_region->i_x = p_sys->i_pos_x;
    p_region->i_y = p_sys->i_pos_y;

    p_spu->p_region = p_region;

    p_spu->i_alpha = p_BarGraph->i_alpha ;

exit:
    vlc_mutex_unlock(&p_sys->lock);

    return p_spu;
}
Ejemplo n.º 22
0
Archivo: puzzle.c Proyecto: etix/vlc
/**
 * Filter a picture
 */
picture_t *Filter( filter_t *p_filter, picture_t *p_pic_in ) {
    if( !p_pic_in || !p_filter) return NULL;

    const video_format_t  *p_fmt_in = &p_filter->fmt_in.video;
    filter_sys_t *p_sys = p_filter->p_sys;

    picture_t *p_pic_out = filter_NewPicture( p_filter );
    if( !p_pic_out ) {
        picture_Release( p_pic_in );
        return NULL;
    }

    int i_ret = 0;
    p_sys->b_bake_request = false;

    if ((p_sys->pi_order == NULL) || (p_sys->ps_desk_planes == NULL) || (p_sys->ps_pict_planes == NULL)  || (p_sys->ps_puzzle_array == NULL) || (p_sys->ps_pieces == NULL))
        p_sys->b_init = false;

    if ((p_sys->ps_pieces_shapes == NULL) && p_sys->s_current_param.b_advanced && (p_sys->s_current_param.i_shape_size != 0))
        p_sys->b_init = false;

    /* assert initialized & allocated data match with current frame characteristics */
    if ( p_sys->s_allocated.i_planes != p_pic_out->i_planes)
        p_sys->b_init = false;
    p_sys->s_current_param.i_planes = p_pic_out->i_planes;
    if (p_sys->ps_pict_planes != NULL) {
        for (uint8_t i_plane = 0; i_plane < p_sys->s_allocated.i_planes; i_plane++) {
            if ( (p_sys->ps_pict_planes[i_plane].i_lines != p_pic_in->p[i_plane].i_visible_lines)
                    || (p_sys->ps_pict_planes[i_plane].i_width != p_pic_in->p[i_plane].i_visible_pitch / p_pic_in->p[i_plane].i_pixel_pitch)
                    || (p_sys->ps_desk_planes[i_plane].i_lines != p_pic_out->p[i_plane].i_visible_lines)
                    || (p_sys->ps_desk_planes[i_plane].i_width != p_pic_out->p[i_plane].i_visible_pitch / p_pic_out->p[i_plane].i_pixel_pitch) )
                p_sys->b_init = false;
        }
    }

    p_sys->s_current_param.i_pict_width  = (int) p_pic_in->p[0].i_visible_pitch / p_pic_in->p[0].i_pixel_pitch;
    p_sys->s_current_param.i_pict_height = (int) p_pic_in->p[0].i_visible_lines;
    p_sys->s_current_param.i_desk_width  = (int) p_pic_out->p[0].i_visible_pitch / p_pic_out->p[0].i_pixel_pitch;
    p_sys->s_current_param.i_desk_height = (int) p_pic_out->p[0].i_visible_lines;

    /* assert no mismatch between sizes */
    if (    p_sys->s_current_param.i_pict_width  != p_sys->s_current_param.i_desk_width
         || p_sys->s_current_param.i_pict_height != p_sys->s_current_param.i_desk_height
         || p_sys->s_current_param.i_pict_width  != (int) p_fmt_in->i_visible_width
         || p_sys->s_current_param.i_pict_height != (int) p_fmt_in->i_visible_height ) {
        picture_Release(p_pic_in);
        picture_Release(p_pic_out);
        return NULL;
    }

    vlc_mutex_lock( &p_sys->lock );

    /* check if we have to compute initial data */
    if ( p_sys->b_change_param || p_sys->b_bake_request || !p_sys->b_init ) {
        if ( p_sys->s_allocated.i_rows != p_sys->s_new_param.i_rows
                || p_sys->s_allocated.i_cols != p_sys->s_new_param.i_cols
                || p_sys->s_allocated.i_rotate != p_sys->s_new_param.i_rotate
                || p_sys->s_allocated.i_mode != p_sys->s_new_param.i_mode
                || p_sys->b_bake_request  || !p_sys->b_init )
        {
            p_sys->b_bake_request = true;
            p_sys->b_init = false;
            p_sys->b_shuffle_rqst = true;
            p_sys->b_shape_init = false;
        }

        if ( p_sys->s_current_param.i_border != p_sys->s_new_param.i_border
                || p_sys->s_current_param.i_shape_size != p_sys->s_new_param.i_shape_size )
        {
            p_sys->b_bake_request = true;
            p_sys->b_shape_init = false;
        }

        /* depending on the game selected, set associated internal flags */
        switch ( p_sys->s_new_param.i_mode )
        {
          case 0:  /* jigsaw puzzle */
            p_sys->s_new_param.b_advanced    = true;
            p_sys->s_new_param.b_blackslot   = false;
            p_sys->s_new_param.b_near        = false;
            break;
          case 1:  /* sliding puzzle */
            p_sys->s_new_param.b_advanced    = false;
            p_sys->s_new_param.b_blackslot   = true;
            p_sys->s_new_param.b_near        = true;
            break;
          case 2:  /* swap puzzle */
            p_sys->s_new_param.b_advanced    = false;
            p_sys->s_new_param.b_blackslot   = false;
            p_sys->s_new_param.b_near        = true;
            break;
          case 3:  /* exchange puzzle */
            p_sys->s_new_param.b_advanced    = false;
            p_sys->s_new_param.b_blackslot   = false;
            p_sys->s_new_param.b_near        = false;
            break;
        }
        p_sys->s_current_param.i_mode = p_sys->s_new_param.i_mode;

        if ( p_sys->s_current_param.b_blackslot != p_sys->s_new_param.b_blackslot
                && p_sys->i_selected == NO_PCE
                && p_sys->s_current_param.b_blackslot )
            p_sys->i_selected = 0;

        if ( p_sys->s_current_param.i_auto_shuffle_speed != p_sys->s_new_param.i_auto_shuffle_speed )
            p_sys->i_auto_shuffle_countdown_val = init_countdown(p_sys->s_new_param.i_auto_shuffle_speed);

        if ( p_sys->s_current_param.i_auto_solve_speed != p_sys->s_new_param.i_auto_solve_speed )
            p_sys->i_auto_solve_countdown_val = init_countdown(p_sys->s_current_param.i_auto_solve_speed);

        p_sys->s_current_param.i_rows       = p_sys->s_new_param.i_rows;
        p_sys->s_current_param.i_cols       = p_sys->s_new_param.i_cols;
        p_sys->s_current_param.i_pieces_nbr = p_sys->s_current_param.i_rows * p_sys->s_current_param.i_cols;
        p_sys->s_current_param.b_advanced   = p_sys->s_new_param.b_advanced;
        if (!p_sys->s_new_param.b_advanced) {
            p_sys->s_current_param.b_blackslot   = p_sys->s_new_param.b_blackslot;
            p_sys->s_current_param.b_near        = p_sys->s_new_param.b_near || p_sys->s_new_param.b_blackslot;
            p_sys->s_current_param.i_border      = 0;
            p_sys->s_current_param.b_preview     = false;
            p_sys->s_current_param.i_preview_size= 0;
            p_sys->s_current_param.i_shape_size  = 0;
            p_sys->s_current_param.i_auto_shuffle_speed  = 0;
            p_sys->s_current_param.i_auto_solve_speed    = 0;
            p_sys->s_current_param.i_rotate      = 0;
        }
        else
        {
            p_sys->s_current_param.b_blackslot = false;
            p_sys->s_current_param.b_near      = false;
            p_sys->s_current_param.i_border    = p_sys->s_new_param.i_border;
            p_sys->s_current_param.b_preview   = p_sys->s_new_param.b_preview;
            p_sys->s_current_param.i_preview_size        = p_sys->s_new_param.i_preview_size;
            p_sys->s_current_param.i_shape_size          = p_sys->s_new_param.i_shape_size;
            p_sys->s_current_param.i_auto_shuffle_speed  = p_sys->s_new_param.i_auto_shuffle_speed;
            p_sys->s_current_param.i_auto_solve_speed    = p_sys->s_new_param.i_auto_solve_speed;
            p_sys->s_current_param.i_rotate     = p_sys->s_new_param.i_rotate;
        }
        p_sys->b_change_param = false;
    }

    vlc_mutex_unlock( &p_sys->lock );

    /* generate initial puzzle data when needed */
    if ( p_sys->b_bake_request ) {
        if (!p_sys->b_shuffle_rqst) {
            /* here we have to keep the same position
             * we have to save locations before generating new data
             */
            save_game_t *ps_save_game = puzzle_save(p_filter);
            if (!ps_save_game)
                return CopyInfoAndRelease( p_pic_out, p_pic_in );
            i_ret = puzzle_bake( p_filter, p_pic_out, p_pic_in );
            if ( i_ret != VLC_SUCCESS )
            {
                free(ps_save_game->ps_pieces);
                free(ps_save_game);
                return CopyInfoAndRelease( p_pic_out, p_pic_in );
            }
            puzzle_load( p_filter, ps_save_game);
            free(ps_save_game->ps_pieces);
            free(ps_save_game);
        }
        else {
            i_ret = puzzle_bake( p_filter, p_pic_out, p_pic_in );
            if ( i_ret != VLC_SUCCESS )
                return CopyInfoAndRelease( p_pic_out, p_pic_in );
        }
    }

    /* shuffle the desk and generate pieces data  */
    if ( p_sys->b_shuffle_rqst && p_sys->b_init ) {
        i_ret = puzzle_bake_piece ( p_filter );
        if (i_ret != VLC_SUCCESS)
            return CopyInfoAndRelease( p_pic_out, p_pic_in );
    }

    /* preset output pic */
    if ( !p_sys->b_bake_request && !p_sys->b_shuffle_rqst && p_sys->b_init && !p_sys->b_finished )
        puzzle_preset_desk_background(p_pic_out, 0, 127, 127);
    else {
        /* copy src to dst during init & bake process */
        for( uint8_t i_plane = 0; i_plane < p_pic_out->i_planes; i_plane++ )
            memcpy( p_pic_out->p[i_plane].p_pixels, p_pic_in->p[i_plane].p_pixels,
                p_pic_in->p[i_plane].i_pitch * (int32_t) p_pic_in->p[i_plane].i_visible_lines );
    }

    vlc_mutex_lock( &p_sys->pce_lock );

    /* manage the game, adjust locations, groups and regenerate some corrupted data if any */
    for (uint32_t i = 0; i < __MAX( 4, p_sys->s_allocated.i_pieces_nbr / 4 )
                             && ( !p_sys->b_bake_request && !p_sys->b_mouse_drag
                             && p_sys->b_init && p_sys->s_current_param.b_advanced ); i++)
    {
        puzzle_solve_pces_accuracy( p_filter );
    }

    for (uint32_t i = 0; i < __MAX( 4, p_sys->s_allocated.i_pieces_nbr / 4 )
                             && ( !p_sys->b_bake_request && !p_sys->b_mouse_drag
                             && p_sys->b_init && p_sys->s_current_param.b_advanced ); i++)
    {
        puzzle_solve_pces_group( p_filter );
    }

    if ( !p_sys->b_bake_request && !p_sys->b_mouse_drag && p_sys->b_init
            && p_sys->s_current_param.b_advanced )
        puzzle_count_pce_group( p_filter);
    if ( !p_sys->b_bake_request && !p_sys->b_mouse_drag && p_sys->b_init
            && p_sys->s_current_param.b_advanced ) {
        i_ret = puzzle_sort_layers( p_filter);
        if (i_ret != VLC_SUCCESS)
        {
            vlc_mutex_unlock( &p_sys->pce_lock );
            return CopyInfoAndRelease( p_pic_out, p_pic_in );
        }
    }

    for (uint32_t i = 0; i < __MAX( 4, p_sys->s_allocated.i_pieces_nbr / 24 )
                            && ( !p_sys->b_bake_request && !p_sys->b_mouse_drag
                            && p_sys->b_init && p_sys->s_current_param.b_advanced ); i++)
    {
        p_sys->i_calc_corn_loop++;
        p_sys->i_calc_corn_loop %= p_sys->s_allocated.i_pieces_nbr;
        puzzle_calculate_corners( p_filter, p_sys->i_calc_corn_loop );
    }

    /* computer moves some piece depending on auto_solve and auto_shuffle param */
    if ( !p_sys->b_bake_request && !p_sys->b_mouse_drag && p_sys->b_init
             && p_sys->ps_puzzle_array != NULL && p_sys->s_current_param.b_advanced )
    {
        puzzle_auto_shuffle( p_filter );
        puzzle_auto_solve( p_filter );
    }

    vlc_mutex_unlock( &p_sys->pce_lock );

    /* draw output pic */
    if ( !p_sys->b_bake_request && p_sys->b_init  && p_sys->ps_puzzle_array != NULL ) {

        puzzle_draw_borders(p_filter, p_pic_in, p_pic_out);

        p_sys->i_pointed_pce = NO_PCE;
        puzzle_draw_pieces(p_filter, p_pic_in, p_pic_out);

        /* when puzzle_draw_pieces() has not updated p_sys->i_pointed_pce,
         * use puzzle_find_piece to define the piece pointed by the mouse
         */
        if (p_sys->i_pointed_pce == NO_PCE)
            p_sys->i_mouse_drag_pce = puzzle_find_piece( p_filter, p_sys->i_mouse_x, p_sys->i_mouse_y, -1);
        else
            p_sys->i_mouse_drag_pce = p_sys->i_pointed_pce;

        if (p_sys->s_current_param.b_preview )
            puzzle_draw_preview(p_filter, p_pic_in, p_pic_out);

        /* highlight the selected piece when not playing jigsaw mode */
        if ( p_sys->i_selected != NO_PCE && !p_sys->s_current_param.b_blackslot
                && !p_sys->s_current_param.b_advanced )
        {
            int32_t c = (p_sys->i_selected % p_sys->s_allocated.i_cols);
            int32_t r = (p_sys->i_selected / p_sys->s_allocated.i_cols);

            puzzle_draw_rectangle(p_pic_out,
                p_sys->ps_puzzle_array[r][c][0].i_x,
                p_sys->ps_puzzle_array[r][c][0].i_y,
                p_sys->ps_puzzle_array[r][c][0].i_width,
                p_sys->ps_puzzle_array[r][c][0].i_lines,
                255, 127, 127);
        }

        /* draw the blackslot when playing sliding puzzle mode */
        if ( p_sys->i_selected != NO_PCE && p_sys->s_current_param.b_blackslot
                && !p_sys->s_current_param.b_advanced )
        {
            int32_t c = (p_sys->i_selected % p_sys->s_allocated.i_cols);
            int32_t r = (p_sys->i_selected / p_sys->s_allocated.i_cols);

            puzzle_fill_rectangle(p_pic_out,
                p_sys->ps_puzzle_array[r][c][0].i_x,
                p_sys->ps_puzzle_array[r][c][0].i_y,
                p_sys->ps_puzzle_array[r][c][0].i_width,
                p_sys->ps_puzzle_array[r][c][0].i_lines,
                0, 127, 127);
        }

        /* Draw the 'puzzle_shuffle' button if the puzzle is finished */
        if ( p_sys->b_finished )
            puzzle_draw_sign(p_pic_out, 0, 0, SHUFFLE_WIDTH, SHUFFLE_LINES, ppsz_shuffle_button, false);

        /* draw an arrow at mouse pointer to indicate current action (rotation...) */
        if ((p_sys->i_mouse_drag_pce != NO_PCE) && !p_sys->b_mouse_drag
                && !p_sys->b_finished && p_sys->s_current_param.b_advanced )
        {
            vlc_mutex_lock( &p_sys->pce_lock );

            int32_t i_delta_x;

            if (p_sys->s_current_param.i_rotate != 3)
                i_delta_x = 0;
            else if ( (p_sys->ps_pieces[p_sys->i_mouse_drag_pce].i_actual_angle & 1) == 0)
                i_delta_x = p_sys->ps_desk_planes[0].i_pce_max_width / 6;
            else
                i_delta_x = p_sys->ps_desk_planes[0].i_pce_max_lines / 6;

            if (p_sys->s_current_param.i_rotate == 0)
                p_sys->i_mouse_action = 0;
            else if (p_sys->s_current_param.i_rotate == 1)
                p_sys->i_mouse_action = 2;
            else if ( p_sys->i_mouse_x >= ( p_sys->ps_pieces[p_sys->i_mouse_drag_pce].i_center_x + i_delta_x) )
                p_sys->i_mouse_action = -1;  /* rotate counterclockwise */
            else if ( p_sys->i_mouse_x <= ( p_sys->ps_pieces[p_sys->i_mouse_drag_pce].i_center_x - i_delta_x) )
                p_sys->i_mouse_action = +1;
            else
                p_sys->i_mouse_action = 4;   /* center click: only mirror */

            if ( p_sys->i_mouse_action == +1 )
                puzzle_draw_sign(p_pic_out, p_sys->i_mouse_x - ARROW_WIDTH,
                                 p_sys->i_mouse_y, ARROW_WIDTH, ARROW_LINES, ppsz_rot_arrow_sign, false);
            else if ( p_sys->i_mouse_action == -1 )
                puzzle_draw_sign(p_pic_out, p_sys->i_mouse_x - ARROW_WIDTH,
                                 p_sys->i_mouse_y, ARROW_WIDTH, ARROW_LINES, ppsz_rot_arrow_sign, true);
            else if ( p_sys->i_mouse_action == 4 )
                puzzle_draw_sign(p_pic_out, p_sys->i_mouse_x - ARROW_WIDTH,
                                 p_sys->i_mouse_y, ARROW_WIDTH, ARROW_LINES, ppsz_mir_arrow_sign, false);

            vlc_mutex_unlock( &p_sys->pce_lock );
        }
    }

    return CopyInfoAndRelease( p_pic_out, p_pic_in );
}
Ejemplo n.º 23
0
/*****************************************************************************
 * RunIntf: main loop
 *****************************************************************************/
static void 
RunIntf( intf_thread_t *p_intf )
{
    vlc_object_t      * p_vout = NULL;
    mtime_t             mtime = 0;
    mtime_t             mlast = 0;
    vcdplayer_t       * p_vcdplayer;
    input_thread_t    * p_input;
    access_t          * p_access;

    /* What you add to the last input number entry. It accumulates all of
       the 10_ADD keypresses */
    int number_addend = 0;

    if( InitThread( p_intf ) < 0 )
    {
        msg_Err( p_intf, "can't initialize intf" );
        return;
    }

    p_input = p_intf->p_sys->p_input;

    while ( !p_intf->p_sys->p_vcdplayer )
    {
        msleep( INTF_IDLE_SLEEP );
    }
    
    p_vcdplayer = p_intf->p_sys->p_vcdplayer;
    p_access    = p_vcdplayer->p_access;

    dbg_print( INPUT_DBG_CALL, "intf initialized" );

    /* Main loop */
    while( !p_intf->b_die )
    {
      vlc_mutex_lock( &p_intf->change_lock );

        /*
         * Have we timed-out in showing a still frame?
         */
        if( p_intf->p_sys->b_still && !p_intf->p_sys->b_infinite_still )
        {
            if( p_intf->p_sys->m_still_time > 0 )
            {
                /* Update remaining still time */
                dbg_print(INPUT_DBG_STILL, "updating still time");
                mtime = mdate();
                if( mlast )
                {
                    p_intf->p_sys->m_still_time -= mtime - mlast;
                }

                mlast = mtime;
            }
            else
            {
                /* Still time has elapsed; set to continue playing. */
                dbg_print(INPUT_DBG_STILL, "wait time done - setting play");
                var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
                p_intf->p_sys->m_still_time = 0;
                p_intf->p_sys->b_still = 0;
                mlast = 0;
            }
        }

      /*
       * Do we have a keyboard event?
       */
      if( p_vout && p_intf->p_sys->b_key_pressed )
        {
          vlc_value_t val;
          int i, i_action = -1;
          struct hotkey *p_hotkeys = p_intf->p_vlc->p_hotkeys;

          p_intf->p_sys->b_key_pressed = VLC_FALSE;

          /* Find action triggered by hotkey (if any) */
          var_Get( p_intf->p_vlc, "key-pressed", &val );

          dbg_print( INPUT_DBG_EVENT, "Key pressed %d", val.i_int );

          for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
            {
              if( p_hotkeys[i].i_key == val.i_int )
                {
                  i_action = p_hotkeys[i].i_action;
                }
            }

          if( i_action != -1) {
            switch (i_action) {

            case ACTIONID_NAV_LEFT:
              dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_LEFT - prev (%d)",
                         number_addend );
              do {
                vcdplayer_play_prev( p_access );
              }        while (number_addend-- > 0);
              break;

            case ACTIONID_NAV_RIGHT:
              dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_RIGHT - next (%d)",
                         number_addend );
              do {
                vcdplayer_play_next( p_access );
              } while (number_addend-- > 0);
              break;

            case ACTIONID_NAV_UP:
              dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_UP - return" );
              do {
                vcdplayer_play_return( p_access );
              } while (number_addend-- > 0);
              break;

            case ACTIONID_NAV_DOWN:
              dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_DOWN - default"  );
              vcdplayer_play_default( p_access );
              break;

            case ACTIONID_NAV_ACTIVATE:
              {
                vcdinfo_itemid_t itemid;
                itemid.type=p_vcdplayer->play_item.type;

                dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_ACTIVATE" );

                if ( vcdplayer_pbc_is_on( p_vcdplayer ) 
		     && number_addend != 0 ) {
                  lid_t next_num=vcdinfo_selection_get_lid(p_vcdplayer->vcd,
                                                           p_vcdplayer->i_lid,
                                                           number_addend);
                  if (VCDINFO_INVALID_LID != next_num) {
                    itemid.num  = next_num;
                    itemid.type = VCDINFO_ITEM_TYPE_LID;
                    vcdplayer_play( p_access, itemid );
                  }
                } else {
                  itemid.num = number_addend;
                  vcdplayer_play( p_access, itemid );
                }
                break;
              }
            }
            number_addend = 0;

            /* Any keypress gets rid of still frame waiting.
               FIXME - should handle just the ones that cause an action.
            */
            if( p_intf->p_sys->b_still )
              {
                dbg_print(INPUT_DBG_STILL, "Playing still after activate");
                var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
                p_intf->p_sys->b_still = 0;
                p_intf->p_sys->b_infinite_still = 0;
                p_intf->p_sys->m_still_time = 0;
              }

          } else {
            unsigned int digit_entered=0;

            switch (val.i_int) {
            case '9':
              digit_entered++;
            case '8':
              digit_entered++;
            case '7':
              digit_entered++;
            case '6':
              digit_entered++;
            case '5':
              digit_entered++;
            case '4':
              digit_entered++;
            case '3':
              digit_entered++;
            case '2':
              digit_entered++;
            case '1':
              digit_entered++;
            case '0':
              {
                number_addend *= 10;
                number_addend += digit_entered;
                dbg_print( INPUT_DBG_EVENT,
                           "Added %d. Number is now: %d\n",
                           digit_entered, number_addend);
                break;
              }
            }
          }
        }


      vlc_mutex_unlock( &p_intf->change_lock );

      if( p_vout == NULL )
        {
          p_vout = vlc_object_find( p_intf->p_sys->p_input,
                                    VLC_OBJECT_VOUT, FIND_CHILD );
          if( p_vout )
            {
              var_AddCallback( p_vout, "key-pressed", KeyEvent, p_intf );
            }
        }


      /* Wait a bit */
      msleep( INTF_IDLE_SLEEP );
    }

    if( p_vout )
    {
        var_DelCallback( p_vout, "key-pressed", KeyEvent, p_intf );
        vlc_object_release( p_vout );
    }

    vlc_object_release( p_intf->p_sys->p_input );
}
Ejemplo n.º 24
0
Archivo: puzzle.c Proyecto: etix/vlc
/* mouse callback */
int puzzle_mouse( filter_t *p_filter, vlc_mouse_t *p_mouse,
                  const vlc_mouse_t *p_old, const vlc_mouse_t *p_new )
{
    filter_sys_t *p_sys = p_filter->p_sys;
    const video_format_t  *p_fmt_in = &p_filter->fmt_in.video;

    /* Only take events inside the puzzle area */
    if( p_new->i_x < 0 || p_new->i_x >= (int)p_fmt_in->i_width ||
        p_new->i_y < 0 || p_new->i_y >= (int)p_fmt_in->i_height )
        return VLC_EGENERIC;

    if (! p_sys->b_init || p_sys->b_change_param) {
        *p_mouse = *p_new;
        return VLC_SUCCESS;
    }

    p_sys->i_mouse_x = p_new->i_x;
    p_sys->i_mouse_y = p_new->i_y;

    /* If the puzzle is finished, shuffle it if needed */
    if( p_sys->b_finished ) {
        p_sys->b_mouse_drag = false;
        p_sys->b_mouse_mvt = false;
        if( vlc_mouse_HasPressed( p_old, p_new, MOUSE_BUTTON_LEFT ) &&
            p_new->i_x < SHUFFLE_WIDTH && p_new->i_y < SHUFFLE_LINES )
        {
            p_sys->b_shuffle_rqst = true;
            return VLC_EGENERIC;
        }
        else
        {
            /* otherwise we can forward the mouse */
            *p_mouse = *p_new;
            return VLC_SUCCESS;
        }
    }

    if ( !p_sys->s_current_param.b_advanced ) {
        /* "square" game mode (sliding puzzle, swap...) */
        const bool b_clicked = vlc_mouse_HasPressed( p_old, p_new, MOUSE_BUTTON_LEFT );

        if( b_clicked )
        {
            /* */
            const int32_t i_border_width = p_fmt_in->i_width * p_sys->s_current_param.i_border / 100 / 2;
            const int32_t i_border_height = p_fmt_in->i_height * p_sys->s_current_param.i_border / 100 / 2;
            const int32_t i_pos_x = (p_new->i_x - i_border_width) * p_sys->s_allocated.i_cols / (p_fmt_in->i_width - 2*i_border_width);
            const int32_t i_pos_y = (p_new->i_y - i_border_height) * p_sys->s_allocated.i_rows / (p_fmt_in->i_height - 2*i_border_height);

            const int32_t i_pos = i_pos_y * p_sys->s_allocated.i_cols + i_pos_x;
            p_sys->i_mouse_drag_pce = i_pos;

            /* do not take into account if border clicked */
            if ((p_new->i_x <= i_border_width) || (p_new->i_y <=  i_border_height) || (p_new->i_x >= (int) p_fmt_in->i_width -  i_border_width) || (p_new->i_y >= (int) p_fmt_in->i_height -  i_border_height ) )
            {
                *p_mouse = *p_new;
                return VLC_SUCCESS;
            }
            else if( p_sys->i_selected == NO_PCE )
                p_sys->i_selected = i_pos;
            else if( p_sys->i_selected == i_pos && !p_sys->s_current_param.b_blackslot )
                p_sys->i_selected = -1;
            else if( ( p_sys->i_selected == i_pos + 1 && p_sys->i_selected%p_sys->s_allocated.i_cols != 0 )
                  || ( p_sys->i_selected == i_pos - 1 && i_pos % p_sys->s_allocated.i_cols != 0 )
                  || p_sys->i_selected == i_pos +  p_sys->s_allocated.i_cols
                  || p_sys->i_selected == i_pos -  p_sys->s_allocated.i_cols
                  || !p_sys->s_current_param.b_near )

            {
                /* Swap two pieces */
                int32_t a = p_sys->pi_order[ p_sys->i_selected ];
                p_sys->pi_order[ p_sys->i_selected ] = p_sys->pi_order[ i_pos ];
                p_sys->pi_order[ i_pos ] = a;

                /* regen piece location from updated pi_order */
                if ( p_sys->ps_pieces != NULL && p_sys->pi_order != NULL )
                {
                    int32_t i = 0;
                    for (int32_t row = 0; row < p_sys->s_allocated.i_rows; row++) {
                        for (int32_t col = 0; col < p_sys->s_allocated.i_cols; col++) {
                            int32_t orow = p_sys->pi_order[i] / (p_sys->s_allocated.i_cols);
                            int32_t ocol = p_sys->pi_order[i] % (p_sys->s_allocated.i_cols);

                            p_sys->ps_pieces[i].i_original_row = orow;
                            p_sys->ps_pieces[i].i_original_col = ocol;
                            p_sys->ps_pieces[i].i_top_shape    = 0;
                            p_sys->ps_pieces[i].i_btm_shape    = 0;
                            p_sys->ps_pieces[i].i_right_shape  = 0;
                            p_sys->ps_pieces[i].i_left_shape   = 0;
                            p_sys->ps_pieces[i].i_actual_angle = 0;
                            p_sys->ps_pieces[i].i_actual_mirror = +1;
                            p_sys->ps_pieces[i].b_overlap      = false;
                            p_sys->ps_pieces[i].b_finished     = false;
                            p_sys->ps_pieces[i].i_group_ID     = i;

                            for (uint8_t i_plane = 0; i_plane < p_sys->s_allocated.i_planes; i_plane++) {
                                p_sys->ps_pieces[i].ps_piece_in_plane[i_plane].i_width     = p_sys->ps_puzzle_array[row][col][i_plane].i_width;
                                p_sys->ps_pieces[i].ps_piece_in_plane[i_plane].i_lines     = p_sys->ps_puzzle_array[row][col][i_plane].i_lines;
                                p_sys->ps_pieces[i].ps_piece_in_plane[i_plane].i_original_x = p_sys->ps_puzzle_array[orow][ocol][i_plane].i_x;
                                p_sys->ps_pieces[i].ps_piece_in_plane[i_plane].i_original_y = p_sys->ps_puzzle_array[orow][ocol][i_plane].i_y;
                                p_sys->ps_pieces[i].ps_piece_in_plane[i_plane].i_actual_x   = p_sys->ps_puzzle_array[row][col][i_plane].i_x;
                                p_sys->ps_pieces[i].ps_piece_in_plane[i_plane].i_actual_y   = p_sys->ps_puzzle_array[row][col][i_plane].i_y;
                            }
                            i++;
                        }
                    }
                }

                p_sys->i_selected = p_sys->s_current_param.b_blackslot ? i_pos : NO_PCE;
                p_sys->b_finished = puzzle_is_finished( p_sys, p_sys->pi_order );
            }
        }
    }
    else /* jigsaw puzzle mode */
    {
        if ((p_sys->ps_desk_planes == NULL)  || (p_sys->ps_pict_planes == NULL)  || (p_sys->ps_puzzle_array == NULL) || (p_sys->ps_pieces == NULL)) {
            *p_mouse = *p_new;
            return VLC_SUCCESS;
        }

        if( vlc_mouse_HasPressed( p_old, p_new, MOUSE_BUTTON_LEFT ) )
        {

            vlc_mutex_lock( &p_sys->pce_lock );

            if (p_sys->i_mouse_drag_pce != NO_PCE) {
                int i_ret = puzzle_piece_foreground( p_filter, p_sys->i_mouse_drag_pce);
                if (i_ret != VLC_SUCCESS)
                {
                    vlc_mutex_unlock( &p_sys->pce_lock );
                    return i_ret;
                }
                p_sys->i_mouse_drag_pce = 0;

                uint32_t i_group_ID = p_sys->ps_pieces[0].i_group_ID;
                for (uint32_t i = 0; i < p_sys->s_allocated.i_pieces_nbr; i++) {
                    if ( i_group_ID == p_sys->ps_pieces[i].i_group_ID ) {
                        p_sys->ps_pieces[i].b_finished = false;
                    }
                    else {
                        break;
                    }
                }

                p_sys->b_mouse_drag = true;
                p_sys->b_mouse_mvt = false;
            }
            else {
            /* player click an empty area then search a piece which is overlapping another one and place it here */
                p_sys->b_mouse_drag = false;
                for (uint32_t i = 0; i < p_sys->s_allocated.i_pieces_nbr; i++)
                    if ( p_sys->ps_pieces[i].b_overlap ) {
                        puzzle_move_group( p_filter, i, p_new->i_x - p_sys->ps_pieces[i].i_center_x,  p_new->i_y - p_sys->ps_pieces[i].i_center_y );
                        p_sys->ps_pieces[i].b_overlap = false;
                        break;
                    }
                p_sys->b_mouse_drag = false;
            }

            vlc_mutex_unlock( &p_sys->pce_lock );

        }
        else if( vlc_mouse_HasReleased( p_old, p_new, MOUSE_BUTTON_LEFT ) )
        {
            if ( !p_sys->b_mouse_mvt && p_sys->b_mouse_drag ) {
                /* piece clicked without any mouse mvt => rotate it or mirror */
                if ( p_sys->s_current_param.i_rotate != 0) {
                    vlc_mutex_lock( &p_sys->pce_lock );

                    uint32_t i_group_ID = p_sys->ps_pieces[0].i_group_ID;

                    for (uint32_t i = 0; i < p_sys->s_allocated.i_pieces_nbr; i++)
                        if ( i_group_ID == p_sys->ps_pieces[i].i_group_ID )
                            puzzle_rotate_pce( p_filter, i, p_sys->i_mouse_action, p_sys->ps_pieces[0].i_center_x, p_sys->ps_pieces[0].i_center_y, p_sys->i_mouse_action != 4 ? true : false );

                    vlc_mutex_unlock( &p_sys->pce_lock );
                }
            }
            p_sys->b_mouse_drag = false;
            p_sys->b_mouse_mvt = false;
        }
        else /* no action on left button */
        {
            /* check if the mouse is in the preview area */
            switch ( p_sys->i_preview_pos )
            {
              case 0:
                if ( p_new->i_x < (int)p_fmt_in->i_width / 2 && p_new->i_y < (int)p_fmt_in->i_height / 2 )
                    p_sys->i_preview_pos++;
                break;
              case 1:
                if ( p_new->i_x > (int)p_fmt_in->i_width / 2 && p_new->i_y < (int)p_fmt_in->i_height / 2 )
                    p_sys->i_preview_pos++;
                break;
              case 2:
                if ( p_new->i_x > (int)p_fmt_in->i_width / 2 && p_new->i_y > (int)p_fmt_in->i_height / 2 )
                    p_sys->i_preview_pos++;
                break;
              case 3:
                if ( p_new->i_x < (int)p_fmt_in->i_width / 2 && p_new->i_y > (int)p_fmt_in->i_height / 2 )
                    p_sys->i_preview_pos++;
                break;
            }
            p_sys->i_preview_pos %= 4;

            if ( !vlc_mouse_IsLeftPressed( p_new ) )
                p_sys->b_mouse_drag = false;

            int i_dx, i_dy;
            vlc_mouse_GetMotion( &i_dx, &i_dy, p_old, p_new );
            if ( i_dx != 0 || i_dy != 0 )
                p_sys->b_mouse_mvt = true;

            if (p_sys->b_mouse_drag) {
                if ( ( p_new->i_x <= 0 ) || ( p_new->i_y <=  0 ) || ( p_new->i_x >= (int) p_fmt_in->i_width )
                        || ( p_new->i_y >= (int) p_fmt_in->i_height ) )
                {
                    /* if the mouse is outside the window, stop moving the piece/group */
                    p_sys->b_mouse_drag = false;
                    p_sys->b_mouse_mvt = true;
                }
                else if ( i_dx != 0 || i_dy != 0 )
                {
                    vlc_mutex_lock( &p_sys->pce_lock );

                    puzzle_move_group( p_filter, p_sys->i_mouse_drag_pce, i_dx, i_dy);

                    vlc_mutex_unlock( &p_sys->pce_lock );
                }
            }
        }
    }
    return VLC_EGENERIC;
}
Ejemplo n.º 25
0
/**************************************************************************
 *       libvlc_media_list_lock (Public)
 *
 * The lock must be held in access operations. It is never used in the
 * Public method.
 **************************************************************************/
void libvlc_media_list_lock( libvlc_media_list_t * p_mlist )
{
    vlc_mutex_lock( &p_mlist->object_lock );
}
Ejemplo n.º 26
0
Archivo: dbus.c Proyecto: etix/vlc
int GetInputMeta( playlist_item_t *item, DBusMessageIter *args )
{
    input_item_t *p_input = item->p_input;
    DBusMessageIter dict, dict_entry, variant, list;
    /** The duration of the track can be expressed in second, milli-seconds and
        µ-seconds */
    dbus_int64_t i_mtime = input_item_GetDuration( p_input );
    dbus_uint32_t i_time = i_mtime / 1000000;
    dbus_int64_t i_length = i_mtime / 1000;
    char *psz_trackid;

    if( -1 == asprintf( &psz_trackid, MPRIS_TRACKID_FORMAT, item->i_id ) )
        return VLC_ENOMEM;

    const char* ppsz_meta_items[] =
    {
        "mpris:trackid", "xesam:url", "xesam:title", "xesam:artist",
        "xesam:album", "xesam:tracknumber", "vlc:time", "mpris:length",
        "xesam:genre", "xesam:userRating", "xesam:contentCreated",
        "mpris:artUrl", "mb:trackId", "vlc:audio-bitrate",
        "vlc:audio-samplerate", "vlc:video-bitrate", "vlc:audio-codec",
        "vlc:copyright", "xesam:comment", "vlc:encodedby", "language",
        "vlc:length", "vlc:nowplaying", "vlc:publisher", "vlc:setting",
        "status", "vlc:url", "vlc:video-codec"
    };

    dbus_message_iter_open_container( args, DBUS_TYPE_ARRAY, "{sv}", &dict );

    ADD_META( 0, DBUS_TYPE_OBJECT_PATH, psz_trackid );
    ADD_VLC_META_STRING( 1,  URI );
    ADD_VLC_META_STRING( 2,  Title );
    ADD_META_SINGLETON_STRING_LIST( 3,  Artist );
    ADD_VLC_META_STRING( 4,  Album );
    ADD_VLC_META_STRING( 5,  TrackNum );
    ADD_META( 6, DBUS_TYPE_UINT32, i_time );
    ADD_META( 7, DBUS_TYPE_INT64,  i_mtime );
    ADD_META_SINGLETON_STRING_LIST( 8,  Genre );
    //ADD_META( 9, DBUS_TYPE_DOUBLE, rating );
    ADD_VLC_META_STRING( 10, Date ); // this is supposed to be in ISO 8601 extended format
    ADD_VLC_META_STRING( 11, ArtURL );
    ADD_VLC_META_STRING( 12, TrackID );

    ADD_VLC_META_STRING( 17, Copyright );
    ADD_META_SINGLETON_STRING_LIST( 18, Description );
    ADD_VLC_META_STRING( 19, EncodedBy );
    ADD_VLC_META_STRING( 20, Language );
    ADD_META( 21, DBUS_TYPE_INT64, i_length );
    ADD_VLC_META_STRING( 22, NowPlaying );
    ADD_VLC_META_STRING( 23, Publisher );
    ADD_VLC_META_STRING( 24, Setting );
    ADD_VLC_META_STRING( 25, URL );

    free( psz_trackid );

    vlc_mutex_lock( &p_input->lock );
    if( p_input->p_meta )
    {
        int i_status = vlc_meta_GetStatus( p_input->p_meta );
        ADD_META( 23, DBUS_TYPE_INT32, i_status );
    }
    vlc_mutex_unlock( &p_input->lock );

    dbus_message_iter_close_container( args, &dict );
    return VLC_SUCCESS;
}
Ejemplo n.º 27
0
/****************************************************************************
 * DecodeBlock:
 ****************************************************************************/
static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    subpicture_t *p_spu = NULL;
    block_t *p_block;

    if( !pp_block || *pp_block == NULL )
        return NULL;

    p_block = *pp_block;
    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
    {
        p_sys->i_max_stop = VLC_TS_INVALID;
        block_Release( p_block );
        return NULL;
    }
    *pp_block = NULL;

    if( p_block->i_buffer == 0 || p_block->p_buffer[0] == '\0' )
    {
        block_Release( p_block );
        return NULL;
    }

    subpicture_updater_sys_t *p_spu_sys = malloc( sizeof(*p_spu_sys) );
    if( !p_spu_sys )
    {
        block_Release( p_block );
        return NULL;
    }

    subpicture_updater_t updater = {
        .pf_validate = SubpictureValidate,
        .pf_update   = SubpictureUpdate,
        .pf_destroy  = SubpictureDestroy,
        .p_sys       = p_spu_sys,
    };
    p_spu = decoder_NewSubpicture( p_dec, &updater );
    if( !p_spu )
    {
        msg_Warn( p_dec, "can't get spu buffer" );
        free( p_spu_sys );
        block_Release( p_block );
        return NULL;
    }

    p_spu_sys->p_img = NULL;
    p_spu_sys->p_dec_sys = p_sys;
    p_spu_sys->i_subs_len = p_block->i_buffer;
    p_spu_sys->p_subs_data = malloc( p_block->i_buffer );
    p_spu_sys->i_pts = p_block->i_pts;
    if( !p_spu_sys->p_subs_data )
    {
        decoder_DeleteSubpicture( p_dec, p_spu );
        block_Release( p_block );
        return NULL;
    }
    memcpy( p_spu_sys->p_subs_data, p_block->p_buffer,
            p_block->i_buffer );

    p_spu->i_start = p_block->i_pts;
    p_spu->i_stop = __MAX( p_sys->i_max_stop, p_block->i_pts + p_block->i_length );
    p_spu->b_ephemer = true;
    p_spu->b_absolute = true;

    p_sys->i_max_stop = p_spu->i_stop;

    vlc_mutex_lock( &p_sys->lock );
    if( p_sys->p_track )
    {
        ass_process_chunk( p_sys->p_track, p_spu_sys->p_subs_data, p_spu_sys->i_subs_len,
                           p_block->i_pts / 1000, p_block->i_length / 1000 );
    }
    vlc_mutex_unlock( &p_sys->lock );

    DecSysHold( p_sys ); /* Keep a reference for the returned subpicture */

    block_Release( p_block );

    return p_spu;
}
Ejemplo n.º 28
0
Archivo: dbus.c Proyecto: etix/vlc
static void *Run( void *data )
{
    intf_thread_t *p_intf = data;
    intf_sys_t    *p_sys = p_intf->p_sys;

    int canc = vlc_savecancel();

    for( ;; )
    {
        vlc_mutex_lock( &p_sys->lock );

        int i_watches = vlc_array_count( p_sys->p_watches );
        struct pollfd fds[i_watches];
        memset(fds, 0, sizeof fds);

        int i_fds = GetPollFds( p_intf, fds );
        int timeout = next_timeout(p_intf);

        vlc_mutex_unlock( &p_sys->lock );

        /* thread cancellation is allowed while the main loop sleeps */
        vlc_restorecancel( canc );

        while (poll(fds, i_fds, timeout) == -1)
        {
            if (errno != EINTR)
                goto error;
        }

        canc = vlc_savecancel();

        /* Was the main loop woken up manually ? */
        if (fds[0].revents & POLLIN)
        {
            char buf;
            (void)read( fds[0].fd, &buf, 1 );
        }

        /* We need to lock the mutex while building lists of events,
         * timeouts and watches to process but we can't keep the lock while
         * processing them, or else we risk a deadlock:
         *
         * The signal functions could lock mutex X while p_events is locked;
         * While some other function in vlc (playlist) might lock mutex X
         * and then set a variable which would call AllCallback(), which itself
         * needs to lock p_events to add a new event.
         */
        vlc_mutex_lock( &p_intf->p_sys->lock );

        process_timeouts(p_intf);

        /* Get the list of watches to process */
        i_watches = vlc_array_count( p_sys->p_watches );
        DBusWatch *p_watches[i_watches ? i_watches : 1];
        for( int i = 0; i < i_watches; i++ )
        {
            p_watches[i] = vlc_array_item_at_index( p_sys->p_watches, i );
        }

        /* Get the list of events to process */
        int i_events = vlc_array_count( p_intf->p_sys->p_events );
        callback_info_t* p_info[i_events ? i_events : 1];
        for( int i = i_events - 1; i >= 0; i-- )
        {
            p_info[i] = vlc_array_item_at_index( p_intf->p_sys->p_events, i );
            vlc_array_remove( p_intf->p_sys->p_events, i );
        }

        /* now we can release the lock and process what's pending */
        vlc_mutex_unlock( &p_intf->p_sys->lock );

        ProcessEvents( p_intf, p_info, i_events );
        ProcessWatches( p_intf, p_watches, i_watches, fds, i_fds );

        DispatchDBusMessages( p_intf );
    }
error:
    vlc_restorecancel(canc);
    return NULL;
}
Ejemplo n.º 29
0
static void EqzFilter( filter_t *p_filter, float *out, float *in,
                       int i_samples, int i_channels )
{
    filter_sys_t *p_sys = p_filter->p_sys;
    int i, ch, j;

    vlc_mutex_lock( &p_sys->lock );
    for( i = 0; i < i_samples; i++ )
    {
        for( ch = 0; ch < i_channels; ch++ )
        {
            const float x = in[ch];
            float o = 0.0;

            for( j = 0; j < p_sys->i_band; j++ )
            {
                float y = p_sys->f_alpha[j] * ( x - p_sys->x[ch][1] ) +
                          p_sys->f_gamma[j] * p_sys->y[ch][j][0] -
                          p_sys->f_beta[j]  * p_sys->y[ch][j][1];

                p_sys->y[ch][j][1] = p_sys->y[ch][j][0];
                p_sys->y[ch][j][0] = y;

                o += y * p_sys->f_amp[j];
            }
            p_sys->x[ch][1] = p_sys->x[ch][0];
            p_sys->x[ch][0] = x;

            /* Second filter */
            if( p_sys->b_2eqz )
            {
                const float x2 = EQZ_IN_FACTOR * x + o;
                o = 0.0;
                for( j = 0; j < p_sys->i_band; j++ )
                {
                    float y = p_sys->f_alpha[j] * ( x2 - p_sys->x2[ch][1] ) +
                              p_sys->f_gamma[j] * p_sys->y2[ch][j][0] -
                              p_sys->f_beta[j]  * p_sys->y2[ch][j][1];

                    p_sys->y2[ch][j][1] = p_sys->y2[ch][j][0];
                    p_sys->y2[ch][j][0] = y;

                    o += y * p_sys->f_amp[j];
                }
                p_sys->x2[ch][1] = p_sys->x2[ch][0];
                p_sys->x2[ch][0] = x2;

                /* We add source PCM + filtered PCM */
                out[ch] = p_sys->f_gamp *( EQZ_IN_FACTOR * x2 + o );
            }
            else
            {
                /* We add source PCM + filtered PCM */
                out[ch] = p_sys->f_gamp *( EQZ_IN_FACTOR * x + o );
            }
        }

        in  += i_channels;
        out += i_channels;
    }
    vlc_mutex_unlock( &p_sys->lock );
}
Ejemplo n.º 30
0
static int SendIn( sout_stream_t *p_stream, sout_stream_id_t *id,
                   block_t *p_buffer )
{
    in_sout_stream_sys_t *p_sys = (in_sout_stream_sys_t *)p_stream->p_sys;
    bridge_t *p_bridge;
    bool b_no_es = true;
    int i;
    int i_date = mdate();

    /* First forward the packet for our own ES */
    if( !p_sys->b_placeholder )
        p_stream->p_next->pf_send( p_stream->p_next, id->id, p_buffer );

    /* Then check all bridged streams */
    vlc_mutex_lock( &lock );

    p_bridge = var_GetAddress( p_stream->p_libvlc, p_sys->psz_name );

    if( p_bridge )
    {
    for ( i = 0; i < p_bridge->i_es_num; i++ )
    {
        if ( !p_bridge->pp_es[i]->b_empty )
            b_no_es = false;

        while ( p_bridge->pp_es[i]->p_block != NULL
                 && (p_bridge->pp_es[i]->p_block->i_dts + p_sys->i_delay
                       < i_date
                      || p_bridge->pp_es[i]->p_block->i_dts + p_sys->i_delay
                          < p_bridge->pp_es[i]->i_last) )
        {
            block_t *p_block = p_bridge->pp_es[i]->p_block;
            msg_Dbg( p_stream, "dropping a packet (%"PRId64 ")",
                     i_date - p_block->i_dts - p_sys->i_delay );
            p_bridge->pp_es[i]->p_block
                = p_bridge->pp_es[i]->p_block->p_next;
            block_Release( p_block );
        }

        if ( p_bridge->pp_es[i]->p_block == NULL )
        {
            p_bridge->pp_es[i]->pp_last = &p_bridge->pp_es[i]->p_block;
        }

        if ( p_bridge->pp_es[i]->b_changed )
        {
            if ( p_bridge->pp_es[i]->b_empty && p_bridge->pp_es[i]->id != NULL )
            {
                p_stream->p_next->pf_del( p_stream->p_next, p_bridge->pp_es[i]->id );
            }
            else
            {
                /* We need at least two packets to enter the mux. */
                if ( p_bridge->pp_es[i]->p_block == NULL
                      || p_bridge->pp_es[i]->p_block->p_next == NULL )
                {
                    continue;
                }

                p_bridge->pp_es[i]->fmt.i_id += p_sys->i_id_offset;
                if( !p_sys->b_placeholder )
                {
                    p_bridge->pp_es[i]->id = p_stream->p_next->pf_add(
                                p_stream->p_next, &p_bridge->pp_es[i]->fmt );
                    if ( p_bridge->pp_es[i]->id == NULL )
                    {
                        msg_Warn( p_stream, "couldn't create chain for id %d",
                                  p_bridge->pp_es[i]->fmt.i_id );
                    }
                }
                msg_Dbg( p_stream, "bridging in input codec=%4.4s id=%d pos=%d",
                         (char*)&p_bridge->pp_es[i]->fmt.i_codec,
                         p_bridge->pp_es[i]->fmt.i_id, i );
            }
        }
        p_bridge->pp_es[i]->b_changed = false;

        if ( p_bridge->pp_es[i]->b_empty )
            continue;

        if ( p_bridge->pp_es[i]->p_block == NULL )
        {
            if ( p_bridge->pp_es[i]->id != NULL
                  && p_bridge->pp_es[i]->i_last < i_date )
            {
                if( !p_sys->b_placeholder )
                    p_stream->p_next->pf_del( p_stream->p_next,
                                          p_bridge->pp_es[i]->id );
                p_bridge->pp_es[i]->fmt.i_id -= p_sys->i_id_offset;
                p_bridge->pp_es[i]->b_changed = true;
                p_bridge->pp_es[i]->id = NULL;
            }
            continue;
        }

        if ( p_bridge->pp_es[i]->id != NULL || p_sys->b_placeholder)
        {
            block_t *p_block = p_bridge->pp_es[i]->p_block;
            while ( p_block != NULL )
            {
                p_bridge->pp_es[i]->i_last = p_block->i_dts;
                p_block->i_pts += p_sys->i_delay;
                p_block->i_dts += p_sys->i_delay;
                p_block = p_block->p_next;
            }
            sout_stream_id_t *newid = NULL;
            if( p_sys->b_placeholder )
            {
                switch( p_bridge->pp_es[i]->fmt.i_cat )
                {
                    case VIDEO_ES:
                        p_sys->i_last_video = i_date;
                        newid = p_sys->id_video;
                        if( !newid )
                            break;
                        if( !p_sys->b_switch_on_iframe ||
                            p_sys->i_state == placeholder_off ||
                            ( p_bridge->pp_es[i]->fmt.i_cat == VIDEO_ES &&
                              p_bridge->pp_es[i]->p_block->i_flags & BLOCK_FLAG_TYPE_I ) )
                        {
                            p_stream->p_next->pf_send( p_stream->p_next,
                                       newid,
                                       p_bridge->pp_es[i]->p_block );
                            p_sys->i_state = placeholder_off;
                        }
                        break;
                    case AUDIO_ES:
                        newid = p_sys->id_audio;
                        if( !newid )
                            break;
                        p_sys->i_last_audio = i_date;
                    default:
                        p_stream->p_next->pf_send( p_stream->p_next,
                                   newid?newid:p_bridge->pp_es[i]->id,
                                   p_bridge->pp_es[i]->p_block );
                        break;
                }
            }
            else /* !b_placeholder */
                p_stream->p_next->pf_send( p_stream->p_next,
                                       p_bridge->pp_es[i]->id,
                                       p_bridge->pp_es[i]->p_block );
        }
        else
        {
            block_ChainRelease( p_bridge->pp_es[i]->p_block );
        }

        p_bridge->pp_es[i]->p_block = NULL;
        p_bridge->pp_es[i]->pp_last = &p_bridge->pp_es[i]->p_block;
    }

    if( b_no_es )
    {
        for ( i = 0; i < p_bridge->i_es_num; i++ )
            free( p_bridge->pp_es[i] );
        free( p_bridge->pp_es );
        free( p_bridge );
        var_Destroy( p_stream->p_libvlc, p_sys->psz_name );
    }
    }

    if( p_sys->b_placeholder )
    {
        switch( id->i_cat )
        {
            case VIDEO_ES:
                if( ( p_sys->i_last_video + p_sys->i_placeholder_delay < i_date
                    && (  !p_sys->b_switch_on_iframe
                       || p_buffer->i_flags & BLOCK_FLAG_TYPE_I ) )
                  || p_sys->i_state == placeholder_on )
                {
                    p_stream->p_next->pf_send( p_stream->p_next, id->id, p_buffer );
                    p_sys->i_state = placeholder_on;
                }
                else
                    block_Release( p_buffer );
                break;

            case AUDIO_ES:
                if( p_sys->i_last_audio + p_sys->i_placeholder_delay < i_date )
                    p_stream->p_next->pf_send( p_stream->p_next, id->id, p_buffer );
                else
                    block_Release( p_buffer );
                break;

            default:
                block_Release( p_buffer ); /* FIXME: placeholder subs anyone? */
                break;
        }
    }

    vlc_mutex_unlock( &lock );

    return VLC_SUCCESS;
}