Example #1
0
static void ParseRequest( services_discovery_t *p_sd )
{
    services_discovery_sys_t *p_sys = p_sd->p_sys;

    char *psz_request = p_sys->psz_request;

    int i;

    char *psz_tok = strchr( psz_request, ':' );
    if( !psz_tok ) return;
    *psz_tok = '\0';
    if( !strcmp( psz_request, "ADD" ) )
    {
        psz_request = psz_tok + 1;
        for( i = 0; i<p_sys->i_urls; i++ )
            if( !strcmp(p_sys->ppsz_urls[i],psz_request) )
              break;
        if( i == p_sys->i_urls )
        {
            INSERT_ELEM( p_sys->ppsz_urls, p_sys->i_urls, p_sys->i_urls,
              strdup( psz_request ) );

            input_item_t *p_input;
            p_input = input_item_New( p_sd, psz_request, psz_request );
            input_item_AddOption( p_input, "demux=podcast", VLC_INPUT_OPTION_TRUSTED );

            INSERT_ELEM( p_sys->pp_items, p_sys->i_items, p_sys->i_items, p_input );
            services_discovery_AddItem( p_sd, p_input, NULL /* no cat */ );

            INSERT_ELEM( p_sys->pp_input, p_sys->i_input, p_sys->i_input,
                         input_CreateAndStart( p_sd, p_input, NULL ) );
            SaveUrls( p_sd );
        }
    }
    else if ( !strcmp( psz_request, "RM" ) )
    {
        psz_request = psz_tok + 1;
        for( i = 0; i<p_sys->i_urls; i++ )
          if( !strcmp(p_sys->ppsz_urls[i],psz_request) )
            break;
        if( i != p_sys->i_urls )
        {
            services_discovery_RemoveItem( p_sd, p_sys->pp_items[i] );
            vlc_gc_decref( p_sys->pp_items[i] );
            REMOVE_ELEM( p_sys->ppsz_urls, p_sys->i_urls, i );
            REMOVE_ELEM( p_sys->pp_items, p_sys->i_items, i );
        }
        SaveUrls( p_sd );
    }

    free( p_sys->psz_request );
    p_sys->psz_request = NULL;
}
Example #2
0
/**
 * This function does the preparsing and issues the art fetching requests
 */
static void *Thread( void *data )
{
    playlist_preparser_t *p_preparser = data;
    playlist_t *p_playlist = p_preparser->p_playlist;

    for( ;; )
    {
        input_item_t *p_current;

        /* */
        vlc_mutex_lock( &p_preparser->lock );
        if( p_preparser->i_waiting > 0 )
        {
            p_current = p_preparser->pp_waiting[0];
            REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, 0 );
        }
        else
        {
            p_current = NULL;
            p_preparser->b_live = false;
        }
        vlc_mutex_unlock( &p_preparser->lock );

        if( !p_current )
            break;

        Preparse( p_playlist, p_current );

        Art( p_preparser, p_current );
    }
    return NULL;
}
Example #3
0
void playlist_preparser_Delete( playlist_preparser_t *p_preparser )
{
    vlc_mutex_lock( &p_preparser->lock );
    /* Remove pending item to speed up preparser thread exit */
    while( p_preparser->i_waiting > 0 )
    {
        preparser_entry_t *p_entry = p_preparser->pp_waiting[0];
        vlc_gc_decref( p_entry->p_item );
        free( p_entry );
        REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, 0 );
    }

    vlc_sem_post( &p_preparser->item_done );

    while( p_preparser->b_live )
        vlc_cond_wait( &p_preparser->wait, &p_preparser->lock );
    vlc_mutex_unlock( &p_preparser->lock );

    /* Destroy the item preparser */
    vlc_sem_destroy( &p_preparser->item_done );
    vlc_cond_destroy( &p_preparser->wait );
    vlc_mutex_destroy( &p_preparser->lock );

    if( p_preparser->p_fetcher != NULL )
        playlist_fetcher_Delete( p_preparser->p_fetcher );
    free( p_preparser );
}
Example #4
0
File: sap.c Project: forthyen/SDesk
/* Remove a SAP Announce */
static int announce_SAPAnnounceDel( sap_handler_t *p_sap,
                             session_descriptor_t *p_session )
{
    int i;
    vlc_mutex_lock( &p_sap->object_lock );

    msg_Dbg( p_sap,"removing SAP announce %p",p_session->p_sap);

    /* Dequeue the announce */
    for( i = 0; i< p_sap->i_sessions; i++)
    {
        if( p_session->p_sap == p_sap->pp_sessions[i] )
        {
            REMOVE_ELEM( p_sap->pp_sessions,
                         p_sap->i_sessions,
                         i );
            break;
        }
    }

    /* XXX: Dequeue the address too if it is not used anymore
     * TODO: - address refcount
             - send a SAP deletion packet */

    msg_Dbg( p_sap,"%i announces remaining", p_sap->i_sessions );

    vlc_mutex_unlock( &p_sap->object_lock );

    return VLC_SUCCESS;
}
Example #5
0
/**
 * This function does the preparsing and issues the art fetching requests
 */
static void *Thread( void *data )
{
    playlist_preparser_t *p_preparser = data;
    vlc_object_t *obj = p_preparser->object;

    for( ;; )
    {
        input_item_t *p_current;

        /* */
        vlc_mutex_lock( &p_preparser->lock );
        if( p_preparser->i_waiting > 0 )
        {
            p_current = p_preparser->pp_waiting[0];
            REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, 0 );
        }
        else
        {
            p_current = NULL;
            p_preparser->b_live = false;
            vlc_cond_signal( &p_preparser->wait );
        }
        vlc_mutex_unlock( &p_preparser->lock );

        if( !p_current )
            break;

        Preparse( obj, p_current );

        Art( p_preparser, p_current );
        vlc_gc_decref(p_current);
    }
    return NULL;
}
Example #6
0
File: item.c Project: BossKing/vlc
/**
 * Moves an array of items
 *
 * This function must be entered with the playlist lock
 *
 * \param p_playlist the playlist
 * \param i_items the number of indexes to move
 * \param pp_items the array of indexes to move
 * \param p_node the target node
 * \param i_newpos the target position under this node
 * \return VLC_SUCCESS or an error
 */
