27 #include "mcepreconditions.h" |
27 #include "mcepreconditions.h" |
28 #include "mcesdpsession.h" |
28 #include "mcesdpsession.h" |
29 #include "mcesip.h" |
29 #include "mcesip.h" |
30 #include "mcemediamanager.h" |
30 #include "mcemediamanager.h" |
31 #include "mcenatpluginmanager.h" |
31 #include "mcenatpluginmanager.h" |
|
32 #include "mcemessagesdpcodec.h" |
|
33 #include "mcedefs.h" |
|
34 #include <mceexternalsink.h> |
|
35 #include <mceexternalsource.h> |
32 |
36 |
33 #include <sdpconnectionfield.h> |
37 #include <sdpconnectionfield.h> |
34 #include <sdpdocument.h> |
38 #include <sdpdocument.h> |
35 #include <sdpcodecstringconstants.h> |
39 #include <sdpcodecstringconstants.h> |
36 #include <sdpcodecstringpool.h> |
40 #include <sdpcodecstringpool.h> |
38 #include <sdpattributefield.h> |
42 #include <sdpattributefield.h> |
39 #include <sdprtpmapvalue.h> |
43 #include <sdprtpmapvalue.h> |
40 #include <sdpfmtattributefield.h> |
44 #include <sdpfmtattributefield.h> |
41 #include <sdporiginfield.h> |
45 #include <sdporiginfield.h> |
42 #include <sdpbandwidthfield.h> |
46 #include <sdpbandwidthfield.h> |
|
47 #include <sdpconnectionfield.h> |
43 #include <mmcccodecinformation.h> |
48 #include <mmcccodecinformation.h> |
44 #include <sdpcodecstringpool.h> |
49 #include <sdpcodecstringpool.h> |
45 #include <delimitedpathsegment8.h> |
50 #include <delimitedpathsegment8.h> |
|
51 #include <mcemessagestream.h> |
|
52 #include <mcemessagesink.h> |
|
53 #include <mcemessagesource.h> |
46 |
54 |
47 |
55 |
48 // ================= MEMBER FUNCTIONS ======================= |
56 // ================= MEMBER FUNCTIONS ======================= |
49 |
57 |
50 // ----------------------------------------------------------------------------- |
58 // ----------------------------------------------------------------------------- |
83 CMceComCodec::TIterator codecs( allCodecs, CMceComCodec::TIterator::EFilterIsNegotiated ); |
91 CMceComCodec::TIterator codecs( allCodecs, CMceComCodec::TIterator::EFilterIsNegotiated ); |
84 |
92 |
85 // Set the fmt list containing all supported payload |
93 // Set the fmt list containing all supported payload |
86 // types supported by this media |
94 // types supported by this media |
87 // i.e. all the rtpmap fields in the pointer array |
95 // i.e. all the rtpmap fields in the pointer array |
88 HBufC8* fmtlist = CreateFormatListL( codecs ); |
96 // Set the format list to '*' for MESSAGE streams |
89 CleanupStack::PushL( fmtlist ); |
97 HBufC8* fmtlist; |
|
98 fmtlist = CreateFormatListL( codecs ); |
|
99 CleanupStack::PushL( fmtlist ); |
90 codecs.Reset(); |
100 codecs.Reset(); |
91 |
101 |
92 aMediaLine.SetFormatListL( *fmtlist ); |
102 aMediaLine.SetFormatListL( *fmtlist ); |
93 CleanupStack::PopAndDestroy( fmtlist ); |
103 CleanupStack::PopAndDestroy( fmtlist ); |
94 |
104 |
96 |
106 |
97 // For each codec supported by this stream create a rtpmap field |
107 // For each codec supported by this stream create a rtpmap field |
98 // e.g. a=rtpmap: 97 AMR/8000 |
108 // e.g. a=rtpmap: 97 AMR/8000 |
99 // and ptime and maxptime |
109 // and ptime and maxptime |
100 // e.g. a=ptime:20 a=maxptime:40 |
110 // e.g. a=ptime:20 a=maxptime:40 |
101 while( codecs.Next( codec ) ) |
111 while( codecs.Next( codec ) && (aStream.iType != KMceMessage)) |
102 { |
112 { |
103 CSdpFmtAttributeField* rtpmap = EncodeRtpmapAttributeLC( *codec ); |
113 CSdpFmtAttributeField* rtpmap = EncodeRtpmapAttributeLC( *codec ); |
104 |
114 |
105 EncodeMediaAttributesL( *codec, aMediaLine, *rtpmap ); |
115 EncodeMediaAttributesL( *codec, aMediaLine, *rtpmap ); |
106 |
116 |
147 CMceComCodec::TIterator codecs( allCodecs ); |
157 CMceComCodec::TIterator codecs( allCodecs ); |
148 |
158 |
149 //decode direction or old school hold if necessary |
159 //decode direction or old school hold if necessary |
150 DecodeDirectionL( aMediaLine, aStream, aSdpDocument, EMceRoleOfferer ); |
160 DecodeDirectionL( aMediaLine, aStream, aSdpDocument, EMceRoleOfferer ); |
151 |
161 |
152 __ASSERT_ALWAYS( codecs.Count() > 0, User::Leave( KErrNotReady ) ); |
162 // If the type of the source/sink is external then it is expected that the application takes care of |
|
163 // data path and hence the codec count can be zero |
|
164 TBool Allow = EFalse; |
|
165 if ( IS_SENDSTREAM(&aStream)) |
|
166 { |
|
167 if ( (aStream.Source()->Type() == KMceExternalSource) || (aStream.Source()->Type() == KMceMessageSource) ) |
|
168 { |
|
169 Allow = ETrue; |
|
170 } |
|
171 } |
|
172 else |
|
173 { |
|
174 for (TInt i=0; i<aStream.Sinks().Count();i++) |
|
175 { |
|
176 if ( (aStream.Sinks()[i]->Type() == KMceExternalSink) || (aStream.Sinks()[i]->Type() == KMceMessageSink) ) |
|
177 { |
|
178 Allow = ETrue; |
|
179 } |
|
180 } |
|
181 } |
|
182 |
|
183 if (!Allow) |
|
184 { |
|
185 __ASSERT_ALWAYS( codecs.Count() > 0, User::Leave( KErrNotReady ) ); |
|
186 } |
|
187 |
153 __ASSERT_ALWAYS( aMediaLine.Port() != 0 , User::Leave( KErrNotReady ) ); |
188 __ASSERT_ALWAYS( aMediaLine.Port() != 0 , User::Leave( KErrNotReady ) ); |
154 |
189 |
155 //decode based on rtpmaps + their media attributes |
190 //decode based on rtpmaps + their media attributes |
156 TInt decoded = DecodePayloadsL( aMediaLine, aStream, EMceRoleOfferer ); |
191 TInt decoded = DecodePayloadsL( aMediaLine, aStream, EMceRoleOfferer ); |
157 |
192 |
158 if ( !decoded ) |
193 if ( !decoded && !Allow) |
159 { |
194 { |
160 MCEMM_DEBUG("ERROR: No codecs decoded") |
195 MCEMM_DEBUG("ERROR: No codecs decoded") |
161 User::Leave( KErrNotReady ); |
196 User::Leave( KErrNotReady ); |
162 } |
197 } |
163 |
198 |
338 |
373 |
339 const RPointerArray<CMceComCodec>& allCodecs = CodecsL( aStream ); |
374 const RPointerArray<CMceComCodec>& allCodecs = CodecsL( aStream ); |
340 CMceComCodec* codec = NULL; |
375 CMceComCodec* codec = NULL; |
341 CMceComCodec::TIterator codecs( allCodecs, CMceComCodec::TIterator::EFilterIsNegotiated ); |
376 CMceComCodec::TIterator codecs( allCodecs, CMceComCodec::TIterator::EFilterIsNegotiated ); |
342 |
377 |
343 if ( codecs.Count() > 0 ) |
378 // If the type of the source/sink is external then it is expected that the application takes care of |
|
379 // data path and hence the codec count can be zero |
|
380 TBool CanCodecsBeZero = EFalse; |
|
381 if ( IS_SENDSTREAM(&aStream)) |
|
382 { |
|
383 if (aStream.Source()->Type() == KMceExternalSource) |
|
384 { |
|
385 CanCodecsBeZero = ETrue; |
|
386 } |
|
387 } |
|
388 else |
|
389 { |
|
390 for (TInt i=0; i<aStream.Sinks().Count();i++) |
|
391 { |
|
392 if (aStream.Sinks()[i]->Type() == KMceExternalSink) |
|
393 { |
|
394 CanCodecsBeZero = ETrue; |
|
395 } |
|
396 } |
|
397 } |
|
398 |
|
399 if ( codecs.Count() > 0 || CanCodecsBeZero) |
344 { |
400 { |
345 |
401 |
346 // Set the fmt list containing all supported payload |
402 // Set the fmt list containing all supported payload |
347 // types supported by this media |
403 // types supported by this media |
348 // i.e. all the rtpmap fields in the pointer array |
404 // i.e. all the rtpmap fields in the pointer array |
349 HBufC8* fmtlist = CreateFormatListL( codecs ); |
405 HBufC8* fmtlist = CreateFormatListL( codecs ); |
|
406 // Presently for message type streams the codecs will be zero and as per RFC the fomat should be *. |
|
407 if (CanCodecsBeZero && codecs.Count() == 0 ) |
|
408 { |
|
409 TPtr8 ptr(fmtlist->Des()); |
|
410 |
|
411 ptr.Append(_L8("*")); |
|
412 } |
350 CleanupStack::PushL( fmtlist ); |
413 CleanupStack::PushL( fmtlist ); |
351 codecs.Reset(); |
414 codecs.Reset(); |
352 |
415 |
353 aMediaLine.SetFormatListL( *fmtlist ); |
416 aMediaLine.SetFormatListL( *fmtlist ); |
354 CleanupStack::PopAndDestroy( fmtlist ); |
417 CleanupStack::PopAndDestroy( fmtlist ); |
355 |
418 |
356 MCEMM_DEBUG_SVALUE("encoded formatlist", aMediaLine.FormatList() ) |
419 MCEMM_DEBUG_SVALUE("encoded formatlist", aMediaLine.FormatList() ) |
357 |
420 |
358 aMediaLine.SetPortL( aStream.iLocalMediaPort ); |
421 if(IS_RECEIVESTREAM(&aStream)) |
|
422 { |
|
423 aMediaLine.SetPortL( aStream.iLocalMediaPort ); |
|
424 } |
|
425 else |
|
426 { |
|
427 aMediaLine.SetPortL( aStream.iRemoteMediaPort ); |
|
428 } |
|
429 |
359 MCEMM_DEBUG_DVALUE("encoded local port", aMediaLine.Port() ) |
430 MCEMM_DEBUG_DVALUE("encoded local port", aMediaLine.Port() ) |
360 |
431 |
361 // add the direction attribute |
432 // add the direction attribute |
362 EncodeDirectionL( aStream, aMediaLine, aSdpDocument, EMceRoleAnswerer ); |
433 EncodeDirectionL( aStream, aMediaLine, aSdpDocument, EMceRoleAnswerer ); |
363 |
434 |
364 while( codecs.Next( codec ) ) |
435 while( codecs.Next( codec ) && (aStream.iType != KMceMessage) ) |
365 { |
436 { |
366 CSdpFmtAttributeField* rtpmap = EncodeRtpmapAttributeLC( *codec ); |
437 CSdpFmtAttributeField* rtpmap = EncodeRtpmapAttributeLC( *codec ); |
367 |
438 |
368 EncodeMediaAttributesL( *codec, aMediaLine, *rtpmap ); |
439 EncodeMediaAttributesL( *codec, aMediaLine, *rtpmap ); |
369 |
440 |
445 TInt decoded = 0; |
516 TInt decoded = 0; |
446 |
517 |
447 const RPointerArray<CMceComCodec>& allCodecs = CodecsL( aStream ); |
518 const RPointerArray<CMceComCodec>& allCodecs = CodecsL( aStream ); |
448 CMceComCodec* codec = NULL; |
519 CMceComCodec* codec = NULL; |
449 CMceComCodec::TIterator codecs( allCodecs ); |
520 CMceComCodec::TIterator codecs( allCodecs ); |
|
521 if(aStream.iType == KMceMessage) |
|
522 { |
|
523 codecs.Next(codec); |
|
524 if(codec) |
|
525 { |
|
526 codec->iIsNegotiated = ETrue; |
|
527 codec->iPayloadType = 120; |
|
528 } |
|
529 |
|
530 if ( aRole == EMceRoleAnswerer ) |
|
531 { |
|
532 if ( DecodeRtpmapLineL( aMediaLine, aStream ) ) |
|
533 { |
|
534 decoded++; |
|
535 } |
|
536 } |
|
537 else |
|
538 { |
|
539 // NOP |
|
540 } |
|
541 } |
450 |
542 |
451 RArray<TUint> payloadTypesInMediaLine; |
543 RArray<TUint> payloadTypesInMediaLine; |
452 CleanupClosePushL( payloadTypesInMediaLine ); |
544 CleanupClosePushL( payloadTypesInMediaLine ); |
453 |
545 |
454 User::LeaveIfError( DecodeFormatList( aMediaLine, payloadTypesInMediaLine ) ); |
546 User::LeaveIfError( DecodeFormatList( aMediaLine, payloadTypesInMediaLine ) ); |
675 |
767 |
676 TUint rtpMapPT = ConvertDesToUintL( payloadTypeInRtpMap ); |
768 TUint rtpMapPT = ConvertDesToUintL( payloadTypeInRtpMap ); |
677 CMceComCodec* codec = NULL; |
769 CMceComCodec* codec = NULL; |
678 |
770 |
679 // Ingoring if there is no matching pt in medialine for this rtmpmap line |
771 // Ingoring if there is no matching pt in medialine for this rtmpmap line |
680 if ( payloadTypesInMediaLine.Find( rtpMapPT ) != KErrNotFound ) |
772 if ( payloadTypesInMediaLine.Find( rtpMapPT ) != KErrNotFound || (aStream.iType == KMceMessage) ) |
681 { |
773 { |
682 codec = CreateCodecLC( aRtpMaptLine ); |
774 codec = CreateCodecLC( aRtpMaptLine ); |
683 if ( codec ) |
775 if ( codec ) |
684 { |
776 { |
685 codec->InitializeL( aStream ); |
777 codec->InitializeL( aStream ); |
696 codec->iIsNegotiated = ETrue; |
788 codec->iIsNegotiated = ETrue; |
697 MCEMM_DEBUG_SVALUE("adding codec", codec->iSdpName ) |
789 MCEMM_DEBUG_SVALUE("adding codec", codec->iSdpName ) |
698 aStream.AddCodecL( codec ); |
790 aStream.AddCodecL( codec ); |
699 CleanupStack::Pop( codec ); |
791 CleanupStack::Pop( codec ); |
700 } |
792 } |
|
793 } |
|
794 } |
|
795 |
|
796 CleanupStack::PopAndDestroy( &payloadTypesInMediaLine ); |
|
797 |
|
798 MCEMM_DEBUG("CMceMediaSdpCodec::DecodeFmtpLineL(), Exit ") |
|
799 return codec; |
|
800 } |
|
801 |
|
802 |
|
803 // ----------------------------------------------------------------------------- |
|
804 // CMceMediaSdpCodec::DecodeRtpmapLineL |
|
805 // ----------------------------------------------------------------------------- |
|
806 // |
|
807 CMceComCodec* CMceMediaSdpCodec::DecodeRtpmapLineL( |
|
808 CSdpMediaField& aMediaLine, |
|
809 CMceComMediaStream& aStream ) const |
|
810 { |
|
811 MCEMM_DEBUG("CMceMediaSdpCodec::DecodeFmtpLineL(), Entry ") |
|
812 |
|
813 CSdpFmtAttributeField* aRtpMaptLine = NULL; |
|
814 RArray<TUint> payloadTypesInMediaLine; |
|
815 CleanupClosePushL( payloadTypesInMediaLine ); |
|
816 |
|
817 User::LeaveIfError( DecodeFormatList( aMediaLine, payloadTypesInMediaLine ) ); |
|
818 |
|
819 CMceComCodec* codec = NULL; |
|
820 |
|
821 // Ingoring if there is no matching pt in medialine for this rtmpmap line |
|
822 if ( aStream.iType == KMceMessage ) |
|
823 { |
|
824 codec = CreateCodecLC( *aRtpMaptLine ); |
|
825 if ( codec ) |
|
826 { |
|
827 codec->InitializeL( aStream ); |
|
828 |
|
829 // check if ptime or maxptime attributes are present |
|
830 DecodeMediaAttributesL( aMediaLine, *codec, *aRtpMaptLine ); |
|
831 codec->iIsNegotiated = ETrue; |
|
832 MCEMM_DEBUG_SVALUE("adding codec", codec->iSdpName ) |
|
833 aStream.AddCodecL( codec ); |
|
834 CleanupStack::Pop( codec ); |
|
835 |
701 } |
836 } |
702 } |
837 } |
703 |
838 |
704 CleanupStack::PopAndDestroy( &payloadTypesInMediaLine ); |
839 CleanupStack::PopAndDestroy( &payloadTypesInMediaLine ); |
705 |
840 |
794 MCEMM_DEBUG_SVALUE( "encoded fmtp", fmtpLine->Value() ) |
929 MCEMM_DEBUG_SVALUE( "encoded fmtp", fmtpLine->Value() ) |
795 } |
930 } |
796 |
931 |
797 MCEMM_DEBUG("CMceMediaSdpCodec::EncodeFmtpAttributeL(), Exit ") |
932 MCEMM_DEBUG("CMceMediaSdpCodec::EncodeFmtpAttributeL(), Exit ") |
798 } |
933 } |
|
934 |
799 |
935 |
800 // ----------------------------------------------------------------------------- |
936 // ----------------------------------------------------------------------------- |
801 // CMceMediaSdpCodec::CreateFormatListL |
937 // CMceMediaSdpCodec::CreateFormatListL |
802 // Creates fmtlist that can be used as media field fmt list -attribute |
938 // Creates fmtlist that can be used as media field fmt list -attribute |
803 // (other items were commented in a header). |
939 // (other items were commented in a header). |
1477 remoteAttributes->AppendL( encodeBuf->Ptr( 0 ) ); |
1613 remoteAttributes->AppendL( encodeBuf->Ptr( 0 ) ); |
1478 |
1614 |
1479 CleanupStack::PopAndDestroy(); // writeStream |
1615 CleanupStack::PopAndDestroy(); // writeStream |
1480 CleanupStack::PopAndDestroy( encodeBuf ); // encodeBuf |
1616 CleanupStack::PopAndDestroy( encodeBuf ); // encodeBuf |
1481 } |
1617 } |
|
1618 |
|
1619 for ( TInt i = 0; i < aMediaLine.ConnectionFields().Count(); i++ ) |
|
1620 { |
|
1621 |
|
1622 encodeBuf = CBufFlat::NewL( KMceExternalizeBufferExpandSize ); |
|
1623 CleanupStack::PushL( encodeBuf ); |
|
1624 RBufWriteStream writeStream( *encodeBuf, 0 ); |
|
1625 writeStream.PushL(); |
|
1626 |
|
1627 aMediaLine.ConnectionFields()[ i ]->EncodeL( writeStream ); |
|
1628 MCEMM_DEBUG_SVALUE("found attribute", encodeBuf->Ptr( 0 ) ) |
|
1629 remoteAttributes->AppendL( encodeBuf->Ptr( 0 ) ); |
|
1630 |
|
1631 CleanupStack::PopAndDestroy(); // writeStream |
|
1632 CleanupStack::PopAndDestroy( encodeBuf ); // encodeBuf |
|
1633 } |
1482 |
1634 |
1483 if ( aStream.BoundStream() ) |
1635 if ( aStream.BoundStream() ) |
1484 { |
1636 { |
1485 MCEMM_DEBUG("copy attributes to bound stream" ) |
1637 MCEMM_DEBUG("copy attributes to bound stream" ) |
1486 // copy attributes to bound stream |
1638 // copy attributes to bound stream |