Symbian
Symbian OS Library

SYMBIAN OS V9.3

[Index] [Spacer] [Previous] [Next]



MmfExCodec: Multimedia Framework codec plug-in example


Example code

Found in: Examples\MultiMedia\MmfExCodec\

These are the main files contained in the examples. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

//
// main.cpp
// Copyright © 1997-2005 Symbian Software Ltd.  All rights reserved.
//

#include <e32base.h>
#include <ecom.h>
#include <ImplementationProxy.h>

#include "MMFExPcm8toPcm16codec.h"
#include "UIDs.hrh"

// __________________________________________________________________________
// Exported proxy for instantiation method resolution
// Define the interface UIDs

const TImplementationProxy ImplementationTable[] = 
    {
        IMPLEMENTATION_PROXY_ENTRY(KExCodecUID, CMMFExPcm8Pcm16Codec::NewL)
    };

EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
    {
    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);

    return ImplementationTable;
    }

// MMFExPcm8Pcm16Codec.cpp
// Copyright 1997-2005 Symbian Software Ltd.  All rights reserved.
//

#include "MMFExPcm8ToPcm16Codec.h"


// Factory function
CMMFCodec* CMMFExPcm8Pcm16Codec::NewL(TAny* )
    {
    CMMFExPcm8Pcm16Codec* self=new(ELeave) CMMFExPcm8Pcm16Codec();
    return self;
    }

// Process source buffer and writes converted data to destination buffer
// The codec expands 1 byte to 2 bytes
TCodecProcessResult CMMFExPcm8Pcm16Codec::ProcessL(const CMMFBuffer& aSrc, CMMFBuffer& aDst)
    {
    TCodecProcessResult result;
    result.iStatus = TCodecProcessResult::EProcessIncomplete;

    // cast from generic CMMFBuffer to CMMFDataBuffer
    iSrc = STATIC_CAST(const CMMFDataBuffer*, &aSrc);
    iDst = STATIC_CAST(CMMFDataBuffer*, &aDst);

    const TUint dstMaxLen = iDst->Data().MaxLength();
    if (!dstMaxLen)
        User::Leave(KErrArgument);

    //don't scribble Destination (pDst) by only consuming enough source to fill pDst
    TUint srcUse = (dstMaxLen - iDst->Position()) / 2;
    const TUint srcLen = iSrc->Data().Length();
    const TUint sourceRemain = srcLen - iSrc->Position();

    //make sure we don't blow source by checking against remaining
    //and clipping to minimum remaining if necessary
    srcUse = (srcUse<sourceRemain ? srcUse : sourceRemain);
    
    //we need to cast away CONST even on the source, as the TClass needs a TUint8*
    TUint8* pSrc = CONST_CAST(TUint8*,iSrc->Data().Ptr());
    pSrc += iSrc->Position();
    TUint8* pDst = CONST_CAST(TUint8*,iDst->Data().Ptr());
    pDst += iDst->Position();

    Convert(pSrc, pDst, srcUse );

    if ((srcUse * 2) + iDst->Position() < dstMaxLen)
        result.iStatus = TCodecProcessResult::EDstNotFilled;

    else if (srcUse + iSrc->Position() >= srcLen)
        result.iStatus = TCodecProcessResult::EProcessComplete;

    result.iSrcBytesProcessed = srcUse;
    result.iDstBytesAdded = srcUse * 2;

    iDst->Data().SetLength(iDst->Position() + (srcUse * 2));

    return result;
    }


// Helper to convert signed 8-bit to signed 16-bit
void CMMFExPcm8Pcm16Codec::Convert(TUint8* aSrc, TUint8* aDst, TInt aSamples)
    {
    const TInt KAndMask8bit = 0xff;
    TInt s16;
    while (aSamples--)
        { 
        s16 = (*aSrc++)<<8;
        *aDst++ = STATIC_CAST( TInt8, s16&KAndMask8bit);
        *aDst++ = STATIC_CAST( TInt8, (s16>>8)&KAndMask8bit);
        }
    }

// MMFExPcm8Pcm16Codec.h
// Copyright 1997-2005 Symbian Software Ltd.  All rights reserved.
//


#ifndef __EXPCM8_PCM16_CODEC_H__
#define __EXPCM8_PCM16_CODEC_H__

#include <mmf\server\mmfcodec.h>

// Declares a MMF plug-in codec that converts
// from PCM8 format to PCM16
class CMMFExPcm8Pcm16Codec : public CMMFCodec
    {
public:
    // Construction
    static CMMFCodec* NewL(TAny* aInitParams);
    // Implement CMMFCodec
    TCodecProcessResult ProcessL(const CMMFBuffer& aSrc, CMMFBuffer& aDst);

private:
    // Helper function
    void Convert(TUint8* aSrc, TUint8* aDst, TInt aSamples);

private:
    //owned by the Datapath
    const CMMFDataBuffer* iSrc;
    CMMFDataBuffer* iDst;
    };

#endif

UIDs.hrh
#ifndef _MmfExCodecUIDS_H_
#define _MmfExCodecUIDS_H_

#define KPluginDLLUID 0x101F81D6
#define KExCodecUID 0x101F81D7

#endif

bld.inf
PRJ_MMPFILES
MMFExCodec.mmp

// MMFExCodec.mmp
//
// Copyright (c) 1997-2005 Symbian Software Ltd.  All rights reserved.
//

TARGET MMFExCodec.dll
TARGETTYPE PLUGIN

// ECom Dll recognition UID followed by the unique UID for this dll
UID 0x10009D8D 0x101F81D6
VENDORID 0x70000001
CAPABILITY ALL -TCB

USERINCLUDE .
SYSTEMINCLUDE  \epoc32\include \epoc32\include\ecom

SOURCEPATH  .
SOURCE      main.cpp
SOURCE      MMFExPcm8ToPcm16Codec.cpp

START RESOURCE 101F81D6.rss
TARGETPATH     \resource\Plugins
HEADER
END

LIBRARY euser.lib
LIBRARY ECom.lib

101F81D6.rss
#include <mmfPluginInterfaceUIDs.hrh>
#include "RegistryInfo.rh"

#include "UIDs.hrh"

RESOURCE REGISTRY_INFO theInfo
    {
    dll_uid = KPluginDLLUID;
    interfaces = 
        {
        INTERFACE_INFO
            {
            interface_uid = KMmfUidPluginInterfaceCodec ;  // CMMFCodec
            implementations = 
                {
                IMPLEMENTATION_INFO
                    {
                    implementation_uid = KExCodecUID;
                    version_no = 1;
                    display_name = "PCM8 ->PCM16";
                    default_data = "  P8, P16" ;//four CC codes.
                    opaque_data = "";
                    }
                };
            }
        };
    }

[Top]


Description

MmfExCodec demonstrates how to implement a codec plug-in for the Multimedia Framework. A codec converts media data in one encoding into another encoding. The example converts audio data encoded with PCM8 into PCM16.

The program is an ECom plug-in that implements the codec interface CMMFCodec by the class CMMFExPcm8Pcm16Codec. When a client or media format requires a PCM8 to PCM16 codec, the Multimedia Framework will instantiate a CMMFExPcm8Pcm16Codec object, and call its ProcessL() member function to convert data supplied a source buffer. As converting PCM8 into PCM16 only requires expanding each byte in the source buffer into two bytes in the destination buffer, CMMFExPcm8Pcm16Codec::ProcessL() is not very complex.