1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 #if !defined(LOGICAL_CHANNEL_H) 19 #define LOGICAL_CHANNEL_H 20 #include "oscl_mem.h" 21 #include "adaptationlayer.h" 22 #include "h324utils.h" 23 24 #ifndef OSCL_MEM_MEMPOOL_H_INCLUDED 25 #include "oscl_mem_mempool.h" 26 #endif 27 28 #ifndef PVMF_MEDIA_CLOCK_H_INCLUDED 29 #include "pvmf_media_clock.h" 30 #endif 31 32 #ifndef OSCL_MAP_H_INCLUDED 33 #include "oscl_map.h" 34 #endif 35 36 #ifndef PVMF_MEDIA_DATA_H_INCLUDED 37 #include "pvmf_media_data.h" 38 #endif 39 40 #ifndef PVMF_SIMPLE_MEDIA_BUFFER_H_INCLUDED 41 #include "pvmf_simple_media_buffer.h" 42 #endif 43 44 #ifndef PVMF_NODE_INTERFACE_H_INCLUDED 45 #include "pvmf_node_interface.h" 46 #endif 47 48 #ifndef PVMF_PORT_BASE_IMPL_H_INCLUDED 49 #include "pvmf_port_base_impl.h" 50 #endif 51 52 #ifndef PVMF_MEDIA_FRAG_GROUP_H_INCLUDED 53 #include "pvmf_media_frag_group.h" 54 #endif 55 56 #ifndef PVLOGGER_H_INCLUDED 57 #include "pvlogger.h" 58 #endif 59 60 #ifndef PVMI_CONFIG_AND_CAPABILITY_H_INCLUDED 61 #include "pvmi_config_and_capability_utils.h" 62 #endif 63 64 #define INVALID_MUX_CODE 0xFF 65 #define DEF_NUM_MEDIA_DATA 100 66 #define SKEW_CHECK_INTERVAL 2000 67 #define PARSING_JITTER_DURATION 200 68 #define PVDEBUG_LOG_BITSTREAM_PKT(iDebug, comp, pkt) \ 69 {\ 70 uint8* ptrbuf = pkt->GetMediaPtr();\ 71 PVDEBUG_LOG_BITSTREAM(iDebug, (comp, ptrbuf, pkt->GetMediaSize()) );\ 72 pkt->ClearMediaPtr();\ 73 } 74 75 class LCMediaDataEntry 76 { 77 public: LCMediaDataEntry()78 LCMediaDataEntry() : next(NULL) {} ~LCMediaDataEntry()79 ~LCMediaDataEntry() 80 { 81 mediaData.Unbind(); 82 } 83 PVMFSharedMediaDataPtr mediaData; 84 LCMediaDataEntry* next; 85 }; 86 87 class LcnAlloc : public Oscl_DefAlloc 88 { 89 public: allocate(const uint32 size)90 void* allocate(const uint32 size) 91 { 92 void* tmp = (void*)OSCL_DEFAULT_MALLOC(size); 93 OSCL_ASSERT(tmp != 0); 94 return tmp; 95 } deallocate(void * p)96 void deallocate(void* p) 97 { 98 OSCL_DEFAULT_FREE(p); 99 } 100 }; 101 102 class LogicalChannelObserver 103 { 104 public: ~LogicalChannelObserver()105 virtual ~LogicalChannelObserver() {} 106 virtual int32 GetTimestamp() = 0; 107 virtual void LogicalChannelError(TPVDirection direction, TPVChannelId id, PVMFStatus error) = 0; 108 virtual void SkewDetected(TPVChannelId lcn1, TPVChannelId lcn2, uint32 skew) = 0; 109 virtual void ReceivedFormatSpecificInfo(TPVChannelId lcn, uint8* fsi, uint32 fsi_len) = 0; 110 }; 111 112 class H223LogicalChannel : public PvmfPortBaseImpl, 113 public PVMFPortActivityHandler, 114 public PvmiCapabilityAndConfig, 115 public virtual LogicalChannelInfo 116 { 117 public: 118 H223LogicalChannel(TPVChannelId num, 119 bool segmentable, 120 OsclSharedPtr<AdaptationLayer>& al, 121 PS_DataType data_type, 122 LogicalChannelObserver* observer, 123 uint32 bitrate, 124 uint32 sample_interval, 125 uint32 num_media_data); 126 virtual ~H223LogicalChannel(); 127 128 /* allocate resources in this function */ 129 virtual void Init() = 0; 130 131 // LogicalChannelInfo virtuals GetLogicalChannelNumber()132 TPVChannelId GetLogicalChannelNumber() 133 { 134 return lcn; 135 } 136 GetSduSize()137 uint32 GetSduSize() 138 { 139 return iAl->GetSduSize(); 140 } 141 IsSegmentable()142 bool IsSegmentable() 143 { 144 return iSegmentable; 145 } 146 GetBitrate()147 uint32 GetBitrate() 148 { 149 return iBitrate; 150 } 151 GetSampleInterval()152 uint32 GetSampleInterval() 153 { 154 return iSampleInterval; 155 } 156 157 const uint8* GetFormatSpecificInfo(uint32* format_specific_info_len); GetLastSduTimestamp()158 PVMFTimestamp GetLastSduTimestamp() 159 { 160 return iLastSduTimestamp; 161 } 162 GetFormatType()163 PVMFFormatType GetFormatType() 164 { 165 PVCodecType_t codec_type = GetCodecType(iDataType); 166 return PVCodecTypeToPVMFFormatType(codec_type); 167 } 168 SetNext(H223LogicalChannel * lcn_next)169 OsclAny SetNext(H223LogicalChannel* lcn_next) 170 { 171 next = lcn_next; 172 } GetNext()173 H223LogicalChannel* GetNext() 174 { 175 return next; 176 } 177 GetAl()178 OsclSharedPtr<AdaptationLayer>GetAl() 179 { 180 return iAl; 181 } 182 SetSampleInterval(uint16 sample_interval)183 OsclAny SetSampleInterval(uint16 sample_interval) 184 { 185 iSampleInterval = sample_interval; 186 } 187 188 /* Flushes the pending AL SDU data */ 189 virtual OsclAny Flush() = 0; 190 191 virtual OsclAny ResetStats() = 0; 192 virtual OsclAny LogStats() = 0; 193 194 // Functions to pause and resume 195 virtual void Pause(); 196 virtual void Resume(); 197 198 // Set format specific information 199 PVMFStatus SetFormatSpecificInfo(uint8* info, uint16 info_len); 200 SetTimestampOffset(uint32 offset)201 void SetTimestampOffset(uint32 offset) 202 { 203 iIncomingSkew = offset; 204 } 205 void SetDatapathLatency(uint32 aLatency); 206 SetClock(PVMFMediaClock * aClock)207 void SetClock(PVMFMediaClock* aClock) 208 { 209 iClock = aClock; 210 } 211 212 //CapabilityAndConfig virtuals 213 OSCL_IMPORT_REF void QueryInterface(const PVUuid& aUuid, OsclAny*& aPtr); 214 215 /* PVMFPortActivityHandler virtuals */ HandlePortActivity(const PVMFPortActivity & aActivity)216 void HandlePortActivity(const PVMFPortActivity &aActivity) 217 { 218 OSCL_UNUSED_ARG(aActivity); 219 } 220 PVMFStatus setConfigParametersSync(PvmiKvp* selectedKvp, PvmiCapabilityAndConfig* aConfig, PVMFFormatType lcn_format_type = PVMF_MIME_FORMAT_UNKNOWN, bool aTryTwice = false); 221 222 223 224 //Set the audio/video MIO latencies for the respective channel SetAudioLatency(int32 aAudioLatency)225 void SetAudioLatency(int32 aAudioLatency) 226 { 227 iAudioLatency = aAudioLatency; 228 } SetVideoLatency(int32 aVideoLatency)229 void SetVideoLatency(int32 aVideoLatency) 230 { 231 iVideoLatency = aVideoLatency; 232 } 233 234 protected: 235 TPVChannelId lcn; 236 bool iSegmentable; 237 H223LogicalChannel* next; 238 OsclSharedPtr<AdaptationLayer> iAl; 239 uint32 iBitrate; 240 uint32 iSampleInterval; 241 LogicalChannelObserver* iObserver; 242 uint8* iFormatSpecificInfo; 243 uint32 iFormatSpecificInfoLen; 244 PVLogger* iLogger; 245 uint32 iIncomingSkew; 246 PVMFTimestamp iLastSduTimestamp; 247 PS_DataType iDataType; 248 OsclMemAllocator iKvpMemAlloc; 249 uint32 iNumMediaData; 250 uint32 iMaxSduSize; 251 bool iSendFormatSpecificInfo; 252 uint32 iDatapathLatency; 253 PVMFFormatType iMediaType; 254 bool iPaused; 255 PVMFMediaClock* iClock; 256 int32 iAudioLatency; 257 int32 iVideoLatency; 258 259 }; 260 261 /* For outgoing A/V/C ( to be muxed) */ 262 class H223OutgoingChannel : public H223LogicalChannel 263 { 264 public: 265 H223OutgoingChannel(TPVChannelId num, 266 bool segmentable, 267 OsclSharedPtr<AdaptationLayer>& al, 268 PS_DataType data_type, 269 LogicalChannelObserver* observer, 270 uint32 bitrate, 271 uint32 sample_interval, 272 uint32 num_media_data); 273 ~H223OutgoingChannel(); 274 275 void Init(); 276 GetDirection()277 TPVDirection GetDirection() 278 { 279 return OUTGOING; 280 } 281 bool GetNextPacket(PVMFSharedMediaDataPtr& aMediaData, PVMFStatus aStatus); 282 283 OsclAny ReleasePacket(PVMFSharedMediaDataPtr& aMediaData); 284 285 OsclAny Flush(); 286 287 OsclAny ResetStats(); 288 OsclAny LogStats(); SetSkewReference(LogicalChannelInfo * reference_channel)289 OsclAny SetSkewReference(LogicalChannelInfo* reference_channel) 290 { 291 iSkewReferenceChannel = reference_channel; 292 } 293 294 void BufferMedia(uint16 aMs); 295 void SetBufferSizeMs(uint32 buffer_size_ms); 296 GetNumBytesTransferred()297 uint32 GetNumBytesTransferred() 298 { 299 return iNumBytesIn; 300 } 301 // Functions to pause and resume the output of data from the logical channel to the mux 302 void Resume(); 303 304 OSCL_IMPORT_REF PVMFStatus Connect(PVMFPortInterface* aPort); 305 OSCL_IMPORT_REF virtual PVMFStatus PeerConnect(PVMFPortInterface* aPort); 306 307 // Implement pure virtuals from PvmiCapabilityAndConfig interface 308 OSCL_IMPORT_REF void setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver); 309 OSCL_IMPORT_REF PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, 310 PvmiKvp*& aParameters, int& num_parameter_elements, 311 PvmiCapabilityContext aContext); 312 OSCL_IMPORT_REF PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); 313 OSCL_IMPORT_REF void createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext); 314 OSCL_IMPORT_REF void setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, 315 PvmiKvp* aParameters, int num_parameter_elements); 316 OSCL_IMPORT_REF void DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext); 317 OSCL_IMPORT_REF void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, 318 int num_elements, PvmiKvp * & aRet_kvp); 319 OSCL_IMPORT_REF PVMFCommandId setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, 320 int num_elements, PvmiKvp*& aRet_kvp, OsclAny* context = NULL); 321 OSCL_IMPORT_REF uint32 getCapabilityMetric(PvmiMIOSession aSession); 322 OSCL_IMPORT_REF PVMFStatus verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); 323 /* PVMFPortActivityHandler virtuals */ 324 void HandlePortActivity(const PVMFPortActivity &aActivity); 325 protected: 326 virtual PVMFStatus PutData(PVMFSharedMediaMsgPtr media_msg); 327 328 bool FragmentPacket(PVMFSharedMediaDataPtr& aMediaData, PVMFSharedMediaDataPtr& newpack); 329 330 OsclSharedPtr<PVMFMediaDataImpl> StartAlPdu(); 331 332 PVMFStatus CompletePdu(); 333 334 PVMFStatus AppendOutgoingPkt(OsclSharedPtr<PVMFMediaDataImpl>& pdu, PVMFTimestamp timestamp, 335 OsclRefCounterMemFrag* fsi = NULL); 336 337 OsclAny ResetSkewParameters(); 338 339 340 PVMFStatus VerifyAndSetParameter(PvmiKvp* aKvp, bool aSetParam); 341 342 PVMFStatus NegotiateInputSettings(PvmiCapabilityAndConfig* config); 343 PVMFStatus NegotiateFSISettings(PvmiCapabilityAndConfig* config); 344 PVMFStatus ReceivedFSIFromPeer(PvmiKvp* kvp); 345 346 OsclMemPoolFixedChunkAllocator* iMediaMsgMemoryPool; 347 OsclMemPoolFixedChunkAllocator* iMediaDataEntryAlloc; 348 LCMediaDataEntry* lastMediaData; 349 PVMFMediaFragGroupCombinedAlloc<OsclMemAllocator>* iMediaFragGroupAlloc; 350 OsclMemPoolFixedChunkAllocator* iPduPktMemPool; 351 OsclSharedPtr<PVMFMediaDataImpl> iCurPdu; 352 353 TimeValue iCreateTime; 354 TimeValue iStartTime; 355 uint32 iNumPacketsIn; 356 uint32 iNumSdusIn; 357 uint32 iNumSdusDropped; 358 uint32 iNumBytesIn; 359 uint32 iNumSdusOut; 360 uint32 iNumBytesOut; 361 uint32 iMaxPacketMuxTime; 362 uint32 iMaxSduMuxTime; 363 uint32 iNumFlush; 364 uint32 iNumBytesFlushed; 365 // skew related 366 LogicalChannelInfo* iSkewReferenceChannel; 367 int32 iSetBufferMediaMs; 368 int32 iSetBufferMediaBytes; 369 int32 iBufferMediaMs; 370 int32 iBufferMediaBytes; 371 bool iMuxingStarted; 372 PVMFTimestamp iCurPduTimestamp; 373 uint32 iNumPendingPdus; 374 PVLogger* iOutgoingAudioLogger; 375 PVLogger* iOutgoingVideoLogger; 376 bool iWaitForRandomAccessPoint; 377 uint32 iBufferSizeMs; 378 OsclRefCounterMemFrag iFsiFrag; 379 }; 380 381 class H223OutgoingControlChannel : public H223OutgoingChannel 382 { 383 public: H223OutgoingControlChannel(OsclSharedPtr<AdaptationLayer> & al,PS_DataType data_type,LogicalChannelObserver * observer,uint32 bitrate,uint32 sample_interval,uint32 num_media_data)384 H223OutgoingControlChannel(OsclSharedPtr<AdaptationLayer>& al, 385 PS_DataType data_type, 386 LogicalChannelObserver* observer, 387 uint32 bitrate, 388 uint32 sample_interval, 389 uint32 num_media_data) 390 : H223OutgoingChannel(0, SEGMENTABLE, al, data_type, observer, bitrate, sample_interval, num_media_data) 391 { 392 } 393 394 PVMFStatus PutData(PVMFSharedMediaMsgPtr aMsg); 395 OSCL_IMPORT_REF PVMFStatus PeerConnect(PVMFPortInterface* aPort); 396 397 }; 398 399 #define NUM_INCOMING_SDU_BUFFERS 8 400 /* For incoming (from the remote terminal) A/V/C */ 401 class H223IncomingChannel : public H223LogicalChannel 402 { 403 public: 404 H223IncomingChannel(TPVChannelId num, 405 bool segmentable, 406 OsclSharedPtr<AdaptationLayer>& al, 407 PS_DataType data_type, 408 LogicalChannelObserver* observer, 409 uint32 bitrate, 410 uint32 sample_interval, 411 uint32 num_media_data); 412 ~H223IncomingChannel(); 413 void Init(); 414 GetDirection()415 TPVDirection GetDirection() 416 { 417 return INCOMING; 418 } 419 PutData(PVMFSharedMediaMsgPtr aMsg)420 virtual PVMFStatus PutData(PVMFSharedMediaMsgPtr aMsg) 421 { 422 OSCL_UNUSED_ARG(aMsg); 423 return PVMFErrNotSupported; 424 } 425 GetData(PVMFSharedMediaMsgPtr aMsg)426 PVMFStatus GetData(PVMFSharedMediaMsgPtr aMsg) 427 { 428 OSCL_UNUSED_ARG(aMsg); 429 return PVMFErrNotSupported; 430 } 431 432 /* Dispaches packets to bound PAcketInput */ 433 PVMFStatus AlPduData(uint8* buf, uint16 len); 434 435 PVMFStatus AlDispatch(); 436 437 OsclAny ResetAlPdu(); 438 OsclAny AllocateAlPdu(); 439 OsclAny AppendAlPduFrag(); 440 uint32 CopyAlPduData(uint8* buf, uint16 len); 441 uint32 CopyToCurrentFrag(uint8* buf, uint16 len); 442 443 OsclAny Flush(); 444 445 OsclAny ResetStats(); 446 OsclAny LogStats(); 447 GetNumSdusIn()448 uint32 GetNumSdusIn() 449 { 450 return iNumSdusIn; 451 } 452 // overload Connect to send out format specific info if available 453 PVMFStatus Connect(PVMFPortInterface* aPort); 454 455 456 // Implement pure virtuals from PvmiCapabilityAndConfig interface 457 OSCL_IMPORT_REF void setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver); 458 OSCL_IMPORT_REF PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, 459 PvmiKvp*& aParameters, int& num_parameter_elements, 460 PvmiCapabilityContext aContext); 461 OSCL_IMPORT_REF PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); 462 OSCL_IMPORT_REF void createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext); 463 OSCL_IMPORT_REF void setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, 464 PvmiKvp* aParameters, int num_parameter_elements); 465 OSCL_IMPORT_REF void DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext); 466 OSCL_IMPORT_REF void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, 467 int num_elements, PvmiKvp * & aRet_kvp); 468 OSCL_IMPORT_REF PVMFCommandId setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, 469 int num_elements, PvmiKvp*& aRet_kvp, OsclAny* context = NULL); 470 OSCL_IMPORT_REF uint32 getCapabilityMetric(PvmiMIOSession aSession); 471 OSCL_IMPORT_REF PVMFStatus verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); 472 /* PVMFPortActivityHandler virtuals */ 473 void HandlePortActivity(const PVMFPortActivity &aActivity); 474 475 private: 476 void PreAlPduData(); 477 PVMFStatus VerifyAndSetParameter(PvmiKvp* aKvp, bool aSetParam); 478 PVMFStatus NegotiateOutputSettings(PvmiCapabilityAndConfig* config); 479 480 OsclAny SendFormatSpecificInfo(); 481 482 PVMFStatus DispatchPendingSdus(); 483 484 PVMFStatus SendBeginOfStreamMediaCommand(); 485 486 void SetSampleTimestamps(PVMFTimestamp& aTSOffset); 487 PVMFBufferPoolAllocator iMemFragmentAlloc; 488 OsclMemPoolFixedChunkAllocator* iMediaMsgMemoryPool; 489 PVMFMediaFragGroupCombinedAlloc<OsclMemAllocator>* iMediaFragGroupAlloc; 490 OsclMemPoolFixedChunkAllocator* iPduPktMemPool; 491 492 OsclMemAllocator iMemAlloc; 493 PVMFSimpleMediaBufferCombinedAlloc iMediaDataAlloc; 494 Oscl_Vector<PVMFSharedMediaMsgPtr, OsclMemAllocator> iPendingSdus; 495 OsclSharedPtr<PVMFMediaDataImpl> iAlPduMediaData; 496 uint8* iAlPduFragPos; 497 OsclRefCounterMemFrag iAlPduFrag; 498 uint32 iPduSize; 499 uint32 iCurPduSize; 500 TimeValue iCreateTime; 501 TimeValue iStartTime; 502 uint32 iNumPdusIn; 503 uint32 iNumSdusIn; 504 uint32 iNumBytesIn; 505 uint32 iSduSizeExceededCnt; 506 uint32 iNumCrcErrors; 507 uint32 iNumSeqNumErrors; 508 uint32 iNumAbort; 509 uint32 iNumBytesFlushed; 510 PVMFTimestamp iCurTimestamp; 511 friend class TSC_324m; 512 PVLogger* iIncomingAudioLogger; 513 PVLogger* iIncomingVideoLogger; 514 int32 iRenderingSkew; 515 }; 516 517 class MuxSduData 518 { 519 public: 520 MuxSduData(); 521 OsclSharedPtr<H223OutgoingChannel> lcn; 522 PVMFSharedMediaDataPtr sdu; 523 uint16 size; 524 uint16 cur_frag_num; 525 uint16 cur_pos; 526 }; 527 typedef Oscl_Vector<MuxSduData, OsclMemAllocator> MuxSduDataList; 528 529 #endif 530 531