int playlist_TreeMoveMany( playlist_t *p_playlist,
                            int i_items, playlist_item_t **pp_items,
                            playlist_item_t *p_node, int i_newpos )
{
    PL_ASSERT_LOCKED;

    if ( p_node->i_children == -1 ) return VLC_EGENERIC;

    int i;
    for( i = 0; i < i_items; i++ )
    {
        playlist_item_t *p_item = pp_items[i];
        int i_index = ItemIndex( p_item );
        playlist_item_t *p_parent = p_item->p_parent;
        REMOVE_ELEM( p_parent->pp_children, p_parent->i_children, i_index );
        if ( p_parent == p_node && i_index < i_newpos ) i_newpos--;
    }
    for( i = i_items - 1; i >= 0; i-- )
    {
        playlist_item_t *p_item = pp_items[i];
        INSERT_ELEM( p_node->pp_children, p_node->i_children, i_newpos, p_item );
        p_item->p_parent = p_node;
    }

    pl_priv( p_playlist )->b_reset_currently_playing = true;
    vlc_cond_signal( &pl_priv( p_playlist )->signal );
    return VLC_SUCCESS;
}
Example #7
0
static void DelCallback( vlc_object_t *p_this, const char *psz_name,
                         callback_entry_t entry, vlc_callback_type_t i_type )
{
    int i_entry;
    variable_t *p_var;
#ifndef NDEBUG
    bool b_found_similar = false;
#endif

    assert( p_this );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
        vlc_mutex_unlock( &p_priv->var_lock );
        msg_Err( p_this, "cannot delete callback %p from nonexistent "
                 "variable '%s'", entry.p_callback, psz_name );
        return;
    }

    WaitUnused( p_this, p_var );

    callback_table_t *p_table;
    if (i_type == vlc_value_callback)
        p_table = &p_var->value_callbacks;
    else
        p_table = &p_var->list_callbacks;

    for( i_entry = p_table->i_entries ; i_entry-- ; )
    {
        if( p_table->p_entries[i_entry].p_callback == entry.p_callback
            && p_table->p_entries[i_entry].p_data == entry.p_data )
        {
            break;
        }
#ifndef NDEBUG
        else if( p_table->p_entries[i_entry].p_callback == entry.p_callback )
            b_found_similar = true;
#endif
    }

    if( i_entry < 0 )
    {
#ifndef NDEBUG
        if( b_found_similar )
            fprintf( stderr, "Calling var_DelCallback for '%s' with the same "
                             "function but not the same data.", psz_name );
        vlc_assert_unreachable();
#endif
        vlc_mutex_unlock( &p_priv->var_lock );
        return;
    }

    REMOVE_ELEM( p_table->p_entries, p_table->i_entries, i_entry );

    vlc_mutex_unlock( &p_priv->var_lock );
}
Example #8
0
/*****************************************************************************
 * Run: Thread entry-point
 ****************************************************************************/
static void* Run( void *data )
{
    services_discovery_t *p_sd = ( services_discovery_t * )data;
    services_discovery_sys_t *p_sys = p_sd->p_sys;
    lua_State *L = p_sys->L;

    int cancel = vlc_savecancel();

    lua_getglobal( L, "main" );
    if( !lua_isfunction( L, lua_gettop( L ) ) || lua_pcall( L, 0, 1, 0 ) )
    {
        msg_Err( p_sd, "Error while running script %s, "
                  "function main(): %s", p_sys->psz_filename,
                  lua_tostring( L, lua_gettop( L ) ) );
        lua_pop( L, 1 );
        vlc_restorecancel( cancel );
        return NULL;
    }
    msg_Dbg( p_sd, "LuaSD script loaded: %s", p_sys->psz_filename );

    /* Force garbage collection, because the core will keep the SD
     * open, but lua will never gc until lua_close(). */
    lua_gc( L, LUA_GCCOLLECT, 0 );

    vlc_restorecancel( cancel );

    /* Main loop to handle search requests */
    vlc_mutex_lock( &p_sys->lock );
    mutex_cleanup_push( &p_sys->lock );
    for( ;; )
    {
        /* Wait for a request */
        if( !p_sys->i_query )
        {
            vlc_cond_wait( &p_sys->cond, &p_sys->lock );
            continue;
        }

        /* Execute one query (protected against cancellation) */
        char *psz_query = p_sys->ppsz_query[p_sys->i_query - 1];
        REMOVE_ELEM( p_sys->ppsz_query, p_sys->i_query, p_sys->i_query - 1 );
        vlc_mutex_unlock( &p_sys->lock );

        cancel = vlc_savecancel();
        DoSearch( p_sd, psz_query );
        free( psz_query );
        /* Force garbage collection, because the core will keep the SD
         * open, but lua will never gc until lua_close(). */
        lua_gc( L, LUA_GCCOLLECT, 0 );
        vlc_restorecancel( cancel );

        vlc_mutex_lock( &p_sys->lock );
    }
    vlc_cleanup_run();

    return NULL;
}
Example #9
0
/**
 * Remove a callback from a variable
 *
 * pf_callback and p_data have to be given again, because different objects
 * might have registered the same callback function.
 */
int var_DelCallback( vlc_object_t *p_this, const char *psz_name,
                     vlc_callback_t pf_callback, void *p_data )
{
    int i_entry;
    variable_t *p_var;
#ifndef NDEBUG
    bool b_found_similar = false;
#endif

    assert( p_this );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    vlc_mutex_lock( &p_priv->var_lock );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
        vlc_mutex_unlock( &p_priv->var_lock );
        return VLC_ENOVAR;
    }

    WaitUnused( p_this, p_var );

    for( i_entry = p_var->i_entries ; i_entry-- ; )
    {
        if( p_var->p_entries[i_entry].pf_callback == pf_callback
            && p_var->p_entries[i_entry].p_data == p_data )
        {
            break;
        }
#ifndef NDEBUG
        else if( p_var->p_entries[i_entry].pf_callback == pf_callback )
            b_found_similar = true;
#endif
    }

    if( i_entry < 0 )
    {
#ifndef NDEBUG
        if( b_found_similar )
            fprintf( stderr, "Calling var_DelCallback for '%s' with the same "
                             "function but not the same data.", psz_name );
        assert( 0 );
#endif
        vlc_mutex_unlock( &p_priv->var_lock );
        return VLC_EGENERIC;
    }

    REMOVE_ELEM( p_var->p_entries, p_var->i_entries, i_entry );

    vlc_mutex_unlock( &p_priv->var_lock );

    return VLC_SUCCESS;
}
Example #10
0
/**
 * Moves an item
 *
 * This function must be entered with the playlist lock
 *
 * \param p_playlist the playlist
 * \param p_item the item to move
 * \param p_node the new parent of the item
 * \param i_newpos the new position under this new parent
 * \param i_view the view in which the move must be done or ALL_VIEWS
 * \return VLC_SUCCESS or an error
 */
int playlist_TreeMove( playlist_t * p_playlist, playlist_item_t *p_item,
                       playlist_item_t *p_node, int i_newpos, int i_view )
{
    int i;
    playlist_item_t *p_detach = NULL;
    struct item_parent_t *p_parent;

    if( p_node->i_children == -1 ) return VLC_EGENERIC;

    /* Detach from the parent */
    for( i = 0 ; i< p_item->i_parents; i++ )
    {
        if( p_item->pp_parents[i]->i_view == i_view )
        {
            int j;
            p_detach = p_item->pp_parents[i]->p_parent;
            for( j = 0; j < p_detach->i_children; j++ )
            {
                if( p_detach->pp_children[j] == p_item ) break;
            }
            REMOVE_ELEM( p_detach->pp_children, p_detach->i_children, j );
            p_detach->i_serial++;
            free( p_item->pp_parents[i] );
            REMOVE_ELEM( p_item->pp_parents, p_item->i_parents, i );
            i--;
        }
    }

    /* Attach to new parent */
    INSERT_ELEM( p_node->pp_children, p_node->i_children, i_newpos, p_item );

    p_parent = malloc( sizeof( struct item_parent_t ) );
    p_parent->p_parent = p_node;
    p_parent->i_view = i_view;

    INSERT_ELEM( p_item->pp_parents, p_item->i_parents, p_item->i_parents,
                 p_parent );
    p_node->i_serial++;
    p_item->i_serial++;

    return VLC_SUCCESS;
}
Example #11
0
File: stats.c Project: etix/vlc
/** Update a counter element with new values
 * \param p_counter the counter to update
 * \param val the vlc_value union containing the new value to aggregate. For
 * more information on how data is aggregated, \see stats_Create
 * \param val_new a pointer that will be filled with new data
 */
