/*****************************************************************************
* MediaList.java
*****************************************************************************
* Copyright © 2015 VLC authors, VideoLAN and VideoLabs
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
package org.videolan.libvlc;
import android.util.SparseArray;
@SuppressWarnings("unused")
public class MediaList extends VLCObject<MediaList.Event> {
private final static String TAG = "LibVLC/MediaList";
public static class Event extends VLCEvent {
public static final int ItemAdded = 0x200;
//public static final int WillAddItem = 0x201;
public static final int ItemDeleted = 0x202;
//public static final int WillDeleteItem = 0x203;
public static final int EndReached = 0x204;
/**
* The media can be already released. If it's released, cached attributes are still
* available (like media.getMrl()).
* You should call {@link Media#retain()} and check the return value
* before calling media native methods.
*/
public final Media media;
public final int index;
protected Event(int type, Media media, int index) {
super(type);
this.media = media;
this.index = index;
}
}
public interface EventListener extends VLCEvent.Listener<MediaList.Event> {}
private int mCount = 0;
private final SparseArray<Media> mMediaArray = new SparseArray<Media>();
private boolean mLocked = false;
private void init() {
lock();
mCount = nativeGetCount();
for (int i = 0; i < mCount; ++i)
mMediaArray.put(i, new Media(this, i));
unlock();
}
/**
* Create a MediaList from libVLC
* @param libVLC a valid libVLC
*/
public MediaList(LibVLC libVLC) {
nativeNewFromLibVlc(libVLC);
init();
}
/**
*
* @param md Should not be released
*/
protected MediaList(MediaDiscoverer md) {
nativeNewFromMediaDiscoverer(md);
init();
}
/**
*
* @param m Should not be released
*/
protected MediaList(Media m) {
nativeNewFromMedia(m);
init();
}
private synchronized Media insertMediaFromEvent(int index) {
mCount++;
for (int i = mCount - 1; i >= index; --i)
mMediaArray.put(i + 1, mMediaArray.valueAt(i));
final Media media = new Media(this, index);
mMediaArray.put(index, media);
return media;
}
private synchronized Media removeMediaFromEvent(int index) {
mCount--;
final Media media = mMediaArray.get(index);
if (media != null)
media.release();
for (int i = index; i < mCount; ++i) {
mMediaArray.put(i, mMediaArray.valueAt(i + 1));
}
return media;
}
public void setEventListener(EventListener listener) {
super.setEventListener(listener);
}
@Override
protected synchronized Event onEventNative(int eventType, long arg1, float arg2) {
if (mLocked)
throw new IllegalStateException("already locked from event callback");
mLocked = true;
Event event = null;
int index;
switch (eventType) {
case Event.ItemAdded:
index = (int) arg1;
if (index != -1) {
final Media media = insertMediaFromEvent(index);
event = new Event(eventType, media, index);
}
break;
case Event.ItemDeleted:
index = (int) arg1;
if (index != -1) {
final Media media = removeMediaFromEvent(index);
event = new Event(eventType, media, index);
}
break;
case Event.EndReached:
event = new Event(eventType, null, -1);
break;
}
mLocked = false;
return event;
}
/**
* Get the number of Media.
*/
public synchronized int getCount() {
return mCount;
}
/**
* Get a Media at specified index.
*
* @param index index of the media
* @return Media hold by MediaList. This Media should be released with {@link #release()}.
*/
public synchronized Media getMediaAt(int index) {
if (index < 0 || index >= getCount())
throw new IndexOutOfBoundsException();
final Media media = mMediaArray.get(index);
media.retain();
return media;
}
@Override
public void onReleaseNative() {
for (int i = 0; i < mMediaArray.size(); ++i) {
final Media media = mMediaArray.get(i);
if (media != null)
media.release();
}
nativeRelease();
}
private synchronized void lock() {
if (mLocked)
throw new IllegalStateException("already locked");
mLocked = true;
nativeLock();
}
private synchronized void unlock() {
if (!mLocked)
throw new IllegalStateException("not locked");
mLocked = false;
nativeUnlock();
}
protected synchronized boolean isLocked() {
return mLocked;
}
/* JNI */
private native void nativeNewFromLibVlc(LibVLC libvlc);
private native void nativeNewFromMediaDiscoverer(MediaDiscoverer md);
private native void nativeNewFromMedia(Media m);
private native void nativeRelease();
private native int nativeGetCount();
private native void nativeLock();
private native void nativeUnlock();
}