| /* ------------------------------------------------------------------ |
| * 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. |
| * ------------------------------------------------------------------- |
| */ |
| #if !defined(LOGICAL_CHANNEL_H) |
| #define LOGICAL_CHANNEL_H |
| #include "oscl_mem.h" |
| #include "adaptationlayer.h" |
| #include "h324utils.h" |
| |
| #ifndef OSCL_MEM_MEMPOOL_H_INCLUDED |
| #include "oscl_mem_mempool.h" |
| #endif |
| |
| #ifndef PVMF_MEDIA_CLOCK_H_INCLUDED |
| #include "pvmf_media_clock.h" |
| #endif |
| |
| #ifndef OSCL_MAP_H_INCLUDED |
| #include "oscl_map.h" |
| #endif |
| |
| #ifndef PVMF_MEDIA_DATA_H_INCLUDED |
| #include "pvmf_media_data.h" |
| #endif |
| |
| #ifndef PVMF_SIMPLE_MEDIA_BUFFER_H_INCLUDED |
| #include "pvmf_simple_media_buffer.h" |
| #endif |
| |
| #ifndef PVMF_NODE_INTERFACE_H_INCLUDED |
| #include "pvmf_node_interface.h" |
| #endif |
| |
| #ifndef PVMF_PORT_BASE_IMPL_H_INCLUDED |
| #include "pvmf_port_base_impl.h" |
| #endif |
| |
| #ifndef PVMF_MEDIA_FRAG_GROUP_H_INCLUDED |
| #include "pvmf_media_frag_group.h" |
| #endif |
| |
| #ifndef PVLOGGER_H_INCLUDED |
| #include "pvlogger.h" |
| #endif |
| |
| #ifndef PVMI_CONFIG_AND_CAPABILITY_H_INCLUDED |
| #include "pvmi_config_and_capability_utils.h" |
| #endif |
| |
| #define INVALID_MUX_CODE 0xFF |
| #define DEF_NUM_MEDIA_DATA 100 |
| #define SKEW_CHECK_INTERVAL 2000 |
| #define PARSING_JITTER_DURATION 200 |
| #define PVDEBUG_LOG_BITSTREAM_PKT(iDebug, comp, pkt) \ |
| {\ |
| uint8* ptrbuf = pkt->GetMediaPtr();\ |
| PVDEBUG_LOG_BITSTREAM(iDebug, (comp, ptrbuf, pkt->GetMediaSize()) );\ |
| pkt->ClearMediaPtr();\ |
| } |
| |
| class LCMediaDataEntry |
| { |
| public: |
| LCMediaDataEntry() : next(NULL) {} |
| ~LCMediaDataEntry() |
| { |
| mediaData.Unbind(); |
| } |
| PVMFSharedMediaDataPtr mediaData; |
| LCMediaDataEntry* next; |
| }; |
| |
| class LcnAlloc : public Oscl_DefAlloc |
| { |
| public: |
| void* allocate(const uint32 size) |
| { |
| void* tmp = (void*)OSCL_DEFAULT_MALLOC(size); |
| OSCL_ASSERT(tmp != 0); |
| return tmp; |
| } |
| void deallocate(void* p) |
| { |
| OSCL_DEFAULT_FREE(p); |
| } |
| }; |
| |
| class LogicalChannelObserver |
| { |
| public: |
| virtual ~LogicalChannelObserver() {} |
| virtual int32 GetTimestamp() = 0; |
| virtual void LogicalChannelError(TPVDirection direction, TPVChannelId id, PVMFStatus error) = 0; |
| virtual void SkewDetected(TPVChannelId lcn1, TPVChannelId lcn2, uint32 skew) = 0; |
| virtual void ReceivedFormatSpecificInfo(TPVChannelId lcn, uint8* fsi, uint32 fsi_len) = 0; |
| }; |
| |
| class H223LogicalChannel : public PvmfPortBaseImpl, |
| public PVMFPortActivityHandler, |
| public PvmiCapabilityAndConfig, |
| public virtual LogicalChannelInfo |
| { |
| public: |
| H223LogicalChannel(TPVChannelId num, |
| bool segmentable, |
| OsclSharedPtr<AdaptationLayer>& al, |
| PS_DataType data_type, |
| LogicalChannelObserver* observer, |
| uint32 bitrate, |
| uint32 sample_interval, |
| uint32 num_media_data); |
| virtual ~H223LogicalChannel(); |
| |
| /* allocate resources in this function */ |
| virtual void Init() = 0; |
| |
| // LogicalChannelInfo virtuals |
| TPVChannelId GetLogicalChannelNumber() |
| { |
| return lcn; |
| } |
| |
| uint32 GetSduSize() |
| { |
| return iAl->GetSduSize(); |
| } |
| |
| bool IsSegmentable() |
| { |
| return iSegmentable; |
| } |
| |
| uint32 GetBitrate() |
| { |
| return iBitrate; |
| } |
| |
| uint32 GetSampleInterval() |
| { |
| return iSampleInterval; |
| } |
| |
| const uint8* GetFormatSpecificInfo(uint32* format_specific_info_len); |
| PVMFTimestamp GetLastSduTimestamp() |
| { |
| return iLastSduTimestamp; |
| } |
| |
| PVMFFormatType GetFormatType() |
| { |
| PVCodecType_t codec_type = GetCodecType(iDataType); |
| return PVCodecTypeToPVMFFormatType(codec_type); |
| } |
| |
| OsclAny SetNext(H223LogicalChannel* lcn_next) |
| { |
| next = lcn_next; |
| } |
| H223LogicalChannel* GetNext() |
| { |
| return next; |
| } |
| |
| OsclSharedPtr<AdaptationLayer>GetAl() |
| { |
| return iAl; |
| } |
| |
| OsclAny SetSampleInterval(uint16 sample_interval) |
| { |
| iSampleInterval = sample_interval; |
| } |
| |
| /* Flushes the pending AL SDU data */ |
| virtual OsclAny Flush() = 0; |
| |
| virtual OsclAny ResetStats() = 0; |
| virtual OsclAny LogStats() = 0; |
| |
| // Functions to pause and resume |
| virtual void Pause(); |
| virtual void Resume(); |
| |
| // Set format specific information |
| PVMFStatus SetFormatSpecificInfo(uint8* info, uint16 info_len); |
| |
| void SetTimestampOffset(uint32 offset) |
| { |
| iIncomingSkew = offset; |
| } |
| void SetDatapathLatency(uint32 aLatency); |
| |
| void SetClock(PVMFMediaClock* aClock) |
| { |
| iClock = aClock; |
| } |
| |
| //CapabilityAndConfig virtuals |
| OSCL_IMPORT_REF void QueryInterface(const PVUuid& aUuid, OsclAny*& aPtr); |
| |
| /* PVMFPortActivityHandler virtuals */ |
| void HandlePortActivity(const PVMFPortActivity &aActivity) |
| { |
| OSCL_UNUSED_ARG(aActivity); |
| } |
| PVMFStatus setConfigParametersSync(PvmiKvp* selectedKvp, PvmiCapabilityAndConfig* aConfig, PVMFFormatType lcn_format_type = PVMF_MIME_FORMAT_UNKNOWN, bool aTryTwice = false); |
| |
| |
| |
| //Set the audio/video MIO latencies for the respective channel |
| void SetAudioLatency(int32 aAudioLatency) |
| { |
| iAudioLatency = aAudioLatency; |
| } |
| void SetVideoLatency(int32 aVideoLatency) |
| { |
| iVideoLatency = aVideoLatency; |
| } |
| |
| protected: |
| TPVChannelId lcn; |
| bool iSegmentable; |
| H223LogicalChannel* next; |
| OsclSharedPtr<AdaptationLayer> iAl; |
| uint32 iBitrate; |
| uint32 iSampleInterval; |
| LogicalChannelObserver* iObserver; |
| uint8* iFormatSpecificInfo; |
| uint32 iFormatSpecificInfoLen; |
| PVLogger* iLogger; |
| uint32 iIncomingSkew; |
| PVMFTimestamp iLastSduTimestamp; |
| PS_DataType iDataType; |
| OsclMemAllocator iKvpMemAlloc; |
| uint32 iNumMediaData; |
| uint32 iMaxSduSize; |
| bool iSendFormatSpecificInfo; |
| uint32 iDatapathLatency; |
| PVMFFormatType iMediaType; |
| OsclRefCounterMemFrag iFsiFrag; |
| bool iPaused; |
| PVMFMediaClock* iClock; |
| int32 iAudioLatency; |
| int32 iVideoLatency; |
| |
| }; |
| |
| /* For outgoing A/V/C ( to be muxed) */ |
| class H223OutgoingChannel : public H223LogicalChannel |
| { |
| public: |
| H223OutgoingChannel(TPVChannelId num, |
| bool segmentable, |
| OsclSharedPtr<AdaptationLayer>& al, |
| PS_DataType data_type, |
| LogicalChannelObserver* observer, |
| uint32 bitrate, |
| uint32 sample_interval, |
| uint32 num_media_data); |
| ~H223OutgoingChannel(); |
| |
| void Init(); |
| |
| TPVDirection GetDirection() |
| { |
| return OUTGOING; |
| } |
| bool GetNextPacket(PVMFSharedMediaDataPtr& aMediaData, PVMFStatus aStatus); |
| |
| OsclAny ReleasePacket(PVMFSharedMediaDataPtr& aMediaData); |
| |
| OsclAny Flush(); |
| |
| OsclAny ResetStats(); |
| OsclAny LogStats(); |
| OsclAny SetSkewReference(LogicalChannelInfo* reference_channel) |
| { |
| iSkewReferenceChannel = reference_channel; |
| } |
| |
| void BufferMedia(uint16 aMs); |
| void SetBufferSizeMs(uint32 buffer_size_ms); |
| |
| uint32 GetNumBytesTransferred() |
| { |
| return iNumBytesIn; |
| } |
| // Functions to pause and resume the output of data from the logical channel to the mux |
| void Resume(); |
| |
| OSCL_IMPORT_REF PVMFStatus Connect(PVMFPortInterface* aPort); |
| |
| // Implement pure virtuals from PvmiCapabilityAndConfig interface |
| OSCL_IMPORT_REF void setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver); |
| OSCL_IMPORT_REF PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, |
| PvmiKvp*& aParameters, int& num_parameter_elements, |
| PvmiCapabilityContext aContext); |
| OSCL_IMPORT_REF PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); |
| OSCL_IMPORT_REF void createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext); |
| OSCL_IMPORT_REF void setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, |
| PvmiKvp* aParameters, int num_parameter_elements); |
| OSCL_IMPORT_REF void DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext); |
| OSCL_IMPORT_REF void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, |
| int num_elements, PvmiKvp * & aRet_kvp); |
| OSCL_IMPORT_REF PVMFCommandId setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, |
| int num_elements, PvmiKvp*& aRet_kvp, OsclAny* context = NULL); |
| OSCL_IMPORT_REF uint32 getCapabilityMetric(PvmiMIOSession aSession); |
| OSCL_IMPORT_REF PVMFStatus verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); |
| /* PVMFPortActivityHandler virtuals */ |
| void HandlePortActivity(const PVMFPortActivity &aActivity); |
| protected: |
| virtual PVMFStatus PutData(PVMFSharedMediaMsgPtr media_msg); |
| |
| bool FragmentPacket(PVMFSharedMediaDataPtr& aMediaData, PVMFSharedMediaDataPtr& newpack); |
| |
| OsclSharedPtr<PVMFMediaDataImpl> StartAlPdu(); |
| |
| PVMFStatus CompletePdu(); |
| |
| PVMFStatus AppendOutgoingPkt(OsclSharedPtr<PVMFMediaDataImpl>& pdu, PVMFTimestamp timestamp, |
| OsclRefCounterMemFrag* fsi = NULL); |
| |
| OsclAny ResetSkewParameters(); |
| |
| |
| PVMFStatus VerifyAndSetParameter(PvmiKvp* aKvp, bool aSetParam); |
| |
| PVMFStatus NegotiateInputSettings(PvmiCapabilityAndConfig* config); |
| |
| OsclMemPoolFixedChunkAllocator* iMediaMsgMemoryPool; |
| OsclMemPoolFixedChunkAllocator* iMediaDataEntryAlloc; |
| LCMediaDataEntry* lastMediaData; |
| PVMFMediaFragGroupCombinedAlloc<OsclMemAllocator>* iMediaFragGroupAlloc; |
| OsclMemPoolFixedChunkAllocator* iPduPktMemPool; |
| OsclSharedPtr<PVMFMediaDataImpl> iCurPdu; |
| |
| TimeValue iCreateTime; |
| TimeValue iStartTime; |
| uint32 iNumPacketsIn; |
| uint32 iNumSdusIn; |
| uint32 iNumSdusDropped; |
| uint32 iNumBytesIn; |
| uint32 iNumSdusOut; |
| uint32 iNumBytesOut; |
| uint32 iMaxPacketMuxTime; |
| uint32 iMaxSduMuxTime; |
| uint32 iNumFlush; |
| uint32 iNumBytesFlushed; |
| // skew related |
| LogicalChannelInfo* iSkewReferenceChannel; |
| int32 iSetBufferMediaMs; |
| int32 iSetBufferMediaBytes; |
| int32 iBufferMediaMs; |
| int32 iBufferMediaBytes; |
| bool iMuxingStarted; |
| PVMFTimestamp iCurPduTimestamp; |
| uint32 iNumPendingPdus; |
| PVLogger* iOutgoingAudioLogger; |
| PVLogger* iOutgoingVideoLogger; |
| bool iWaitForRandomAccessPoint; |
| uint32 iBufferSizeMs; |
| }; |
| |
| class H223OutgoingControlChannel : public H223OutgoingChannel |
| { |
| public: |
| H223OutgoingControlChannel(OsclSharedPtr<AdaptationLayer>& al, |
| PS_DataType data_type, |
| LogicalChannelObserver* observer, |
| uint32 bitrate, |
| uint32 sample_interval, |
| uint32 num_media_data) |
| : H223OutgoingChannel(0, SEGMENTABLE, al, data_type, observer, bitrate, sample_interval, num_media_data) |
| { |
| } |
| |
| PVMFStatus PutData(PVMFSharedMediaMsgPtr aMsg); |
| }; |
| |
| #define NUM_INCOMING_SDU_BUFFERS 8 |
| /* For incoming (from the remote terminal) A/V/C */ |
| class H223IncomingChannel : public H223LogicalChannel |
| { |
| public: |
| H223IncomingChannel(TPVChannelId num, |
| bool segmentable, |
| OsclSharedPtr<AdaptationLayer>& al, |
| PS_DataType data_type, |
| LogicalChannelObserver* observer, |
| uint32 bitrate, |
| uint32 sample_interval, |
| uint32 num_media_data); |
| ~H223IncomingChannel(); |
| void Init(); |
| |
| TPVDirection GetDirection() |
| { |
| return INCOMING; |
| } |
| |
| virtual PVMFStatus PutData(PVMFSharedMediaMsgPtr aMsg) |
| { |
| OSCL_UNUSED_ARG(aMsg); |
| return PVMFErrNotSupported; |
| } |
| |
| PVMFStatus GetData(PVMFSharedMediaMsgPtr aMsg) |
| { |
| OSCL_UNUSED_ARG(aMsg); |
| return PVMFErrNotSupported; |
| } |
| |
| /* Dispaches packets to bound PAcketInput */ |
| PVMFStatus AlPduData(uint8* buf, uint16 len); |
| |
| PVMFStatus AlDispatch(); |
| |
| OsclAny ResetAlPdu(); |
| OsclAny AllocateAlPdu(); |
| OsclAny AppendAlPduFrag(); |
| uint32 CopyAlPduData(uint8* buf, uint16 len); |
| uint32 CopyToCurrentFrag(uint8* buf, uint16 len); |
| |
| OsclAny Flush(); |
| |
| OsclAny ResetStats(); |
| OsclAny LogStats(); |
| |
| uint32 GetNumSdusIn() |
| { |
| return iNumSdusIn; |
| } |
| // overload Connect to send out format specific info if available |
| PVMFStatus Connect(PVMFPortInterface* aPort); |
| |
| |
| // Implement pure virtuals from PvmiCapabilityAndConfig interface |
| OSCL_IMPORT_REF void setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver); |
| OSCL_IMPORT_REF PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, |
| PvmiKvp*& aParameters, int& num_parameter_elements, |
| PvmiCapabilityContext aContext); |
| OSCL_IMPORT_REF PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); |
| OSCL_IMPORT_REF void createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext); |
| OSCL_IMPORT_REF void setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, |
| PvmiKvp* aParameters, int num_parameter_elements); |
| OSCL_IMPORT_REF void DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext); |
| OSCL_IMPORT_REF void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, |
| int num_elements, PvmiKvp * & aRet_kvp); |
| OSCL_IMPORT_REF PVMFCommandId setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, |
| int num_elements, PvmiKvp*& aRet_kvp, OsclAny* context = NULL); |
| OSCL_IMPORT_REF uint32 getCapabilityMetric(PvmiMIOSession aSession); |
| OSCL_IMPORT_REF PVMFStatus verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); |
| /* PVMFPortActivityHandler virtuals */ |
| void HandlePortActivity(const PVMFPortActivity &aActivity); |
| |
| private: |
| void PreAlPduData(); |
| PVMFStatus VerifyAndSetParameter(PvmiKvp* aKvp, bool aSetParam); |
| PVMFStatus NegotiateOutputSettings(PvmiCapabilityAndConfig* config); |
| |
| OsclAny SendFormatSpecificInfo(); |
| |
| PVMFStatus DispatchPendingSdus(); |
| |
| PVMFStatus SendBeginOfStreamMediaCommand(); |
| |
| void SetSampleTimestamps(PVMFTimestamp& aTSOffset); |
| PVMFBufferPoolAllocator iMemFragmentAlloc; |
| OsclMemPoolFixedChunkAllocator* iMediaMsgMemoryPool; |
| PVMFMediaFragGroupCombinedAlloc<OsclMemAllocator>* iMediaFragGroupAlloc; |
| OsclMemPoolFixedChunkAllocator* iPduPktMemPool; |
| |
| OsclMemAllocator iMemAlloc; |
| PVMFSimpleMediaBufferCombinedAlloc iMediaDataAlloc; |
| Oscl_Vector<PVMFSharedMediaMsgPtr, OsclMemAllocator> iPendingSdus; |
| OsclSharedPtr<PVMFMediaDataImpl> iAlPduMediaData; |
| uint8* iAlPduFragPos; |
| OsclRefCounterMemFrag iAlPduFrag; |
| uint32 iPduSize; |
| uint32 iCurPduSize; |
| TimeValue iCreateTime; |
| TimeValue iStartTime; |
| uint32 iNumPdusIn; |
| uint32 iNumSdusIn; |
| uint32 iNumBytesIn; |
| uint32 iSduSizeExceededCnt; |
| uint32 iNumCrcErrors; |
| uint32 iNumSeqNumErrors; |
| uint32 iNumAbort; |
| uint32 iNumBytesFlushed; |
| PVMFTimestamp iCurTimestamp; |
| friend class TSC_324m; |
| PVLogger* iIncomingAudioLogger; |
| PVLogger* iIncomingVideoLogger; |
| int32 iRenderingSkew; |
| }; |
| |
| class MuxSduData |
| { |
| public: |
| MuxSduData(); |
| OsclSharedPtr<H223OutgoingChannel> lcn; |
| PVMFSharedMediaDataPtr sdu; |
| uint16 size; |
| uint16 cur_frag_num; |
| uint16 cur_pos; |
| }; |
| typedef Oscl_Vector<MuxSduData, OsclMemAllocator> MuxSduDataList; |
| |
| #endif |
| |