|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: AnimationPlayer |
|
15 * |
|
16 */ |
|
17 package com.nokia.microedition.media.animation; |
|
18 |
|
19 import java.io.ByteArrayOutputStream; |
|
20 import java.io.IOException; |
|
21 import java.io.InputStream; |
|
22 import java.util.Enumeration; |
|
23 import java.util.Hashtable; |
|
24 |
|
25 import javax.microedition.media.Control; |
|
26 import javax.microedition.media.MediaException; |
|
27 import javax.microedition.media.PlayerListener; |
|
28 import javax.microedition.media.protocol.DataSource; |
|
29 |
|
30 import org.eclipse.swt.SWT; |
|
31 import org.eclipse.swt.SWTException; |
|
32 import org.eclipse.swt.events.PaintEvent; |
|
33 import org.eclipse.swt.events.PaintListener; |
|
34 import org.eclipse.swt.graphics.GC; |
|
35 import org.eclipse.swt.graphics.Image; |
|
36 import org.eclipse.swt.graphics.ImageData; |
|
37 import org.eclipse.swt.graphics.ImageLoader; |
|
38 import org.eclipse.swt.graphics.Point; |
|
39 import org.eclipse.swt.widgets.Display; |
|
40 |
|
41 import com.nokia.microedition.media.BufferDataSource; |
|
42 import com.nokia.microedition.media.InputStreamDataSource; |
|
43 import com.nokia.microedition.media.InputStreamSourceStream; |
|
44 import com.nokia.microedition.media.PlayerBase; |
|
45 import com.nokia.microedition.media.PlayerListenerImpl; |
|
46 |
|
47 public class AnimationPlayer extends PlayerBase implements ESWTinitializeListener |
|
48 { |
|
49 // GIF image information, array length will be equal to the number of frames in image |
|
50 protected ImageData [] iImageData; |
|
51 // number of times we need to repeat the animation |
|
52 // by default it's value is one |
|
53 private int iTotalLoopCount=1; |
|
54 // HashTable object which contains all control related to this player |
|
55 private Hashtable iControls= new Hashtable(); |
|
56 // Current frame index of the Animation file |
|
57 private int iFrameIndex; |
|
58 // Current Loop Count |
|
59 private int iCurrentLoopCount; |
|
60 // Indicates if looping indefinitely |
|
61 private boolean iRepeatForeEver; |
|
62 // Current rate of the player, Used for RateControl |
|
63 // Currently only two mode are supported |
|
64 // paused and default rate |
|
65 private int iCurrentRate; |
|
66 // Display object of the eSWT API, creating this object will integrate the current java code with eSWT API. |
|
67 private Display iDisplay; |
|
68 // Control object of ESWT API, return from LCDUIInvoker. |
|
69 org.eclipse.swt.widgets.Control iControl; |
|
70 // Following constants are used for comparison of the string, throughout the class |
|
71 private static final String ANIMATION_CONTENT_TYPE = "image/gif"; |
|
72 private static final String fVideoControl = VideoControl.class.getName(); |
|
73 private static final String fFramePositioningControl = FramePositioningControl.class.getName(); |
|
74 private static final String fStopTimeControl = StopTimeControl.class.getName(); |
|
75 private static final String fRateControl = RateControl.class.getName(); |
|
76 |
|
77 /** |
|
78 * Default control package. Used when getting control with |
|
79 * getControl method which appends default control package if package is |
|
80 * not specified. |
|
81 */ |
|
82 private static final String CONTROL_DEFAULT_PACKAGE = |
|
83 "javax.microedition.media.control."; |
|
84 |
|
85 //For Player listener |
|
86 protected PlayerListenerImpl iPlayerListenerImpl; |
|
87 //Image to be displayed, an object of eSWT API. |
|
88 protected Image iImage; |
|
89 // Actual dimension of the image, this should be initialized while creating the player |
|
90 // as user can change the size of the image later, in that case too, getSourceheight and getSourceWidth |
|
91 // of VideoControl should return the actual width and height of the image |
|
92 private Point iSourceDimension; |
|
93 // Current dimension of the image, MIDlet developer may change the size of VideoControl |
|
94 private Point iCurrentVideoDimension; |
|
95 // Total time taken so far to player the animation, it keeps updating as player moves |
|
96 private long iMediaTime; |
|
97 // Time at which, player should be stopped |
|
98 // This will set through StopTimeControl.setTime(); |
|
99 // otherwise default time is Long.MAX_VALUE |
|
100 //private long iStopTime=Long.MAX_VALUE; |
|
101 AnimationObserver iAnimationObserver; |
|
102 |
|
103 // Display Location, of the image |
|
104 // there won't be any use of this, in case of Form(customItem) |
|
105 private Point iDisplayLocation= new Point(0,0); |
|
106 // in case of Canvas(USE_DIRECT_VIDEO) , it should be invisible by default |
|
107 // this is handled in initDisplayMode function, if the mode is USE_DIRECT_VIDEO, we are |
|
108 // changing it to false |
|
109 private boolean iIsControlVisible=true; |
|
110 // we keep the background pixel in it, used while taking the snapshot of the currentframe |
|
111 private int iBackgroundPixel=-1; |
|
112 // Total duration of the player |
|
113 private long iDuration=TIME_UNKNOWN; |
|
114 /** |
|
115 * |
|
116 * @param ds DataSource which contains the data to be displayed |
|
117 * @throws MediaException |
|
118 */ |
|
119 public AnimationPlayer(DataSource ds) throws MediaException |
|
120 { |
|
121 iPlayerListenerImpl= new PlayerListenerImpl(this); |
|
122 //TODO check if we can do it in better way |
|
123 // this is temporary solution |
|
124 // for this I have written two functions getDataSource and getInputStream function |
|
125 BufferDataSource bds =(BufferDataSource)ds; |
|
126 InputStreamDataSource isds=(InputStreamDataSource)bds.getDataSource(); |
|
127 InputStreamSourceStream isss=(InputStreamSourceStream)isds.getStreams()[0]; |
|
128 InputStream is = isss.getInputStream(); |
|
129 if (is!=null) |
|
130 { |
|
131 ImageLoader imageLoader= new ImageLoader(); |
|
132 |
|
133 // If it is any other format other than the image(jpeg, png and gif), |
|
134 // following line will throw the SWT exception |
|
135 iImageData=imageLoader.load(is); |
|
136 // If the image is loaded properly, we need to check whether it is GIF image or not. |
|
137 // It can be PNG and JPEG as well |
|
138 if (iImageData[0].type!=SWT.IMAGE_GIF) |
|
139 throw new MediaException("Could not create player"); |
|
140 try |
|
141 { |
|
142 is.close(); |
|
143 } |
|
144 catch (IOException e) |
|
145 { |
|
146 e.printStackTrace(); |
|
147 } |
|
148 iSourceDimension= new Point(imageLoader.logicalScreenWidth, imageLoader.logicalScreenHeight); |
|
149 iCurrentVideoDimension= new Point(imageLoader.logicalScreenWidth, imageLoader.logicalScreenHeight); |
|
150 iBackgroundPixel= imageLoader.backgroundPixel; |
|
151 } |
|
152 populateControl(); |
|
153 |
|
154 } |
|
155 |
|
156 /** |
|
157 * |
|
158 * @param locator |
|
159 * @throws SWTException |
|
160 */ |
|
161 public AnimationPlayer(String locator) throws SWTException, MediaException |
|
162 { |
|
163 ImageLoader imageLoader= new ImageLoader(); |
|
164 // If it is any other format other than the image(jpeg, png and gif), |
|
165 // following line will throw the SWT exception |
|
166 iImageData=imageLoader.load(locator); |
|
167 // If the image is loaded properly, we need to check whether it is GIF image or not. |
|
168 // It can be PNG and JPEG as well |
|
169 if (iImageData[0].type!=SWT.IMAGE_GIF) |
|
170 throw new MediaException("Could not create player"); |
|
171 iPlayerListenerImpl= new PlayerListenerImpl(this); |
|
172 iSourceDimension= new Point(imageLoader.logicalScreenWidth, imageLoader.logicalScreenHeight); |
|
173 iCurrentVideoDimension= new Point(imageLoader.logicalScreenWidth, imageLoader.logicalScreenHeight); |
|
174 iBackgroundPixel= imageLoader.backgroundPixel; |
|
175 populateControl(); |
|
176 } |
|
177 |
|
178 /** |
|
179 * Moved the player to close state and releases all resources, called from PlayerBase class |
|
180 */ |
|
181 protected void doClose() |
|
182 { |
|
183 // state is already changed in playerbase.close() method |
|
184 // changePlayerState(CLOSED); |
|
185 iPlayerListenerImpl.postEvent(PlayerListener.CLOSED, null); |
|
186 } |
|
187 |
|
188 /** |
|
189 * Called from the PlayerBase class if the Player is in pre-fetched state |
|
190 * |
|
191 */ |
|
192 protected void doDeallocate() |
|
193 { |
|
194 //when the player is in pre-fetched state, calling this |
|
195 //function should change the state of the player to RELAIZED state |
|
196 changePlayerState(REALIZED); |
|
197 } |
|
198 |
|
199 protected void doPrefetch() throws MediaException |
|
200 { |
|
201 changePlayerState(PREFETCHED); |
|
202 iDuration= getMediaTimeForFrame(getTotalNumberFrames()); |
|
203 } |
|
204 |
|
205 protected void doRealize() throws MediaException |
|
206 { |
|
207 changePlayerState(REALIZED); |
|
208 } |
|
209 |
|
210 /** |
|
211 * |
|
212 */ |
|
213 protected void doStop() throws MediaException |
|
214 { |
|
215 // since after stopping the player the player state will move to pre-fetched state |
|
216 changePlayerState(PREFETCHED); |
|
217 //iPlayerListenerImpl.postEvent(PlayerListener.STOPPED, new Long(iMediaTime * 10000)); |
|
218 iPlayerListenerImpl.postEvent(PlayerListener.STOPPED, new Long(iMediaTime)); |
|
219 } |
|
220 |
|
221 /** |
|
222 * Function of InternalPlayer interface |
|
223 */ |
|
224 public void addControl(Control aControl, String aControlType) |
|
225 { |
|
226 iControls.put(aControlType, aControl); |
|
227 } |
|
228 |
|
229 /** |
|
230 * |
|
231 */ |
|
232 public void addPlayerListener(PlayerListener aPlayerListener) |
|
233 { |
|
234 closeCheck(); |
|
235 iPlayerListenerImpl.addPlayerListener(aPlayerListener); |
|
236 } |
|
237 |
|
238 /** |
|
239 * Returns the Content type("image/GIF") supported for by this player, |
|
240 */ |
|
241 public String getContentType() |
|
242 { |
|
243 closeCheck(); |
|
244 unrealizedCheck(); |
|
245 return ANIMATION_CONTENT_TYPE; |
|
246 } |
|
247 |
|
248 /** |
|
249 * This function will return total time in microseconds, this player can be played |
|
250 */ |
|
251 public long getDuration() |
|
252 { |
|
253 closeCheck(); |
|
254 return iDuration; |
|
255 } |
|
256 |
|
257 /** |
|
258 * This returns the total time taken, till now, to play the video. |
|
259 */ |
|
260 public long getMediaTime() |
|
261 { |
|
262 closeCheck(); |
|
263 return iMediaTime; |
|
264 } |
|
265 |
|
266 public int getState() |
|
267 { |
|
268 return iState; |
|
269 } |
|
270 |
|
271 /** |
|
272 * Removes the specified playerListner from this player |
|
273 */ |
|
274 public void removePlayerListener(PlayerListener aPlayerListener) |
|
275 { |
|
276 closeCheck(); |
|
277 iPlayerListenerImpl.removePlayerListener(aPlayerListener); |
|
278 } |
|
279 |
|
280 /** |
|
281 * |
|
282 */ |
|
283 GC gc = null; |
|
284 public void start() throws MediaException |
|
285 { |
|
286 final String DEBUG_STR = "AnimationPlayer::start()"; |
|
287 // final long inTime = System.currentTimeMillis(); |
|
288 prefetch(); |
|
289 // Only prefetched player may be started. If player is already started |
|
290 // this method returns silently. |
|
291 if (getState() == PREFETCHED) |
|
292 { |
|
293 //initialize(); |
|
294 changePlayerState(STARTED); |
|
295 Thread thread = new Thread("Animation") |
|
296 { |
|
297 int loopCount = iCurrentLoopCount; |
|
298 public void run() |
|
299 { |
|
300 //changePlayerState(STARTED); |
|
301 final int noOfFrames = iImageData.length; |
|
302 while (iState == STARTED) |
|
303 { |
|
304 final int delayTimeForNextFrame = iImageData[iFrameIndex].delayTime*10000 ; |
|
305 // Since we are going to display first frame, notify all |
|
306 // PlayerListener that Player has started |
|
307 if (iFrameIndex == 0) |
|
308 { |
|
309 iMediaTime=0; |
|
310 iPlayerListenerImpl.postEvent( |
|
311 PlayerListener.STARTED, new Long(0)); |
|
312 |
|
313 } |
|
314 if (iDisplay != null) |
|
315 { |
|
316 iDisplay.syncExec(new Runnable() |
|
317 { |
|
318 public void run() |
|
319 { |
|
320 // For out of memory issue in case of full screen, we are scaling the image |
|
321 // while displaying it. |
|
322 ImageData tempImageData =iImageData[iFrameIndex] ; |
|
323 if (iSourceDimension.x!=iCurrentVideoDimension.x || iSourceDimension.x!=iCurrentVideoDimension.x) |
|
324 { |
|
325 tempImageData = iImageData[iFrameIndex].scaledTo(iCurrentVideoDimension.x , iCurrentVideoDimension.y); |
|
326 } |
|
327 Image tempImage = new Image(iDisplay,tempImageData); |
|
328 //Image tempImage = new Image(iDisplay,iImageData[iFrameIndex]); |
|
329 gc.drawImage(tempImage, 0, 0); |
|
330 tempImage.dispose(); |
|
331 iFrameIndex = (iFrameIndex + 1) % noOfFrames; |
|
332 if (iControl != null) |
|
333 { |
|
334 iControl.redraw(); |
|
335 } |
|
336 iMediaTime += delayTimeForNextFrame; |
|
337 } |
|
338 }); |
|
339 } |
|
340 else// if the initDisplayMode is not called yet |
|
341 { |
|
342 iFrameIndex = (iFrameIndex + 1) % noOfFrames; |
|
343 iMediaTime += delayTimeForNextFrame; |
|
344 } |
|
345 try |
|
346 { |
|
347 Thread.sleep(delayTimeForNextFrame / 1000); |
|
348 } |
|
349 catch (InterruptedException e) |
|
350 { |
|
351 e.printStackTrace(); |
|
352 } |
|
353 // post EOM event |
|
354 if (iFrameIndex == 0) |
|
355 { |
|
356 loopCount++; |
|
357 if (!(iRepeatForeEver || (loopCount < iTotalLoopCount))) |
|
358 { |
|
359 // when this loop is getting braked, we need to change the state to pre-fetched |
|
360 //TODO Player should change it's state in doStop(); |
|
361 changePlayerState(PREFETCHED); |
|
362 } |
|
363 // send the END_OF_MEDIA event to all |
|
364 // listener |
|
365 iPlayerListenerImpl.postEvent( |
|
366 PlayerListener.END_OF_MEDIA, |
|
367 new Long(iMediaTime)); |
|
368 } |
|
369 if (iAnimationObserver!=null) |
|
370 { |
|
371 iAnimationObserver.animationAdvanced(iMediaTime); |
|
372 } |
|
373 }// end of while loop |
|
374 iCurrentLoopCount = loopCount; |
|
375 } |
|
376 }; |
|
377 thread.start(); |
|
378 } |
|
379 } |
|
380 |
|
381 /** |
|
382 * State of the player should be changed from this function only. |
|
383 * @param aState |
|
384 */ |
|
385 private synchronized void changePlayerState(int aState) |
|
386 { |
|
387 iState=aState; |
|
388 } |
|
389 /** |
|
390 * On each repaint event, control is getting disposed and created each time, |
|
391 * So we need to call each time the Control is available |
|
392 * @param aControl |
|
393 */ |
|
394 private void addPaintListener(org.eclipse.swt.widgets.Control aControl) |
|
395 { |
|
396 iControl=aControl; |
|
397 if (iControl != null) |
|
398 { |
|
399 iDisplay.syncExec(new Runnable() |
|
400 { |
|
401 public void run() |
|
402 { |
|
403 iControl.addPaintListener(new PaintListener() |
|
404 { |
|
405 public void paintControl(PaintEvent pe) |
|
406 { |
|
407 if (iImage != null && iIsControlVisible) |
|
408 { |
|
409 pe.gc.drawImage(iImage, iDisplayLocation.x, |
|
410 iDisplayLocation.y); |
|
411 } |
|
412 } |
|
413 }); |
|
414 } |
|
415 }); |
|
416 } |
|
417 } |
|
418 |
|
419 |
|
420 /** |
|
421 * This returns player Control. |
|
422 * |
|
423 * @param controlType - the class name of the Control. The class name should be given either |
|
424 * as the fully-qualified name of the class; or if the package of the class is not given, the |
|
425 * package javax.microedition.media.control is assumed. |
|
426 * |
|
427 * @return the object that implements the control, or null. |
|
428 */ |
|
429 public Control getControl(String aControlType) |
|
430 { |
|
431 if (aControlType == null) |
|
432 { |
|
433 throw new IllegalArgumentException("argument is null"); |
|
434 } |
|
435 closeCheck(); |
|
436 unrealizedCheck(); |
|
437 |
|
438 String controlType = aControlType; |
|
439 // check if package name exists |
|
440 if (controlType.indexOf(".") == -1) |
|
441 { |
|
442 // add package name |
|
443 controlType = CONTROL_DEFAULT_PACKAGE + aControlType; |
|
444 } |
|
445 Control control = (Control)iControls.get(controlType); |
|
446 // If control does not exists with default name, check if there is |
|
447 // is a control with same type ( extends the given class name ). |
|
448 if (control == null) |
|
449 { |
|
450 try |
|
451 { |
|
452 // try to create class for control |
|
453 Class controlClass = Class.forName(controlType); |
|
454 Enumeration elements = iControls.elements(); |
|
455 // search if any control is same type that requested control |
|
456 while (elements.hasMoreElements()) |
|
457 { |
|
458 Control tmpControl = (Control) elements.nextElement(); |
|
459 if (controlClass.isInstance(tmpControl)) |
|
460 { |
|
461 // control is found |
|
462 control = tmpControl; |
|
463 } |
|
464 } |
|
465 } |
|
466 catch (ClassNotFoundException cnfe) // the class could not be |
|
467 // found |
|
468 { |
|
469 // Exception is ignored and null is returned from this method |
|
470 } |
|
471 catch (Error e) // the function failed for any other reason. |
|
472 { |
|
473 // Error is ignored and null is returned from this method |
|
474 } |
|
475 } |
|
476 return control; |
|
477 } |
|
478 /** |
|
479 * Returns all the control associated with this player |
|
480 */ |
|
481 public Control[] getControls() |
|
482 { |
|
483 closeCheck(); |
|
484 unrealizedCheck(); |
|
485 Control control[]= new Control[iControls.size()]; |
|
486 Enumeration enumeration= iControls.elements(); |
|
487 byte index=0; |
|
488 while (enumeration.hasMoreElements()) |
|
489 { |
|
490 control[index++]=(Control)enumeration.nextElement(); |
|
491 } |
|
492 return control; |
|
493 } |
|
494 /** |
|
495 * |
|
496 */ |
|
497 public void setLoopCount(int aCount) |
|
498 { |
|
499 iRepeatForeEver = (aCount == -1); |
|
500 super.setLoopCount(aCount); |
|
501 iTotalLoopCount=aCount; |
|
502 } |
|
503 /** |
|
504 * From PlayerBase |
|
505 * Here iFrameIndex variable will be updated according to the argument(aNow) supplied |
|
506 * We are updating the iFrameIndex variable, which is being used in the start function |
|
507 * |
|
508 * @see PlayerBase |
|
509 */ |
|
510 public long setMediaTime(long aNow) throws MediaException |
|
511 { |
|
512 long now = super.setMediaTime(aNow); |
|
513 if (iDuration == TIME_UNKNOWN) |
|
514 iDuration=getMediaTimeForFrame(getTotalNumberFrames()); |
|
515 if (now >= iDuration) |
|
516 { |
|
517 iFrameIndex=getTotalNumberFrames()-1; |
|
518 iMediaTime = iDuration; |
|
519 } |
|
520 else |
|
521 { |
|
522 iFrameIndex = findFrame(now); |
|
523 iMediaTime= getMediaTimeForFrame(iFrameIndex); |
|
524 } |
|
525 return iMediaTime ; |
|
526 } |
|
527 ////////////////////////////////////////////////////////////////////////////////////// |
|
528 // Following functions are for internal use, and not exposed to MIDlet developer////// |
|
529 ///////////////////////////////////////////////////////////////////////////////////// |
|
530 |
|
531 /** |
|
532 * Before calling this function check frameIndex is in range or not, from 0 to last index |
|
533 */ |
|
534 long getMediaTimeForFrame(int aFrameIndex) |
|
535 { |
|
536 long time=0; |
|
537 for (int i=0; i < aFrameIndex; i++) |
|
538 { |
|
539 time+=iImageData[i].delayTime; |
|
540 } |
|
541 return time*10000; |
|
542 } |
|
543 |
|
544 /** |
|
545 * Utility function to calculate the framNumber |
|
546 * @param aTime |
|
547 * @return |
|
548 */ |
|
549 int findFrame(long aTime) |
|
550 { |
|
551 long time=0; |
|
552 int frameIndex=0; |
|
553 if (aTime > iDuration) |
|
554 return -1; |
|
555 else if (aTime==0) |
|
556 return 0; |
|
557 int totalNoOfFrame= getTotalNumberFrames(); |
|
558 while (time *10000 < aTime && frameIndex < totalNoOfFrame) |
|
559 { |
|
560 time += iImageData[frameIndex++].delayTime; |
|
561 } |
|
562 return frameIndex; |
|
563 } |
|
564 /** |
|
565 * This function is responsible for creating all controls and adding it into Controls hashtable. |
|
566 */ |
|
567 private void populateControl() |
|
568 { |
|
569 // there are four control provided by AnimationPlayer |
|
570 // adding all one by one to the controlList(iControls) |
|
571 addControl(new VideoControl(this), fVideoControl); |
|
572 addControl(new FramePositioningControl(this), fFramePositioningControl); |
|
573 addControl(new StopTimeControl(this), fStopTimeControl); |
|
574 addControl(new RateControl(this), fRateControl); |
|
575 } |
|
576 |
|
577 /** |
|
578 * Notified when the display object of ESWT is created |
|
579 * It is getting created, when initDisplayMode of VideoControl class is called. |
|
580 */ |
|
581 public void notifyDisplayAvailable(Display aDisplay) |
|
582 { |
|
583 iDisplay= aDisplay; |
|
584 //iImage=new Image(iDisplay, iImageData[0]); |
|
585 iImage=new Image(iDisplay, iImageData[iFrameIndex]); |
|
586 iDisplay.syncExec(new Runnable() |
|
587 { |
|
588 public void run() |
|
589 { |
|
590 gc = new GC(iImage); |
|
591 } |
|
592 }); |
|
593 } |
|
594 /** |
|
595 * Notified when the control is available |
|
596 * @param aControl(this is eSWTControl ) |
|
597 */ |
|
598 public void notifyControlAvailable(org.eclipse.swt.widgets.Control aControl) |
|
599 { |
|
600 iControl=aControl; |
|
601 addPaintListener(iControl); |
|
602 } |
|
603 |
|
604 |
|
605 |
|
606 /** |
|
607 * This function will be called from setDisplaySize(int width, int height) of animation/VideoControl class |
|
608 * When MIDlet developer will try to alter the size of the image |
|
609 * @param width : to be set of the video(Animated GIF) |
|
610 * @param height : height to be set of video(Animated GIF) |
|
611 */ |
|
612 void updateImageData(int aWidth, int aHeight) |
|
613 { |
|
614 // int noOfFrames= iImageData.length; |
|
615 // for (int i=0; i<noOfFrames; i++) |
|
616 // { |
|
617 // iImageData[i]=iImageData[i].scaledTo(aWidth, aHeight); |
|
618 // } |
|
619 // iImage=new Image(iDisplay, iImageData[iFrameIndex]); |
|
620 iCurrentVideoDimension.x=aWidth; |
|
621 iCurrentVideoDimension.y= aHeight; |
|
622 iImage=new Image(iDisplay, iImageData[iFrameIndex].scaledTo(aWidth, aHeight)); |
|
623 } |
|
624 |
|
625 /** |
|
626 * Overloaded function for calling the above function |
|
627 */ |
|
628 void updateImageData(Point aSize) |
|
629 { |
|
630 updateImageData(aSize.x, aSize.y); |
|
631 } |
|
632 |
|
633 /** |
|
634 * This function will be called from getSnapshot() function of VideoControl class |
|
635 * to get the snap shot of the video |
|
636 * |
|
637 * @param format |
|
638 */ |
|
639 // This function is not implemented fully |
|
640 byte[] getCurrentFrame(String format) |
|
641 { |
|
642 // create a new ImageLoader object |
|
643 ImageLoader il= new ImageLoader(); |
|
644 // create a ImageData array of length 1 and assign it to 'data' member of ImageLoader |
|
645 il.data= new ImageData[1]; |
|
646 int currentFrameIndex= iFrameIndex; |
|
647 // assign the current frame ImageData to image |
|
648 il.data[0]= iImageData[currentFrameIndex]; |
|
649 il.logicalScreenWidth = iImageData[currentFrameIndex].width; |
|
650 il.logicalScreenHeight = iImageData[currentFrameIndex].height; |
|
651 il.backgroundPixel= iBackgroundPixel; |
|
652 ByteArrayOutputStream baos= new ByteArrayOutputStream(); |
|
653 il.save(baos, SWT.IMAGE_PNG); |
|
654 //il.save(baos, SWT.IMAGE_GIF); |
|
655 return baos.toByteArray(); |
|
656 } |
|
657 |
|
658 /** |
|
659 * Returns Point object, which contains the width and height of the image |
|
660 * Called from VideoControl to get the image width and height, |
|
661 * so that Item will be created exactly of same dimension |
|
662 */ |
|
663 Point getCurrentVideoDimension() |
|
664 { |
|
665 return iCurrentVideoDimension; |
|
666 // return new org.eclipse.swt.graphics.Point(iImageData[0].width, iImageData[0].height); |
|
667 } |
|
668 |
|
669 |
|
670 int getTotalNumberFrames() |
|
671 { |
|
672 return iImageData.length; |
|
673 } |
|
674 /** |
|
675 * |
|
676 * @param aDisplayLocation x,y coordinate where image is to be displayed |
|
677 */ |
|
678 void setDisplayLocation(int aX, int aY) |
|
679 { |
|
680 iDisplayLocation.x=aX; |
|
681 iDisplayLocation.y=aY; |
|
682 } |
|
683 /** |
|
684 * @return the position of the image to be displayed |
|
685 */ |
|
686 Point getiDisplayLocation() |
|
687 { |
|
688 return iDisplayLocation; |
|
689 } |
|
690 /** |
|
691 * Called from VideoControl to get the dimension of original image size |
|
692 * @return |
|
693 */ |
|
694 Point getSourceDimension() |
|
695 { |
|
696 return iSourceDimension; |
|
697 //return new Point(iImageData[0].width, iImageData[0].height); |
|
698 } |
|
699 |
|
700 /** |
|
701 * @return the iPlayerListenerImpl |
|
702 */ |
|
703 PlayerListenerImpl getiPlayerListenerImpl() |
|
704 { |
|
705 return iPlayerListenerImpl; |
|
706 } |
|
707 |
|
708 /** |
|
709 * @return the iFrameIndex |
|
710 */ |
|
711 int getiFrameIndex() |
|
712 { |
|
713 return iFrameIndex; |
|
714 } |
|
715 |
|
716 /** |
|
717 * @return the iCurrentRate |
|
718 */ |
|
719 int getiCurrentRate() |
|
720 { |
|
721 return iCurrentRate; |
|
722 } |
|
723 |
|
724 /** |
|
725 * @param aCurrentRate the iCurrentRate to set |
|
726 * @return actual rate set |
|
727 */ |
|
728 int setiCurrentRate(int aCurrentRate) |
|
729 { |
|
730 // if the player is already started and was paused due to setRate |
|
731 // then we need to start the player again from the same frame |
|
732 if (iState == STARTED && iCurrentRate != aCurrentRate) |
|
733 { |
|
734 if (aCurrentRate<=0) |
|
735 { |
|
736 // pause the player |
|
737 // following line will break the while loop in start method |
|
738 // Objective here is to pause the animation, if it is in started state |
|
739 // also we do not need to notify to the playerListener that player has been stopped or paused |
|
740 changePlayerState(PREFETCHED); |
|
741 } |
|
742 else |
|
743 { |
|
744 //start the player |
|
745 // this will start playing animation from the very same frame |
|
746 // where it was paused due to setRate(0) |
|
747 try |
|
748 { |
|
749 start(); |
|
750 } |
|
751 catch (MediaException e) |
|
752 { |
|
753 // ignore the exception |
|
754 e.printStackTrace(); |
|
755 } |
|
756 } |
|
757 } |
|
758 this.iCurrentRate = aCurrentRate; |
|
759 return iCurrentRate; |
|
760 } |
|
761 |
|
762 /** |
|
763 * @param iIsControlVisible the iIsControlVisible to set |
|
764 */ |
|
765 void setiIsControlVisible(boolean iIsControlVisible) |
|
766 { |
|
767 this.iIsControlVisible = iIsControlVisible; |
|
768 } |
|
769 /** |
|
770 * Called from StopTimeControl.animationAdvanced(long), once the stopped time is greater than or equal media time. |
|
771 */ |
|
772 void postEvent(long aMediaTime) |
|
773 { |
|
774 changePlayerState(PREFETCHED); |
|
775 iPlayerListenerImpl.postEvent(PlayerListener.STOPPED_AT_TIME, new Long( |
|
776 aMediaTime)); |
|
777 } |
|
778 |
|
779 /** |
|
780 * @param aAnimationObserver the iAnimationObserver to set |
|
781 */ |
|
782 void setiAnimationObserver(AnimationObserver aAnimationObserver) |
|
783 { |
|
784 this.iAnimationObserver = aAnimationObserver; |
|
785 } |
|
786 |
|
787 |
|
788 } |
|
789 |