Symbian
Symbian OS Library

SYMBIAN OS V9.3

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



Creating a Format Encode Plugin

Format encode plugin implementations derive from the CMMFFormatEncode abstract class and several of the MDataSource and MDataSink mixin functions.


CMMFFormatEncode Implementation

Derived classes must implement the CMMFFormatEncode pure virtual functions and may implement any of the virtual functions.

Format Encode Plugin Instantiation

A derived plugin need only implement the following instantiation method:

static CMMFFormatEncode* NewL(MDataSource* aSource) ;

Note that a client using a format plugin would always instantiate a specific CMMFFormatEncode by using one of the four base class NewL() instantiation functions. It would not instantiate the format encode plugin via the derived class directly.

The derived NewL() function will first need to determine whether or not the sink clip already exists. This is because a CMMFFormatEncode would typically be used for a recording or converting operation, where the clip being recorded or converted to may or may not already exist. The expected behaviour for each of the two alternatives is as follows:

The ECom TImplementationProxy table, which defines the NewL() for a specific format plugin UID, needs defining in a . cpp file.

Audio-Specific Encode Functions

The CMMFFormatEncode base class contains a number of audio-specific functions. Default implementations are provided so there is no need to override these if the format only supports video:

If the format supports audio then, unlike the CMMFFormatDecode equivalents, it will usually be necessary to override the CMMFFormatEncode::SetNumChannels(), CMMFFormatEncode::SetSampleRate() and CMMFFormatEncode::SetBitRate() methods. This is because, if the clip does not already exist, the format will need to be supplied with these settings. If the clip does already exist and can determine the settings for itself then these functions should return KErrAlreadyExists if the requested setting differs from the actual setting.

General CMMFFormatEncode Functions

Other CMMFFormatEncode functions that need to be implemented by a format encode plugin are: CMMFFormatEncode::FrameTimeInterval(), CMMFFormatEncode::Duration(), CMMFFormatEncode:: CanCreateSinkBuffer() and CMMFFormatEncode:: CreateSinkBufferL ().

In addition: CMMFFormatEncode::GetNumberOfMetaDataEntriesL(), CMMFFormatEncode::AddMetaDataEntryL(), CMMFFormatEncode::RemoveMetaDataEntryL(), CMMFFormatEncode::ReplaceMetaDataEntryL() and CMMFFormatEncode::MetaDataEntryL() may optionally be implemented.

CMMFFormatEncode::SetMaximumClipSizeL() is an optional method used to set the maximum size of the clip. For example, to set a limit on the length of a recording. If implemented, then the CMMFFormatEncode::EmptyBufferL() method should check that the value set by this procedure is not about to be exceeded and if so should leave with KErrEof.

CMMFFormatEncode::CropL() is an optional method used to remove part of a clip. The clip can be cropped from a specified position (the default behaviour) where all the clip data from tat position is removed from the clip. Alternatively the format can crop all the data up to a specified position. There may also be restrictions on what state the format is in as to whether the crop operation is permissible, for example the format may need to be paused to crop, but this is up to the specific implementation of this function. Writers of this function must ensure that the clip header, index tables and any other necessary data both on the clip and internally in the format are correct following the crop operation.

The CMMFFormatEncode::SinkDataTypeCode() function must be implemented by the derived format encode plugin. It should return the data type via a four CC code of the sink for the specified media ID. The data type can be determined on instantiation or in the implementation of this function. The data type for a particular format is usually determined by information in the header, although some formats can only have one data type e.g. for the mp3 format, the data type is always mp3. For a WAV file the data type could be pcm8, pcm16, IMA ADPCM or GSM610. If no data type is applicable to the specified media ID, for example if this function was called on an mp3 format plugin with the media ID set to KUidMediaTypeVideo then the procedure should return the default TFourCC code of 'NULL'.

[Top]


Format Encode MDataSource and MDataSink Implementation

Format encode MDataSource and MDataSink implementation is described in the following sections:

Format Encode Buffer Empty

A CMMFFormatEncode derived plugin is a sink of data (usually from a datapath). It therefore derives from the MDataSink mixin class. The MDataSink mixin method concerned with getting data from the format encode plugin is MDataSink::EmptyBufferL().

This method is the means by which data is written to the data source. The buffer must already contain multimedia data. The format should read the frame number of the buffer via the buffer's CMMFBufferClass::FrameNumber() method. From this, the format encode plugin should be able to determine the actual position of the data on the data source. The technique here depends on the nature of the format. For a linear audio format, the position can be obtained by a simple calculation of the frame size, the header size and where appropriate the datatype. For non linear formats either an index table of frame number and location will need to be created in the derived NewL() or some form of approximating algorithm will be required. Some formats have an index table as part of the format, AVI for example. If no random access is required then no index table is required, the format can keep track of the current write position and increment it on each access, and reset it if the frame number is reset to 0 or 1.

For multimedia formats such as mp4 and AVI, the format encode is effectively acting as a multiplexer, and must write the data to the appropriate location on the sink depending on the media ID. If a maximum clip size has been set via the MDataSink::SetMaximumClipSizeL() method then the MDataSink::EmptyBufferL() should ensure that this size is not exceeded.

MDataSink::BufferEmptiedL() function is the MDataSource call back method of the MDataSink::EmptyBufferL() called on the sink (the format encode plugin being the source to the data sink) is optional. The default implementation propagates the callback onto the datapath. If any format specific post buffer emptied processing is required, such as updating the bytes written, then this function should be overridden.

Format Encode State Functions

The MDataSink mixin provides a number of state related functions used to inform a source that the datapath has made a transition to a particular state. These state transition functions are usually called on the sink from the datapath and so will be called on the CMMFFormatEncode plugin. These methods are not pure virtual and so it is not compulsory to implement them on the format encode plugin (they have no default implementation in the CMMFFormatEncode base class). In many cases it will be necessary to override these functions even if only to propagate the state change onto the actual sink as seen by the controller.

In addition, the functions MDataSink::SinkPlayL(), MDataSink::SinkPauseL(), MDataSink::SinkStopL() and MDataSink::SinkThreadLogoff() would not generally have any format encode-specific implementations.

The CMMFFormatEncode state methods may be more complex than those of the CMMFFormatDecode equivalents. The main reason for this is that the format encode needs to ensure that the sink clip is valid i.e. has the correct header information. This should happen every time a MDataSink::SinkPauseL() (since there is no guarantee that it will be resumed) and MDataSink::SinkStopL() is called. This means that the format encode will need to keep track of any parameters required to write the header such as clip size, bytes written and so on.

Other MDataSink Functions

The MDataSink::SetSinkDataTypeCode() function is not pure virtual in the base class, and no default implementation is given in the CMMFFormatEncode base class. However, unlike a CMMFFormatDecode, it would normally be necessary to override this method. This is because the CMMFFormatEncode is typically used when recording or converting, such that the clip may or may not already exist prior to the recording or conversion. If the clip does not already exist then the format needs to know what the expected data type is, and this is set by the MDataSink::SetSinkDataTypeCode() method. If the clip does already exist, and so has a data type that is different to the requested data type, then this method should return KErrAlreadyExists.

No implementation of the MDataSink::BufferFilledL() or MDataSource::FillBufferL() functions are required in the derived plugin.