void stats_Update( counter_t *p_counter, uint64_t val, uint64_t *new_val )
{
    if( !p_counter )
        return;

    switch( p_counter->i_compute_type )
    {
    case STATS_DERIVATIVE:
    {
        counter_sample_t *p_new, *p_old;
        mtime_t now = mdate();
        if( now - p_counter->last_update < CLOCK_FREQ )
            return;
        p_counter->last_update = now;
        /* Insert the new one at the beginning */
        p_new = (counter_sample_t*)malloc( sizeof( counter_sample_t ) );
        if (unlikely(p_new == NULL))
            return; /* NOTE: Losing sample here */

        p_new->value = val;
        p_new->date = p_counter->last_update;
        INSERT_ELEM( p_counter->pp_samples, p_counter->i_samples,
                     0, p_new );

        if( p_counter->i_samples == 3 )
        {
            p_old = p_counter->pp_samples[2];
            REMOVE_ELEM( p_counter->pp_samples, p_counter->i_samples, 2 );
            free( p_old );
        }
        break;
    }
    case STATS_COUNTER:
        if( p_counter->i_samples == 0 )
        {
            counter_sample_t *p_new = (counter_sample_t*)malloc(
                                               sizeof( counter_sample_t ) );
            if (unlikely(p_new == NULL))
                return; /* NOTE: Losing sample here */

            p_new->value = 0;

            INSERT_ELEM( p_counter->pp_samples, p_counter->i_samples,
                         p_counter->i_samples, p_new );
        }
        if( p_counter->i_samples == 1 )
        {
            p_counter->pp_samples[0]->value += val;
            if( new_val )
                *new_val = p_counter->pp_samples[0]->value;
        }
        break;
    }
}
Example #12
0
/**
 * @brief Remove items until everything fits in storage.
 * @note items will be randomly selected for removal.
 * @param[in] base Pointer to the base
 */
void CAP_RemoveItemsExceedingCapacity (base_t *base)
{
	int i;
	int objIdx[MAX_OBJDEFS];	/**< Will contain idx of items that can be removed */
	int num, cnt;

	if (CAP_GetFreeCapacity(base, CAP_ITEMS) >= 0)
		return;

	for (i = 0, num = 0; i < cgi->csi->numODs; i++) {
		const objDef_t *obj = INVSH_GetItemByIDX(i);

		if (!B_ItemIsStoredInBaseStorage(obj))
			continue;

		/* Don't count item that we don't have in base */
		if (B_ItemInBase(obj, base) <= 0)
			continue;

		objIdx[num++] = i;
	}

	cnt = E_CountHired(base, EMPL_ROBOT);
	/* UGV takes room in storage capacity: we store them with a value MAX_OBJDEFS that can't be used by objIdx */
	for (i = 0; i < cnt; i++) {
		objIdx[num++] = MAX_OBJDEFS;
	}

	while (num && CAP_GetFreeCapacity(base, CAP_ITEMS) < 0) {
		/* Select the item to remove */
		const int randNumber = rand() % num;
		if (objIdx[randNumber] >= MAX_OBJDEFS) {
			/* A UGV is destroyed: get first one */
			Employee* employee = E_GetHiredRobot(base, 0);
			/* There should be at least a UGV */
			assert(employee);
			E_DeleteEmployee(employee);
		} else {
			/* items are destroyed. We guess that all items of a given type are stored in the same location
			 *	=> destroy all items of this type */
			const int idx = objIdx[randNumber];
			const objDef_t *od = INVSH_GetItemByIDX(idx);
			B_UpdateStorageAndCapacity(base, od, -B_ItemInBase(od, base), false);
		}
		REMOVE_ELEM(objIdx, randNumber, num);

		/* Make sure that we don't have an infinite loop */
		if (num <= 0)
			break;
	}
	Com_DPrintf(DEBUG_CLIENT, "B_RemoveItemsExceedingCapacity: Remains %i in storage for a maximum of %i\n",
		CAP_GetCurrent(base, CAP_ITEMS), CAP_GetMax(base, CAP_ITEMS));
}
Example #13
0
File: stats.c Project: etix/vlc
void stats_CounterClean( counter_t *p_c )
{
    if( p_c )
    {
        int i = p_c->i_samples - 1 ;
        while( i >= 0 )
        {
            counter_sample_t *p_s = p_c->pp_samples[i];
            REMOVE_ELEM( p_c->pp_samples, p_c->i_samples, i );
            free( p_s );
            i--;
        }
        free( p_c );
    }
}
Example #14
0
File: sap.c Project: forthyen/SDesk
/**
 *  Destroy the SAP handler
 *  \param p_this the SAP Handler to destroy
 *  \return nothing
 */
void announce_SAPHandlerDestroy( sap_handler_t *p_sap )
{
    int i;

    vlc_mutex_destroy( &p_sap->object_lock );

    /* Free the remaining sessions */
    for( i = 0 ; i< p_sap->i_sessions ; i++)
    {
        sap_session_t *p_session = p_sap->pp_sessions[i];
        FREE( p_session->psz_sdp );
        FREE( p_session->psz_data );
        REMOVE_ELEM( p_sap->pp_sessions, p_sap->i_sessions , i );
        FREE( p_session );
    }

    /* Free the remaining addresses */
    for( i = 0 ; i< p_sap->i_addresses ; i++)
    {
        sap_address_t *p_address = p_sap->pp_addresses[i];
        FREE( p_address->psz_address );
        if( p_address->i_rfd > -1 )
        {
            net_Close( p_address->i_rfd );
        }
        if( p_address->i_wfd > -1 && p_sap->b_control )
        {
            net_Close( p_address->i_wfd );
        }
        REMOVE_ELEM( p_sap->pp_addresses, p_sap->i_addresses, i );
        FREE( p_address );
    }

    /* Free the structure */
    vlc_object_destroy( p_sap );
}
Example #15
0
/*****************************************************************************
 * Run: main thread
 *****************************************************************************/
static void *Run( void *data )
{
    services_discovery_t *p_sd = data;
    services_discovery_sys_t *p_sys  = p_sd->p_sys;

    vlc_mutex_lock( &p_sys->lock );
    mutex_cleanup_push( &p_sys->lock );
    for( ;; )
    {
        while( !p_sys->b_update )
            vlc_cond_wait( &p_sys->wait, &p_sys->lock );

        int canc = vlc_savecancel ();
        msg_Dbg( p_sd, "Update required" );

        if( p_sys->update_type == UPDATE_URLS )
        {
          char* psz_urls = var_GetNonEmptyString( p_sd, "podcast-urls" );
          ParseUrls( p_sd, psz_urls );
          free( psz_urls );
        }
        else if( p_sys->update_type == UPDATE_REQUEST )
        {
          ParseRequest( p_sd );
        }

        p_sys->b_update = false;

        for( int i = 0; i < p_sd->p_sys->i_input; i++ )
        {
            input_thread_t *p_input = p_sd->p_sys->pp_input[i];

            if( p_input->b_eof || p_input->b_error )
            {
                input_Stop( p_input, false );
                vlc_thread_join( p_input );
                vlc_object_release( p_input );

                p_sd->p_sys->pp_input[i] = NULL;
                REMOVE_ELEM( p_sys->pp_input, p_sys->i_input, i );
                i--;
            }
        }
        vlc_restorecancel (canc);
    }
    vlc_cleanup_pop();
    assert(0); /* dead code */
}
Example #16
0
/*****************************************************************************
 * Run: main thread
 *****************************************************************************/
