javauis/mmapi_qt/baseline/javasrc/com/nokia/microedition/media/animation/AnimationPlayer.java
changeset 48 e0d6e9bd3ca7
parent 35 85266cc22c7f
child 50 023eef975703
child 61 bf7ee68962da
equal deleted inserted replaced
47:f40128debb5d 48:e0d6e9bd3ca7
    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
   220         unrealizedCheck();
   235         unrealizedCheck();
   221         return ANIMATION_CONTENT_TYPE;
   236         return ANIMATION_CONTENT_TYPE;
   222     }
   237     }
   223 
   238 
   224     /**
   239     /**
   225      * This function will return, total time in microseconds this player can be played
   240      * This function will return total time in microseconds, this player can be played
   226      */
   241      */
   227     public long getDuration()
   242     public long getDuration()
   228     {
   243     {
   229         closeCheck();
   244         closeCheck();
   230         long time = TIME_UNKNOWN;
   245         return iDuration;
   231         int totalNoOfFrames = iImageData.length;
       
   232         for (int i = 0; i < totalNoOfFrames; i++)
       
   233         {
       
   234             time += iImageData[i].delayTime;
       
   235         }
       
   236         // Since we have to return it in microsecond multiply it with 1000;
       
   237         return time * 10000;
       
   238     }
   246     }
   239 
   247 
   240     /**
   248     /**
   241      * This returns the total time taken, till now, to play the video.
   249      * This returns the total time taken, till now, to play the video.
   242      */
   250      */
   243     public long getMediaTime()
   251     public long getMediaTime()
   244     {
   252     {
   245         // Since we have to return it in microsecond multiply it with 1000;
   253         closeCheck();
       
   254         // Since we have to return it in microsecond multiply it with 10000;
   246         return iMediaTime*10000;
   255         return iMediaTime*10000;
   247     }
   256     }
   248 
   257 
   249     public int getState()
   258     public int getState()
   250     {
   259     {
   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             {
   420                 {
   394                 {
   421                     iControl.addPaintListener(new PaintListener()
   395                     iControl.addPaintListener(new PaintListener()
   422                     {
   396                     {
   423                         public void paintControl(PaintEvent pe)
   397                         public void paintControl(PaintEvent pe)
   424                         {
   398                         {
   425                             //System.out.println("AnimationPlayer::addpaintListener paintControl "+ iImage+" iIsControlVisible "+iIsControlVisible+"current time is "+System.currentTimeMillis());
       
   426                             System.out.println("AnimationPlayer::addPaintListener::PaintListener::paintControl");
       
   427                             if (iImage != null && iIsControlVisible)
   399                             if (iImage != null && iIsControlVisible)
   428                             {
   400                             {
   429                                 pe.gc.drawImage(iImage, iDisplayLocation.x,
   401                                 pe.gc.drawImage(iImage, iDisplayLocation.x,
   430                                                 iDisplayLocation.y);
   402                                                 iDisplayLocation.y);
   431                             }
   403                             }
   432                         }
   404                         }
   433                     });
   405                     });
   434                 }
   406                 }
   435             });
   407             });
   436         }
   408         }
   437         System.out.println("AnimationPlayer::addPaintListener ---");
       
   438     }
   409     }
   439 
   410 
   440 
   411 
   441     /**
   412     /**
   442      * This returns player Control.
   413      * This returns player Control.
   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)
   609         int noOfFrames= iImageData.length;
   598         int noOfFrames= iImageData.length;
   610         for (int i=0; i<noOfFrames; i++)
   599         for (int i=0; i<noOfFrames; i++)
   611         {
   600         {
   612             iImageData[i]=iImageData[i].scaledTo(width, height);
   601             iImageData[i]=iImageData[i].scaledTo(width, height);
   613         }
   602         }
   614         iImage=new Image(iDisplay, iImageData[0]);
   603         iImage=new Image(iDisplay, iImageData[iFrameIndex]);
   615     }
   604     }
   616 
   605 
   617     /**
   606     /**
   618      * Overloaded function for calling the above function
   607      * Overloaded function for calling the above function
   619      */
   608      */
   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      */
   675      * @return
   674      * @return
   676      */
   675      */
   677     Point getSourceDimension()
   676     Point getSourceDimension()
   678     {
   677     {
   679         return iSourceDimension;
   678         return iSourceDimension;
       
   679         //return new Point(iImageData[0].width, iImageData[0].height);
   680     }
   680     }
   681 
   681 
   682     /**
   682     /**
   683      * @return the iPlayerListenerImpl
   683      * @return the iPlayerListenerImpl
   684      */
   684      */
   717             {
   717             {
   718                 // pause the player
   718                 // pause the player
   719                 // following line will break the while loop in start method
   719                 // following line will break the while loop in start method
   720                 // Objective here is to pause the animation, if it is in started state
   720                 // Objective here is to pause the animation, if it is in started state
   721                 // also we do not need to notify to the playerListener that player has been stopped or paused
   721                 // also we do not need to notify to the playerListener that player has been stopped or paused
   722                 iState=PREFETCHED;
   722                 changePlayerState(PREFETCHED);
   723             }
   723             }
   724             else
   724             else
   725             {
   725             {
   726                 //start the player
   726                 //start the player
   727                 // this will start playing animation from the very same frame
   727                 // this will start playing animation from the very same frame
   740         this.iCurrentRate = aCurrentRate;
   740         this.iCurrentRate = aCurrentRate;
   741         return iCurrentRate;
   741         return iCurrentRate;
   742     }
   742     }
   743 
   743 
   744     /**
   744     /**
   745      * @param iStopTime the iStopTime to set
       
   746      */
       
   747     void setiStopTime(long iStopTime)
       
   748     {
       
   749         this.iStopTime = iStopTime;
       
   750     }
       
   751 
       
   752     /**
       
   753      * @param iIsControlVisible the iIsControlVisible to set
   745      * @param iIsControlVisible the iIsControlVisible to set
   754      */
   746      */
   755     void setiIsControlVisible(boolean iIsControlVisible)
   747     void setiIsControlVisible(boolean iIsControlVisible)
   756     {
   748     {
   757         this.iIsControlVisible = iIsControlVisible;
   749         this.iIsControlVisible = iIsControlVisible;
   758     }
   750     }
       
   751     /**
       
   752      * Called from
       
   753      */
       
   754     void postEvent(long aMediaTime)
       
   755     {
       
   756         changePlayerState(PREFETCHED);
       
   757         iPlayerListenerImpl.postEvent(PlayerListener.STOPPED_AT_TIME, new Long(
       
   758                                           aMediaTime));
       
   759     }
       
   760 
       
   761     /**
       
   762      * @param aAnimationObserver the iAnimationObserver to set
       
   763      */
       
   764     void setiAnimationObserver(AnimationObserver aAnimationObserver)
       
   765     {
       
   766         this.iAnimationObserver = aAnimationObserver;
       
   767     }
       
   768 
       
   769 
   759 }
   770 }
   760 
   771