javauis/mmapi_akn/audiostreaming/src.emc/cmmaaudiostreamplayer.cpp
branchRCL_3
changeset 19 04becd199f91
child 46 4376525cdefb
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2002 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:  This class is used for streaming audio.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 //  INCLUDE FILES
       
    20 #include <AudioPreference.h>
       
    21 #include <jdebug.h>
       
    22 
       
    23 #include "cmmaaudiostreamplayer.h"
       
    24 #include "cmmadatasourcestream.h"
       
    25 #include "cmmaeventsource.h"
       
    26 #include "cmmastreamhandler.h"
       
    27 
       
    28 _LIT(KMMAStreamErrorMessage, "Internal error: %d");
       
    29 
       
    30 
       
    31 CMMAAudioStreamPlayer* CMMAAudioStreamPlayer::NewLC(
       
    32     CMMAEMCResolver* aResolver)
       
    33 {
       
    34     DEBUG("MMA::CMMAAudioStreamPlayer::NewLC +");
       
    35     CMMAAudioStreamPlayer* self = new(ELeave) CMMAAudioStreamPlayer(aResolver);
       
    36     CleanupStack::PushL(self);
       
    37     self->ConstructL();
       
    38     DEBUG("MMA::CMMAAudioStreamPlayer::NewLC -");
       
    39     return self;
       
    40 }
       
    41 
       
    42 CMMAAudioStreamPlayer::~CMMAAudioStreamPlayer()
       
    43 {
       
    44     DEBUG("MMA::CMMAAudioStreamPlayer::~CMMAAudioStreamPlayer +");
       
    45 
       
    46     if (iMStreamControl->GetState() > MStreamControl::CLOSED)
       
    47     {
       
    48         iMStreamControl->Close();
       
    49     }
       
    50 
       
    51     delete iStreamHandler;
       
    52 
       
    53     DEBUG("MMA::CMMAAudioStreamPlayer::~CMMAAudioStreamPlayer -");
       
    54 }
       
    55 
       
    56 
       
    57 CMMAAudioStreamPlayer::CMMAAudioStreamPlayer(
       
    58     CMMAEMCResolver* aResolver):
       
    59         CMMAEMCAudioPlayer(aResolver)
       
    60 {
       
    61     DEBUG("MMA::CMMAAudioStreamPlayer::CMMAAudioStreamPlayer");
       
    62 }
       
    63 
       
    64 void CMMAAudioStreamPlayer::ConstructL()
       
    65 {
       
    66     DEBUG("MMA::CMMAAudioStreamPlayer::ConstructL +");
       
    67     iControllerPrimed = EFalse;
       
    68     CMMAEMCAudioPlayer::ConstructL();
       
    69     iMetaDataUtility = CMetaDataUtility::NewL();
       
    70     iStreamHandler = CMMAStreamHandler::NewL(*this,
       
    71                      *iMStreamControl,
       
    72                      *iMDataBufferSource,
       
    73                      *iFactory,
       
    74                      *iMetaDataUtility);
       
    75     iActiveSchedulerWait = new(ELeave)CActiveSchedulerWait();
       
    76     DEBUG("MMA::CMMAAudioStreamPlayer::ConstructL -");
       
    77 }
       
    78 
       
    79 CMMASourceStream* CMMAAudioStreamPlayer::AddSourceStreamL(JNIEnv* aJNIEnv,
       
    80         CMMAEventSource* aEventSource,
       
    81         jobject aReader)
       
    82 {
       
    83     DEBUG("MMA::CMMAAudioStreamPlayer::AddSourceStreamL +");
       
    84     CMMADataSourceStream* sourceStream = CMMADataSourceStream::NewLC(aJNIEnv,
       
    85                                          aEventSource,
       
    86                                          aReader,
       
    87                                          this);
       
    88     User::LeaveIfError(iSourceStreams.Append(sourceStream));
       
    89     CleanupStack::Pop(sourceStream);
       
    90     iStreamHandler->SetSourceStream(sourceStream);
       
    91     DEBUG("MMA::CMMAAudioStreamPlayer::AddSourceStreamL -");
       
    92     return sourceStream;
       
    93 }
       
    94 
       
    95 CMetaDataUtility* CMMAAudioStreamPlayer::MetaDataUtilityOwnership()
       
    96 {
       
    97     CMetaDataUtility* temp = iMetaDataUtility;
       
    98     iMetaDataUtility = NULL;
       
    99     return temp;
       
   100 }
       
   101 
       
   102 void CMMAAudioStreamPlayer::DeallocateL()
       
   103 {
       
   104     DEBUG("MMA::CMMAAudioStreamPlayer::DeallocateL +");
       
   105     iStreamHandler->Stop();
       
   106     iControllerPrimed = EFalse;
       
   107     CMMAEMCPlayerBase::DeallocateL();
       
   108     DEBUG("MMA::CMMAAudioStreamPlayer::DeallocateL -");
       
   109 }
       
   110 
       
   111 void CMMAAudioStreamPlayer::PrefetchL()
       
   112 {
       
   113     DEBUG("CMMAAudioStreamPlayer::PrefetchL +");
       
   114     __ASSERT_DEBUG(iSourceStreams.Count() > 0, User::Invariant());
       
   115     iStreamHandler->Prepare(*iMimeType);
       
   116     DEBUG("CMMAAudioStreamPlayer::PrefetchL -");
       
   117 }
       
   118 
       
   119 void CMMAAudioStreamPlayer::StartL()
       
   120 {
       
   121     DEBUG("MMA::CMMAAudioStreamPlayer::StartL +");
       
   122     if (iStreamHandler->LastBufferWritten() &&
       
   123             (iMStreamControl ->GetState() == MStreamControl::PAUSED))
       
   124     {
       
   125         TInt64 time;
       
   126         GetMediaTime(&time);
       
   127         TInt err = iMStreamControl->Start();
       
   128         if (err == KErrNone && iState != EStarted)
       
   129         { // move to started state and post started event
       
   130             PostLongEvent(CMMAPlayerEvent::EStarted, time);
       
   131             ChangeState(EStarted);
       
   132         }
       
   133         else
       
   134         { // post error event
       
   135             HandleError(err);
       
   136             PostActionCompleted(err);   // java start return
       
   137         }
       
   138     }
       
   139     else
       
   140     {
       
   141         iStreamHandler->Start();
       
   142     }
       
   143 
       
   144     DEBUG("MMA::CMMAAudioStreamPlayer::StartL -");
       
   145 }
       
   146 
       
   147 void CMMAAudioStreamPlayer::StopL(TBool aPostEvent)
       
   148 {
       
   149     DEBUG_INT("CMMAAudioStreamPlayer::Stop state %d", iState);
       
   150     if (iState == EStarted)
       
   151     {
       
   152         User::LeaveIfError(Pause());
       
   153         // go back to prefetched state
       
   154         ChangeState(EPrefetched);
       
   155         if (aPostEvent)
       
   156         {
       
   157             TInt64 time;
       
   158             GetMediaTime(&time);
       
   159             PostLongEvent(CMMAPlayerEvent::EStopped, time);
       
   160         }
       
   161     }
       
   162     DEBUG("CMMAAudioStreamPlayer::Stop OK");
       
   163 }
       
   164 
       
   165 TInt CMMAAudioStreamPlayer::Pause()
       
   166 {
       
   167     DEBUG("MMA::CMMAAudioStreamPlayer::Pause +");
       
   168     iStreamHandler->Pause();
       
   169     DEBUG_INT("MMA::CMMAAudioStreamPlayer:: iStreamControl State = %d",iMStreamControl->GetState());
       
   170 
       
   171     TInt err = KErrNone;
       
   172     if (iMStreamControl->GetState() != MStreamControl::PAUSED)
       
   173     {
       
   174         err = iMStreamControl->Pause();
       
   175         DEBUG_INT("MMA::CMMAAudioStreamPlayer:: iStreamControl Pause error = %d", err);
       
   176         if ((!iActiveSchedulerWait->IsStarted()) && (err == KErrNone))
       
   177         {
       
   178             iActiveSchedulerWait->Start();
       
   179         }
       
   180     }
       
   181     DEBUG("MMA::CMMAAudioStreamPlayer::Pause -");
       
   182     return err;
       
   183 }
       
   184 
       
   185 void CMMAAudioStreamPlayer::PlayCompleteL(TInt aError)
       
   186 {
       
   187     DEBUG_INT("MMA::CMMAAudioStreamPlayer::PlayCompleteL error %d",
       
   188               aError);
       
   189 
       
   190     // Before controller is started it must be primed
       
   191     iControllerPrimed = EFalse;
       
   192 
       
   193     TInt64 time;
       
   194     GetDuration(&time);
       
   195 
       
   196     // Send 'Stopped' only when stop() is called.
       
   197     PostLongEvent(CMMAPlayerEvent::EEndOfMedia, time);
       
   198 
       
   199     ChangeState(EPrefetched);   // ready to play again
       
   200 
       
   201     if (aError == KErrNone)
       
   202     {
       
   203         iRepeatCount++;
       
   204 
       
   205         if (iRepeatForever || iRepeatCount < iRepeatNumberOfTimes)
       
   206         {
       
   207             StartL();
       
   208         }
       
   209         else
       
   210         {
       
   211             iRepeatCount = 0;
       
   212         }
       
   213     }
       
   214     else
       
   215     {
       
   216         // error has occured, setting correct number of
       
   217         // repeats for next start
       
   218         SetLoopCount(iRepeatNumberOfTimes);
       
   219     }
       
   220 }
       
   221 
       
   222 void CMMAAudioStreamPlayer::GetDuration(TInt64* aDuration)
       
   223 {
       
   224     CMMAPlayer::GetDuration(aDuration);
       
   225 }
       
   226 
       
   227 void CMMAAudioStreamPlayer::PrepareComplete(TInt aError)
       
   228 {
       
   229     DEBUG_INT("MMA::CMMAAudioStreamPlayer::PrepareComplete error %d",
       
   230               aError);
       
   231 
       
   232     if (aError == KErrNone)
       
   233     {
       
   234         ChangeState(EPrefetched);
       
   235     }
       
   236     PostActionCompleted(aError);   // java prefetch return
       
   237 }
       
   238 
       
   239 void CMMAAudioStreamPlayer::StartComplete(TInt aError)
       
   240 {
       
   241     DEBUG_INT("MMA::CMMAAudioStreamPlayer::StartComplete error %d",
       
   242               aError);
       
   243 
       
   244     // do not start if player is deallocated or closed
       
   245     // RateControl start can start controller in started state
       
   246     if ((iState != EStarted) &&
       
   247             (iState != EPrefetched))
       
   248     {
       
   249         PostActionCompleted(KErrNone);   // java start return
       
   250         return;
       
   251     }
       
   252 
       
   253     TInt err = aError;
       
   254     if (!iControllerPrimed)
       
   255     {
       
   256         // Prime must be called when player is started first time or restarted
       
   257         err = iMStreamControl->Prime();
       
   258 
       
   259         DEBUG_INT("MMA::CMMAAudioStreamPlayer::StartComplete prime error %d",
       
   260                   err);
       
   261     }
       
   262     else
       
   263     {
       
   264         err = KErrNone;
       
   265     }
       
   266 
       
   267     if (iControllerPrimed && (iState == EPrefetched))
       
   268     {
       
   269 
       
   270         TInt64 time;
       
   271         if (err == KErrNone)
       
   272         {
       
   273             // must be primed before media time can be get
       
   274             GetMediaTime(&time);
       
   275             err = iMStreamControl->Start();
       
   276             DEBUG_INT("MMA::CMMAAudioStreamPlayer::StartComplete play error %d",
       
   277                       err);
       
   278 
       
   279         }
       
   280 
       
   281         // RateControl can start controller in started state, then Java event is
       
   282         // not sent
       
   283         if (err == KErrNone && iState != EStarted)
       
   284         { // move to started state and post started event
       
   285             PostLongEvent(CMMAPlayerEvent::EStarted, time);
       
   286             ChangeState(EStarted);
       
   287         }
       
   288         else
       
   289         { // post error event
       
   290             HandleError(aError);
       
   291             PostActionCompleted(aError);   // java start return
       
   292         }
       
   293     }
       
   294 
       
   295 }
       
   296 
       
   297 void CMMAAudioStreamPlayer::HandleError(TInt aError)
       
   298 {
       
   299     DEBUG_INT("MMA::CMMAAudioStreamPlayer::HandleError error %d",
       
   300               aError);
       
   301 
       
   302     TName errorMessage;
       
   303     errorMessage.Format(KMMAStreamErrorMessage, aError);
       
   304     PostStringEvent(CMMAPlayerEvent::EError, errorMessage);
       
   305 }
       
   306 
       
   307 void CMMAAudioStreamPlayer::Event(MControl* aControl, TUint aEventType, TAny* aEventObject)
       
   308 {
       
   309 
       
   310     switch (aEventType)
       
   311     {
       
   312 
       
   313     case MStreamControlObserver::KStateChangedEvent:
       
   314     {
       
   315         MStateChangedEvent* evt = (MStateChangedEvent*)aEventObject;
       
   316         MStreamControl* control1 = (MStreamControl*)(aControl);
       
   317         switch (control1->GetState())
       
   318         {
       
   319         case MStreamControl::CLOSED:
       
   320         {
       
   321             iPrevStreamControlState = MStreamControl::CLOSED;
       
   322             DEBUG("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent :CLOSED");
       
   323         }
       
   324         break;
       
   325 
       
   326         case MStreamControl::INITIALIZED:
       
   327         {
       
   328             DEBUG("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent :INITIALIZED");
       
   329             switch (iPrevStreamControlState)
       
   330             {
       
   331             case MStreamControl::CLOSED:
       
   332             {
       
   333                 iPrevStreamControlState = MStreamControl::INITIALIZED;
       
   334                 if (iActiveSchedulerWait->IsStarted())
       
   335                 {
       
   336                     iActiveSchedulerWait->AsyncStop();
       
   337                 }
       
   338             }
       
   339             break;
       
   340 
       
   341             case MStreamControl::INITIALIZED:
       
   342             {
       
   343                 iPrevStreamControlState = MStreamControl::INITIALIZED;
       
   344                 DEBUG("inner Switch case: MStreamControl::INITIALIZED ");
       
   345                 DEBUG_INT("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent:ErrorCode = %d ",evt->GetErrorCode());
       
   346                 // error occured during prime operation
       
   347                 // move player back to prefetched state
       
   348                 if (iState == EStarted)
       
   349                 {
       
   350                     ChangeState(EPrefetched);
       
   351                 }
       
   352                 PostActionCompleted(evt->GetErrorCode());   // java start return
       
   353             }
       
   354             break;
       
   355 
       
   356             case MStreamControl::PRIMED:
       
   357             {
       
   358                 iPrevStreamControlState = MStreamControl::INITIALIZED;
       
   359                 DEBUG("inner Switch case: MStreamControl::PRIMED ");
       
   360 
       
   361             }
       
   362             break;
       
   363 
       
   364             case MStreamControl::EXECUTING:
       
   365             {
       
   366                 iPrevStreamControlState = MStreamControl::INITIALIZED;
       
   367                 DEBUG("inner Switch case: MStreamControl::EXECUTING ");
       
   368                 DEBUG_INT("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent:ErrorCode = %d ",evt->GetErrorCode());
       
   369                 if (KErrEof == evt->GetErrorCode())
       
   370                 {
       
   371                     TRAPD(error, PlayCompleteL(KErrNone));
       
   372                     if (KErrNone != error)
       
   373                     {
       
   374                         DEBUG_INT("MMA::CMMAAudioStreamPlayer::Event:PlayCompleteL Error = %d", error);
       
   375                     }
       
   376                 }
       
   377             }
       
   378             break;
       
   379 
       
   380             case MStreamControl::BUFFERING:
       
   381             {
       
   382                 iPrevStreamControlState = MStreamControl::INITIALIZED;
       
   383                 DEBUG("inner Switch case: MStreamControl::BUFFERING ");
       
   384             }
       
   385             break;
       
   386 
       
   387             case MStreamControl::PAUSED:
       
   388             {
       
   389                 iPrevStreamControlState = MStreamControl::INITIALIZED;
       
   390                 DEBUG("inner Switch case: MStreamControl::PAUSED ");
       
   391             }
       
   392             break;
       
   393             }
       
   394         }
       
   395         break;
       
   396 
       
   397         case MStreamControl::PRIMED:
       
   398         {
       
   399             DEBUG("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent :PRIMED");
       
   400             iPrevStreamControlState = MStreamControl::PRIMED;
       
   401             iControllerPrimed = ETrue;
       
   402             TInt64 time;
       
   403             // must be primed before media time can be get
       
   404             GetMediaTime(&time);
       
   405             TInt err = iMStreamControl->Start();
       
   406             DEBUG_INT("MMA::CMMAAudioStreamPlayer::Event play error %d",
       
   407                       err);
       
   408 
       
   409             // RateControl can start controller in started state, then Java event is
       
   410             // not sent
       
   411             if (err == KErrNone && iState != EStarted)
       
   412             { // move to started state and post started event
       
   413                 PostLongEvent(CMMAPlayerEvent::EStarted, time);
       
   414                 ChangeState(EStarted);
       
   415             }
       
   416             else
       
   417             {
       
   418                 PostLongEvent(CMMAPlayerEvent::EStarted, time);
       
   419             }
       
   420         }
       
   421         break;
       
   422 
       
   423         case MStreamControl::EXECUTING:
       
   424         {
       
   425             DEBUG("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent :EXECUTING");
       
   426             iPrevStreamControlState = MStreamControl::EXECUTING;
       
   427             PostActionCompleted(KErrNone);   // java start return
       
   428         }
       
   429         break;
       
   430 
       
   431         case MStreamControl::BUFFERING:
       
   432         {
       
   433             iPrevStreamControlState = MStreamControl::BUFFERING;
       
   434             DEBUG("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent :BUFFERING");
       
   435         }
       
   436         break;
       
   437 
       
   438         case MStreamControl::PAUSED:
       
   439         {
       
   440             iPrevStreamControlState = MStreamControl::PAUSED;
       
   441             if (iActiveSchedulerWait->IsStarted())
       
   442             {
       
   443                 iActiveSchedulerWait->AsyncStop();
       
   444             }
       
   445             DEBUG("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent :PAUSED");
       
   446         }
       
   447         break;
       
   448 
       
   449         default:
       
   450             DEBUG("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent :DEFAULT");
       
   451             break;
       
   452         }
       
   453     }
       
   454     break;
       
   455 
       
   456     case MControlObserver::KErrorEvent:
       
   457     {
       
   458         MErrorCode* evt = (MErrorCode*)aEventObject;
       
   459         if (KErrNone != evt->GetErrorCode())
       
   460         {
       
   461             DEBUG_INT("MMA::CMMAAudioStreamPlayer::Event:KErrorEvent, err = %d", evt->GetErrorCode());
       
   462         }
       
   463     }
       
   464     break;
       
   465     }
       
   466 }
       
   467 //  END OF FILE