// Starting at "start_addr" (inclusive) return a memory region
// corresponding to the first maximal contiguous marked ("1") region
// strictly less than end_addr.
inline MemRegion CMSBitMap::getAndClearMarkedRegion(HeapWord* start_addr,
                                                    HeapWord* end_addr) {
  HeapWord *start, *end;
  assert_locked();
  start = getNextMarkedWordAddress  (start_addr, end_addr);
  end   = getNextUnmarkedWordAddress(start,      end_addr);
  assert(start <= end, "Consistency check");
  MemRegion mr(start, end);
  if (!mr.is_empty()) {
    clear_range(mr);
  }
  return mr;
}
// Return the HeapWord address corrsponding to the next "0" bit
// (inclusive).
inline HeapWord* CMSBitMap::getNextUnmarkedWordAddress(
    HeapWord* start_addr, HeapWord* end_addr) const {
    assert_locked();
    size_t nextOffset = _bm.get_next_zero_offset(
                            heapWordToOffset(start_addr),
                            heapWordToOffset(end_addr));
    HeapWord* nextAddr = offsetToHeapWord(nextOffset);
    assert(nextAddr >= start_addr &&
           nextAddr <= end_addr, "get_next_zero postcondition");
    assert((nextAddr == end_addr) ||
           isUnmarked(nextAddr), "get_next_zero postcondition");
    return nextAddr;
}
Пример #3
0
/**************************************************************************
 *       Stop (Private)
 *
 * Lock must be held.
 **************************************************************************/
static void stop(libvlc_media_list_player_t * p_mlp, libvlc_exception_t * p_e)
{
    assert_locked(p_mlp);

    if (p_mlp->p_mi && p_mlp->current_playing_item_path)
    {
        /* We are not interested in getting media stop event now */
        uninstall_media_player_observer(p_mlp);
        libvlc_media_player_stop(p_mlp->p_mi, p_e);
        install_media_player_observer(p_mlp);
    }

    free(p_mlp->current_playing_item_path);
    p_mlp->current_playing_item_path = NULL;
}
Пример #4
0
/**************************************************************************
 *       uninstall_media_player_observer (private)
 **************************************************************************/
static void
uninstall_media_player_observer(libvlc_media_list_player_t * p_mlp)
{
    assert_locked(p_mlp);

    // Allow callbacks to run, because detach() will wait until all callbacks are processed.
    // This is safe because only callbacks are allowed, and there execution will be cancelled.
    vlc_mutex_unlock(&p_mlp->mp_callback_lock);
    libvlc_event_detach(mplayer_em(p_mlp), libvlc_MediaPlayerEndReached, media_player_reached_end, p_mlp);

    // Now, lock back the callback lock. No more callback will be present from this point.
    vlc_mutex_lock(&p_mlp->mp_callback_lock);

    // What is here is safe, because we guarantee that we won't be able to anything concurrently,
    // - except (cancelled) callbacks - thanks to the object_lock.
}
Пример #5
0
/**************************************************************************
 *       Stop (Private)
 *
 * Lock must be held.
 **************************************************************************/
static void stop(libvlc_media_list_player_t * p_mlp)
{
    assert_locked(p_mlp);

    /* We are not interested in getting media stop event now */
    uninstall_media_player_observer(p_mlp);
    libvlc_media_player_stop(p_mlp->p_mi);
    install_media_player_observer(p_mlp);

    free(p_mlp->current_playing_item_path);
    p_mlp->current_playing_item_path = NULL;

    /* Send the event */
    libvlc_event_t event;
    event.type = libvlc_MediaListPlayerStopped;
    libvlc_event_send(&p_mlp->event_manager, &event);
}
Пример #6
0
/**************************************************************************
 *       Set relative playlist position and play (Private)
 *
 * Sets the currently played item to the given relative play item position 
 * (based on the currently playing item) and then begins the new item playback.
 * Lock must be held.  
 **************************************************************************/