VLC_NORETURN
static void *Run( void *data )
{
    services_discovery_t *p_sd = data;
    services_discovery_sys_t *p_sys  = p_sd->p_sys;

    vlc_mutex_lock( &p_sys->lock );
    mutex_cleanup_push( &p_sys->lock );
    for( ;; )
    {
        while( !p_sys->b_update )
            vlc_cond_wait( &p_sys->wait, &p_sys->lock );

        int canc = vlc_savecancel ();
        msg_Dbg( p_sd, "Update required" );

        if( p_sys->update_type == UPDATE_URLS )
        {
            char *psz_urls = var_GetNonEmptyString( p_sd->p_parent,
                                                    "podcast-urls" );
            ParseUrls( p_sd, psz_urls );
            free( psz_urls );
        }
        else if( p_sys->update_type == UPDATE_REQUEST )
            ParseRequest( p_sd );

        p_sys->b_update = false;

        for( int i = 0; i < p_sd->p_sys->i_input; i++ )
        {
            input_thread_t *p_input = p_sd->p_sys->pp_input[i];
            int state = var_GetInteger( p_input, "state" );

            if( state == END_S || state == ERROR_S )
            {
                input_Stop( p_input );
                input_Close( p_input );

                p_sd->p_sys->pp_input[i] = NULL;
                REMOVE_ELEM( p_sys->pp_input, p_sys->i_input, i );
                i--;
            }
        }
        vlc_restorecancel (canc);
    }
    vlc_cleanup_pop();
    vlc_assert_unreachable(); /* dead code */
}
Example #17
0
File: tree.c Project: paa/vlc
/**
 * Deletes an item from the children of a node
 *
 * \param p_playlist the playlist
 * \param p_item the item to remove
 * \param p_parent the parent node
 * \return VLC_SUCCESS or an error
 */
int playlist_NodeRemoveItem( playlist_t *p_playlist,
                        playlist_item_t *p_item,
                        playlist_item_t *p_parent )
{
    PL_ASSERT_LOCKED;
   (void)p_playlist;

   for(int i= 0; i< p_parent->i_children ; i++ )
   {
       if( p_parent->pp_children[i] == p_item )
       {
           REMOVE_ELEM( p_parent->pp_children, p_parent->i_children, i );
       }
   }

   return VLC_SUCCESS;
}
Example #18
0
/**
 * Unsubscribe from a message queue.
 */
void __msg_Unsubscribe( vlc_object_t *p_this, msg_subscription_t *p_sub )
{
    libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc);

    LOCK_BANK;
    vlc_mutex_lock( &QUEUE.lock );
    for( int j = 0 ; j< QUEUE.i_sub ; j++ )
    {
        if( QUEUE.pp_sub[j] == p_sub )
        {
            REMOVE_ELEM( QUEUE.pp_sub, QUEUE.i_sub, j );
            free( p_sub );
        }
    }
    vlc_mutex_unlock( &QUEUE.lock );
    UNLOCK_BANK;
}
Example #19
0
void playlist_preparser_Delete( playlist_preparser_t *p_preparser )
{
    vlc_mutex_lock( &p_preparser->lock );
    /* Remove pending item to speed up preparser thread exit */
    while( p_preparser->i_waiting > 0 )
    {
        vlc_gc_decref( p_preparser->pp_waiting[0] );
        REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, 0 );
    }

    while( p_preparser->b_live )
        vlc_cond_wait( &p_preparser->wait, &p_preparser->lock );
    vlc_mutex_unlock( &p_preparser->lock );

    /* Destroy the item preparser */
    vlc_cond_destroy( &p_preparser->wait );
    vlc_mutex_destroy( &p_preparser->lock );
    free( p_preparser );
}
Example #20
0
/**
 * Transform an item to a node
 *
 * This function must be entered without the playlist lock
 *
 * \param p_playlist the playlist object
 * \param p_item the item to transform
 * \return nothing
 */
int playlist_ItemToNode( playlist_t *p_playlist,playlist_item_t *p_item )
{
    int i = 0;
    if( p_item->i_children == -1 )
    {
        p_item->i_children = 0;
    }

    /* Remove it from the array of available items */
    for( i = 0 ; i < p_playlist->i_size ; i++ )
    {
        if( p_item == p_playlist->pp_items[i] )
        {
            REMOVE_ELEM( p_playlist->pp_items, p_playlist->i_size, i );
        }
    }
    var_SetInteger( p_playlist, "item-change", p_item->input.i_id );

    return VLC_SUCCESS;
}
Example #21
0
File: item.c Project: BossKing/vlc
/**
 * Moves an item
 *
 * This function must be entered with the playlist lock
 *
 * \param p_playlist the playlist
 * \param p_item the item to move
 * \param p_node the new parent of the item
 * \param i_newpos the new position under this new parent
 * \return VLC_SUCCESS or an error
 */
int playlist_TreeMove( playlist_t * p_playlist, playlist_item_t *p_item,
                       playlist_item_t *p_node, int i_newpos )
{
    PL_ASSERT_LOCKED;

    if( p_node->i_children == -1 ) return VLC_EGENERIC;

    playlist_item_t *p_detach = p_item->p_parent;
    int i_index = ItemIndex( p_item );

    REMOVE_ELEM( p_detach->pp_children, p_detach->i_children, i_index );

    if( p_detach == p_node && i_index < i_newpos )
        i_newpos--;

    INSERT_ELEM( p_node->pp_children, p_node->i_children, i_newpos, p_item );
    p_item->p_parent = p_node;

    pl_priv( p_playlist )->b_reset_currently_playing = true;
    vlc_cond_signal( &pl_priv( p_playlist )->signal );
    return VLC_SUCCESS;
}
Example #22
0
/**
 * delete an item from a playlist.
 *
 * \param p_playlist the playlist to remove from.
 * \param i_pos the position of the item to remove
 * \return returns 0
 */
