C++程序  |  494行  |  20.54 KB

/* ------------------------------------------------------------------
 * 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