Methods Summary |
---|
private synchronized void | actionEntry(com.android.mms.dom.smil.SmilPlayer$TimelineEntry entry)
switch (entry.getAction()) {
case TimelineEntry.ACTION_BEGIN:
if (LOCAL_LOGV) {
Log.v(TAG, "[START] " + " at " + mCurrentTime + " "
+ entry.getElement());
}
entry.getElement().beginElement();
mActiveElements.add(entry.getElement());
break;
case TimelineEntry.ACTION_END:
if (LOCAL_LOGV) {
Log.v(TAG, "[STOP] " + " at " + mCurrentTime + " "
+ entry.getElement());
}
entry.getElement().endElement();
mActiveElements.remove(entry.getElement());
break;
default:
break;
}
|
private synchronized void | actionPause()
pauseActiveElements();
mState = SmilPlayerState.PAUSED;
mAction = SmilPlayerAction.NO_ACTIVE_ACTION;
|
private synchronized void | actionReload()
reloadActiveSlide();
mAction = SmilPlayerAction.NO_ACTIVE_ACTION;
|
private synchronized void | actionStop()
endActiveElements();
mCurrentTime = 0;
mCurrentElement = 0;
mCurrentSlide = 0;
mState = SmilPlayerState.STOPPED;
mAction = SmilPlayerAction.NO_ACTIVE_ACTION;
|
private synchronized void | beginSmilDocument()
TimelineEntry entry = mAllEntries.get(0);
actionEntry(entry);
|
private synchronized void | endActiveElements()
for (int i = mActiveElements.size() - 1; i >= 0; i--) {
ElementTime element = mActiveElements.get(i);
if (LOCAL_LOGV) {
Log.v(TAG, "[STOP] " + " at " + mCurrentTime
+ " " + element);
}
element.endElement();
}
|
public synchronized int | getCurrentPosition()
return (int) mCurrentTime;
|
public synchronized int | getDuration()
if ((mAllEntries != null) && !mAllEntries.isEmpty()) {
return (int) mAllEntries.get(mAllEntries.size() - 1).mOffsetTime * 1000;
}
return 0;
|
private synchronized double | getOffsetTime(org.w3c.dom.smil.ElementTime element)
for (int i = mCurrentSlide; i < mCurrentElement; i++) {
TimelineEntry entry = mAllEntries.get(i);
if (element.equals(entry.getElement())) {
return entry.getOffsetTime() * 1000; // in ms
}
}
return -1;
|
private static java.util.ArrayList | getParTimeline(org.w3c.dom.smil.ElementParallelTimeContainer par, double offset, double maxOffset)
ArrayList<TimelineEntry> timeline = new ArrayList<TimelineEntry>();
// Set my begin at first
TimeList myBeginList = par.getBegin();
/*
* Begin list only contain 1 begin time which has been resolved.
* @see com.android.mms.dom.smil.ElementParallelTimeContainerImpl#getBegin()
*/
Time begin = myBeginList.item(0);
double beginOffset = begin.getResolvedOffset() + offset;
if (beginOffset > maxOffset) {
// This element can't be started.
return timeline;
}
TimelineEntry myBegin = new TimelineEntry(beginOffset, par, TimelineEntry.ACTION_BEGIN);
timeline.add(myBegin);
TimeList myEndList = par.getEnd();
/*
* End list only contain 1 end time which has been resolved.
* @see com.android.mms.dom.smil.ElementParallelTimeContainerImpl#getEnd()
*/
Time end = myEndList.item(0);
double endOffset = end.getResolvedOffset() + offset;
if (endOffset > maxOffset) {
endOffset = maxOffset;
}
TimelineEntry myEnd = new TimelineEntry(endOffset, par, TimelineEntry.ACTION_END);
maxOffset = endOffset;
NodeList children = par.getTimeChildren();
for (int i = 0; i < children.getLength(); ++i) {
ElementTime child = (ElementTime) children.item(i);
ArrayList<TimelineEntry> childTimeline = getTimeline(child, offset, maxOffset);
timeline.addAll(childTimeline);
}
Collections.sort(timeline, sTimelineEntryComparator);
// Add end-event to timeline for all active children
NodeList activeChildrenAtEnd = par.getActiveChildrenAt(
(float) (endOffset - offset) * 1000);
for (int i = 0; i < activeChildrenAtEnd.getLength(); ++i) {
timeline.add(new TimelineEntry(endOffset,
(ElementTime) activeChildrenAtEnd.item(i),
TimelineEntry.ACTION_END));
}
// Set my end at last
timeline.add(myEnd);
return timeline;
|
public static com.android.mms.dom.smil.SmilPlayer | getPlayer()
if (sPlayer == null) {
sPlayer = new SmilPlayer();
}
return sPlayer;
|
private static java.util.ArrayList | getSeqTimeline(org.w3c.dom.smil.ElementSequentialTimeContainer seq, double offset, double maxOffset)
ArrayList<TimelineEntry> timeline = new ArrayList<TimelineEntry>();
double orgOffset = offset;
// Set my begin at first
TimeList myBeginList = seq.getBegin();
/*
* Begin list only contain 1 begin time which has been resolved.
* @see com.android.mms.dom.smil.ElementSequentialTimeContainerImpl#getBegin()
*/
Time begin = myBeginList.item(0);
double beginOffset = begin.getResolvedOffset() + offset;
if (beginOffset > maxOffset) {
// This element can't be started.
return timeline;
}
TimelineEntry myBegin = new TimelineEntry(beginOffset, seq, TimelineEntry.ACTION_BEGIN);
timeline.add(myBegin);
TimeList myEndList = seq.getEnd();
/*
* End list only contain 1 end time which has been resolved.
* @see com.android.mms.dom.smil.ElementSequentialTimeContainerImpl#getEnd()
*/
Time end = myEndList.item(0);
double endOffset = end.getResolvedOffset() + offset;
if (endOffset > maxOffset) {
endOffset = maxOffset;
}
TimelineEntry myEnd = new TimelineEntry(endOffset, seq, TimelineEntry.ACTION_END);
maxOffset = endOffset;
// Get children's timelines
NodeList children = seq.getTimeChildren();
for (int i = 0; i < children.getLength(); ++i) {
ElementTime child = (ElementTime) children.item(i);
ArrayList<TimelineEntry> childTimeline = getTimeline(child, offset, maxOffset);
timeline.addAll(childTimeline);
// Since the child timeline has been sorted, the offset of the last one is the biggest.
offset = childTimeline.get(childTimeline.size() - 1).getOffsetTime();
}
// Add end-event to timeline for all active children
NodeList activeChildrenAtEnd = seq.getActiveChildrenAt(
(float) (endOffset - orgOffset));
for (int i = 0; i < activeChildrenAtEnd.getLength(); ++i) {
timeline.add(new TimelineEntry(endOffset,
(ElementTime) activeChildrenAtEnd.item(i),
TimelineEntry.ACTION_END));
}
// Set my end at last
timeline.add(myEnd);
return timeline;
|
private static java.util.ArrayList | getTimeline(org.w3c.dom.smil.ElementTime element, double offset, double maxOffset)
if (element instanceof ElementParallelTimeContainer) {
return getParTimeline((ElementParallelTimeContainer) element, offset, maxOffset);
} else if (element instanceof ElementSequentialTimeContainer) {
return getSeqTimeline((ElementSequentialTimeContainer) element, offset, maxOffset);
} else {
// Not ElementTimeContainer here
ArrayList<TimelineEntry> timeline = new ArrayList<TimelineEntry>();
TimeList beginList = element.getBegin();
for (int i = 0; i < beginList.getLength(); ++i) {
Time begin = beginList.item(i);
if (begin.getResolved()) {
double beginOffset = begin.getResolvedOffset() + offset;
if (beginOffset <= maxOffset) {
TimelineEntry entry = new TimelineEntry(beginOffset,
element, TimelineEntry.ACTION_BEGIN);
timeline.add(entry);
}
}
}
TimeList endList = element.getEnd();
for (int i = 0; i < endList.getLength(); ++i) {
Time end = endList.item(i);
if (end.getResolved()) {
double endOffset = end.getResolvedOffset() + offset;
if (endOffset <= maxOffset) {
TimelineEntry entry = new TimelineEntry(endOffset,
element, TimelineEntry.ACTION_END);
timeline.add(entry);
}
}
}
Collections.sort(timeline, sTimelineEntryComparator);
return timeline;
}
|
public synchronized void | init(org.w3c.dom.smil.ElementTime root)
mRoot = root;
mAllEntries = getTimeline(mRoot, 0, Long.MAX_VALUE);
mMediaTimeUpdatedEvent = ((DocumentEvent) mRoot).createEvent("Event");
mMediaTimeUpdatedEvent.initEvent(MEDIA_TIME_UPDATED_EVENT, false, false);
mActiveElements = new ArrayList<ElementTime>();
|
private synchronized boolean | isBeginOfSlide(com.android.mms.dom.smil.SmilPlayer$TimelineEntry entry)
return (TimelineEntry.ACTION_BEGIN == entry.getAction())
&& (entry.getElement() instanceof SmilParElementImpl);
|
private synchronized boolean | isPauseAction()
return mAction == SmilPlayerAction.PAUSE;
|
public synchronized boolean | isPausedState()
return mState == SmilPlayerState.PAUSED;
|
public synchronized boolean | isPlayedState()
return mState == SmilPlayerState.PLAYED;
|
public synchronized boolean | isPlayingState()
return mState == SmilPlayerState.PLAYING;
|
private synchronized boolean | isReloadAction()
return mAction == SmilPlayerAction.RELOAD;
|
private synchronized boolean | isStartAction()
return mAction == SmilPlayerAction.START;
|
private synchronized boolean | isStopAction()
return mAction == SmilPlayerAction.STOP;
|
public synchronized boolean | isStoppedState()
return mState == SmilPlayerState.STOPPED;
|
public synchronized void | pause()
if (isPlayingState()) {
mAction = SmilPlayerAction.PAUSE;
notifyAll();
} else {
Log.w(TAG, "Error State: Playback is not playing!");
}
|
private synchronized void | pauseActiveElements()
for (int i = mActiveElements.size() - 1; i >= 0; i--) {
ElementTime element = mActiveElements.get(i);
if (LOCAL_LOGV) {
Log.v(TAG, "[PAUSE] " + " at " + mCurrentTime
+ " " + element);
}
element.pauseElement();
}
|
public synchronized void | play()
if (!isPlayingState()) {
mCurrentTime = 0;
mCurrentElement = 0;
mCurrentSlide = 0;
mPlayerThread = new Thread(this);
mState = SmilPlayerState.PLAYING;
mPlayerThread.start();
} else {
Log.w(TAG, "Error State: Playback is playing!");
}
|
public synchronized void | reload()
if (isPlayingState() || isPausedState()) {
mAction = SmilPlayerAction.RELOAD;
notifyAll();
} else if (isPlayedState()) {
actionReload();
}
|
private synchronized void | reloadActiveSlide()
mActiveElements.clear();
beginSmilDocument();
for (int i = mCurrentSlide; i < mCurrentElement; i++) {
TimelineEntry entry = mAllEntries.get(i);
actionEntry(entry);
}
seekActiveMedia();
|
private synchronized com.android.mms.dom.smil.SmilPlayer$TimelineEntry | reloadCurrentEntry()
return mAllEntries.get(mCurrentElement);
|
private synchronized void | resumeActiveElements()
int size = mActiveElements.size();
for (int i = 0; i < size; i++) {
ElementTime element = mActiveElements.get(i);
if (LOCAL_LOGV) {
Log.v(TAG, "[RESUME] " + " at " + mCurrentTime
+ " " + element);
}
element.resumeElement();
}
|
public void | run()
if (isStoppedState()) {
return;
}
// Play the Element by following the timeline
int size = mAllEntries.size();
for (mCurrentElement = 0; mCurrentElement < size; mCurrentElement++) {
TimelineEntry entry = mAllEntries.get(mCurrentElement);
if (isBeginOfSlide(entry)) {
mCurrentSlide = mCurrentElement;
}
long offset = (long) (entry.getOffsetTime() * 1000); // in ms.
while (offset > mCurrentTime) {
try {
waitForEntry(offset - mCurrentTime);
} catch (InterruptedException e) {
Log.e(TAG, "Unexpected InterruptedException.", e);
}
while (isPauseAction() || isStopAction() || isReloadAction()) {
if (isPauseAction()) {
actionPause();
waitForWakeUp();
}
if (isStopAction()) {
actionStop();
return;
}
if (isReloadAction()) {
actionReload();
entry = reloadCurrentEntry();
if (isPausedState()) {
mAction = SmilPlayerAction.PAUSE;
}
}
}
}
mCurrentTime = offset;
actionEntry(entry);
}
mState = SmilPlayerState.PLAYED;
|
private synchronized void | seekActiveMedia()
for (int i = mActiveElements.size() - 1; i >= 0; i--) {
ElementTime element = mActiveElements.get(i);
if (element instanceof SmilParElementImpl) {
return;
}
double offset = getOffsetTime(element);
if ((offset >= 0) && (offset <= mCurrentTime)) {
if (LOCAL_LOGV) {
Log.v(TAG, "[SEEK] " + " at " + mCurrentTime
+ " " + element);
}
element.seekElement( (float) (mCurrentTime - offset) );
}
}
|
public synchronized void | start()
if (isPausedState()) {
resumeActiveElements();
mAction = SmilPlayerAction.START;
notifyAll();
} else if (isPlayedState()) {
play();
} else {
Log.w(TAG, "Error State: Playback can not be started!");
}
|
public synchronized void | stop()
if (isPlayingState() || isPausedState()) {
mAction = SmilPlayerAction.STOP;
notifyAll();
} else if (isPlayedState()) {
actionStop();
}
|
public synchronized void | stopWhenReload()
endActiveElements();
|
private synchronized void | waitForEntry(long interval)
if (LOCAL_LOGV) {
Log.v(TAG, "Waiting for " + interval + "ms.");
}
long overhead = 0;
while (interval > 0) {
long startAt = System.currentTimeMillis();
long sleep = Math.min(interval, TIMESLICE);
if (overhead < sleep) {
wait(sleep - overhead);
mCurrentTime += sleep;
} else {
sleep = 0;
mCurrentTime += overhead;
}
if (isStopAction() || isReloadAction() || isPauseAction()) {
return;
}
((EventTarget) mRoot).dispatchEvent(mMediaTimeUpdatedEvent);
interval -= TIMESLICE;
overhead = System.currentTimeMillis() - startAt - sleep;
}
|
private synchronized void | waitForWakeUp()
try {
while ( !(isStartAction() || isStopAction() || isReloadAction()) ) {
wait(TIMESLICE);
}
if (isStartAction()) {
mAction = SmilPlayerAction.NO_ACTIVE_ACTION;
mState = SmilPlayerState.PLAYING;
}
} catch (InterruptedException e) {
Log.e(TAG, "Unexpected InterruptedException.", e);
}
|