int playlist_Delete( playlist_t * p_playlist, int i_pos )
{
    vlc_value_t     val;

    /* if i_pos is the current played item, playlist should stop playing it */
    if( ( p_playlist->i_status == PLAYLIST_RUNNING) &&
                    (p_playlist->i_index == i_pos) )
    {
        playlist_Command( p_playlist, PLAYLIST_STOP, 0 );
    }

    vlc_mutex_lock( &p_playlist->object_lock );
    if( i_pos >= 0 && i_pos < p_playlist->i_size )
    {
        playlist_item_t *p_item = p_playlist->pp_items[i_pos];

        msg_Dbg( p_playlist, "deleting playlist item `%s'",
                 p_item->input.psz_name );

        playlist_ItemDelete( p_item );

        if( i_pos <= p_playlist->i_index )
        {
            p_playlist->i_index--;
        }

        /* Renumber the playlist */
        REMOVE_ELEM( p_playlist->pp_items, p_playlist->i_size, i_pos );

        if( p_playlist->i_enabled > 0 ) p_playlist->i_enabled--;
    }

    vlc_mutex_unlock( &p_playlist->object_lock );

    val.b_bool = VLC_TRUE;
    var_Set( p_playlist, "intf-change", val );

    return 0;
}
Example #23
0
void RtspDelId( rtsp_stream_t *rtsp, rtsp_stream_id_t *id )
{
    vlc_mutex_lock( &rtsp->lock );
    for( int i = 0; i < rtsp->sessionc; i++ )
    {
        rtsp_session_t *ses = rtsp->sessionv[i];

        for( int j = 0; j < ses->trackc; j++ )
        {
            if( ses->trackv[j].id == id->sout_id )
            {
                rtsp_strack_t *tr = ses->trackv + j;
                net_Close( tr->fd );
                REMOVE_ELEM( ses->trackv, ses->trackc, j );
            }
        }
    }

    vlc_mutex_unlock( &rtsp->lock );
    httpd_UrlDelete( id->url );
    free( id );
}
Example #24
0
int input_item_DelInfo( input_item_t *p_i,
                        const char *psz_cat,
                        const char *psz_name )
{
    vlc_mutex_lock( &p_i->lock );
    int i_cat;
    info_category_t *p_cat = InputItemFindCat( p_i, &i_cat, psz_cat );
    if( !p_cat )
    {
        vlc_mutex_unlock( &p_i->lock );
        return VLC_EGENERIC;
    }

    if( psz_name )
    {
        /* Remove a specific info */
        int i_ret = info_category_DeleteInfo( p_cat, psz_name );
        if( i_ret )
        {
            vlc_mutex_unlock( &p_i->lock );
            return VLC_EGENERIC;
        }
    }
    else
    {
        /* Remove the complete categorie */
        info_category_Delete( p_cat );
        REMOVE_ELEM( p_i->pp_categories, p_i->i_categories, i_cat );
    }
    vlc_mutex_unlock( &p_i->lock );


    vlc_event_t event;
    event.type = vlc_InputItemInfoChanged;
    vlc_event_send( &p_i->event_manager, &event );

    return VLC_SUCCESS;
}
Example #25
0
/**
 * Remove a callback from a variable
 *
 * pf_callback and p_data have to be given again, because different objects
 * might have registered the same callback function.
 */
int __var_DelCallback( vlc_object_t *p_this, const char *psz_name,
                       vlc_callback_t pf_callback, void *p_data )
{
    int i_entry, i_var;
    variable_t *p_var;

    vlc_mutex_lock( &p_this->var_lock );

    i_var = GetUnused( p_this, psz_name );
    if( i_var < 0 )
    {
        vlc_mutex_unlock( &p_this->var_lock );
        return i_var;
    }

    p_var = &p_this->p_vars[i_var];

    for( i_entry = p_var->i_entries ; i_entry-- ; )
    {
        if( p_var->p_entries[i_entry].pf_callback == pf_callback
            && p_var->p_entries[i_entry].p_data == p_data )
        {
            break;
        }
    }

    if( i_entry < 0 )
    {
        vlc_mutex_unlock( &p_this->var_lock );
        return VLC_EGENERIC;
    }

    REMOVE_ELEM( p_var->p_entries, p_var->i_entries, i_entry );

    vlc_mutex_unlock( &p_this->var_lock );

    return VLC_SUCCESS;
}
Example #26
0
/**
 * This function does the preparsing and issues the art fetching requests
 */
static void *Thread( void *data )
{
    playlist_preparser_t *p_preparser = data;

    for( ;; )
    {
        input_item_t *p_current;
        input_item_meta_request_option_t i_options;

        /* */
        vlc_mutex_lock( &p_preparser->lock );
        if( p_preparser->i_waiting > 0 )
        {
            preparser_entry_t *p_entry = p_preparser->pp_waiting[0];
            p_current = p_entry->p_item;
            i_options = p_entry->i_options;
            free( p_entry );
            REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, 0 );
        }
        else
        {
            p_current = NULL;
            p_preparser->b_live = false;
            vlc_cond_signal( &p_preparser->wait );
        }
        vlc_mutex_unlock( &p_preparser->lock );

        if( !p_current )
            break;

        Preparse( p_preparser, p_current, i_options );

        Art( p_preparser, p_current );
        vlc_gc_decref(p_current);
    }
    return NULL;
}
Example #27
0
/**
 ****************************************************************************
 * Destroy a vlc object
 *
 * This function destroys an object that has been previously allocated with
 * vlc_object_create. The object's refcount must be zero and it must not be
 * attached to other objects in any way.
 *****************************************************************************/
void __vlc_object_destroy( vlc_object_t *p_this )
{
    int i_delay = 0;

    if( p_this->i_children )
    {
        msg_Err( p_this, "cannot delete object (%i, %s) with children" ,
                 p_this->i_object_id, p_this->psz_object_name );
        return;
    }

    if( p_this->p_parent )
    {
        msg_Err( p_this, "cannot delete object (%i, %s) with a parent",
                 p_this->i_object_id, p_this->psz_object_name );
        return;
    }

    while( p_this->i_refcount )
    {
        i_delay++;

        /* Don't warn immediately ... 100ms seems OK */
        if( i_delay == 2 )
        {
            msg_Warn( p_this, "refcount is %i, delaying before deletion",
                              p_this->i_refcount );
        }
        else if( i_delay == 12 )
        {
            msg_Err( p_this, "refcount is %i, I have a bad feeling about this",
                             p_this->i_refcount );
        }
        else if( i_delay == 42 )
        {
            msg_Err( p_this, "we waited too long, cancelling destruction" );
            return;
        }

        msleep( 100000 );
    }

    /* Destroy the associated variables, starting from the end so that
     * no memmove calls have to be done. */
    while( p_this->i_vars )
    {
        var_Destroy( p_this, p_this->p_vars[p_this->i_vars - 1].psz_name );
    }

    free( p_this->p_vars );
    vlc_mutex_destroy( &p_this->var_lock );

    if( p_this->i_object_type == VLC_OBJECT_ROOT )
    {
        /* We are the root object ... no need to lock. */
        free( p_this->p_libvlc->pp_objects );
        p_this->p_libvlc->pp_objects = NULL;
        p_this->p_libvlc->i_objects--;

        vlc_mutex_destroy( &structure_lock );
    }
    else
    {
        int i_index;

        vlc_mutex_lock( &structure_lock );

        /* Wooohaa! If *this* fails, we're in serious trouble! Anyway it's
         * useless to try and recover anything if pp_objects gets smashed. */
        i_index = FindIndex( p_this, p_this->p_libvlc->pp_objects,
                             p_this->p_libvlc->i_objects );
        REMOVE_ELEM( p_this->p_libvlc->pp_objects,
                     p_this->p_libvlc->i_objects, i_index );

        vlc_mutex_unlock( &structure_lock );
    }

    vlc_mutex_destroy( &p_this->object_lock );
    vlc_cond_destroy( &p_this->object_wait );

    free( p_this );
}
Example #28
0
/**
 * Deletes an item from a playlist.
 *
 * This function must be entered without the playlist lock
 *
 * \param p_playlist the playlist to remove from.
 * \param i_id the identifier of the item to delete
 * \return returns VLC_SUCCESS or an error
 */