static void set_relative_playlist_position_and_play(
                                      libvlc_media_list_player_t * p_mlp, 
                                      int i_relative_position, 
                                      libvlc_exception_t * p_e)
{
    assert_locked(p_mlp);

    if (!p_mlp->p_mlist)
    {
        libvlc_exception_raise(p_e);
        libvlc_printerr("No media list");
        return;
    }

    libvlc_media_list_lock(p_mlp->p_mlist);

    libvlc_media_list_path_t path = p_mlp->current_playing_item_path;

    if(p_mlp->e_playback_mode != libvlc_playback_mode_repeat)
    {
        bool b_loop = (p_mlp->e_playback_mode == libvlc_playback_mode_loop);
        
        if(i_relative_position > 0)
        {
            do
            {
                path = get_next_path(p_mlp, b_loop);
                set_current_playing_item(p_mlp, path);
                --i_relative_position;
            }
            while(i_relative_position > 0);
        }
        else if(i_relative_position < 0)
        {
            do 
            {
                path = get_previous_path(p_mlp, b_loop);
                set_current_playing_item(p_mlp, path);
                ++i_relative_position;
            } 
            while (i_relative_position < 0);
        }
    }
    else
    {
        set_current_playing_item(p_mlp, path);
    }

#ifdef DEBUG_MEDIA_LIST_PLAYER
    printf("Playing:");
    libvlc_media_list_path_dump(path);
#endif

    if (!path)
    {
        libvlc_media_list_unlock(p_mlp->p_mlist);
        stop(p_mlp, p_e);
        return;
    }

    libvlc_media_player_play(p_mlp->p_mi, p_e);

    libvlc_media_list_unlock(p_mlp->p_mlist);

    /* Send the next item event */
    libvlc_event_t event;
    event.type = libvlc_MediaListPlayerNextItemSet;
    libvlc_media_t * p_md = libvlc_media_list_item_at_path(p_mlp->p_mlist, path);
    event.u.media_list_player_next_item_set.item = p_md;
    libvlc_event_send(p_mlp->p_event_manager, &event);
    libvlc_media_release(p_md);
}
inline bool CMSBitMap::isUnmarked(HeapWord* addr) const {
  assert_locked();
  assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
         "outside underlying space?");
  return !_bm.at(heapWordToOffset(addr));
}
Пример #8
0
/**************************************************************************
 * install_media_player_observer (private)
 **************************************************************************/
static void
install_media_player_observer(libvlc_media_list_player_t * p_mlp)
{
    assert_locked(p_mlp);
    libvlc_event_attach_async(mplayer_em(p_mlp), libvlc_MediaPlayerEndReached, media_player_reached_end, p_mlp, NULL);
}
Пример #9
0
/**************************************************************************
 * install_playlist_observer (private)
 **************************************************************************/
static void
install_playlist_observer(libvlc_media_list_player_t * p_mlp)
{
    assert_locked(p_mlp);
    libvlc_event_attach(mlist_em(p_mlp), libvlc_MediaListItemDeleted, mlist_item_deleted, p_mlp, NULL);
}
Пример #10
0
/**************************************************************************
 *       get_previous_path (private)
 *
 *  Returns the path to the preceding item in the list.  
 *  If looping is specified and the current item is the first list item in
 *  the list it will return the last descendant of the last item in the list.
 **************************************************************************/
static libvlc_media_list_path_t
get_previous_path(libvlc_media_list_player_t * p_mlp, bool b_loop)
{
    assert_locked(p_mlp);

    /* We are entered with libvlc_media_list_lock(p_mlp->p_list) */
    libvlc_media_list_path_t ret;
    libvlc_media_list_t * p_parent_of_playing_item;

    if (!p_mlp->current_playing_item_path)
    {
        if (!libvlc_media_list_count(p_mlp->p_mlist, NULL))
            return NULL;
        return libvlc_media_list_path_with_root_index(0);
    }
    
    /* Try to catch parent element */
    p_parent_of_playing_item = libvlc_media_list_parentlist_at_path(
                                            p_mlp->p_mlist,
                                            p_mlp->current_playing_item_path);

    int depth = libvlc_media_list_path_depth(p_mlp->current_playing_item_path);
    if (depth < 1 || !p_parent_of_playing_item)
        return NULL;

    /* Set the return path to the current path */
    ret = libvlc_media_list_path_copy(p_mlp->current_playing_item_path);

    /* Change the return path to the previous list entry */
    ret[depth - 1]--; /* set to previous element */
    ret[depth] = -1;

    /* Is the return path is beyond the start of the current list? */
    if(ret[depth - 1] < 0)
    {
        /* Move to parent of current item */
        depth--;

        /* Are we at the root level of the tree? */
        if (depth <= 0)
        {
            // Is looping enabled?
            if(b_loop)
            {
                int i_count = libvlc_media_list_count(p_parent_of_playing_item, NULL);

                /* Set current play item to the last element in the list */
                ret[0] = i_count - 1;
                ret[1] = -1;

                /* Set the return path to the last descendant item of the current item */
                ret = find_last_item(p_mlp->p_mlist, ret);
            }
            else
            {
                /* No looping so return empty path. */
                free(ret);
                ret = NULL;
            }
        }
        else
        {
            /* This is the case of moving backward from the beginning of the
            *  subitem list to its parent item.
            *  This ensures that current path is properly terminated to
            *  use that parent.
            */
            ret[depth] = -1;
        }
    }
    else
    {
        ret = find_last_item(p_mlp->p_mlist, ret);
    }

    libvlc_media_list_release(p_parent_of_playing_item);
    return ret;
}
Пример #11
0
/**************************************************************************
 *       get_next_path (private)
 *
 *  Returns the path to the next item in the list.  
 *  If looping is specified and the current item is the last list item in
 *  the list it will return the first item in the list.
 **************************************************************************/
