/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
/**
* @file pvmp4ffcn_node.h
* @brief PVMF node for PVMp4FFComposer
*/
#ifndef PVMP4FFCN_NODE_H_INCLUDED
#define PVMP4FFCN_NODE_H_INCLUDED
#ifndef OSCL_BASE_H_INCLUDED
#include "oscl_base.h"
#endif
#ifndef OSCLCONFIG_IO_H_INCLUDED
#include "osclconfig_io.h"
#endif
#ifndef OSCL_FILE_IO_H_INCLUDED
#include "oscl_file_io.h"
#endif
#ifndef OSCL_SCHEDULER_AO_H_INCLUDED
#include "oscl_scheduler_ao.h"
#endif
#ifndef PVLOGGER_H_INCLUDED
#include "pvlogger.h"
#endif
#ifndef __A_IMpeg4File_H__
#include "a_impeg4file.h"
#endif
#ifndef __MEDIA_CLOCK_CONVERTER_H
#include "media_clock_converter.h"
#endif
#ifndef PVMF_FORMAT_TYPE_H_INCLUDED
#include "pvmf_format_type.h"
#endif
#ifndef PVMF_SIMPLE_MEDIA_BUFFER_H_INCLUDED
#include "pvmf_simple_media_buffer.h"
#endif
#ifndef PVMF_MEDIA_DATA_H_INCLUDED
#include "pvmf_media_data.h"
#endif
#ifndef PVMF_NODE_INTERFACE_H_INCLUDED
#include "pvmf_node_interface.h"
#endif
#ifndef PVMF_NODE_UTILS_H_INCLUDED
#include "pvmf_node_utils.h"
#endif
#ifndef PVMP4FFCN_TYPES_H_INCLUDED
#include "pvmp4ffcn_types.h"
#endif
#ifndef PVMP4FFCN_TUNABLES_H_INCLUDED
#include "pvmp4ffcn_tunables.h"
#endif
#ifndef PVMP4FFCN_CLIPCONFIG_H_INCLUDED
#include "pvmp4ffcn_clipconfig.h"
#endif
#ifndef PVMP4FFCN_TRACKCONFIG_H_INCLUDED
#include "pvmp4ffcn_trackconfig.h"
#endif
#ifndef PVMF_COMPOSER_SIZE_AND_DURATION_H_INCLUDED
#include "pvmf_composer_size_and_duration.h"
#endif
#ifndef PVMI_CONFIG_AND_CAPABILITY_H_INCLUDED
#include "pvmi_config_and_capability.h"
#endif
#ifndef PVMF_MEDIA_MSG_FORMAT_IDS_H_INCLUDED
#include "pvmf_media_msg_format_ids.h"
#endif
#ifndef PVMI_KVP_H_INCLUDED
#include "pvmi_kvp.h"
#endif
// Forward declaration
class PVMp4FFComposerPort;
//memory allocator type for this node.
typedef OsclMemAllocator PVMp4FFCNAlloc;
/** Node command type */
typedef PVMFGenericNodeCommand<PVMp4FFCNAlloc> PVMp4FFCNCmd;
/** Command queue type */
typedef PVMFNodeCommandQueue<PVMp4FFCNCmd, PVMp4FFCNAlloc> PVMp4FFCNCmdQueue;
/** Port vector type */
typedef PVMFPortVector<PVMp4FFComposerPort, PVMp4FFCNAlloc> PVMp4FFCNPortVector;
#define PROFILING_ON (PVLOGGER_INST_LEVEL >= PVLOGMSG_INST_PROF)
#if PROFILING_ON
#ifndef PVMF_MEDIA_CLOCK_H_INCLUDED
#include "pvmf_media_clock.h"
#endif
#endif
#ifdef ANDROID
#include <utils/RefBase.h>
namespace android
{
class FragmentWriter;
}
#endif
////////////////////////////////////////////////////////////////////////////
class PVMp4FFComposerNode : public PVMFNodeInterface,
public OsclActiveObject,
public PVMp4FFCNTrackConfigInterface,
public PVMp4FFCNClipConfigInterface,
public PvmfComposerSizeAndDurationInterface,
public PvmiCapabilityAndConfig
{
public:
PVMp4FFComposerNode(int32 aPriority);
~PVMp4FFComposerNode();
// Pure virtual functions from PVMFNodeInterface
OSCL_IMPORT_REF PVMFStatus ThreadLogon();
OSCL_IMPORT_REF PVMFStatus ThreadLogoff();
OSCL_IMPORT_REF PVMFStatus GetCapability(PVMFNodeCapability& aNodeCapability);
OSCL_IMPORT_REF PVMFPortIter* GetPorts(const PVMFPortFilter* aFilter);
OSCL_IMPORT_REF PVMFCommandId QueryUUID(PVMFSessionId aSession, const PvmfMimeString& aMimeType,
Oscl_Vector<PVUuid, PVMp4FFCNAlloc>& aUuids,
bool aExactUuidsOnly = false,
const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId QueryInterface(PVMFSessionId aSession, const PVUuid& aUuid,
PVInterface*& aInterfacePtr,
const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId RequestPort(PVMFSessionId aSession, int32 aPortTag,
const PvmfMimeString* aPortConfig = NULL,
const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId ReleasePort(PVMFSessionId aSession, PVMFPortInterface& aPort,
const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId Init(PVMFSessionId aSession, const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId Start(PVMFSessionId aSession, const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId Stop(PVMFSessionId aSession, const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId Pause(PVMFSessionId aSession, const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId Flush(PVMFSessionId aSession, const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId Reset(PVMFSessionId aSession, const OsclAny* aContext = NULL);
OSCL_EXPORT_REF PVMFCommandId Prepare(PVMFSessionId aSession, const OsclAny* aContext);
OSCL_IMPORT_REF PVMFCommandId CancelAllCommands(PVMFSessionId aSession, const OsclAny* aContextData = NULL);
OSCL_IMPORT_REF PVMFCommandId CancelCommand(PVMFSessionId aSession, PVMFCommandId aCmdId,
const OsclAny* aContextData = NULL);
// Pure virtual from PVInterface
OSCL_IMPORT_REF void addRef();
OSCL_IMPORT_REF void removeRef();
OSCL_IMPORT_REF bool queryInterface(const PVUuid& uuid, PVInterface*& iface);
// Pure virtual functions from PVMp4FFCNClipConfigInterface
OSCL_IMPORT_REF PVMFStatus SetOutputFileName(const OSCL_wString& aFileName);
OSCL_IMPORT_REF PVMFStatus SetOutputFileDescriptor(const OsclFileHandle* aFileHandle);
OSCL_IMPORT_REF PVMFStatus SetAuthoringMode(PVMp4FFCN_AuthoringMode aAuthoringMode = PVMP4FFCN_3GPP_DOWNLOAD_MODE);
OSCL_IMPORT_REF PVMFStatus SetPresentationTimescale(uint32 aTimescale);
OSCL_IMPORT_REF PVMFStatus SetVersion(const OSCL_wString& aVersion, const OSCL_String& aLangCode);
OSCL_IMPORT_REF PVMFStatus SetTitle(const OSCL_wString& aTitle, const OSCL_String& aLangCode);
OSCL_IMPORT_REF PVMFStatus SetAuthor(const OSCL_wString& aAuthor, const OSCL_String& aLangCode);
OSCL_IMPORT_REF PVMFStatus SetCopyright(const OSCL_wString& aCopyright, const OSCL_String& aLangCode);
OSCL_IMPORT_REF PVMFStatus SetDescription(const OSCL_wString& aDescription, const OSCL_String& aLangCode);
OSCL_IMPORT_REF PVMFStatus SetRating(const OSCL_wString& aRating, const OSCL_String& aLangCode);
OSCL_IMPORT_REF PVMFStatus SetCreationDate(const OSCL_wString& aCreationDate);
OSCL_IMPORT_REF PVMFStatus SetRealTimeAuthoring(const bool aRealTime);
OSCL_IMPORT_REF PVMFStatus SetAlbumInfo(const OSCL_wString& aAlbum_Title, const OSCL_String& aLangCode);
OSCL_IMPORT_REF PVMFStatus SetRecordingYear(uint16 aRecordingYear);
OSCL_IMPORT_REF PVMFStatus SetPerformer(const OSCL_wString& aPerformer, const OSCL_String& aLangCode);
OSCL_EXPORT_REF PVMFStatus SetGenre(const OSCL_wString& aGenre, const OSCL_String& aLangCode);
OSCL_EXPORT_REF PVMFStatus SetClassification(const OSCL_wString& aClassificationInfo, uint32 aClassificationEntity, uint16 aClassificationTable, const OSCL_String& aLangCode);
OSCL_EXPORT_REF PVMFStatus SetKeyWord(const OSCL_wString& aKeyWordInfo, const OSCL_String& aLangCode);
OSCL_EXPORT_REF PVMFStatus SetLocationInfo(PvmfAssetInfo3GPPLocationStruct& aLocation_info);
OSCL_IMPORT_REF uint16 ConvertLangCode(const OSCL_String& aLang);
// Pure virtual functions from PVMp4FFCNTrackConfigInterface
OSCL_IMPORT_REF PVMFStatus SetTrackReference(const PVMFPortInterface& aPort,
const PVMFPortInterface& aReferencePort);
OSCL_IMPORT_REF PVMFStatus SetCodecSpecificInfo(const PVMFPortInterface& aPort, uint8* aInfo, int32 aSize);
// Pure virtual from PvmfComposerSizeAndDurationInterface
OSCL_IMPORT_REF PVMFStatus SetMaxFileSize(bool aEnable, uint32 aMaxFileSizeBytes);
OSCL_IMPORT_REF void GetMaxFileSizeConfig(bool& aEnable, uint32& aMaxFileSizeBytes);
OSCL_IMPORT_REF PVMFStatus SetMaxDuration(bool aEnable, uint32 aMaxDurationMilliseconds);
OSCL_IMPORT_REF void GetMaxDurationConfig(bool& aEnable, uint32& aMaxDurationMilliseconds);
OSCL_IMPORT_REF PVMFStatus SetFileSizeProgressReport(bool aEnable, uint32 aReportFrequency);
OSCL_IMPORT_REF void GetFileSizeProgressReportConfig(bool& aEnable, uint32& aReportFrequency);
OSCL_IMPORT_REF PVMFStatus SetDurationProgressReport(bool aEnable, uint32 aReportFrequency);
OSCL_IMPORT_REF void GetDurationProgressReportConfig(bool& aEnable, uint32& aReportFrequency);
//from PVMFPortActivityHandler
void HandlePortActivity(const PVMFPortActivity& aActivity);
// Friend class
friend class PVMp4FFComposerPort;
Oscl_Vector<OsclMemoryFragment*, OsclMemAllocator> memvector_sps;
Oscl_Vector<OsclMemoryFragment*, OsclMemAllocator> memvector_pps;
uint8 iNum_SPS_Set;
uint8 iNum_PPS_Set;
Oscl_Vector<PVA_FF_TextSampleDescInfo*, OsclMemAllocator> textdecodervector;
int32 iText_sdIndex;
// implemetation of PvmiCapabilityAndConfig class functions here
void setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver);
PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier,
PvmiKvp*& aParameters, int& num_parameter_elements,
PvmiCapabilityContext aContext);
PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements);
void createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext);
void setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext,
PvmiKvp* aParameters, int num_parameter_elements);
void DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext);
void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters,
int num_elements, PvmiKvp * & aRet_kvp);
PVMFCommandId setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters,
int num_elements, PvmiKvp*& aRet_kvp, OsclAny* context = NULL);
uint32 getCapabilityMetric(PvmiMIOSession aSession);
PVMFStatus verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements);
// function used in getParametersSync of capability class
PVMFStatus GetConfigParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr reqattr);
// function used in VerifyParametersSync n SetParametersSync of capability class
PVMFStatus VerifyAndSetConfigParameter(PvmiKvp& aParameter, bool aSetParam);
private:
#ifdef ANDROID
friend class android::FragmentWriter; // Access AddMemFragToTrack
#endif
// Pure virtual from OsclActiveObject
void Run();
/////////////////////////////////////////////////////
// Command processing routines
/////////////////////////////////////////////////////
PVMFCommandId QueueCommandL(PVMp4FFCNCmd& aCmd);
bool ProcessCommand(PVMp4FFCNCmd& aCmd);
void CommandComplete(PVMp4FFCNCmdQueue& aQueue, PVMp4FFCNCmd& aCmd, PVMFStatus aStatus, OsclAny* aData = NULL);
void DoQueryUuid(PVMp4FFCNCmd& aCmd);
void DoQueryInterface(PVMp4FFCNCmd& aCmd);
void DoRequestPort(PVMp4FFCNCmd& aCmd);
void DoReleasePort(PVMp4FFCNCmd& aCmd);
void DoInit(PVMp4FFCNCmd& aCmd);
void DoPrepare(PVMp4FFCNCmd& aCmd);
void DoStart(PVMp4FFCNCmd& aCmd);
PVMFStatus AddTrack(PVMp4FFComposerPort *aPort);
void DoStop(PVMp4FFCNCmd& aCmd);
void DoFlush(PVMp4FFCNCmd& aCmd);
bool IsFlushPending();
void FlushComplete();
void DoPause(PVMp4FFCNCmd& aCmd);
void DoReset(PVMp4FFCNCmd& aCmd);
void DoCancelAllCommands(PVMp4FFCNCmd& aCmd);
void DoCancelCommand(PVMp4FFCNCmd& aCmd);
/////////////////////////////////////////////////////
// Port activity processing routines
/////////////////////////////////////////////////////
bool IsProcessIncomingMsgReady();
/**
* Process an incoming message of a the specified port
* @param aPort Port where outgoing message is queued.
* @return Completion status
*/
PVMFStatus ProcessIncomingMsg(PVMFPortInterface* aPort);
PVMFStatus AddMemFragToTrack(Oscl_Vector<OsclMemoryFragment, OsclMemAllocator> aFrame, OsclRefCounterMemFrag& aMemFrag, PVMFFormatType aFormat,
uint32& aTimestamp, int32 aTrackId, PVMp4FFComposerPort *aPort);
int32 GetIETFFrameSize(uint8 aFrameType, int32 aCodecType);
/////////////////////////////////////////////////////
// Progress and max size / duration routines
/////////////////////////////////////////////////////
/**
* Send file size or duration report if enabled.
* @param aTimestamp Timestamp of current frame in milliseconds.
* @return PVMFFailure if informational observer is not set, else PVMFSuccess
*/
PVMFStatus SendProgressReport(uint32 aTimestamp);
/**
* Check if maximum file size or duration is reached if a maximum is set.
*
* @param aFrameSize Size of current frame in bytes.
* @return PVMFSuccess if feature is enabled and the maximum file size / duration is reached.
* PVMFPending if feature is enabled and the max file size / duration has not been reached.
* PVMFErrNotSupported if feature is not enabled.
* PVMFFailure if informational observer is not set or if max file size or duration is set
* but the finalizing output file failed.
*/
PVMFStatus CheckMaxFileSize(uint32 aFrameSize);
/**
* Check if maximum file size or duration is reached if a maximum is set.
*
* @param aTimestamp Timestamp of current frame in milliseconds.
* @return PVMFSuccess if feature is enabled and the maximum file size / duration is reached.
* PVMFPending if feature is enabled and the max file size / duration has not been reached.
* PVMFErrNotSupported if feature is not enabled.
* PVMFFailure if informational observer is not set or if max file size or duration is set
* but the finalizing output file failed.
*/
PVMFStatus CheckMaxDuration(uint32 aTimestamp);
/**
* Finalize the output file.
* @return PVMFSuccess if output file is successfully finalized, else PVMFFailure
*/
PVMFStatus RenderToFile();
/**
* Write DecoderSpecific Info at the end of encoding.
* @return void
*/
void WriteDecoderSpecificInfo();
/** Clear all pending port activity after max file size or duration is reached. */
void ClearPendingPortActivity();
/////////////////////////////////////////////////////
// Event reporting routines
/////////////////////////////////////////////////////
void ReportErrorEvent(PvmfMp4FFCNError aEventType, OsclAny* aEventData = NULL);
void ReportInfoEvent(PVMFEventType aEventType, OsclAny* aEventData = NULL);
void SetState(TPVMFNodeInterfaceState);
private:
void GenerateDiagnostics(uint32 aTime, uint32 aSize);
void LogDiagnostics();
int32 StoreCurrentCommand(PVMp4FFCNCmdQueue&, PVMp4FFCNCmd&, PVMp4FFCNCmdQueue&);
// Node command queue
PVMp4FFCNCmdQueue iCmdQueue;
PVMp4FFCNCmdQueue iCurrentCmd;
// Vector of ports contained in this node
PVMp4FFCNPortVector iInPorts;
// File format
PVA_FF_IMpeg4File* iMpeg4File;
OSCL_wHeapString<OsclMemAllocator> iFileName;
OSCL_wHeapString<OsclMemAllocator> iPostfix;
OSCL_wHeapString<OsclMemAllocator> iOutputPath;
Oscl_FileServer iFs;
int32 iFileType;
uint32 iAuthoringMode;
uint32 iPresentationTimescale;
uint32 iMovieFragmentDuration;
Oscl_File* iFileObject;
#ifdef ANDROID
// Fragment to track writer thread.
android::sp<android::FragmentWriter> iFragmentWriter;
// Marker to report to the author node an event. It is really of
// type PVMFComposerSizeAndDurationEvent but there is no value
// in the enum for 'none' so we use a generic int.
int iMaxReachedEvent;
bool iMaxReachedReported;
#endif
// Meta data strings
struct PVMP4FFCN_MetaDataString
{
PVMP4FFCN_MetaDataString(): iClassificationEntity(0), iClassificationTable(0), iLangCode(0) {};
OSCL_wHeapString<OsclMemAllocator> iDataString;
uint32 iClassificationEntity;
uint16 iClassificationTable;
uint16 iLangCode;
};
class PVMP4FFCN_KeyWord
{
public:
PVMP4FFCN_KeyWord(): iKeyWordSize(0), iLang_Code(0) {};
~PVMP4FFCN_KeyWord() {};
uint32 iKeyWordSize;
uint16 iLang_Code;
OSCL_wHeapString<OsclMemAllocator> iData_String;
PVMP4FFCN_KeyWord(const OSCL_wString& aData_String, uint32 aKeyWordSize, uint16 aLang_Code)
{
iData_String = aData_String;
iKeyWordSize = aKeyWordSize;
iLang_Code = aLang_Code;
}
};
PVMP4FFCN_MetaDataString iVersion;
PVMP4FFCN_MetaDataString iTitle;
PVMP4FFCN_MetaDataString iAuthor;
PVMP4FFCN_MetaDataString iCopyright;
PVMP4FFCN_MetaDataString iDescription;
PVMP4FFCN_MetaDataString iRating;
PVMP4FFCN_MetaDataString iAlbumTitle;
uint16 iRecordingYear;
PVMP4FFCN_MetaDataString iPerformer;
PVMP4FFCN_MetaDataString iGenre;
PVMP4FFCN_MetaDataString iClassification;
Oscl_Vector<PVMP4FFCN_KeyWord* , OsclMemAllocator> iKeyWordVector;
PvmfAssetInfo3GPPLocationStruct iLocationInfo;
OSCL_wHeapString<OsclMemAllocator> iCreationDate;
// Convert from timescale
MediaClockConverter iClockConverter;
// Debug logging
PVLogger* iLogger;
PVLogger* iDataPathLogger;
uint32 iExtensionRefCount;
bool iRealTimeTS;
bool iInitTSOffset;
uint32 iTSOffset;
//variables for fileoutputduration config
bool iMaxFileSizeEnabled;
bool iMaxDurationEnabled;
uint32 iMaxFileSize;
uint32 iMaxTimeDuration;
bool iFileSizeReportEnabled;
bool iDurationReportEnabled;
uint32 iFileSizeReportFreq;
uint32 iDurationReportFreq;
uint32 iNextDurationReport;
uint32 iNextFileSizeReport;
uint32 iCacheSize;
int32 iConfigSize;
uint8 *pConfig;
int32 iTrackId_H264;
int32 iTrackId_Text;
int32 iSyncSample;
PVMFFormatType iformat_h264;
PVMFFormatType iformat_text;
bool iNodeEndOfDataReached;
bool iSampleInTrack;
bool iFileRendered;
#if PROFILING_ON
uint32 iMaxSampleAddTime;
uint32 iMinSampleAddTime;
uint32 iMinSampleSize;
uint32 iMaxSampleSize;
uint32 iNumSamplesAdded;
PVLogger* iDiagnosticsLogger;
bool oDiagnosticsLogged;
// Statistics
struct PVMp4FFCNStats
{
int32 iTrackId;
uint32 iNumFrames;
uint32 iDuration;
};
PVMp4FFCNStats iStats[3];
#endif
#ifdef _TEST_AE_ERROR_HANDLING
bool iErrorHandlingAddMemFrag;
bool iErrorHandlingAddTrack;
bool iErrorCreateComposer;
bool iErrorRenderToFile;
PVMFFormatType iErrorAddTrack;
uint32 iErrorNodeCmd;
uint32 iTestFileSize;
uint32 iTestTimeStamp;
uint32 iErrorAddSample;
uint32 iFileSize;
uint32 iFileDuration;
uint32 iErrorDataPathStall;
#endif
};
#endif // PVMP4FFC_NODE_H_INCLUDED