int playlist_Delete( playlist_t * p_playlist, int i_id )
{
    int i, i_top, i_bottom;
    int i_pos;
    vlc_bool_t b_flag = VLC_FALSE;

    playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id );

    if( p_item == NULL )
    {
        return VLC_EGENERIC;
    }
    if( p_item->i_children > -1 )
    {
        return playlist_NodeDelete( p_playlist, p_item, VLC_TRUE, VLC_FALSE );
    }

    var_SetInteger( p_playlist, "item-deleted", i_id );

    i_bottom = 0; i_top = p_playlist->i_all_size - 1;
    i = i_top / 2;
    while( p_playlist->pp_all_items[i]->input.i_id != i_id &&
           i_top > i_bottom )
    {
        if( p_playlist->pp_all_items[i]->input.i_id < i_id )
        {
            i_bottom = i + 1;
        }
        else
        {
            i_top = i - 1;
        }
        i = i_bottom + ( i_top - i_bottom ) / 2;
    }
    if( p_playlist->pp_all_items[i]->input.i_id == i_id )
    {
        REMOVE_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size, i );
    }

    /* Check if it is the current item */
    if( p_playlist->status.p_item == p_item )
    {
        /* Hack we don't call playlist_Control for lock reasons */
        p_playlist->status.i_status = PLAYLIST_STOPPED;
        p_playlist->request.b_request = VLC_TRUE;
        p_playlist->request.p_item = NULL;
        msg_Info( p_playlist, "stopping playback" );
        b_flag = VLC_TRUE;
    }

    /* Get position and update index if needed */
    i_pos = playlist_GetPositionById( p_playlist, i_id );

    if( i_pos >= 0 && i_pos <= p_playlist->i_index )
    {
        p_playlist->i_index--;
    }

    msg_Dbg( p_playlist, "deleting playlist item `%s'",
                          p_item->input.psz_name );

    /* Remove the item from all its parent nodes */
    for ( i= 0 ; i < p_item->i_parents ; i++ )
    {
        playlist_NodeRemoveItem( p_playlist, p_item,
                                 p_item->pp_parents[i]->p_parent );
        if( p_item->pp_parents[i]->i_view == VIEW_ALL )
        {
            p_playlist->i_size--;
        }
    }

    /* TODO : Update views */

    if( b_flag == VLC_FALSE )
        playlist_ItemDelete( p_item );
    else
        p_item->i_flags |= PLAYLIST_REMOVE_FLAG;

    return VLC_SUCCESS;
}
Example #29
0
/** RTSP requests handler
 * @param id selected track for non-aggregate URLs,
 *           NULL for aggregate URLs
 */