static libvlc_media_list_path_t
get_next_path(libvlc_media_list_player_t * p_mlp, bool b_loop)
{
    assert_locked(p_mlp);

    /* We are entered with libvlc_media_list_lock(p_mlp->p_list) */
    libvlc_media_list_path_t ret;
    libvlc_media_list_t * p_parent_of_playing_item;
    libvlc_media_list_t * p_sublist_of_playing_item;

    if (!p_mlp->current_playing_item_path)
    {
        if (!libvlc_media_list_count(p_mlp->p_mlist, NULL))
            return NULL;
        return libvlc_media_list_path_with_root_index(0);
    }
    
    p_sublist_of_playing_item = libvlc_media_list_sublist_at_path(
                            p_mlp->p_mlist,
                            p_mlp->current_playing_item_path);
 
    /* If item just gained a sublist just play it */
    if (p_sublist_of_playing_item)
    {
        libvlc_media_list_release(p_sublist_of_playing_item);
        return libvlc_media_list_path_copy_by_appending(p_mlp->current_playing_item_path, 0);
    }

    /* Try to catch parent element */
    p_parent_of_playing_item = libvlc_media_list_parentlist_at_path(p_mlp->p_mlist,
                            p_mlp->current_playing_item_path);

    int depth = libvlc_media_list_path_depth(p_mlp->current_playing_item_path);
    if (depth < 1 || !p_parent_of_playing_item)
        return NULL;

    ret = libvlc_media_list_path_copy(p_mlp->current_playing_item_path);
    ret[depth - 1]++; /* set to next element */

    /* If this goes beyond the end of the list */
    while(ret[depth-1] >= libvlc_media_list_count(p_parent_of_playing_item, NULL))
    {
        depth--;
        if (depth <= 0)
        {
            if(b_loop)
            {
                ret[0] = 0;
                ret[1] = -1;
                break;
            }
            else
            {
                free(ret);
                libvlc_media_list_release(p_parent_of_playing_item);
                return NULL;
            }
        }
        ret[depth] = -1;
        ret[depth-1]++;
        p_parent_of_playing_item  = libvlc_media_list_parentlist_at_path(
                                        p_mlp->p_mlist,
                                        ret);
    }

    libvlc_media_list_release(p_parent_of_playing_item);
    return ret;
}
Пример #12
0
static inline libvlc_event_manager_t * mplayer_em(libvlc_media_list_player_t * p_mlp)
{
    assert_locked(p_mlp);
    return libvlc_media_player_event_manager(p_mlp->p_mi, NULL);
}
Пример #13
0
 static void assert_locked(const Mutex* lock) {
     assert_locked(lock, NULL);
 }
inline void CMSBitMap::par_clear(HeapWord* addr) {
  assert_locked();
  assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
         "outside underlying space?");
  _bm.par_at_put(heapWordToOffset(addr), false);
}
inline bool CMSBitMap::par_mark(HeapWord* addr) {
  assert_locked();
  assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
         "outside underlying space?");
  return _bm.par_at_put(heapWordToOffset(addr), true);
}
inline void CMSBitMap::mark(HeapWord* addr) {
  assert_locked();
  assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
         "outside underlying space?");
  _bm.set_bit(heapWordToOffset(addr));
}
inline void CMSBitMap::clear_all() {
  assert_locked();
  // CMS bitmaps are usually cover large memory regions
  _bm.clear_large();
  return;
}
inline bool CMSBitMap::isAllClear() const {
  assert_locked();
  return getNextMarkedWordAddress(startWord()) >= endWord();
}