javauis/mmapi_qt/baseline/javasrc/com/nokia/microedition/media/animation/AnimationPlayer.java
changeset 61 bf7ee68962da
parent 48 e0d6e9bd3ca7
child 79 2f468c1958d0
equal deleted inserted replaced
48:e0d6e9bd3ca7 61:bf7ee68962da
    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.ByteArrayOutputStream;
    21 import java.io.IOException;
    20 import java.io.IOException;
    22 import java.io.InputStream;
    21 import java.io.InputStream;
    23 import java.io.OutputStream;
       
    24 import java.util.Enumeration;
    22 import java.util.Enumeration;
    25 import java.util.Hashtable;
    23 import java.util.Hashtable;
    26 import java.util.Timer;
       
    27 import java.util.TimerTask;
       
    28 
    24 
    29 import javax.microedition.media.Control;
    25 import javax.microedition.media.Control;
    30 import javax.microedition.media.MediaException;
    26 import javax.microedition.media.MediaException;
    31 import javax.microedition.media.Player;
       
    32 import javax.microedition.media.PlayerListener;
    27 import javax.microedition.media.PlayerListener;
    33 import javax.microedition.media.protocol.DataSource;
    28 import javax.microedition.media.protocol.DataSource;
    34 
    29 
    35 import org.eclipse.swt.SWT;
    30 import org.eclipse.swt.SWT;
    36 import org.eclipse.swt.SWTException;
    31 import org.eclipse.swt.SWTException;
    46 import com.nokia.microedition.media.BufferDataSource;
    41 import com.nokia.microedition.media.BufferDataSource;
    47 import com.nokia.microedition.media.InputStreamDataSource;
    42 import com.nokia.microedition.media.InputStreamDataSource;
    48 import com.nokia.microedition.media.InputStreamSourceStream;
    43 import com.nokia.microedition.media.InputStreamSourceStream;
    49 import com.nokia.microedition.media.PlayerBase;
    44 import com.nokia.microedition.media.PlayerBase;
    50 import com.nokia.microedition.media.PlayerListenerImpl;
    45 import com.nokia.microedition.media.PlayerListenerImpl;
    51 import com.nokia.mj.impl.nokialcdui.LCDUIInvoker;
       
    52 import com.nokia.mj.impl.utils.Logger;
       
    53 
    46 
    54 public class AnimationPlayer extends PlayerBase implements ESWTinitializeListener
    47 public class AnimationPlayer extends PlayerBase implements ESWTinitializeListener
    55 {
    48 {
    56     // GIF image information, array length will be equal to the number of frames in image
    49     // GIF image information, array length will be equal to the number of frames in image
    57     protected ImageData [] iImageData;
    50     protected ImageData [] iImageData;
    96     // Actual dimension of the image, this should be initialized while creating the player
    89     // Actual dimension of the image, this should be initialized while creating the player
    97     // as user can change the size of the image later, in that case too, getSourceheight and getSourceWidth
    90     // as user can change the size of the image later, in that case too, getSourceheight and getSourceWidth
    98     // of VideoControl should return the actual width and height of the image
    91     // of VideoControl should return the actual width and height of the image
    99     private Point iSourceDimension;
    92     private Point iSourceDimension;
   100     // Current dimension of the image, MIDlet developer may change the size of VideoControl
    93     // Current dimension of the image, MIDlet developer may change the size of VideoControl
   101 //    private Point iCurrentVideoDimension;
    94     private Point iCurrentVideoDimension;
   102     // Total time taken so far to player the animation, it keeps updating as player moves
    95     // Total time taken so far to player the animation, it keeps updating as player moves
   103     private long iMediaTime;
    96     private long iMediaTime;
   104     // Time at which, player should be stopped
    97     // Time at which, player should be stopped
   105     // This will set through StopTimeControl.setTime();
    98     // This will set through StopTimeControl.setTime();
   106     // otherwise default time is Long.MAX_VALUE
    99     // otherwise default time is Long.MAX_VALUE
   119     // Total duration of the player
   112     // Total duration of the player
   120     private long iDuration=TIME_UNKNOWN;
   113     private long iDuration=TIME_UNKNOWN;
   121     /**
   114     /**
   122      *
   115      *
   123      * @param ds DataSource which contains the data to be displayed
   116      * @param ds DataSource which contains the data to be displayed
   124      */
   117      * @throws MediaException
   125     public AnimationPlayer(DataSource ds)
   118      */
       
   119     public AnimationPlayer(DataSource ds) throws MediaException
   126     {
   120     {
   127         iPlayerListenerImpl= new PlayerListenerImpl(this);
   121         iPlayerListenerImpl= new PlayerListenerImpl(this);
   128         //TODO check if we can do it in better way
   122         //TODO check if we can do it in better way
   129         // this is temporary solution
   123         // this is temporary solution
   130         // for this I have written two functions getDataSource and getInputStream function
   124         // for this I have written two functions getDataSource and getInputStream function
   133         InputStreamSourceStream isss=(InputStreamSourceStream)isds.getStreams()[0];
   127         InputStreamSourceStream isss=(InputStreamSourceStream)isds.getStreams()[0];
   134         InputStream is = isss.getInputStream();
   128         InputStream is = isss.getInputStream();
   135         if (is!=null)
   129         if (is!=null)
   136         {
   130         {
   137             ImageLoader imageLoader= new ImageLoader();
   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
   138             iImageData=imageLoader.load(is);
   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");
   139             try
   140             try
   140             {
   141             {
   141                 is.close();
   142                 is.close();
   142             }
   143             }
   143             catch (IOException e)
   144             catch (IOException e)
   144             {
   145             {
   145                 e.printStackTrace();
   146                 e.printStackTrace();
   146             }
   147             }
   147             iSourceDimension= new Point(imageLoader.logicalScreenWidth, imageLoader.logicalScreenHeight);
   148             iSourceDimension= new Point(imageLoader.logicalScreenWidth, imageLoader.logicalScreenHeight);
       
   149             iCurrentVideoDimension= new Point(imageLoader.logicalScreenWidth, imageLoader.logicalScreenHeight);
   148             iBackgroundPixel= imageLoader.backgroundPixel;
   150             iBackgroundPixel= imageLoader.backgroundPixel;
   149         }
   151         }
   150         populateControl();
   152         populateControl();
   151 
   153 
   152     }
   154     }
   154     /**
   156     /**
   155      *
   157      *
   156      * @param locator
   158      * @param locator
   157      * @throws SWTException
   159      * @throws SWTException
   158      */
   160      */
   159     public AnimationPlayer(String locator) throws SWTException
   161     public AnimationPlayer(String locator) throws SWTException, MediaException
   160     {
   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");
   161         iPlayerListenerImpl= new PlayerListenerImpl(this);
   171         iPlayerListenerImpl= new PlayerListenerImpl(this);
   162         ImageLoader imageLoader= new ImageLoader();
       
   163         // Following line may throw SWTException
       
   164         iImageData=imageLoader.load(locator);
       
   165         iSourceDimension= new Point(imageLoader.logicalScreenWidth, imageLoader.logicalScreenHeight);
   172         iSourceDimension= new Point(imageLoader.logicalScreenWidth, imageLoader.logicalScreenHeight);
       
   173         iCurrentVideoDimension= new Point(imageLoader.logicalScreenWidth, imageLoader.logicalScreenHeight);
   166         iBackgroundPixel= imageLoader.backgroundPixel;
   174         iBackgroundPixel= imageLoader.backgroundPixel;
   167         populateControl();
   175         populateControl();
   168     }
   176     }
   169 
   177 
   170     /**
   178     /**
   204      */
   212      */
   205     protected void doStop() throws MediaException
   213     protected void doStop() throws MediaException
   206     {
   214     {
   207         // since after stopping the player the player state will move to pre-fetched state
   215         // since after stopping the player the player state will move to pre-fetched state
   208         changePlayerState(PREFETCHED);
   216         changePlayerState(PREFETCHED);
   209         iPlayerListenerImpl.postEvent(PlayerListener.STOPPED, new Long(iMediaTime * 10000));
   217         //iPlayerListenerImpl.postEvent(PlayerListener.STOPPED, new Long(iMediaTime * 10000));
       
   218         iPlayerListenerImpl.postEvent(PlayerListener.STOPPED, new Long(iMediaTime));
   210     }
   219     }
   211 
   220 
   212     /**
   221     /**
   213      * Function of InternalPlayer interface
   222      * Function of InternalPlayer interface
   214      */
   223      */
   249      * This returns the total time taken, till now, to play the video.
   258      * This returns the total time taken, till now, to play the video.
   250      */
   259      */
   251     public long getMediaTime()
   260     public long getMediaTime()
   252     {
   261     {
   253         closeCheck();
   262         closeCheck();
   254         // Since we have to return it in microsecond multiply it with 10000;
   263         return iMediaTime;
   255         return iMediaTime*10000;
       
   256     }
   264     }
   257 
   265 
   258     public int getState()
   266     public int getState()
   259     {
   267     {
   260         return iState;
   268         return iState;
   270     }
   278     }
   271 
   279 
   272     /**
   280     /**
   273      *
   281      *
   274      */
   282      */
   275 
   283     GC gc = null;
   276     public void start() throws MediaException
   284     public void start() throws MediaException
   277     {
   285     {
   278         final String DEBUG_STR = "AnimationPlayer::start()";
   286         final String DEBUG_STR = "AnimationPlayer::start()";
   279         final long inTime = System.currentTimeMillis();
   287 //        final long inTime = System.currentTimeMillis();
   280 
       
   281         prefetch();
   288         prefetch();
   282         // Only prefetched player may be started. If player is already started
   289         // Only prefetched player may be started. If player is already started
   283         // this method returns silently.
   290         // this method returns silently.
   284         if (getState() == PREFETCHED)
   291         if (getState() == PREFETCHED)
   285         {
   292         {
   286             //initialize();
   293             //initialize();
   287             changePlayerState(STARTED);
   294             changePlayerState(STARTED);
   288             Thread thread = new Thread("Animation")
   295             Thread thread = new Thread("Animation")
   289             {
   296             {
   290                 int loopCount = iCurrentLoopCount;
   297                 int loopCount = iCurrentLoopCount;
   291                 GC gc = null;
       
   292                 public void run()
   298                 public void run()
   293                 {
   299                 {
   294                     //changePlayerState(STARTED);
   300                     //changePlayerState(STARTED);
   295                     final int noOfFrames = iImageData.length;
   301                     final int noOfFrames = iImageData.length;
   296                     while (iState == STARTED)
   302                     while (iState == STARTED)
   297                     {
   303                     {
   298                         final int delayTimeForNextFrame = iImageData[iFrameIndex].delayTime;
   304                         final int delayTimeForNextFrame = iImageData[iFrameIndex].delayTime*10000 ;
   299                         // Since we are going to display first frame, notify all
   305                         // Since we are going to display first frame, notify all
   300                         // PlayerListener that Player has started
   306                         // PlayerListener that Player has started
   301                         if (iFrameIndex == 0)
   307                         if (iFrameIndex == 0)
   302                         {
   308                         {
       
   309                             iMediaTime=0;
   303                             iPlayerListenerImpl.postEvent(
   310                             iPlayerListenerImpl.postEvent(
   304                                 PlayerListener.STARTED, new Long(
   311                                 PlayerListener.STARTED, new Long(0));
   305                                     iMediaTime * 10000));
   312 
   306                         }
   313                         }
   307                         if (iDisplay != null)
   314                         if (iDisplay != null)
   308                         {
   315                         {
   309                             iDisplay.syncExec(new Runnable()
   316                             iDisplay.syncExec(new Runnable()
   310                             {
   317                             {
   311                                 public void run()
   318                                 public void run()
   312                                 {
   319                                 {
   313                                     if (gc == null)
   320                                     // For out of memory issue in case of full screen, we are scaling the image
   314                                         gc = new GC(iImage);
   321                                     // while displaying it.
   315                                     Image tempImage = new Image(iDisplay,iImageData[iFrameIndex]);
   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]);
   316                                     gc.drawImage(tempImage, 0, 0);
   329                                     gc.drawImage(tempImage, 0, 0);
   317                                     tempImage.dispose();
   330                                     tempImage.dispose();
   318                                     iFrameIndex = (iFrameIndex + 1) % noOfFrames;
   331                                     iFrameIndex = (iFrameIndex + 1) % noOfFrames;
   319                                     if (iControl != null)
   332                                     if (iControl != null)
   320                                     {
   333                                     {
   322                                     }
   335                                     }
   323                                     iMediaTime += delayTimeForNextFrame;
   336                                     iMediaTime += delayTimeForNextFrame;
   324                                 }
   337                                 }
   325                             });
   338                             });
   326                         }
   339                         }
   327                         else// if the initDisplayMode is not called yer
   340                         else// if the initDisplayMode is not called yet
   328                         {
   341                         {
   329                             iFrameIndex = (iFrameIndex + 1) % noOfFrames;
   342                             iFrameIndex = (iFrameIndex + 1) % noOfFrames;
   330                             iMediaTime += delayTimeForNextFrame;
   343                             iMediaTime += delayTimeForNextFrame;
   331                         }
   344                         }
   332                         try
   345                         try
   333                         {
   346                         {
   334                             Thread.sleep(delayTimeForNextFrame * 10);
   347                             Thread.sleep(delayTimeForNextFrame / 1000);
   335                         }
   348                         }
   336                         catch (InterruptedException e)
   349                         catch (InterruptedException e)
   337                         {
   350                         {
   338                             // TODO Auto-generated catch block
       
   339                             e.printStackTrace();
   351                             e.printStackTrace();
   340                         }
   352                         }
   341                         // post EOM event
   353                         // post EOM event
   342                         if (iFrameIndex == 0)
   354                         if (iFrameIndex == 0)
   343                         {
   355                         {
   350                             }
   362                             }
   351                             // send the END_OF_MEDIA event to all
   363                             // send the END_OF_MEDIA event to all
   352                             // listener
   364                             // listener
   353                             iPlayerListenerImpl.postEvent(
   365                             iPlayerListenerImpl.postEvent(
   354                                 PlayerListener.END_OF_MEDIA,
   366                                 PlayerListener.END_OF_MEDIA,
   355                                 new Long(iMediaTime * 10000));
   367                                 new Long(iMediaTime));
   356                             iMediaTime = 0;
       
   357                         }
   368                         }
   358                         if (iAnimationObserver!=null)
   369                         if (iAnimationObserver!=null)
   359                         {
   370                         {
   360                             iAnimationObserver.animationAdvanced(iMediaTime*10000);
   371                             iAnimationObserver.animationAdvanced(iMediaTime);
   361                         }
   372                         }
   362                     }// end of while loop
   373                     }// end of while loop
   363                     iCurrentLoopCount = loopCount;
   374                     iCurrentLoopCount = loopCount;
   364                     // Logger.LOG(Logger.EJavaMMAPI, Logger.EInfo, DEBUG_STR
       
   365 
       
   366                 }
   375                 }
   367             };
   376             };
   368             thread.start();
   377             thread.start();
   369         }
   378         }
   370         // Logger.LOG(Logger.EJavaMMAPI, Logger.EInfo,DEBUG_STR + "-");
       
   371     }
   379     }
   372 
   380 
   373     /**
   381     /**
   374      * State of the player should be changed from this function only.
   382      * State of the player should be changed from this function only.
   375      * @param aState
   383      * @param aState
   571      *  It is getting created, when initDisplayMode of VideoControl class is called.
   579      *  It is getting created, when initDisplayMode of VideoControl class is called.
   572      */
   580      */
   573     public void notifyDisplayAvailable(Display aDisplay)
   581     public void notifyDisplayAvailable(Display aDisplay)
   574     {
   582     {
   575         iDisplay= aDisplay;
   583         iDisplay= aDisplay;
   576         iImage=new Image(iDisplay, iImageData[0]);
   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         });
   577     }
   593     }
   578     /**
   594     /**
   579      * Notified when the control is available
   595      * Notified when the control is available
   580      * @param aControl(this is eSWTControl )
   596      * @param aControl(this is eSWTControl )
   581      */
   597      */
   591      * This function will be called from setDisplaySize(int width, int height) of animation/VideoControl class
   607      * This function will be called from setDisplaySize(int width, int height) of animation/VideoControl class
   592      * When MIDlet developer will try to alter the size of the image
   608      * When MIDlet developer will try to alter the size of the image
   593      * @param width : to be set of the video(Animated GIF)
   609      * @param width : to be set of the video(Animated GIF)
   594      * @param height : height to be set of video(Animated GIF)
   610      * @param height : height to be set of video(Animated GIF)
   595      */
   611      */
   596     void updateImageData(int width, int height)
   612     void updateImageData(int aWidth, int aHeight)
   597     {
   613     {
   598         int noOfFrames= iImageData.length;
   614 //        int noOfFrames= iImageData.length;
   599         for (int i=0; i<noOfFrames; i++)
   615 //        for (int i=0; i<noOfFrames; i++)
   600         {
   616 //        {
   601             iImageData[i]=iImageData[i].scaledTo(width, height);
   617 //            iImageData[i]=iImageData[i].scaledTo(aWidth, aHeight);
   602         }
   618 //        }
   603         iImage=new Image(iDisplay, iImageData[iFrameIndex]);
   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));
   604     }
   623     }
   605 
   624 
   606     /**
   625     /**
   607      * Overloaded function for calling the above function
   626      * Overloaded function for calling the above function
   608      */
   627      */
   639     /**
   658     /**
   640      * Returns Point object, which contains the width and height of the image
   659      * Returns Point object, which contains the width and height of the image
   641      * Called from VideoControl to get the image width and height,
   660      * Called from VideoControl to get the image width and height,
   642      * so that Item will be created exactly of same dimension
   661      * so that Item will be created exactly of same dimension
   643      */
   662      */
   644     Point getImageDimension()
   663     Point getCurrentVideoDimension()
   645     {
   664     {
   646 //      return iCurrentVideoDimension;
   665         return iCurrentVideoDimension;
   647         return new org.eclipse.swt.graphics.Point(iImageData[0].width, iImageData[0].height);
   666         // return new org.eclipse.swt.graphics.Point(iImageData[0].width, iImageData[0].height);
   648     }
   667     }
   649 
   668 
   650 
   669 
   651     int getTotalNumberFrames()
   670     int getTotalNumberFrames()
   652     {
   671     {
   659     void setDisplayLocation(int aX, int aY)
   678     void setDisplayLocation(int aX, int aY)
   660     {
   679     {
   661         iDisplayLocation.x=aX;
   680         iDisplayLocation.x=aX;
   662         iDisplayLocation.y=aY;
   681         iDisplayLocation.y=aY;
   663     }
   682     }
   664 
       
   665     /**
   683     /**
   666      * @return the position of the image to be displayed
   684      * @return the position of the image to be displayed
   667      */
   685      */
   668     Point getiDisplayLocation()
   686     Point getiDisplayLocation()
   669     {
   687     {
   747     void setiIsControlVisible(boolean iIsControlVisible)
   765     void setiIsControlVisible(boolean iIsControlVisible)
   748     {
   766     {
   749         this.iIsControlVisible = iIsControlVisible;
   767         this.iIsControlVisible = iIsControlVisible;
   750     }
   768     }
   751     /**
   769     /**
   752      * Called from
   770      * Called from StopTimeControl.animationAdvanced(long), once the stopped time is greater than or equal media time.
   753      */
   771      */
   754     void postEvent(long aMediaTime)
   772     void postEvent(long aMediaTime)
   755     {
   773     {
   756         changePlayerState(PREFETCHED);
   774         changePlayerState(PREFETCHED);
   757         iPlayerListenerImpl.postEvent(PlayerListener.STOPPED_AT_TIME, new Long(
   775         iPlayerListenerImpl.postEvent(PlayerListener.STOPPED_AT_TIME, new Long(