14 * Description: AnimationPlayer |
14 * Description: AnimationPlayer |
15 * |
15 * |
16 */ |
16 */ |
17 package com.nokia.microedition.media.animation; |
17 package com.nokia.microedition.media.animation; |
18 |
18 |
|
19 import java.io.ByteArrayInputStream; |
|
20 import java.io.ByteArrayOutputStream; |
19 import java.io.IOException; |
21 import java.io.IOException; |
20 import java.io.InputStream; |
22 import java.io.InputStream; |
|
23 import java.io.OutputStream; |
21 import java.util.Enumeration; |
24 import java.util.Enumeration; |
22 import java.util.Hashtable; |
25 import java.util.Hashtable; |
|
26 import java.util.Timer; |
|
27 import java.util.TimerTask; |
23 |
28 |
24 import javax.microedition.media.Control; |
29 import javax.microedition.media.Control; |
25 import javax.microedition.media.MediaException; |
30 import javax.microedition.media.MediaException; |
26 import javax.microedition.media.Player; |
31 import javax.microedition.media.Player; |
27 import javax.microedition.media.PlayerListener; |
32 import javax.microedition.media.PlayerListener; |
28 import javax.microedition.media.protocol.DataSource; |
33 import javax.microedition.media.protocol.DataSource; |
29 |
34 |
|
35 import org.eclipse.swt.SWT; |
30 import org.eclipse.swt.SWTException; |
36 import org.eclipse.swt.SWTException; |
31 import org.eclipse.swt.events.PaintEvent; |
37 import org.eclipse.swt.events.PaintEvent; |
32 import org.eclipse.swt.events.PaintListener; |
38 import org.eclipse.swt.events.PaintListener; |
33 import org.eclipse.swt.graphics.GC; |
39 import org.eclipse.swt.graphics.GC; |
34 import org.eclipse.swt.graphics.Image; |
40 import org.eclipse.swt.graphics.Image; |
43 import com.nokia.microedition.media.PlayerBase; |
49 import com.nokia.microedition.media.PlayerBase; |
44 import com.nokia.microedition.media.PlayerListenerImpl; |
50 import com.nokia.microedition.media.PlayerListenerImpl; |
45 import com.nokia.mj.impl.nokialcdui.LCDUIInvoker; |
51 import com.nokia.mj.impl.nokialcdui.LCDUIInvoker; |
46 import com.nokia.mj.impl.utils.Logger; |
52 import com.nokia.mj.impl.utils.Logger; |
47 |
53 |
48 public class AnimationPlayer extends PlayerBase |
54 public class AnimationPlayer extends PlayerBase implements ESWTinitializeListener |
49 { |
55 { |
50 // GIF image information, array length will be equal to the number of frames in image |
56 // GIF image information, array length will be equal to the number of frames in image |
51 protected ImageData [] iImageData; |
57 protected ImageData [] iImageData; |
52 // number of times we need to repeat the animation |
58 // number of times we need to repeat the animation |
53 // by default it's value is one |
59 // by default it's value is one |
54 private int iTotalLoopCount=1; |
60 private int iTotalLoopCount=1; |
55 // this holds all control related to this player |
61 // HashTable object which contains all control related to this player |
56 private Hashtable iControls= new Hashtable(); |
62 private Hashtable iControls= new Hashtable(); |
57 // Current frame index of the Animation file |
63 // Current frame index of the Animation file |
58 private int iFrameIndex; |
64 private int iFrameIndex; |
59 // Current Loop Count |
65 // Current Loop Count |
60 private int iCurrentLoopCount; |
66 private int iCurrentLoopCount; |
89 protected Image iImage; |
95 protected Image iImage; |
90 // Actual dimension of the image, this should be initialized while creating the player |
96 // Actual dimension of the image, this should be initialized while creating the player |
91 // as user can change the size of the image later, in that case too, getSourceheight and getSourceWidth |
97 // as user can change the size of the image later, in that case too, getSourceheight and getSourceWidth |
92 // of VideoControl should return the actual width and height of the image |
98 // of VideoControl should return the actual width and height of the image |
93 private Point iSourceDimension; |
99 private Point iSourceDimension; |
94 // Total time taken so far to playe the animation |
100 // Current dimension of the image, MIDlet developer may change the size of VideoControl |
|
101 // private Point iCurrentVideoDimension; |
|
102 // Total time taken so far to player the animation, it keeps updating as player moves |
95 private long iMediaTime; |
103 private long iMediaTime; |
96 // Time at which, player should be stopped |
104 // Time at which, player should be stopped |
97 // This will set through StopTimeControl.setTime(); |
105 // This will set through StopTimeControl.setTime(); |
98 private long iStopTime=Long.MAX_VALUE; |
106 // otherwise default time is Long.MAX_VALUE |
|
107 //private long iStopTime=Long.MAX_VALUE; |
|
108 AnimationObserver iAnimationObserver; |
99 |
109 |
100 // Display Location, of the image |
110 // Display Location, of the image |
101 // there won't be any use of this, in case of Form(customItem) |
111 // there won't be any use of this, in case of Form(customItem) |
102 private Point iDisplayLocation= new Point(0,0); |
112 private Point iDisplayLocation= new Point(0,0); |
103 |
113 // in case of Canvas(USE_DIRECT_VIDEO) , it should be invisible by default |
|
114 // this is handled in initDisplayMode function, if the mode is USE_DIRECT_VIDEO, we are |
|
115 // changing it to false |
104 private boolean iIsControlVisible=true; |
116 private boolean iIsControlVisible=true; |
|
117 // we keep the background pixel in it, used while taking the snapshot of the currentframe |
|
118 private int iBackgroundPixel=-1; |
|
119 // Total duration of the player |
|
120 private long iDuration=TIME_UNKNOWN; |
105 /** |
121 /** |
106 * |
122 * |
107 * @param ds DataSource which contains the data to be displayed |
123 * @param ds DataSource which contains the data to be displayed |
108 */ |
124 */ |
109 public AnimationPlayer(DataSource ds) |
125 public AnimationPlayer(DataSource ds) |
110 { |
126 { |
111 System.out.println("AnimationPlayer(DataSource ds) + "); |
|
112 iPlayerListenerImpl= new PlayerListenerImpl(this); |
127 iPlayerListenerImpl= new PlayerListenerImpl(this); |
113 //TODO check if we can do it in better way |
128 //TODO check if we can do it in better way |
114 // this is temporary solution |
129 // this is temporary solution |
115 // for this I have written two functions getDataSource and getInputStream function |
130 // for this I have written two functions getDataSource and getInputStream function |
116 BufferDataSource bds =(BufferDataSource)ds; |
131 BufferDataSource bds =(BufferDataSource)ds; |
127 } |
142 } |
128 catch (IOException e) |
143 catch (IOException e) |
129 { |
144 { |
130 e.printStackTrace(); |
145 e.printStackTrace(); |
131 } |
146 } |
132 //iRepeatCount=imageLoader.repeatCount; |
|
133 iSourceDimension= new Point(imageLoader.logicalScreenWidth, imageLoader.logicalScreenHeight); |
147 iSourceDimension= new Point(imageLoader.logicalScreenWidth, imageLoader.logicalScreenHeight); |
|
148 iBackgroundPixel= imageLoader.backgroundPixel; |
134 } |
149 } |
135 populateControl(); |
150 populateControl(); |
136 System.out.println("AnimationPlayer(DataSource ds) - "); |
151 |
137 } |
152 } |
138 |
153 |
139 /** |
154 /** |
140 * |
155 * |
141 * @param locator |
156 * @param locator |
142 * @throws SWTException |
157 * @throws SWTException |
143 */ |
158 */ |
144 public AnimationPlayer(String locator) throws SWTException |
159 public AnimationPlayer(String locator) throws SWTException |
145 { |
160 { |
146 System.out.println("AnimationPlayer(String locator) + "); |
|
147 iPlayerListenerImpl= new PlayerListenerImpl(this); |
161 iPlayerListenerImpl= new PlayerListenerImpl(this); |
148 ImageLoader imageLoader= new ImageLoader(); |
162 ImageLoader imageLoader= new ImageLoader(); |
149 // Following line may throw SWTException |
163 // Following line may throw SWTException |
150 iImageData=imageLoader.load(locator); |
164 iImageData=imageLoader.load(locator); |
151 //iRepeatCount=imageLoader.repeatCount; |
|
152 iSourceDimension= new Point(imageLoader.logicalScreenWidth, imageLoader.logicalScreenHeight); |
165 iSourceDimension= new Point(imageLoader.logicalScreenWidth, imageLoader.logicalScreenHeight); |
|
166 iBackgroundPixel= imageLoader.backgroundPixel; |
153 populateControl(); |
167 populateControl(); |
154 System.out.println("AnimationPlayer(String locator) - "); |
|
155 } |
168 } |
156 |
169 |
157 /** |
170 /** |
158 * Moved the player to close state and releases all resources, called from PlayerBase class |
171 * Moved the player to close state and releases all resources, called from PlayerBase class |
159 */ |
172 */ |
160 protected void doClose() |
173 protected void doClose() |
161 { |
174 { |
162 iState=CLOSED; |
175 // state is already changed in playerbase.close() method |
|
176 // changePlayerState(CLOSED); |
163 iPlayerListenerImpl.postEvent(PlayerListener.CLOSED, null); |
177 iPlayerListenerImpl.postEvent(PlayerListener.CLOSED, null); |
164 } |
178 } |
165 |
179 |
166 /** |
180 /** |
167 * Called from the PlayerBase class |
181 * Called from the PlayerBase class if the Player is in pre-fetched state |
|
182 * |
168 */ |
183 */ |
169 protected void doDeallocate() |
184 protected void doDeallocate() |
170 { |
185 { |
171 // dummy implementation |
186 //when the player is in pre-fetched state, calling this |
|
187 //function should change the state of the player to RELAIZED state |
|
188 changePlayerState(REALIZED); |
172 } |
189 } |
173 |
190 |
174 protected void doPrefetch() throws MediaException |
191 protected void doPrefetch() throws MediaException |
175 { |
192 { |
176 iState=PREFETCHED; |
193 changePlayerState(PREFETCHED); |
|
194 iDuration= getMediaTimeForFrame(getTotalNumberFrames()); |
177 } |
195 } |
178 |
196 |
179 protected void doRealize() throws MediaException |
197 protected void doRealize() throws MediaException |
180 { |
198 { |
181 iState=REALIZED; |
199 changePlayerState(REALIZED); |
182 // this is temporary solution implement it in proper way |
|
183 // initialize the iImage object with first frame |
|
184 iImage=new Image(iDisplay, iImageData[0]); |
|
185 } |
200 } |
186 |
201 |
187 /** |
202 /** |
188 * |
203 * |
189 */ |
204 */ |
190 protected void doStop() throws MediaException |
205 protected void doStop() throws MediaException |
191 { |
206 { |
192 // since after stopping the player the player state will move to pre-fetched state |
207 // since after stopping the player the player state will move to pre-fetched state |
193 iState=PREFETCHED; |
208 changePlayerState(PREFETCHED); |
194 iPlayerListenerImpl.postEvent(PlayerListener.STOPPED, new Long(iMediaTime * 10000)); |
209 iPlayerListenerImpl.postEvent(PlayerListener.STOPPED, new Long(iMediaTime * 10000)); |
195 } |
210 } |
196 |
211 |
197 /** |
212 /** |
198 * Function of InternalPlayer interface |
213 * Function of InternalPlayer interface |
265 */ |
274 */ |
266 |
275 |
267 public void start() throws MediaException |
276 public void start() throws MediaException |
268 { |
277 { |
269 final String DEBUG_STR = "AnimationPlayer::start()"; |
278 final String DEBUG_STR = "AnimationPlayer::start()"; |
270 final long inTime= System.currentTimeMillis(); |
279 final long inTime = System.currentTimeMillis(); |
271 // Logger.LOG(Logger.EJavaMMAPI, Logger.EInfo,DEBUG_STR + "++++++++"); |
280 |
272 System.out.println(DEBUG_STR + "+++"); |
|
273 prefetch(); |
281 prefetch(); |
274 // Only prefetched player may be started. If player is already started |
282 // Only prefetched player may be started. If player is already started |
275 // this method returns silently. |
283 // this method returns silently. |
276 if (getState() == PREFETCHED) |
284 if (getState() == PREFETCHED) |
277 { |
285 { |
278 initialize(); |
286 //initialize(); |
279 iState = STARTED; |
287 changePlayerState(STARTED); |
280 Thread thread = new Thread("Animation") |
288 Thread thread = new Thread("Animation") |
281 { |
289 { |
282 int loopCount = iCurrentLoopCount; |
290 int loopCount = iCurrentLoopCount; |
283 GC gc = null; |
291 GC gc = null; |
284 |
|
285 public void run() |
292 public void run() |
286 { |
293 { |
|
294 //changePlayerState(STARTED); |
287 final int noOfFrames = iImageData.length; |
295 final int noOfFrames = iImageData.length; |
288 while (iFrameIndex < noOfFrames && |
296 while (iState == STARTED) |
289 (iRepeatForeEver || (loopCount < iTotalLoopCount))&& |
|
290 (iState == STARTED)) |
|
291 { |
297 { |
292 final int delayTimeForNextFrame = iImageData[iFrameIndex].delayTime; |
298 final int delayTimeForNextFrame = iImageData[iFrameIndex].delayTime; |
293 // if stop time has become more than the media time |
299 // Since we are going to display first frame, notify all |
294 // TODO This solution may not give the accurate result, if the delay |
300 // PlayerListener that Player has started |
295 // between two frames is grater than 1 second. |
301 if (iFrameIndex == 0) |
296 // Do we need to implement the TimerTask only? |
|
297 if (iMediaTime > iStopTime) |
|
298 { |
302 { |
299 iPlayerListenerImpl.postEvent( |
303 iPlayerListenerImpl.postEvent( |
300 PlayerListener.STOPPED_AT_TIME, new Long( |
304 PlayerListener.STARTED, new Long( |
301 iMediaTime * 10000)); |
305 iMediaTime * 10000)); |
302 break; |
|
303 } |
306 } |
304 |
|
305 if (iDisplay != null) |
307 if (iDisplay != null) |
306 { |
308 { |
307 iDisplay.asyncExec(new Runnable() |
309 iDisplay.syncExec(new Runnable() |
308 { |
310 { |
309 public void run() |
311 public void run() |
310 { |
312 { |
311 System.out.println(DEBUG_STR+"asynchronous block +++"); |
|
312 // Since we are going to display first frame, notify all |
|
313 // PlayerListener that Player has started |
|
314 if (iFrameIndex == 0) |
|
315 { |
|
316 iPlayerListenerImpl.postEvent( |
|
317 PlayerListener.STARTED, new Long( |
|
318 iMediaTime * 10000)); |
|
319 } |
|
320 if (gc == null) |
313 if (gc == null) |
321 gc = new GC(iImage); |
314 gc = new GC(iImage); |
322 Image tempImage = new Image(iDisplay, |
315 Image tempImage = new Image(iDisplay,iImageData[iFrameIndex]); |
323 iImageData[iFrameIndex]); |
|
324 gc.drawImage(tempImage, 0, 0); |
316 gc.drawImage(tempImage, 0, 0); |
325 tempImage.dispose(); |
317 tempImage.dispose(); |
326 iFrameIndex = (iFrameIndex + 1) % noOfFrames; |
318 iFrameIndex = (iFrameIndex + 1) % noOfFrames; |
327 if (iControl != null) |
319 if (iControl != null) |
328 { |
320 { |
329 iControl.redraw(); |
321 iControl.redraw(); |
330 } |
322 } |
331 // update the mediaTime, as Animation |
|
332 // progress |
|
333 iMediaTime += delayTimeForNextFrame; |
323 iMediaTime += delayTimeForNextFrame; |
334 // If imageIndex becomes zero it means, all frames |
|
335 // has been displayed |
|
336 // So increase the loopCount |
|
337 if (iFrameIndex == 0) |
|
338 { |
|
339 // send the END_OF_MEDIA event to all |
|
340 // listener |
|
341 iPlayerListenerImpl.postEvent( |
|
342 PlayerListener.END_OF_MEDIA, |
|
343 new Long(iMediaTime * 10000)); |
|
344 loopCount++; |
|
345 // set iMediaTime to 0 |
|
346 iMediaTime = 0; |
|
347 } |
|
348 System.out.println(DEBUG_STR+"asynchronous block ---"); |
|
349 } |
324 } |
350 }); |
325 }); |
351 } |
326 } |
352 else |
327 else// if the initDisplayMode is not called yer |
353 { |
328 { |
354 System.out.println(DEBUG_STR+"InitDisplaymode has not been called yet"); |
|
355 if (iFrameIndex == 0) |
|
356 { |
|
357 iPlayerListenerImpl.postEvent( |
|
358 PlayerListener.STARTED, new Long( |
|
359 iMediaTime * 10000)); |
|
360 } |
|
361 // This else block will execute if the initDisplayMode hasn't been called yet |
|
362 // check if initDisplayMode has been called |
|
363 initialize(); |
|
364 iFrameIndex = (iFrameIndex + 1) % noOfFrames; |
329 iFrameIndex = (iFrameIndex + 1) % noOfFrames; |
365 iMediaTime += delayTimeForNextFrame; |
330 iMediaTime += delayTimeForNextFrame; |
366 // post EOM event |
|
367 if (iFrameIndex == 0) |
|
368 { |
|
369 // send the END_OF_MEDIA event to all |
|
370 // listener |
|
371 iPlayerListenerImpl.postEvent( |
|
372 PlayerListener.END_OF_MEDIA, new Long( |
|
373 iMediaTime * 10000)); |
|
374 loopCount++; |
|
375 // since player is again going to start from |
|
376 // the first frame |
|
377 // so media time should be set to zero |
|
378 iMediaTime = 0; |
|
379 } |
|
380 } |
331 } |
381 try |
332 try |
382 { |
333 { |
383 Thread.sleep(delayTimeForNextFrame * 10); |
334 Thread.sleep(delayTimeForNextFrame * 10); |
384 } |
335 } |
385 catch (InterruptedException e) |
336 catch (InterruptedException e) |
386 { |
337 { |
387 // TODO Auto-generated catch block |
338 // TODO Auto-generated catch block |
388 e.printStackTrace(); |
339 e.printStackTrace(); |
389 } |
340 } |
390 System.out.println(DEBUG_STR+"while lopp ---"); |
341 // post EOM event |
|
342 if (iFrameIndex == 0) |
|
343 { |
|
344 loopCount++; |
|
345 if (!(iRepeatForeEver || (loopCount < iTotalLoopCount))) |
|
346 { |
|
347 // when this loop is getting braked, we need to change the state to pre-fetched |
|
348 //TODO Player should change it's state in doStop(); |
|
349 changePlayerState(PREFETCHED); |
|
350 } |
|
351 // send the END_OF_MEDIA event to all |
|
352 // listener |
|
353 iPlayerListenerImpl.postEvent( |
|
354 PlayerListener.END_OF_MEDIA, |
|
355 new Long(iMediaTime * 10000)); |
|
356 iMediaTime = 0; |
|
357 } |
|
358 if (iAnimationObserver!=null) |
|
359 { |
|
360 iAnimationObserver.animationAdvanced(iMediaTime*10000); |
|
361 } |
391 }// end of while loop |
362 }// end of while loop |
392 iCurrentLoopCount = loopCount; |
363 iCurrentLoopCount = loopCount; |
393 // Logger.LOG(Logger.EJavaMMAPI, Logger.EInfo, DEBUG_STR |
364 // Logger.LOG(Logger.EJavaMMAPI, Logger.EInfo, DEBUG_STR |
394 System.out.println(DEBUG_STR |
365 |
395 + "Came out side the while loop " + iState |
|
396 + " iFrameIndex " + iFrameIndex + " loopCount " |
|
397 + loopCount); |
|
398 } |
366 } |
399 }; |
367 }; |
400 thread.start(); |
368 thread.start(); |
401 } |
369 } |
402 // Logger.LOG(Logger.EJavaMMAPI, Logger.EInfo,DEBUG_STR + "-"); |
370 // Logger.LOG(Logger.EJavaMMAPI, Logger.EInfo,DEBUG_STR + "-"); |
403 System.out.println(DEBUG_STR+" Total time taken:> "+(System.currentTimeMillis()-inTime)+" ---"); |
371 } |
404 } |
372 |
405 |
373 /** |
406 /** |
374 * State of the player should be changed from this function only. |
407 * This function is also being called from VideoControl class, |
375 * @param aState |
408 * since on each repaint event, control is getting disposed and created each time |
376 */ |
|
377 private synchronized void changePlayerState(int aState) |
|
378 { |
|
379 iState=aState; |
|
380 } |
|
381 /** |
|
382 * On each repaint event, control is getting disposed and created each time, |
|
383 * So we need to call each time the Control is available |
409 * @param aControl |
384 * @param aControl |
410 */ |
385 */ |
411 void addPaintListener(org.eclipse.swt.widgets.Control aControl) |
386 private void addPaintListener(org.eclipse.swt.widgets.Control aControl) |
412 { |
387 { |
413 System.out.println("AnimationPlayer::addPaintListener +++"); |
|
414 iControl=aControl; |
388 iControl=aControl; |
415 if (iControl != null) |
389 if (iControl != null) |
416 { |
390 { |
417 iDisplay.syncExec(new Runnable() |
391 iDisplay.syncExec(new Runnable() |
418 { |
392 { |
528 * |
499 * |
529 * @see PlayerBase |
500 * @see PlayerBase |
530 */ |
501 */ |
531 public long setMediaTime(long aNow) throws MediaException |
502 public long setMediaTime(long aNow) throws MediaException |
532 { |
503 { |
533 final String DEBUG_STR="AnimationPlayer::setmediaTime()"; |
|
534 long now = super.setMediaTime(aNow); |
504 long now = super.setMediaTime(aNow); |
535 int totalFrames = iImageData.length; |
505 if (iDuration == TIME_UNKNOWN) |
536 int totalTime = 0; |
506 iDuration=getMediaTimeForFrame(getTotalNumberFrames()); |
537 for (int i = 0; i < totalFrames; i++) |
507 if (now >= iDuration) |
538 { |
508 { |
539 totalTime += iImageData[i].delayTime; |
509 iFrameIndex=getTotalNumberFrames()-1; |
540 if (totalTime*10000 >= now) |
510 iMediaTime = iDuration; |
541 { |
511 } |
542 iFrameIndex=i; |
512 else |
543 break; |
513 { |
544 } |
514 iFrameIndex = findFrame(now); |
545 } |
515 iMediaTime= getMediaTimeForFrame(iFrameIndex); |
546 // we need to update the iMediaTime as well |
516 } |
547 iMediaTime=totalTime; |
517 return iMediaTime ; |
548 return totalTime * 10000; |
|
549 } |
518 } |
550 ////////////////////////////////////////////////////////////////////////////////////// |
519 ////////////////////////////////////////////////////////////////////////////////////// |
551 // Following functions are for internal use, and not exposed to MIDlet developer////// |
520 // Following functions are for internal use, and not exposed to MIDlet developer////// |
552 ///////////////////////////////////////////////////////////////////////////////////// |
521 ///////////////////////////////////////////////////////////////////////////////////// |
|
522 |
|
523 /** |
|
524 * Before calling this function check frameIndex is in range or not, from 0 to last index |
|
525 */ |
|
526 long getMediaTimeForFrame(int aFrameIndex) |
|
527 { |
|
528 long time=0; |
|
529 for (int i=0; i < aFrameIndex; i++) |
|
530 { |
|
531 time+=iImageData[i].delayTime; |
|
532 } |
|
533 return time*10000; |
|
534 } |
|
535 |
|
536 /** |
|
537 * Utility function to calculate the framNumber |
|
538 * @param aTime |
|
539 * @return |
|
540 */ |
|
541 int findFrame(long aTime) |
|
542 { |
|
543 long time=0; |
|
544 int frameIndex=0; |
|
545 if (aTime > iDuration) |
|
546 return -1; |
|
547 else if (aTime==0) |
|
548 return 0; |
|
549 int totalNoOfFrame= getTotalNumberFrames(); |
|
550 while (time *10000 < aTime && frameIndex < totalNoOfFrame) |
|
551 { |
|
552 time += iImageData[frameIndex++].delayTime; |
|
553 } |
|
554 return frameIndex; |
|
555 } |
553 /** |
556 /** |
554 * This function is responsible for creating all controls and adding it into Controls hashtable. |
557 * This function is responsible for creating all controls and adding it into Controls hashtable. |
555 */ |
558 */ |
556 private void populateControl() |
559 private void populateControl() |
557 { |
560 { |
558 // VideoControl videoControl = new VideoControl(this); |
|
559 // FramePositioningControl fpc = new FramePositioningControl(this); |
|
560 // StopTimeControl stc = new StopTimeControl(this); |
|
561 // RateControl rc = new RateControl(this); |
|
562 // there are four control provided by AnimationPlayer |
561 // there are four control provided by AnimationPlayer |
563 // adding all one by one to the controlList(iControls) |
562 // adding all one by one to the controlList(iControls) |
564 addControl(new VideoControl(this), fVideoControl); |
563 addControl(new VideoControl(this), fVideoControl); |
565 addControl(new FramePositioningControl(this), fFramePositioningControl); |
564 addControl(new FramePositioningControl(this), fFramePositioningControl); |
566 addControl(new StopTimeControl(this), fStopTimeControl); |
565 addControl(new StopTimeControl(this), fStopTimeControl); |
567 addControl(new RateControl(this), fRateControl); |
566 addControl(new RateControl(this), fRateControl); |
568 } |
567 } |
569 |
568 |
570 /** |
569 /** |
571 * This function initialize iControl and iDisplay object if it is null, |
570 * Notified when the display object of ESWT is created |
572 * otherwise return immediately. |
571 * It is getting created, when initDisplayMode of VideoControl class is called. |
573 * |
572 */ |
574 * In case of Canvas, eSWT control will be returned immediately from VideoControl(vc.getControl()), |
573 public void notifyDisplayAvailable(Display aDisplay) |
575 * but in case of CustomItem we need to keep polling, eSWT doesn't return the control for CustomItem |
574 { |
576 * until CustomItem is appended to Form. |
575 iDisplay= aDisplay; |
577 */ |
576 iImage=new Image(iDisplay, iImageData[0]); |
578 |
577 } |
579 private void initialize() |
578 /** |
580 { |
579 * Notified when the control is available |
581 System.out.println("AnimationPlayer::initialize +++"); |
580 * @param aControl(this is eSWTControl ) |
582 if (iControl == null || iDisplay == null) |
581 */ |
583 { |
582 public void notifyControlAvailable(org.eclipse.swt.widgets.Control aControl) |
584 VideoControl vc = (VideoControl) getControl(fVideoControl); |
583 { |
585 iDisplay = vc.getiDisplay(); |
584 iControl=aControl; |
586 iControl=vc.getControl(); |
585 addPaintListener(iControl); |
587 addPaintListener(iControl); |
586 } |
588 System.out.println("AnimationPlayer::initialize iDsplay "+iDisplay+" iControl "+iControl); |
587 |
589 // in case of CustomItem, |
588 |
590 // while ((iControl = vc.getControl()) == null) { |
|
591 // try { |
|
592 // Thread.sleep(100); |
|
593 // } catch (InterruptedException e) { |
|
594 // e.printStackTrace(); |
|
595 // } |
|
596 // } |
|
597 } |
|
598 System.out.println("AnimationPlayer::initialize ---"); |
|
599 } |
|
600 |
589 |
601 /** |
590 /** |
602 * This function will be called from setDisplaySize(int width, int height) of animation/VideoControl class |
591 * This function will be called from setDisplaySize(int width, int height) of animation/VideoControl class |
603 * When MIDlet developer will try to alter the size of the image |
592 * When MIDlet developer will try to alter the size of the image |
604 * @param width : to be set of the video(Animated GIF) |
593 * @param width : to be set of the video(Animated GIF) |
627 * to get the snap shot of the video |
616 * to get the snap shot of the video |
628 * |
617 * |
629 * @param format |
618 * @param format |
630 */ |
619 */ |
631 // This function is not implemented fully |
620 // This function is not implemented fully |
632 javax.microedition.lcdui.Image getCurrentFrame(String format) |
621 byte[] getCurrentFrame(String format) |
633 { |
622 { |
634 javax.microedition.lcdui.Image currentFrameImage= LCDUIInvoker.createLcduiImage(iImage); |
623 // create a new ImageLoader object |
635 return currentFrameImage; |
624 ImageLoader il= new ImageLoader(); |
|
625 // create a ImageData array of length 1 and assign it to 'data' member of ImageLoader |
|
626 il.data= new ImageData[1]; |
|
627 int currentFrameIndex= iFrameIndex; |
|
628 // assign the current frame ImageData to image |
|
629 il.data[0]= iImageData[currentFrameIndex]; |
|
630 il.logicalScreenWidth = iImageData[currentFrameIndex].width; |
|
631 il.logicalScreenHeight = iImageData[currentFrameIndex].height; |
|
632 il.backgroundPixel= iBackgroundPixel; |
|
633 ByteArrayOutputStream baos= new ByteArrayOutputStream(); |
|
634 il.save(baos, SWT.IMAGE_PNG); |
|
635 //il.save(baos, SWT.IMAGE_GIF); |
|
636 return baos.toByteArray(); |
636 } |
637 } |
637 |
638 |
638 /** |
639 /** |
639 * Returns Point object, which contains the width and height of the image |
640 * Returns Point object, which contains the width and height of the image |
640 * Called from VideoControl to get the image width and height, |
641 * Called from VideoControl to get the image width and height, |
641 * so that Item will be created exactly of same dimension |
642 * so that Item will be created exactly of same dimension |
642 */ |
643 */ |
643 org.eclipse.swt.graphics.Point getImageDimension() |
644 Point getImageDimension() |
644 { |
645 { |
|
646 // return iCurrentVideoDimension; |
645 return new org.eclipse.swt.graphics.Point(iImageData[0].width, iImageData[0].height); |
647 return new org.eclipse.swt.graphics.Point(iImageData[0].width, iImageData[0].height); |
646 } |
648 } |
647 |
649 |
648 /** |
650 |
649 * This returns the imageData array, |
651 int getTotalNumberFrames() |
650 * called from FramePositioningControl class to calculate the frame time |
652 { |
651 */ |
653 return iImageData.length; |
652 ImageData[] getImageData() |
654 } |
653 { |
|
654 return iImageData; |
|
655 } |
|
656 |
|
657 /** |
655 /** |
658 * |
656 * |
659 * @param aDisplayLocation x,y coordinate where image is to be displayed |
657 * @param aDisplayLocation x,y coordinate where image is to be displayed |
660 */ |
658 */ |
661 void setDisplayLocation(int aX, int aY) |
659 void setDisplayLocation(int aX, int aY) |
662 { |
660 { |
663 iDisplayLocation=new Point(aX,aY); |
661 iDisplayLocation.x=aX; |
|
662 iDisplayLocation.y=aY; |
664 } |
663 } |
665 |
664 |
666 /** |
665 /** |
667 * @return the position of the image to be displayed |
666 * @return the position of the image to be displayed |
668 */ |
667 */ |