javauis/mmapi_akn/audiostreaming/src.emc/cmmaaudiostreamplayer.cpp
branchRCL_3
changeset 26 2455ef1f5bbc
equal deleted inserted replaced
25:ae942d28ec0e 26:2455ef1f5bbc
       
     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(TBool aPostEvent)
       
   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         {
       
   130             // move to started state and post started event
       
   131             if (aPostEvent)
       
   132             {
       
   133                 PostLongEvent(CMMAPlayerEvent::EStarted, time);
       
   134             }
       
   135             ChangeState(EStarted);
       
   136         }
       
   137         else
       
   138         { // post error event
       
   139             HandleError(err);
       
   140             PostActionCompleted(err);   // java start return
       
   141         }
       
   142     }
       
   143     else
       
   144     {
       
   145         iStreamHandler->Start();
       
   146     }
       
   147 
       
   148     DEBUG("MMA::CMMAAudioStreamPlayer::StartL -");
       
   149 }
       
   150 
       
   151 void CMMAAudioStreamPlayer::StopL(TBool aPostEvent)
       
   152 {
       
   153     DEBUG_INT("CMMAAudioStreamPlayer::Stop state %d", iState);
       
   154     if (iState == EStarted)
       
   155     {
       
   156         User::LeaveIfError(Pause());
       
   157         // go back to prefetched state
       
   158         ChangeState(EPrefetched);
       
   159         if (aPostEvent)
       
   160         {
       
   161             TInt64 time;
       
   162             GetMediaTime(&time);
       
   163             PostLongEvent(CMMAPlayerEvent::EStopped, time);
       
   164         }
       
   165     }
       
   166     DEBUG("CMMAAudioStreamPlayer::Stop OK");
       
   167 }
       
   168 
       
   169 TInt CMMAAudioStreamPlayer::Pause()
       
   170 {
       
   171     DEBUG("MMA::CMMAAudioStreamPlayer::Pause +");
       
   172     iStreamHandler->Pause();
       
   173     DEBUG_INT("MMA::CMMAAudioStreamPlayer:: iStreamControl State = %d",iMStreamControl->GetState());
       
   174 
       
   175     TInt err = KErrNone;
       
   176     if (iMStreamControl->GetState() != MStreamControl::PAUSED)
       
   177     {
       
   178         err = iMStreamControl->Pause();
       
   179         DEBUG_INT("MMA::CMMAAudioStreamPlayer:: iStreamControl Pause error = %d", err);
       
   180         if ((!iActiveSchedulerWait->IsStarted()) && (err == KErrNone))
       
   181         {
       
   182             iActiveSchedulerWait->Start();
       
   183         }
       
   184     }
       
   185     DEBUG("MMA::CMMAAudioStreamPlayer::Pause -");
       
   186     return err;
       
   187 }
       
   188 
       
   189 void CMMAAudioStreamPlayer::PlayCompleteL(TInt aError)
       
   190 {
       
   191     DEBUG_INT("MMA::CMMAAudioStreamPlayer::PlayCompleteL error %d",
       
   192               aError);
       
   193 
       
   194     // Before controller is started it must be primed
       
   195     iControllerPrimed = EFalse;
       
   196 
       
   197     TInt64 time;
       
   198     GetDuration(&time);
       
   199 
       
   200     // Send 'Stopped' only when stop() is called.
       
   201     PostLongEvent(CMMAPlayerEvent::EEndOfMedia, time);
       
   202 
       
   203     ChangeState(EPrefetched);   // ready to play again
       
   204 
       
   205     if (aError == KErrNone)
       
   206     {
       
   207         iRepeatCount++;
       
   208 
       
   209         if (iRepeatForever || iRepeatCount < iRepeatNumberOfTimes)
       
   210         {
       
   211             StartL(ETrue);
       
   212         }
       
   213         else
       
   214         {
       
   215             iRepeatCount = 0;
       
   216         }
       
   217     }
       
   218     else
       
   219     {
       
   220         // error has occured, setting correct number of
       
   221         // repeats for next start
       
   222         SetLoopCount(iRepeatNumberOfTimes);
       
   223     }
       
   224 }
       
   225 
       
   226 void CMMAAudioStreamPlayer::GetDuration(TInt64* aDuration)
       
   227 {
       
   228     CMMAPlayer::GetDuration(aDuration);
       
   229 }
       
   230 
       
   231 void CMMAAudioStreamPlayer::PrepareComplete(TInt aError)
       
   232 {
       
   233     DEBUG_INT("MMA::CMMAAudioStreamPlayer::PrepareComplete error %d",
       
   234               aError);
       
   235 
       
   236     if (aError == KErrNone)
       
   237     {
       
   238         ChangeState(EPrefetched);
       
   239     }
       
   240     PostActionCompleted(aError);   // java prefetch return
       
   241 }
       
   242 
       
   243 void CMMAAudioStreamPlayer::StartComplete(TInt aError)
       
   244 {
       
   245     DEBUG_INT("MMA::CMMAAudioStreamPlayer::StartComplete error %d",
       
   246               aError);
       
   247 
       
   248     // do not start if player is deallocated or closed
       
   249     // RateControl start can start controller in started state
       
   250     if ((iState != EStarted) &&
       
   251             (iState != EPrefetched))
       
   252     {
       
   253         PostActionCompleted(KErrNone);   // java start return
       
   254         return;
       
   255     }
       
   256 
       
   257     TInt err = aError;
       
   258     if (!iControllerPrimed)
       
   259     {
       
   260         // Prime must be called when player is started first time or restarted
       
   261         err = iMStreamControl->Prime();
       
   262 
       
   263         DEBUG_INT("MMA::CMMAAudioStreamPlayer::StartComplete prime error %d",
       
   264                   err);
       
   265     }
       
   266     else
       
   267     {
       
   268         err = KErrNone;
       
   269     }
       
   270 
       
   271     if (iControllerPrimed && (iState == EPrefetched))
       
   272     {
       
   273 
       
   274         TInt64 time;
       
   275         if (err == KErrNone)
       
   276         {
       
   277             // must be primed before media time can be get
       
   278             GetMediaTime(&time);
       
   279             err = iMStreamControl->Start();
       
   280             DEBUG_INT("MMA::CMMAAudioStreamPlayer::StartComplete play error %d",
       
   281                       err);
       
   282 
       
   283         }
       
   284 
       
   285         // RateControl can start controller in started state, then Java event is
       
   286         // not sent
       
   287         if (err == KErrNone && iState != EStarted)
       
   288         { // move to started state and post started event
       
   289             PostLongEvent(CMMAPlayerEvent::EStarted, time);
       
   290             ChangeState(EStarted);
       
   291         }
       
   292         else
       
   293         { // post error event
       
   294             HandleError(aError);
       
   295             PostActionCompleted(aError);   // java start return
       
   296         }
       
   297     }
       
   298 
       
   299 }
       
   300 
       
   301 void CMMAAudioStreamPlayer::HandleError(TInt aError)
       
   302 {
       
   303     DEBUG_INT("MMA::CMMAAudioStreamPlayer::HandleError error %d",
       
   304               aError);
       
   305 
       
   306     TName errorMessage;
       
   307     errorMessage.Format(KMMAStreamErrorMessage, aError);
       
   308     PostStringEvent(CMMAPlayerEvent::EError, errorMessage);
       
   309 }
       
   310 
       
   311 void CMMAAudioStreamPlayer::Event(MControl* aControl, TUint aEventType, TAny* aEventObject)
       
   312 {
       
   313 
       
   314     switch (aEventType)
       
   315     {
       
   316 
       
   317     case MStreamControlObserver::KStateChangedEvent:
       
   318     {
       
   319         MStateChangedEvent* evt = (MStateChangedEvent*)aEventObject;
       
   320         MStreamControl* control1 = (MStreamControl*)(aControl);
       
   321         switch (control1->GetState())
       
   322         {
       
   323         case MStreamControl::CLOSED:
       
   324         {
       
   325             iPrevStreamControlState = MStreamControl::CLOSED;
       
   326             DEBUG("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent :CLOSED");
       
   327         }
       
   328         break;
       
   329 
       
   330         case MStreamControl::INITIALIZED:
       
   331         {
       
   332             DEBUG("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent :INITIALIZED");
       
   333             switch (iPrevStreamControlState)
       
   334             {
       
   335             case MStreamControl::CLOSED:
       
   336             {
       
   337                 iPrevStreamControlState = MStreamControl::INITIALIZED;
       
   338                 if (iActiveSchedulerWait->IsStarted())
       
   339                 {
       
   340                     iActiveSchedulerWait->AsyncStop();
       
   341                 }
       
   342             }
       
   343             break;
       
   344 
       
   345             case MStreamControl::INITIALIZED:
       
   346             {
       
   347                 iPrevStreamControlState = MStreamControl::INITIALIZED;
       
   348                 DEBUG("inner Switch case: MStreamControl::INITIALIZED ");
       
   349                 DEBUG_INT("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent:ErrorCode = %d ",evt->GetErrorCode());
       
   350                 // error occured during prime operation
       
   351                 // move player back to prefetched state
       
   352                 if (iState == EStarted)
       
   353                 {
       
   354                     ChangeState(EPrefetched);
       
   355                 }
       
   356                 PostActionCompleted(evt->GetErrorCode());   // java start return
       
   357             }
       
   358             break;
       
   359 
       
   360             case MStreamControl::PRIMED:
       
   361             {
       
   362                 iPrevStreamControlState = MStreamControl::INITIALIZED;
       
   363                 DEBUG("inner Switch case: MStreamControl::PRIMED ");
       
   364 
       
   365             }
       
   366             break;
       
   367 
       
   368             case MStreamControl::EXECUTING:
       
   369             {
       
   370                 iPrevStreamControlState = MStreamControl::INITIALIZED;
       
   371                 DEBUG("inner Switch case: MStreamControl::EXECUTING ");
       
   372                 DEBUG_INT("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent:ErrorCode = %d ",evt->GetErrorCode());
       
   373                 if (KErrEof == evt->GetErrorCode())
       
   374                 {
       
   375                     TRAPD(error, PlayCompleteL(KErrNone));
       
   376                     if (KErrNone != error)
       
   377                     {
       
   378                         DEBUG_INT("MMA::CMMAAudioStreamPlayer::Event:PlayCompleteL Error = %d", error);
       
   379                     }
       
   380                 }
       
   381             }
       
   382             break;
       
   383 
       
   384             case MStreamControl::BUFFERING:
       
   385             {
       
   386                 iPrevStreamControlState = MStreamControl::INITIALIZED;
       
   387                 DEBUG("inner Switch case: MStreamControl::BUFFERING ");
       
   388             }
       
   389             break;
       
   390 
       
   391             case MStreamControl::PAUSED:
       
   392             {
       
   393                 iPrevStreamControlState = MStreamControl::INITIALIZED;
       
   394                 DEBUG("inner Switch case: MStreamControl::PAUSED ");
       
   395             }
       
   396             break;
       
   397             }
       
   398         }
       
   399         break;
       
   400 
       
   401         case MStreamControl::PRIMED:
       
   402         {
       
   403             DEBUG("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent :PRIMED");
       
   404             iPrevStreamControlState = MStreamControl::PRIMED;
       
   405             iControllerPrimed = ETrue;
       
   406             TInt64 time;
       
   407             // must be primed before media time can be get
       
   408             GetMediaTime(&time);
       
   409             TInt err = iMStreamControl->Start();
       
   410             DEBUG_INT("MMA::CMMAAudioStreamPlayer::Event play error %d",
       
   411                       err);
       
   412 
       
   413             // RateControl can start controller in started state, then Java event is
       
   414             // not sent
       
   415             if (err == KErrNone && iState != EStarted)
       
   416             { // move to started state and post started event
       
   417                 PostLongEvent(CMMAPlayerEvent::EStarted, time);
       
   418                 ChangeState(EStarted);
       
   419             }
       
   420             else
       
   421             {
       
   422                 PostLongEvent(CMMAPlayerEvent::EStarted, time);
       
   423             }
       
   424         }
       
   425         break;
       
   426 
       
   427         case MStreamControl::EXECUTING:
       
   428         {
       
   429             DEBUG("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent :EXECUTING");
       
   430             iPrevStreamControlState = MStreamControl::EXECUTING;
       
   431             PostActionCompleted(KErrNone);   // java start return
       
   432         }
       
   433         break;
       
   434 
       
   435         case MStreamControl::BUFFERING:
       
   436         {
       
   437             iPrevStreamControlState = MStreamControl::BUFFERING;
       
   438             DEBUG("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent :BUFFERING");
       
   439         }
       
   440         break;
       
   441 
       
   442         case MStreamControl::PAUSED:
       
   443         {
       
   444             iPrevStreamControlState = MStreamControl::PAUSED;
       
   445             if (iActiveSchedulerWait->IsStarted())
       
   446             {
       
   447                 iActiveSchedulerWait->AsyncStop();
       
   448             }
       
   449             DEBUG("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent :PAUSED");
       
   450         }
       
   451         break;
       
   452 
       
   453         default:
       
   454             DEBUG("MMA::CMMAAudioStreamPlayer::Event:KStateChangedEvent :DEFAULT");
       
   455             break;
       
   456         }
       
   457     }
       
   458     break;
       
   459 
       
   460     case MControlObserver::KErrorEvent:
       
   461     {
       
   462         MErrorCode* evt = (MErrorCode*)aEventObject;
       
   463         if (KErrNone != evt->GetErrorCode())
       
   464         {
       
   465             DEBUG_INT("MMA::CMMAAudioStreamPlayer::Event:KErrorEvent, err = %d", evt->GetErrorCode());
       
   466         }
       
   467     }
       
   468     break;
       
   469     }
       
   470 }
       
   471 //  END OF FILE