camcordermmfplugin/mediarecorder/Src/CCMRVideoRecorderClient.cpp
changeset 0 9b3e960ffc8a
child 10 6bc4220d7f67
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/camcordermmfplugin/mediarecorder/Src/CCMRVideoRecorderClient.cpp	Thu Dec 17 08:51:24 2009 +0200
@@ -0,0 +1,642 @@
+/*
+* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Implementation for video recorder client class
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "CCMRRecorderBase.h"
+#include "CCMRVideoSettings.h"  // default video settings
+#include "CCMRSupportedCodecs.h"
+#include "CCMRVideoRecorderClient.h"
+#include "CCMRVideoCodecs.h"
+
+#include <mmf/common/mmfvideo.h>
+#include <badesca.h>
+
+// Assertion macro wrapper for code cleanup
+#define VRCASSERT(x) __ASSERT_DEBUG(x, User::Panic(_L("CCMRVIDEORECORDER"), EInternalAssertionFailure)) 
+
+// Debug print macro
+#ifdef _DEBUG
+#include <e32svr.h>
+#define PRINT(x) RDebug::Print x
+#else
+#define PRINT(x)
+#endif
+
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::NewL
+// Standard Symbian OS two-phased constructor
+// Returns: CCMRVideoRecorderClient*: Pointer to the newly-created 
+//                              video recorder
+// ---------------------------------------------------------
+//
+CCMRVideoRecorderClient* CCMRVideoRecorderClient::NewL()
+    {
+
+    PRINT((_L("CCMRVideoRecorderClient::NewL()"))); 
+
+    CCMRVideoRecorderClient* self = new (ELeave) CCMRVideoRecorderClient;    
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+
+    return self;    
+
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::ConstructL()
+// Symbian OS Constructor
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::ConstructL()
+    {
+
+    PRINT((_L("CCMRVideoRecorderClient::ConstructL()")));    
+
+    iVideoCodecs = CCMRVideoCodecs::NewL();
+
+    SetState(EStateNone);
+
+    }
+
+
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::~CCMRVideoRecorderClient()
+// Destructor
+// ---------------------------------------------------------
+//
+CCMRVideoRecorderClient::~CCMRVideoRecorderClient()
+    {
+
+    PRINT((_L("CCMRVideoRecorderClient::~CCMRVideoRecorderClient() in")));
+
+    // This is the counterpart to NewL & OpenL, e.g. Close & Delete
+
+    // free all memory allocated and uninitalize & delete objects created
+
+    delete iThreadEventMonitor;
+    iThreadEventMonitor = NULL;
+    // close thread
+    if ( iThreadCreated )
+        {
+        iThreadProxy.Close();
+        }
+
+    delete iVideoCodecs;
+    iVideoCodecs = NULL;
+
+    iObserver = NULL;
+
+    SetState(EStateNone);
+
+    // enable for RTRT code coverage
+    //#pragma attol insert _ATCPQ_DUMP(0);
+    PRINT((_L("CCMRVideoRecorderClient::~CCMRVideoRecorderClient() out")));
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::OpenL
+// Opens the video recorder instance, creates submodules
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::OpenL(MCMRVideoRecorderObserver* aObserver, 
+                              CCMRActiveOutput* aOutput,
+                              TInt aCameraHandle, 
+                              const TDesC8& aVideoMimeType,
+                              MMMFClockSource* aClockSource,
+                              CCMRConfigManager* aConfig  )
+    {
+    PRINT((_L("CCMRVideoRecorderClient::OpenL()")));
+
+    if ( State() != EStateNone ) 
+        {
+        PRINT((_L("CCMRVideoRecorderClient::OpenL() already exists")));
+        User::Leave( KErrAlreadyExists );
+        }
+
+    User::LeaveIfError(iThreadProxy.CreateSubThread(iThreadCreated, aConfig));
+
+    iThreadEventMonitor = CCMRSubThreadEventMonitor::NewL(*this, iThreadProxy); 
+    iThreadEventMonitor->Start();
+
+    VRCASSERT( aObserver );
+    iObserver = aObserver;
+
+    // set output AO to thread
+    VRCASSERT( aOutput );
+    User::LeaveIfError(iThreadProxy.SetOutput( aOutput ));
+    
+    // set clocksource
+    User::LeaveIfError(iThreadProxy.SetClockSource( aClockSource));
+
+    // set camera handle to thread
+    User::LeaveIfError(iThreadProxy.SetCameraHandle( aCameraHandle ));
+
+    // check that it is supported
+    if ( iVideoCodecs->DoWeSupportThisL( aVideoMimeType ) )
+        {
+        User::LeaveIfError(iThreadProxy.SetCodec( aVideoMimeType ));
+        //Event is signaled if state change is needed
+        }
+    else
+        {
+        // codec doesn't exist in the system
+        PRINT((_L("CCMRVideoRecorderClient::OpenL() unsupported codec")));
+        User::Leave( KErrNotSupported );
+        }
+
+    SetState(EStateOpen);
+    iObserver->MvroStateChange( State() );
+
+    }
+
+
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::PrepareL
+// Prepares the recorder for recording
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::PrepareL()
+    {
+
+    PRINT((_L("CCMRVideoRecorderClient::PrepareL() in")));
+
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+
+    SetState(EStatePreparing);
+    // prepare thread
+    User::LeaveIfError(iThreadProxy.Prepare());
+
+                              
+    PRINT((_L("CCMRVideoRecorderClient::PrepareL() out")));
+    }
+
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::RecordL
+// Starts recording
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::RecordL()
+    {
+
+    PRINT((_L("CCMRVideoRecorderClient::Record()           ")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+
+    // start recording
+    User::LeaveIfError(iThreadProxy.Record());
+
+    SetState(EStateRecording);
+    PRINT((_L("CCMRVideoRecorderClient::Record() complete           ")));
+    }
+
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::StopL
+// Stops recording
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::StopL()
+    {
+    PRINT((_L("CCMRVideoRecorderClient::Stop() in")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+            
+    SetState(EStateStopping);
+    // Stop thread
+    User::LeaveIfError(iThreadProxy.Stop());
+    PRINT((_L("CCMRVideoRecorderClient::Stop() out, must wait for state change before stop completed")));
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::RequestBuffersAndWaitEOSL
+// Waits until video thread stops recording and receives EOS (end of stream) marker
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::RequestBuffersAndWaitEOSL(TInt& aVideoEOSReached)
+    {
+    PRINT((_L("CCMRVideoRecorderClient::RequestBuffersAndWaitEOSL() in")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+            
+    User::LeaveIfError(iThreadProxy.RequestBuffersAndWaitEOSL(aVideoEOSReached));
+    PRINT((_L("CCMRVideoRecorderClient::RequestBuffersAndWaitEOSL() out, stop completed")));
+    }
+
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::PauseL
+// Pauses recording
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::PauseL()
+    {
+
+    PRINT((_L("CCMRVideoRecorderClient::Pause() in")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+
+    // pause thread
+    User::LeaveIfError(iThreadProxy.Pause());
+    
+    SetState(EStatePaused);
+               
+    PRINT((_L("CCMRVideoRecorderClient::Pause() out")));
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::ResumeL
+// Resumes recording
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::ResumeL()
+    {
+
+    PRINT((_L("CCMRVideoRecorderClient::Resume() in")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+
+    // resume thread
+    User::LeaveIfError(iThreadProxy.Resume());
+
+    SetState(EStateRecording);
+    PRINT((_L("CCMRVideoRecorderClient::Resume() out")));
+
+    }
+
+
+
+// Setters & Getters
+
+// -----------------------------------------------------------------------------
+// CCMRVideoRecorderClient::SetVideoCodecL
+// Set video codec.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCMRVideoRecorderClient::SetVideoCodecL(const TDesC8& aMimeType) const
+    {
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+
+    // check that it is supported
+    if ( iVideoCodecs->DoWeSupportThisL( aMimeType ) )
+        {
+        User::LeaveIfError(iThreadProxy.SetCodec( aMimeType ));
+        //Event is signaled if state change is needed
+        }
+    else
+        {
+        // codec doesn't exist in the system
+        PRINT((_L("CCMRVideoRecorderClient::OpenL() unsupported codec")));
+        User::Leave( KErrNotSupported );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCMRVideoRecorderClient::GetVideoCodecL
+// Get the used video codec.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCMRVideoRecorderClient::GetVideoCodecL( TDes8& aVideoMimeType ) const
+    {
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+
+    User::LeaveIfError(iThreadProxy.GetCodec( aVideoMimeType ));
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCMRVideoRecorderClient::GetSupportedVideoCodecsL
+// Get list of supported video codecs.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCMRVideoRecorderClient::GetSupportedVideoCodecsL( CDesC8Array& aVideoMimeTypes ) const
+    {
+    if ( iVideoCodecs )
+        {
+        iVideoCodecs->GetSupportedVideoCodecsL( aVideoMimeTypes );
+        }
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::SetTargetBitRateL
+// Sets new target bitrate
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::SetTargetBitRateL(TInt aBitRate) 
+    {
+    PRINT((_L("CCMRVideoRecorderClient::SetTargetBitRate, aBitrate = % d"),aBitRate));
+
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+
+    User::LeaveIfError(iThreadProxy.SetBitRate( aBitRate ));
+
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::TargetBitrateL
+// Gets current target bitrate
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::TargetBitRateL(TInt& aBitRate)
+    {
+    PRINT((_L("CCMRVideoRecorderClient::TargetBitRate")));
+
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+
+    User::LeaveIfError(iThreadProxy.GetBitRate(aBitRate));
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::SetFrameSizeL
+// Sets new input & output frame size
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::SetFrameSizeL(const TSize& aSize) const
+    {
+
+    PRINT((_L("CCMRVideoRecorderClient::SetFrameSize")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+    
+
+    User::LeaveIfError(iThreadProxy.SetFrameSize( aSize ));
+    //Event is signaled if state change is needed
+
+    }
+
+
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::FrameSizeL
+// Gets current frame size
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::FrameSizeL(TSize& aSize) const
+    {
+    PRINT((_L("CCMRVideoRecorderClient::FrameSizeL()")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+                
+    User::LeaveIfError(iThreadProxy.GetFrameSize( aSize )); 
+                
+    }
+
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::SetFrameRateL
+// Sets new target frame rate
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::SetFrameRateL(TReal32 aFrameRate) const
+    {
+
+    PRINT((_L("CCMRVideoRecorderClient::SetFrameRate")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+
+
+    User::LeaveIfError(iThreadProxy.SetFrameRate( aFrameRate ));
+
+    //Event is signaled if state change is needed
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::FrameRateL
+// Get the used encoding frame rate
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::FrameRateL(TReal32& aFrameRate) const
+    {
+    PRINT((_L("CCMRVideoRecorderClient::FrameRateL()")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+                
+    User::LeaveIfError(iThreadProxy.GetFrameRate(aFrameRate));
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::SetVideoCodingOptionsL
+// Set misc video coding options
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::SetVideoCodingOptionsL(const TCCMRVideoCodingOptions& aOptions) const
+    {
+    PRINT((_L("CCMRVideoRecorderClient::SetVideoCodingOptionsL()")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+
+    User::LeaveIfError(iThreadProxy.SetMiscOptions(aOptions));
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::SetVideoRateControlOptionsL
+// Set video rate control options
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::SetVideoRateControlOptionsL(const TRateControlOptions& aOptions) const
+    {
+    PRINT((_L("CCMRVideoRecorderClient::SetVideoRateControlOptionsL()")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+
+    User::LeaveIfError(iThreadProxy.SetVideoRateControlOptions(aOptions));
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::GetVideoRateControlOptionsL
+// Get video rate control options
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::GetVideoRateControlOptionsL(TRateControlOptions& aOptions) const
+    {
+    PRINT((_L("CCMRVideoRecorderClient::GetVideoRateControlOptionsL()")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+
+    User::LeaveIfError( iThreadProxy.GetVideoRateControlOptions(aOptions) );
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::SetPreferredVideoEncoderL
+// Set video encoder using its UID. Usage optional.
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::SetPreferredVideoEncoderL(TUid& aEncoder)
+    {
+    PRINT((_L("CCMRVideoRecorderClient::SetPreferredVideoEncoderL()")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+    User::LeaveIfError(iThreadProxy.SetPreferredVideoEncoder(aEncoder));
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::SetPreferredVideoEncapsulationL
+// Set video encoder output format encapsulation. Usage optional.
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::SetPreferredVideoEncapsulationL(TVideoDataUnitEncapsulation aCapsulation)
+    {
+    PRINT((_L("CCMRVideoRecorderClient::SetPreferredVideoEncapsulationL()")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+    User::LeaveIfError(iThreadProxy.SetPreferredVideoEncapsulation(aCapsulation));
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::SetSegmentTargetSizeL
+// Set video encoder target segment size. Usage optional.
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::SetSegmentTargetSizeL(TUint aLayer, TUint aSizeBytes, TUint aSizeMacroblocks )
+    {
+    PRINT((_L("CCMRVideoRecorderClient::SetSegmentTargetSizeL()")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+    User::LeaveIfError(iThreadProxy.SetSegmentTargetSize(aLayer, aSizeBytes, aSizeMacroblocks));
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::AdjustTimeStampsL
+// Adjust time stamps of video
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::AdjustTimeStampsL(const TInt aAdjustmentMs) const
+    {
+    PRINT((_L("CCMRVideoRecorderClient::AdjustTimeStampsL()")));
+    // other state checks handled in the thread, but in this state there is no thread
+    VRCASSERT( State() != EStateNone );
+                
+    User::LeaveIfError(iThreadProxy.AdjustTimeStamps(aAdjustmentMs));
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::SetThreadPriorityL
+// Set video thread priority, based on audio thread priority
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::SetThreadPriorityL(const TThreadPriority& aAudioThreadPriority) const
+    {
+    User::LeaveIfError(iThreadProxy.SetThreadPriority( aAudioThreadPriority ));
+    }
+
+// ---------------------------------------------------------
+// CCMRVideoRecorderClient::HandleEvent
+// Handle events from video recorder thread
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCMRVideoRecorderClient::HandleEvent(const TMMFEvent& aEvent)
+    {
+    PRINT((_L("CCMRVideoRecorderClient::HandleEvent(), aEvent.iEventType %d"),aEvent.iEventType.iUid));
+    // note: can't use switch here since it can't compare Uids
+    if ( aEvent.iEventType == KCMRCameraPrepareError )
+        {
+        SetState( EStateOpen );// no need to call state change
+        iObserver->MvroError( aEvent.iErrorCode );
+        }
+    else if ( aEvent.iEventType == KCMRCameraReserveError )
+        {
+        SetState( EStateOpen );// no need to call state change
+        iObserver->MvroError( aEvent.iErrorCode );
+        }
+    else if ( aEvent.iEventType == KCMRCameraCaptureError )
+        {
+        // assume the client will stop us
+        iObserver->MvroError( aEvent.iErrorCode );
+        }
+    else if ( aEvent.iEventType == KCMREncoderInitError )
+        {
+        SetState( EStateOpen );// no need to call state change
+        iObserver->MvroError( aEvent.iErrorCode );
+        }
+    else if ( aEvent.iEventType == KCMRRunTimeError )
+        {
+        // assume the client will stop us
+        iObserver->MvroError( aEvent.iErrorCode );
+        }
+    else if ( aEvent.iEventType == KCMRPrepareComplete )
+        {
+        SetState( EStateReadyToRecord );
+        iObserver->MvroStateChange( EStateReadyToRecord );
+        }
+    else if ( aEvent.iEventType == KCMRRecordingComplete )
+        {
+        SetState( EStateReadyToRecord );
+        iObserver->MvroStateChange( EStateReadyToRecord );
+        }
+    else if ( aEvent.iEventType == KCMRPrepareNeeded )
+        {
+        if ( State() == EStateReadyToRecord )
+            {
+            SetState( EStateOpen );
+            iObserver->MvroStateChange( EStateOpen );
+            }
+        }
+    else if ( aEvent.iErrorCode == KErrServerTerminated )
+        {
+        // thread was terminated, can't use it any more
+        SetState( EStateNone );
+        iObserver->MvroStateChange( EStateNone );
+        iObserver->MvroError( aEvent.iErrorCode );
+        }
+    else
+        {
+        // something unknown, perhaps from the system
+        PRINT((_L("CCMRVideoRecorderClient::HandleEvent() unknown event")));
+        iObserver->MvroError( aEvent.iErrorCode );
+        }
+
+    }
+