static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
                        httpd_client_t *cl,
                        httpd_message_t *answer,
                        const httpd_message_t *query )
{
    sout_stream_t *p_stream = rtsp->owner;
    char psz_sesbuf[17];
    const char *psz_session = NULL, *psz;
    char control[sizeof("rtsp://[]:12345") + NI_MAXNUMERICHOST
                  + strlen( rtsp->psz_path )];
    time_t now;

    time (&now);

    if( answer == NULL || query == NULL || cl == NULL )
        return VLC_SUCCESS;
    else
    {
        /* Build self-referential control URL */
        char ip[NI_MAXNUMERICHOST], *ptr;

        httpd_ServerIP( cl, ip );
        ptr = strchr( ip, '%' );
        if( ptr != NULL )
            *ptr = '\0';

        if( strchr( ip, ':' ) != NULL )
            sprintf( control, "rtsp://[%s]:%u%s", ip, rtsp->port,
                     rtsp->psz_path );
        else
            sprintf( control, "rtsp://%s:%u%s", ip, rtsp->port,
                     rtsp->psz_path );
    }

    /* */
    answer->i_proto = HTTPD_PROTO_RTSP;
    answer->i_version= 0;
    answer->i_type   = HTTPD_MSG_ANSWER;
    answer->i_body = 0;
    answer->p_body = NULL;

    httpd_MsgAdd( answer, "Server", "%s", PACKAGE_STRING );

    /* Date: is always allowed, and sometimes mandatory with RTSP/2.0. */
    struct tm ut;
    if (gmtime_r (&now, &ut) != NULL)
    {   /* RFC1123 format, GMT is mandatory */
        static const char wdays[7][4] = {
            "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
        static const char mons[12][4] = {
            "Jan", "Feb", "Mar", "Apr", "May", "Jun",
            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
        httpd_MsgAdd (answer, "Date", "%s, %02u %s %04u %02u:%02u:%02u GMT",
                      wdays[ut.tm_wday], ut.tm_mday, mons[ut.tm_mon],
                      1900 + ut.tm_year, ut.tm_hour, ut.tm_min, ut.tm_sec);
    }

    if( query->i_proto != HTTPD_PROTO_RTSP )
    {
        answer->i_status = 505;
    }
    else
    if( httpd_MsgGet( query, "Require" ) != NULL )
    {
        answer->i_status = 551;
        httpd_MsgAdd( answer, "Unsupported", "%s",
                      httpd_MsgGet( query, "Require" ) );
    }
    else
    switch( query->i_type )
    {
        case HTTPD_MSG_DESCRIBE:
        {   /* Aggregate-only */
            if( id != NULL )
            {
                answer->i_status = 460;
                break;
            }

            answer->i_status = 200;
            httpd_MsgAdd( answer, "Content-Type",  "%s", "application/sdp" );
            httpd_MsgAdd( answer, "Content-Base",  "%s", control );
            answer->p_body = (uint8_t *)SDPGenerate( rtsp->owner, control );
            if( answer->p_body != NULL )
                answer->i_body = strlen( (char *)answer->p_body );
            else
                answer->i_status = 500;
            break;
        }

        case HTTPD_MSG_SETUP:
            /* Non-aggregate-only */
            if( id == NULL )
            {
                answer->i_status = 459;
                break;
            }

            psz_session = httpd_MsgGet( query, "Session" );
            answer->i_status = 461;

            for( const char *tpt = httpd_MsgGet( query, "Transport" );
                 tpt != NULL;
                 tpt = transport_next( tpt ) )
            {
                bool b_multicast = true, b_unsupp = false;
                unsigned loport = 5004, hiport = 5005; /* from RFC3551 */

                /* Check transport protocol. */
                /* Currently, we only support RTP/AVP over UDP */
                if( strncmp( tpt, "RTP/AVP", 7 ) )
                    continue;
                tpt += 7;
                if( strncmp( tpt, "/UDP", 4 ) == 0 )
                    tpt += 4;
                if( strchr( ";,", *tpt ) == NULL )
                    continue;

                /* Parse transport options */
                for( const char *opt = parameter_next( tpt );
                     opt != NULL;
                     opt = parameter_next( opt ) )
                {
                    if( strncmp( opt, "multicast", 9 ) == 0)
                        b_multicast = true;
                    else
                    if( strncmp( opt, "unicast", 7 ) == 0 )
                        b_multicast = false;
                    else
                    if( sscanf( opt, "client_port=%u-%u", &loport, &hiport )
                                == 2 )
                        ;
                    else
                    if( strncmp( opt, "mode=", 5 ) == 0 )
                    {
                        if( strncasecmp( opt + 5, "play", 4 )
                         && strncasecmp( opt + 5, "\"PLAY\"", 6 ) )
                        {
                            /* Not playing?! */
                            b_unsupp = true;
                            break;
                        }
                    }
                    else
                    if( strncmp( opt,"destination=", 12 ) == 0 )
                    {
                        answer->i_status = 403;
                        b_unsupp = true;
                    }
                    else
                    {
                    /*
                     * Every other option is unsupported:
                     *
                     * "source" and "append" are invalid (server-only);
                     * "ssrc" also (as clarified per RFC2326bis).
                     *
                     * For multicast, "port", "layers", "ttl" are set by the
                     * stream output configuration.
                     *
                     * For unicast, we want to decide "server_port" values.
                     *
                     * "interleaved" is not implemented.
                     */
                        b_unsupp = true;
                        break;
                    }
                }

                if( b_unsupp )
                    continue;

                if( b_multicast )
                {
                    const char *dst = id->dst;
                    if( dst == NULL )
                        continue;

                    if( psz_session == NULL )
                    {
                        /* Create a dummy session ID */
                        snprintf( psz_sesbuf, sizeof( psz_sesbuf ), "%d",
                                  rand() );
                        psz_session = psz_sesbuf;
                    }
                    answer->i_status = 200;

                    httpd_MsgAdd( answer, "Transport",
                                  "RTP/AVP/UDP;destination=%s;port=%u-%u;"
                                  "ttl=%d;mode=play",
                                  dst, id->loport, id->hiport,
                                  ( id->ttl > 0 ) ? id->ttl : 1 );
                }
                else
                {
                    char ip[NI_MAXNUMERICHOST], src[NI_MAXNUMERICHOST];
                    rtsp_session_t *ses = NULL;
                    rtsp_strack_t track = { id->sout_id, -1, false };
                    int sport;

                    if( httpd_ClientIP( cl, ip ) == NULL )
                    {
                        answer->i_status = 500;
                        continue;
                    }

                    track.fd = net_ConnectDgram( p_stream, ip, loport, -1,
                                                 IPPROTO_UDP );
                    if( track.fd == -1 )
                    {
                        msg_Err( p_stream,
                                 "cannot create RTP socket for %s port %u",
                                 ip, loport );
                        answer->i_status = 500;
                        continue;
                    }

                    net_GetSockAddress( track.fd, src, &sport );

                    vlc_mutex_lock( &rtsp->lock );
                    if( psz_session == NULL )
                    {
                        ses = RtspClientNew( rtsp );
                        snprintf( psz_sesbuf, sizeof( psz_sesbuf ), "%"PRIx64,
                                  ses->id );
                        psz_session = psz_sesbuf;
                    }
                    else
                    {
                        /* FIXME: we probably need to remove an access out,
                         * if there is already one for the same ID */
                        ses = RtspClientGet( rtsp, psz_session );
                        if( ses == NULL )
                        {
                            answer->i_status = 454;
                            vlc_mutex_unlock( &rtsp->lock );
                            continue;
                        }
                    }

                    INSERT_ELEM( ses->trackv, ses->trackc, ses->trackc,
                                 track );
                    vlc_mutex_unlock( &rtsp->lock );

                    httpd_ServerIP( cl, ip );

                    if( strcmp( src, ip ) )
                    {
                        /* Specify source IP if it is different from the RTSP
                         * control connection server address */
                        char *ptr = strchr( src, '%' );
                        if( ptr != NULL ) *ptr = '\0'; /* remove scope ID */

                        httpd_MsgAdd( answer, "Transport",
                                      "RTP/AVP/UDP;unicast;source=%s;"
                                      "client_port=%u-%u;server_port=%u-%u;"
                                      "ssrc=%08X;mode=play",
                                      src, loport, loport + 1, sport,
                                      sport + 1, id->ssrc );
                    }
                    else
                    {
                        httpd_MsgAdd( answer, "Transport",
                                      "RTP/AVP/UDP;unicast;"
                                      "client_port=%u-%u;server_port=%u-%u;"
                                      "ssrc=%08X;mode=play",
                                      loport, loport + 1, sport, sport + 1,
                                      id->ssrc );
                    }

                    answer->i_status = 200;
                }
                break;
            }
            break;

        case HTTPD_MSG_PLAY:
        {
            rtsp_session_t *ses;
            answer->i_status = 200;

            psz_session = httpd_MsgGet( query, "Session" );
            const char *range = httpd_MsgGet (query, "Range");
            if (range && strncmp (range, "npt=", 4))
            {
                answer->i_status = 501;
                break;
            }

            vlc_mutex_lock( &rtsp->lock );
            ses = RtspClientGet( rtsp, psz_session );
            if( ses != NULL )
            {
                /* FIXME: we really need to limit the number of tracks... */
                char info[ses->trackc * ( strlen( control )
                              + sizeof("url=/trackID=123;seq=65535, ") ) + 1];
                size_t infolen = 0;

                for( int i = 0; i < ses->trackc; i++ )
                {
                    rtsp_strack_t *tr = ses->trackv + i;
                    if( ( id == NULL ) || ( tr->id == id->sout_id ) )
                    {
                        if( !tr->playing )
                        {
                            tr->playing = true;
                            rtp_add_sink( tr->id, tr->fd, false );
                        }
                        infolen += sprintf( info + infolen,
                                            "url=%s/trackID=%u;seq=%u, ",
                                            control,
                                            rtp_get_num( tr->id ),
                                            rtp_get_seq( tr->id ) );
                    }
                }
                if( infolen > 0 )
                {
                    info[infolen - 2] = '\0'; /* remove trailing ", " */
                    httpd_MsgAdd( answer, "RTP-Info", "%s", info );
                }
            }
            vlc_mutex_unlock( &rtsp->lock );

            if( httpd_MsgGet( query, "Scale" ) != NULL )
                httpd_MsgAdd( answer, "Scale", "1." );
            break;
        }

        case HTTPD_MSG_PAUSE:
            answer->i_status = 405;
            httpd_MsgAdd( answer, "Allow",
                          "%s, TEARDOWN, PLAY, GET_PARAMETER",
                          ( id != NULL ) ? "SETUP" : "DESCRIBE" );
            break;

        case HTTPD_MSG_GETPARAMETER:
            if( query->i_body > 0 )
            {
                answer->i_status = 451;
                break;
            }

            psz_session = httpd_MsgGet( query, "Session" );
            answer->i_status = 200;
            break;

        case HTTPD_MSG_TEARDOWN:
        {
            rtsp_session_t *ses;

            answer->i_status = 200;

            psz_session = httpd_MsgGet( query, "Session" );

            vlc_mutex_lock( &rtsp->lock );
            ses = RtspClientGet( rtsp, psz_session );
            if( ses != NULL )
            {
                if( id == NULL ) /* Delete the entire session */
                    RtspClientDel( rtsp, ses );
                else /* Delete one track from the session */
                for( int i = 0; i < ses->trackc; i++ )
                {
                    if( ses->trackv[i].id == id->sout_id )
                    {
                        rtp_del_sink( id->sout_id, ses->trackv[i].fd );
                        REMOVE_ELEM( ses->trackv, ses->trackc, i );
                    }
                }
            }
            vlc_mutex_unlock( &rtsp->lock );
            break;
        }

        default:
            return VLC_EGENERIC;
    }

    if( psz_session )
        httpd_MsgAdd( answer, "Session", "%s"/*;timeout=5*/, psz_session );

    httpd_MsgAdd( answer, "Content-Length", "%d", answer->i_body );
    httpd_MsgAdd( answer, "Cache-Control", "no-cache" );

    psz = httpd_MsgGet( query, "Cseq" );
    if( psz != NULL )
        httpd_MsgAdd( answer, "Cseq", "%s", psz );
    psz = httpd_MsgGet( query, "Timestamp" );
    if( psz != NULL )
        httpd_MsgAdd( answer, "Timestamp", "%s", psz );

    return VLC_SUCCESS;
}
Example #30
0
/**
 * Perform an action on a variable
 *
 * \param p_this The object that holds the variable
 * \param psz_name The name of the variable
 * \param i_action The action to perform. Must be one of \ref var_action
 * \param p_val First action parameter
 * \param p_val2 Second action parameter
 */
int var_Change( vlc_object_t *p_this, const char *psz_name,
                int i_action, vlc_value_t *p_val, vlc_value_t *p_val2 )
{
    int ret = VLC_SUCCESS;
    variable_t *p_var;
    vlc_value_t oldval;
    vlc_value_t newval;

    assert( p_this );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
        vlc_mutex_unlock( &p_priv->var_lock );
        return VLC_ENOVAR;
    }

    switch( i_action )
    {
        case VLC_VAR_SETMIN:
            if( p_var->i_type & VLC_VAR_HASMIN )
            {
                p_var->ops->pf_free( &p_var->min );
            }
            p_var->i_type |= VLC_VAR_HASMIN;
            p_var->min = *p_val;
            p_var->ops->pf_dup( &p_var->min );
            CheckValue( p_var, &p_var->val );
            break;
        case VLC_VAR_GETMIN:
            if( p_var->i_type & VLC_VAR_HASMIN )
                *p_val = p_var->min;
            else
                ret = VLC_EGENERIC;
            break;
        case VLC_VAR_SETMAX:
            if( p_var->i_type & VLC_VAR_HASMAX )
            {
                p_var->ops->pf_free( &p_var->max );
            }
            p_var->i_type |= VLC_VAR_HASMAX;
            p_var->max = *p_val;
            p_var->ops->pf_dup( &p_var->max );
            CheckValue( p_var, &p_var->val );
            break;
        case VLC_VAR_GETMAX:
            if( p_var->i_type & VLC_VAR_HASMAX )
                *p_val = p_var->max;
            else
                ret = VLC_EGENERIC;
            break;
        case VLC_VAR_SETSTEP:
            if( p_var->i_type & VLC_VAR_HASSTEP )
            {
                p_var->ops->pf_free( &p_var->step );
            }
            p_var->i_type |= VLC_VAR_HASSTEP;
            p_var->step = *p_val;
            p_var->ops->pf_dup( &p_var->step );
            CheckValue( p_var, &p_var->val );
            break;
        case VLC_VAR_GETSTEP:
            if( p_var->i_type & VLC_VAR_HASSTEP )
                *p_val = p_var->step;
            else
                ret = VLC_EGENERIC;
            break;
        case VLC_VAR_ADDCHOICE:
        {
            int i = p_var->choices.i_count;

            INSERT_ELEM( p_var->choices.p_values, p_var->choices.i_count,
                         i, *p_val );
            INSERT_ELEM( p_var->choices_text.p_values,
                         p_var->choices_text.i_count, i, *p_val );
            p_var->ops->pf_dup( &p_var->choices.p_values[i] );
            p_var->choices_text.p_values[i].psz_string =
                ( p_val2 && p_val2->psz_string ) ?
                strdup( p_val2->psz_string ) : NULL;

            CheckValue( p_var, &p_var->val );

            TriggerListCallback(p_this, p_var, psz_name, VLC_VAR_ADDCHOICE, p_val);
            break;
        }
        case VLC_VAR_DELCHOICE:
        {
            int i;

            for( i = 0 ; i < p_var->choices.i_count ; i++ )
                if( p_var->ops->pf_cmp( p_var->choices.p_values[i], *p_val ) == 0 )
                    break;

            if( i == p_var->choices.i_count )
            {
                /* Not found */
                vlc_mutex_unlock( &p_priv->var_lock );
                return VLC_EGENERIC;
            }

            if( p_var->i_default > i )
                p_var->i_default--;
            else if( p_var->i_default == i )
                p_var->i_default = -1;

            p_var->ops->pf_free( &p_var->choices.p_values[i] );
            free( p_var->choices_text.p_values[i].psz_string );
            REMOVE_ELEM( p_var->choices.p_values, p_var->choices.i_count, i );
            REMOVE_ELEM( p_var->choices_text.p_values,
                         p_var->choices_text.i_count, i );

            CheckValue( p_var, &p_var->val );

            TriggerListCallback(p_this, p_var, psz_name, VLC_VAR_DELCHOICE, p_val);
            break;
        }
        case VLC_VAR_CHOICESCOUNT:
            p_val->i_int = p_var->choices.i_count;
            break;
        case VLC_VAR_CLEARCHOICES:
            for( int i = 0 ; i < p_var->choices.i_count ; i++ )
                p_var->ops->pf_free( &p_var->choices.p_values[i] );
            for( int i = 0 ; i < p_var->choices_text.i_count ; i++ )
                free( p_var->choices_text.p_values[i].psz_string );

            if( p_var->choices.i_count ) free( p_var->choices.p_values );
            if( p_var->choices_text.i_count ) free( p_var->choices_text.p_values );

            p_var->choices.i_count = 0;
            p_var->choices.p_values = NULL;
            p_var->choices_text.i_count = 0;
            p_var->choices_text.p_values = NULL;
            p_var->i_default = -1;
            TriggerListCallback(p_this, p_var, psz_name, VLC_VAR_CLEARCHOICES, NULL);
            break;
        case VLC_VAR_SETDEFAULT:
        {
            int i;
            /* FIXME: the list is sorted, dude. Use something cleverer. */
            for( i = 0 ; i < p_var->choices.i_count ; i++ )
                if( p_var->ops->pf_cmp( p_var->choices.p_values[i], *p_val ) == 0 )
                    break;

            if( i == p_var->choices.i_count )
                /* Not found */
                break;

            p_var->i_default = i;
            CheckValue( p_var, &p_var->val );
            break;
        }
        case VLC_VAR_SETVALUE:
            /* Duplicate data if needed */
            newval = *p_val;
            p_var->ops->pf_dup( &newval );
            /* Backup needed stuff */
            oldval = p_var->val;
            /* Check boundaries and list */
            CheckValue( p_var, &newval );
            /* Set the variable */
            p_var->val = newval;
            /* Free data if needed */
            p_var->ops->pf_free( &oldval );
            break;
        case VLC_VAR_GETCHOICES:
            p_val->p_list = xmalloc( sizeof(vlc_list_t) );
            p_val->p_list->p_values =
                xmalloc( p_var->choices.i_count * sizeof(vlc_value_t) );
            p_val->p_list->i_type = p_var->i_type;
            p_val->p_list->i_count = p_var->choices.i_count;
            if( p_val2 )
            {
                p_val2->p_list = xmalloc( sizeof(vlc_list_t) );
                p_val2->p_list->p_values =
                    xmalloc( p_var->choices.i_count * sizeof(vlc_value_t) );
                p_val2->p_list->i_type = VLC_VAR_STRING;
                p_val2->p_list->i_count = p_var->choices.i_count;
            }
            for( int i = 0 ; i < p_var->choices.i_count ; i++ )
            {
                p_val->p_list->p_values[i] = p_var->choices.p_values[i];
                p_var->ops->pf_dup( &p_val->p_list->p_values[i] );
                if( p_val2 )
                {
                    p_val2->p_list->p_values[i].psz_string =
                        p_var->choices_text.p_values[i].psz_string ?
                    strdup(p_var->choices_text.p_values[i].psz_string) : NULL;
                }
            }
            break;
        case VLC_VAR_SETTEXT:
            free( p_var->psz_text );
            if( p_val && p_val->psz_string )
                p_var->psz_text = strdup( p_val->psz_string );
            else
                p_var->psz_text = NULL;
            break;
        case VLC_VAR_GETTEXT:
            p_val->psz_string = p_var->psz_text ? strdup( p_var->psz_text )
                                                : NULL;
            break;
        default:
            break;
    }

    vlc_mutex_unlock( &p_priv->var_lock );

    return ret;
}