منتدى مدرسة الهاشمية الثانوية للبنين

عزيزي الزائر / عزيزتي الزائرة يرجي التكرم بتسجبل الدخول اذا كنت عضو معنا
او التسجيل ان لم تكن عضو وترغب في الانضمام الي اسرة المنتدي
سنتشرف بتسجيلك
شكرا
ادارة المنتدي

منتدى مدرسة الهاشمية الثانوية للبنين

منتدى المدارس الاردنية و العربية و العالمية
 
الرئيسيةمكتبة الصورس .و .جالتسجيلدخول

شاطر | 
 

 سلسلة دروس برمجة الـ Rtp In Voip & Video Conferencing, C# RTP VOIP Video In Multicasting Systems

استعرض الموضوع السابق استعرض الموضوع التالي اذهب الى الأسفل 
كاتب الموضوعرسالة
Abdulbasit
عبدالباسط غرايبة
عبدالباسط غرايبة
avatar

ذكر عدد الرسائل : 1668
الموقع : alhash-school.yolasite.com
العمر : 34
العمل/الترفيه : فني مختبرات
نقاط التميز مسابقات : 130
نقاط التميز : 13767
السٌّمعَة : 48
الاوسمة :
الاوسمة2 : وسام ادارة
احترام قوانين المنتدى :
100 / 100100 / 100

الدولة :
تاريخ التسجيل : 28/11/2008

مُساهمةموضوع: سلسلة دروس برمجة الـ Rtp In Voip & Video Conferencing, C# RTP VOIP Video In Multicasting Systems   الجمعة مايو 08, 2009 8:58 pm

بسم الله الرحمن الرحيم

سوف ابدأ مستعينا بالله بكتابة سلسلة دروس تتعلق بالـRTP Protocol ومناقشة مشكلات ووضع حلول عملية لنقل الصوت والصورة ذات الجودة العالية عبر شبكات الـMulticasting والـInternet2 وسوف تحتوي هذه السلسلة على المواضيع التالية:

1- مقدمة في المشكلات والحلول في عملية نقل الصوت والصورة ذات الجودة العالية عبر شبكات الـMulticasting والـInternet2 مبيننا فيها اهم تلك الأسباب والتحديات التي تواجه مبرمجي تلك الأنظمة.
2- التعامل مع بروتوكول النقل في الزمن الحقيقي RTP وشرح مكوناته واجزائه وبرمجته تحت منصة الدوت نيت
3- التعامل مع الـDirect Sound والـRTP لعلية نقل الصوت كذلك حل بعض المشاكل المتعلقة بالـ Jitter
4- التعامل مع الـMicrosoft Direct Show والـRTP لعملية نقل الصورة وحل بعض المشاكل المتعلقة بالمزامنة بين الصوت والصورة
5- امن وتشفير الـVOIP وحل مشكلات الـQoS لعملية نقل الصوت بشكل امن.

الدرس الأول: مقدمة في المشكلات والحلول في عملية نقل الصوت والصورة ذات الجودة العالية عبر شبكات الـMulticasting والـInternet2 مبيننا فيها اهم تلك الأسباب والتحديات التي تواجه مبرمجي تلك الأنظمة

سأقدم في هذا الدرس تحليل لأهم التحديات التي تواجه مبرمجي أنظمة المؤتمرات وذلك من خلال دراسة العوامل المؤثرة على جودة نقل الصوت والصورة عبر شبكة الإنترنت وكيفية التغلب على هذه المشكلات باستخدام بروتوكول النقل في الزمن الحقيقي RTP Real Time Protocol وشرح كيفية التعامل معه برمجيا.

يعتبر استخدام برمجيات الدردشة Chatting وأيضا الـConferencing من أكثر الأمور التي تستخدم بشكل يومي ومع دخول هذه المجالات في أنظمة التعلم الإلكتروني تتزايد الحاجة لنقل كميات اكبر من البيانات بزمن الحقيقي Real Time Transportation لعدد اكبر من المتصلين و يعتبر عامل الزمن Timestamp من أهم التحديات والتي تواجه مبرمجي هذه الأنظمة ويظهر هذا التحدي جليا عند التعامل مع شبكة الإنترنت لنقل صوت المحاضر إلى عدد كبير من المتصلين فتأخر وصول جزء من البيانات يعني تقطع في الصوت ووصول جزء قبل الأخر يعني خروج صوت غير مفهوم ومشاكل أخرى قد تحدث في المزامنة بين الصوت والصورة وهذا الأمر غير مقبول في أنظمة الـConferencing التي تعتمد على الزمن الحقيقي والجودة العالية المفترضة منها.

ويمكننا أن نلخص هذه التحديات بثلاثة عوامل رئيسية:

أولا حجم البيانات المرسلة وعلاقته بحجم الـBuffer عند المرسل بناء على سرعة الشبكة:
يعرف الـBuffer من طرف المرسل بأنه المساحة التخزينية التي يتم حجزها بذاكرة وبمقدار محدد لتخزين البيانات بشكل مؤقت قبل إرسالها و من الطبيعي في برمجيات الـConferencing أنه كلما زادت جودة وسرعة الشبكة قلت حاجتنا للـBuffer من طرف المرسل إذ يزيد حجم الـBuffer نسبة التأخر في عملية نقل الصوت ولكنه يضمن وصول أكثر أمانا للبيانات فبزيادة حجم الـBuffer يكون هنالك أمل أكبر لإعادة إرسال البيانات التي يتم فقدانها إثناء النقل. والتحكم في حجم الـBuffer يعتمد أيضا على طبيعة البرنامج وكمثال فإن برمجيات البث الإذاعي أقل حاجة لزمن الحقيقي من البرمجيات التي يتم فيها التفاعل بين الأطراف وبذلك يمكن أن نزيد فيها حجم الـBuffer لتخزين مدة محددة من العرض قبل عملية الإرسال ومن الأمثلة على ذلك برنامج Microsoft Media Encoder وهو برنامج يأتي مع المجموعة Microsoft Expression Studio والذي من ضمن خواصه التعامل مع والـWindows Media Server لعملية بث الصوت والصورة سواء بشكل مباشر Live أو من ملف MM مسجل.

************************
الرجوع الى أعلى الصفحة اذهب الى الأسفل
http://alhash-school.yoo7.com
Abdulbasit
عبدالباسط غرايبة
عبدالباسط غرايبة
avatar

ذكر عدد الرسائل : 1668
الموقع : alhash-school.yolasite.com
العمر : 34
العمل/الترفيه : فني مختبرات
نقاط التميز مسابقات : 130
نقاط التميز : 13767
السٌّمعَة : 48
الاوسمة :
الاوسمة2 : وسام ادارة
احترام قوانين المنتدى :
100 / 100100 / 100

الدولة :
تاريخ التسجيل : 28/11/2008

مُساهمةموضوع: رد: سلسلة دروس برمجة الـ Rtp In Voip & Video Conferencing, C# RTP VOIP Video In Multicasting Systems   الجمعة مايو 08, 2009 9:01 pm

ثانيا Voice Jitter Loss & Delay:
يعتبر هذا التحدي من واحد من أكبر التحديات التي تواجه مبرمجي أنظمة المؤتمرات وذلك لسبب هام ومعروف وهو أنه كلما زاد حجم البيانات المحملة على الـRTP Packet زاد الاحتياج إلى قناة نقل ذات جودة أعلى والسبب اختلاف حجم الـFrame الأقصى Max Size of frame والتي تستطيع قناة النقل أن تحمله وكمثال فإن الحجم الأقصى للـFrame في شبكة الـEthernet هو 1500 Bytes وهذا يعني أنه في حالة نقل البيانات على شبكات أبطأ عندها يجب تقليل حجم الـFrame وكلما قل حجم الـFrame زاد عدد تلك الـFrames وبالتالي فرصة اكبر لضياع Frames إثناء النقل كما سيحتاج المستقبل فترة أطول و Buffer أكبر لإعادة ترتيب تلك الـFrames إذ يتراوح حجم الـHeader الخاص بالـIPv4 من 20 إلى 60 Bytes بناءا على الـOptions المستخدم فإذا لم يتم استخدام الـOptions عندها سيكون حجم الـHeader ثابت وهو 20 Bytes ويحتاج الـUDP Header إلى 8Bytes و الـRTP Header إلى 12 Bytes وفي هذه الحالة فإن صافي حجم الـRTP Frame الواحد بدون البيانات هو 40 Bytes.

كود
Empty RTP Frame Size = 20 Bytes for IPv4 Header+ 8 Bytes for UDP Header + 12 Bytes For RTP Header = 40Bytes.


وكمثال إذا كنت تريد نقل 1024 K Bytes من البيانات على شبكة الـEthernet فإنك ستحتاج إلى تقسيم البيانات على الحجم ألأعظمي لقناة النقل هذه وهو 1500 Bytes ولحساب ذلك:

كود
1500 Bytes – 40 Bytes for each frame = 1460 Bytes
1024 KB to Bytes = 1024^2
(1024^2) / 1460 = 718 Frames



وبذلك نحتاج إلى تقسيم تلك البيانات إلى 718 Frames مما يعني زيادة حجم البيانات بمقدار 28720 Bytes وهي ناتج ضرب حجم الـFrame الواحد بعدد الـFrames أي 718 * 40 وتعتبر هذه الزيادة حجم زائد يتحملها في النهاية المستقبل وبالتالي زيادة في Delay لإجراء عمليات الترتيب والمعالجة لتلك البيانات قبل عرضها.


ثالثا وصول البيانات بشكل غير مرتب Out-Of- Sequence وكيفية التغلب على هذه المشكلة:
تحدثت في كتاب (احترف برمجة الشبكات الجزء الأول) عن عملية نقل البيانات من خلال بروتوكولات النقل المعروفة وهي الـ TCP والـ UDP وقد بينا عيوب كل منها في عملية النقل فمن المعروف أن الـTCP بروتوكول جيد لنقل البيانات الكبيرة الحجم والتي لا يعتبر فيها عامل الزمن الحقيقي لنقل أمر مهم ومن عيوبه أنه لا يدعم عمليات الـMulticasting والـBroadcasting لكن من أهم خواصه التأكد من نقل البيانات بالشكل الصحيح وبالترتيب السليم وبهذا فإن بروتوكول الـUDP سريع في عملية النقل للبيانات التي لا يزيد حجمها عن الحجم الأقصى للـFrame والتي تستطيع قناة النقل تحمله وبالتالي فإن نقل البيانات التي يزيد حجمها عن الحجم الأقصى للـFrame لا يمكن نقلها باستخدام الـUDP إلا إذا تم تقسيمها على مجموعة من الـFrames ومن المعروف أن الـUDP لا يدعم عملية ترتيب الـFrames وبالتالي فإن وصول Frame قبل الآخر قد يسبب فشل عملية النقل بأكملها ومن هنا دعم بروتوكول الـUDP ببروتوكول الـRTP لكي يتمكن المستقبل من إعادة ترتيب الـFrames بعد نقلها كما ويدعم الـRTP عملية محاولة لتصليح الـFrames التي قد تصل مشوهة وذلك من خلال FEC – Frame Error Correction وبالتالي محاولة الإصلاح بدلا من إعادة طلب الإرسال.

************************
الرجوع الى أعلى الصفحة اذهب الى الأسفل
http://alhash-school.yoo7.com
Abdulbasit
عبدالباسط غرايبة
عبدالباسط غرايبة
avatar

ذكر عدد الرسائل : 1668
الموقع : alhash-school.yolasite.com
العمر : 34
العمل/الترفيه : فني مختبرات
نقاط التميز مسابقات : 130
نقاط التميز : 13767
السٌّمعَة : 48
الاوسمة :
الاوسمة2 : وسام ادارة
احترام قوانين المنتدى :
100 / 100100 / 100

الدولة :
تاريخ التسجيل : 28/11/2008

مُساهمةموضوع: رد: سلسلة دروس برمجة الـ Rtp In Voip & Video Conferencing, C# RTP VOIP Video In Multicasting Systems   الجمعة مايو 08, 2009 9:02 pm

الدرس الثاني: التعامل مع بروتوكول النقل في الزمن الحقيقي RTP وشرح مكوناته واجزائه وبرمجته تحت منصة الدوت نيت

مكونات الـRTP Real-Time Transport Protocol Header:

يتكون الـRTP Header من 12 Bytes أساسية Fixed مقسمة كما هو واضح في الشكل التالي:



1-Version: ويتكون من 2 bits ويوضع فيه الإصدار الـRTP المستخدم وحاليا نحن نعمل على الإصدار الثاني.

2-Padding: ويتكون من 1 bit وهو Flag يبين إذا كنا سنضيف معلومات إضافية على الـRTP Header وكمثال يمكن أن يستخدم هذا الـ Padding في حالة كنا نريد إرسال الـRTP Payload بشكل مشفر وبهذه الحالة يضاف الـPadding والذي سيحتوي على معلومات حول موقع الـPayload المشفر في أسفل الـRTP Header.

3-Extension: ويتكون من 1 bit وهو Flag يبين إذا كان الـRTP Header يحتوي على Extensions في نهاية الـRTP Header أم لا والتي قد تحتوي على معلومات خاصة بالـApplication الذي يستخدم الـRTP لنقل البيانات.

4-CSRC Count : ويتكون من 4 bits وفيه يبين عدد الـ Content Source Identifiers الملحقة مع الـRTP Header ويستخدم هذا الـField في حالة كنا نريد دمج أكثر من RTP Stream في RTP Stream واحد فمن المعروف أنه لا يمكن تحميل أكثر من Payload Type واحد على الـRTP Stream وبالتالي في حالة كنا نريد إرسال الصوت والصورة فلا بد من استخدام اثنين من الـRTP Stream وبالتالي قد تظهر مشاكل لاحقة في عملية المزامنة بين الصوت والصورة ولحل هذه المشكلة يمكن دمج الـRTP Stream الخاص بالصوت والـRTP Stream الخاص بالصورة بـ RTP Stream واحد وتميزها بإعطاء Identifier خاص لكل منها ويتكون الـ IdentifierللـCSRC من 32 bits وقد يصل عدد الـCSRC التي يمكن تحميلها على الـRTP Header إلى 16 بحجم أعظمي 32X16 = 480 bits.

5-Marker: ويتكون من 1 bit وهو Flag يبين بداية ونهاية الإرسال لكل مجموعة من البيانات وكمثال في حالة نقل صورة Image Frame على أكثر من RTP Packet فإن ذلك الـMarker سيحتوي على قيمة 1 في أول Frame يتم إرساله لمعرفة بداية ونهاية الإرسال لتلك الصورة.

6-Payload Type: ويتكون من 7 bits توضح فيها نوع البيانات التي سيتم تحميلها على الـRTP Packet وكما أوضحنا سابقا لا يمكن أن يتم تحميل أكثر من نوع من البيانات على نفس الـRTP Stream ويبين الجدول التالي أنواع الـRTP Payload التي يمكن تحميلها على الـRTP Stream:


************************
الرجوع الى أعلى الصفحة اذهب الى الأسفل
http://alhash-school.yoo7.com
Abdulbasit
عبدالباسط غرايبة
عبدالباسط غرايبة
avatar

ذكر عدد الرسائل : 1668
الموقع : alhash-school.yolasite.com
العمر : 34
العمل/الترفيه : فني مختبرات
نقاط التميز مسابقات : 130
نقاط التميز : 13767
السٌّمعَة : 48
الاوسمة :
الاوسمة2 : وسام ادارة
احترام قوانين المنتدى :
100 / 100100 / 100

الدولة :
تاريخ التسجيل : 28/11/2008

مُساهمةموضوع: رد: سلسلة دروس برمجة الـ Rtp In Voip & Video Conferencing, C# RTP VOIP Video In Multicasting Systems   الجمعة مايو 08, 2009 9:04 pm

7-Sequence Number: ويتكون من 16 bits ويحتوي على الرقم المتسلسل والذي يولد في البداية بشكل عشوائي ويزيد بمقدار واحد لكل RTP Packet يتم إرساله ويستفاد من هذا الرقم لمعرفة موقع الـRTP Packet عند استلامه لإجراء عملية الترتيب كذلك يستفاد منه في اكتشاف فقدان إي من الـRTP Packets المرسلة.

8-Timestamp: ويتكون من 32 bits ويحتوي على الوقت الزمني الذي تم فيه تحميل البيانات على الـRTP Packet ويستفاد من هذه البيانات بشكل كبير لتغلب على مشكلات الـJitter والمزامنة بين عملية الإرسال والاستقبال والزمن المستغرق بينهما.

9-SSRC Identifier Synchronization Source : ويتكون من 32 bits ويحتوي على رقم متسلسل يولد عشوائيا لتميز كل RTP Stream عن غيره بحيث لا يتشابه RTP Stream مع الآخر على نفس الـSession مما قد يؤدي إلى ما يسمى بالـRTP Stream Conflict.

استخدام الـ RTP In .NET:
لا يدعم الـ.NET Framework 3.5 أية Classes للـRTP Protocol لكن قدمت Microsoft مجموعة من الـThird Party Kits ضمن مشروعها المفتوح المصدر Microsoft Conference XP والذي يحتوي على نواة الـRTP Protocol بشكل كامل وقد تم تقسيمه إلى مجموعة من الـClasses بناء على كيفية عمل الـRTP وكما في الشكل التالي:



أولا الـRTPSession والـ RtpParticipant : يستخدم الـRTP Session بشكل أساسي في عملية إدارة جلسة الاتصال والتي يمكن أن يتم فيها إرسال مجموعة من الـRTP Stream كما ويمكن أن يتصل بالـSession الواحدة مجموعة من المشتركين Participants كذلك يمكن للمشترك الواحد أن يتصل بأكثر من RTP Session وتميز كل RTP Session بالعنوان ورقم الـPort الذي يتم الإرسال له كذلك يتم إضافة CNAME لتميز محتويات كل RTP Session عن الأخرى وكمثال في الدوت نيت:

كود
RtpSession rtpSession = new RtpSession(endpoint, new RtpParticipant("My Audio Session", ParticipatorName), true, true);


إذ يمرر الـEndpoint Object والذي يحتوي على عنوان Multicast IP بالإضافة إلى Port الاستقبال وينضم المرسل أو المستقبل إلى الـRTP Session بتمرير الـ RtpParticipant Object إلى الـRTP Session ولتعريفه يجب أن يتم تمرير الـCNAME واسم المتصل إليه بعد ذلك نكمل تعريف الـRTP Session بتمرير قيم True أو False ويحدد في الأول أنك تريد الانضمام إلى الـRTP Session فقط ويحدد الثاني إذا كنت تنوي الإرسال باستخدام تلك Session.

ثانيا الـRtpEvents: وهو مجموعة الأحداث التي تحدث داخل الـRTP Session والتي يمكن أن يوضع Action معين عند حدوث أي منها وتقسم هذه الأحداث إلى ثلاثة أقسام وهي:

أولا أحداث ترتبط باكتشاف أخطاء أو مشاكل إثناء الإرسال أو الاستقبال ويمكن أن نسميها Exceptions Events وهي:

كود
1-DuplicateCNameDetected
2-FrameOutOfSequence
3-HiddenSocketException
4-InvalidPacket
5-InvalidPacketInFrame
6-NetworkTimeout
7-PacketOutOfSequence
8-RtpParticipantTimeout
9-RtpStreamTimeout

************************
الرجوع الى أعلى الصفحة اذهب الى الأسفل
http://alhash-school.yoo7.com
Abdulbasit
عبدالباسط غرايبة
عبدالباسط غرايبة
avatar

ذكر عدد الرسائل : 1668
الموقع : alhash-school.yolasite.com
العمر : 34
العمل/الترفيه : فني مختبرات
نقاط التميز مسابقات : 130
نقاط التميز : 13767
السٌّمعَة : 48
الاوسمة :
الاوسمة2 : وسام ادارة
احترام قوانين المنتدى :
100 / 100100 / 100

الدولة :
تاريخ التسجيل : 28/11/2008

مُساهمةموضوع: رد: سلسلة دروس برمجة الـ Rtp In Voip & Video Conferencing, C# RTP VOIP Video In Multicasting Systems   الجمعة مايو 08, 2009 9:06 pm

ثانيا حدث وحيد لجلب معلومات Report عن حالة الـRTP Received Data وهو ReceiverReport.
ثالثا أحداث تتعلق بالانضمام إلى Session وإضافة وحذف Session RTP Participant & Stream Add/Remove Events وهي:

كود
1-RtpParticipantAdded
2-RtpParticipantDataChanged
3-RtpParticipantRemoved
4-RtpStreamRemoved
5-RtpStreamAdded



وأكثر ما يهمنا في هذه الأحداث هو ضبط متى يتم الانضمام إلى RTP Session لبدأ عملية الاستقبال وكذلك متى يتم الخروج من الـRTP Session لإيقاف الاستقبال ولتعامل مع هذه الأحداث يجب أولا أن نقوم بعمل Hook لها وربط الحدث بالدالة التي سيتم تنفيذها عند حدوث ذلك الحدث وكما يلي كمثال:

كود
private void HookRtpParticipantEvents()
{
// Add Remove Participant Events
RtpEvents.RtpParticipantAdded += new RtpEvents.RtpParticipantAddedEventHandler(RtpParticipantAdded);
RtpEvents.RtpParticipantRemoved += new RtpEvents.RtpParticipantRemovedEventHandler(RtpParticipantRemoved);
}

private void HookRtpStreamEvents()
{
// Add Remove Stream Events
RtpEvents.RtpStreamAdded += new RtpEvents.RtpStreamAddedEventHandler(RtpStreamAdded);
RtpEvents.RtpStreamRemoved += new RtpEvents.RtpStreamRemovedEventHandler(RtpStreamRemoved);
}
private void RtpParticipantAdded(object sender, RtpEvents.RtpParticipantEventArgs ea)
{
ShowMessage(ea.RtpParticipant.Name + " has joined");
}

private void RtpParticipantRemoved(object sender, RtpEvents.RtpParticipantEventArgs ea)
{
ShowMessage(ea.RtpParticipant.Name + " has left");
}

private void RtpStreamAdded(object sender, RtpEvents.RtpStreamEventArgs ea)
{
ea.RtpStream.FrameReceived += new RtpStream.FrameReceivedEventHandler(FrameReceived);
}

private void RtpStreamRemoved(object sender, RtpEvents.RtpStreamEventArgs ea)
{
ea.RtpStream.FrameReceived -= new RtpStream.FrameReceivedEventHandler(FrameReceived);
}



وينطبق ذلك الشكل في التعامل مع كافة أحداث الـRTP Events السابقة الذكر.

ثالثا الـRtpSender والـ : RtpListener يمكن الإرسال مباشرة بعد تعريف الـRTP Session ولتعريف الـRtpSender يجب أن يمرر له الـRTP Session الذي قمنا بتعريفه سابقا ويضاف إليها أيضا الـPayload Type الذي سيتم إرساله على الـRTP Session ولتمييز الـRTP Sender في الـSession عن غيره يمكن أن يتم تعريف Hash Table لذلك اختياريا أو قيمة null وتمريره لدالة CreateRtpSender وكما يلي كمثال:

كود
RtpSender rtpsender = rtpSession.CreateRtpSender("My VOIP Sender", PayloadType.dynamicAudio, null);


أو يمكن تعريفه بالشكل التالي بحيث تدعم عملية FEC – Frame Error Correction للـRTP Packet وذلك لدعم إمكانية تصحيح الـPacket عند وصوله مع وجود أخطاء بدلا من طلب إعادة الإرسال له ويصبح الشكل العام لدالة كما يلي كمثال:

كود
RtpSender rtpsender = rtpSession.CreateRtpSenderFec("My VOIP Sender With FEC", PayloadType.dynamicAudio, null, CDataPX, CFecPX);
rtpSender.Send(buffer);



وأما بخصوص الاستقبال بالـ RtpListener فتعمل هذه الدالة ضمن الـRTP Session وذلك بربط تلك الدالة بحدث الانضمام إلى الجلسة وفي هذه الحالة بمجرد انضمامك إلى الجلسة يتم تنفيذ الحدث وبدأ الاستقبال ولتنفيذ ذلك يجب أولا عمل Hook للـRTP Events التي قمنا بتعريفها سابقا وعند بدأ إرسال بيانات ما من قبل أي طرف من الأطراف يتم تنفيذ الحدث وبدأ الاستقبال ويمكنك الوصول إلى محتويات البيانات المستقبلة من خلال الخاصية Frame.Buffer والمستلمة من الـ FrameReceivedEventArgs :

كود
private void FrameReceived(object sender, RtpStream.FrameReceivedEventArgs ea)
{
Byte[] Buufer = ea.Frame.Buffer;
}



رابعا الـRTCP وهو مختصر لـReal-Time Transport Control Protocol: ومن أهم استخداماته أنه يعمل مع الـRTP لإدارة التحكم في العمليات التي تتم في أنظمة المؤتمرات وكذلك تقديم تقارير عن حالة تلك العمليات وتقسم إلى:
1-تقارير الإرسال SR وتقارير الاستقبال RR
2-تفاصيل مرسل البيانات Source description SDES
3-إدارة الانضمام والخروج ل\ومن مجموعة Add Remove Membership.
4-تعريف application-defined APP جديد على الـRTP Session.

ويمكن أن نستفيد من كل ذلك من خلال الـRTCP Namespace وكمثال يمكن استخدام الـ RtcpListener Class لتعامل مع البيانات التي يتم استقبالها من خلال الـRTP Session و إدارة عمليات الـMembership والتي ذكرناها سابقا وأيضا تقديم معلومات عن حالة شبكة الاتصال والتي تربط المرسل بالمستقبل, وسأقدم بدروس لاحقة معلومات أكبر عن استخدامات الـRTCP Protocol في إدارة أنظمة الـConferencing.



************************
الرجوع الى أعلى الصفحة اذهب الى الأسفل
http://alhash-school.yoo7.com
Abdulbasit
عبدالباسط غرايبة
عبدالباسط غرايبة
avatar

ذكر عدد الرسائل : 1668
الموقع : alhash-school.yolasite.com
العمر : 34
العمل/الترفيه : فني مختبرات
نقاط التميز مسابقات : 130
نقاط التميز : 13767
السٌّمعَة : 48
الاوسمة :
الاوسمة2 : وسام ادارة
احترام قوانين المنتدى :
100 / 100100 / 100

الدولة :
تاريخ التسجيل : 28/11/2008

مُساهمةموضوع: رد: سلسلة دروس برمجة الـ Rtp In Voip & Video Conferencing, C# RTP VOIP Video In Multicasting Systems   الجمعة مايو 08, 2009 9:08 pm

الدرس الثالث: التعامل مع الـDirect Sound والـRTP لعلية نقل الصوت كذلك حل بعض المشاكل المتعلقة بالـ Jitter في أنظمة الـMulticast VOIP Conferencing:

تحدت في الدرس السابق عن مكونات الـRTP وكيفية استخدامه في بيئة الدوت نيت وفي هذا الدرس سنقوم بتطبيق برمجة نظام بسيط لبث الصوت من نقطة إلى مجموعة One-To-Many وسنقوم أيضا بالتحكم بخواص الـBuffer بهدف المزامنة بين عملية التسجيل والإرسال والعرض والتحكم به لتقليل الـDelay والـLoss في عملية الإرسال بناءا على سرعة الشبكة.

أولا: استخدام الـDirectSound في التعامل مع الصوت :
لتعامل مع الـDirectSound لابد أولا من إضافة الـ Microsoft.DirectX والـ Microsoft.DirectX.DirectSound Namespaces إلى الـReferences في المشروع ويحتوي الـDirectSound على عدد من الـClasses والتي تستخدم في برمجة كل ما يتعلق بالصوت تقريبا مثل التسجيل والـEncoding والعرض والكثير من الأمور وما يهمنا في هذا المشروع هو استخدام الـClasses التالية:

WaveFormat: ويستخدم لتحديد تفاصيل الـWave Format مثل عدد الـ Channels مثلا 1 أو 2 و ونوع الـ Modulation المستخدم مثل الـPCM-Pulse Code Modulation وعدد الـ SamplesPerSecond وعدد الـ BitsPerSample لأستخدم هذه المعلومات في عملية تحويل الذبذبات الصوتية إلى Bits لتمكين نقلها عبر الشبكة.

CaptureBufferDescription: ويستخدم لتحديد حجم الـBytes Buffer والذي سيتم حجزه في الذاكرة لاستقبال WAVE Bits الملتقطة.

CaptureDevicesCollection: وهو Array Of Devices ويستخدم لإرجاع كافة الـHardware Devices Info المتعلقة بوحدات الإدخال\الإخراج الصوتية المتاحة لديك لتحديد واحد منها في عملية التقاط الصوت من المايكروفون وعرض الصوت على السماعات.

DeviceInformation: ويستخدم لتحديد واحد من الـDevices التي سيتم إرجاعها من CaptureDevicesCollection حيث سيرجع الـGUID Globally Unique Identifier الخاص بالـSound Driver لديك.

Capture: ويعرف به الـDriver GUID الذي يتم جلبه من DeviceInformation لاستخدامه في الـ CaptureBuffer لالتقاط الصوت وتخزينه في الـBuffer.

CaptureBuffer: وهو الـClass المسئول عن عملية التقاط الصوت ووضعه في الـBuffer إذ يمرر له الـ CaptureBufferDescription Object والـ Capture Object لبدأ عملية التقاط الصوت ضمن المعلومات الممررة له وتخزينه في الـ Buffer المحدد.

BufferPositionNotify: وهو Handler Notification Class يستخدم لتنفيذ Event محدد عند وصول الـBuffer إلى منطقة معينة.

Notify: ويحدد فيه عدد الـBytes التي إن وصل لها معبئ الـBuffer فسيتم عمل Trigger للـEvent الذي سيقوم بعملية معينة كتفريغ الـBuffer من جديد.

Device: وسيستخدم في طرف المستمع وفيه يتم تحديد الـSound Card الذي سيتم عرض الصوت عليه ويربط فيه جزأين أولا الـApplication الذي سيتم التعامل معه في عملية معالجة وعرض الصوت والثاني الـ CooperativeLevel Priority.

BufferDescription: وسيستخدم في طرف المستمع إذ يحتوي على مجموعة من الـ Properties والـ Methods لتحديد وإرجاع معلومات عن الـBuffer الذي سيستخدم في تجميع الـBytes الواردة من مصدر ما.

SecondaryBuffer: وسيستخدم في طرف المستمع ويمرر له الـ BufferDescriptionوالـDevice Object لبدأ عملية تجميع الـBuffer ومن ثم إمكانية عرضه على الـSound Device المحدد.

ثانيا: مراحل بناء نظام لنقل الصوت إلى مجموعة من المتصلين باستخدام الـDirectSound والـRTP:
بعدما قمنا بشرح موجز عن استخدام كل Class من الـClasses التي سيتم التعامل معها في الـDirect Sound سنتحدث في هذه الجزء عن كيفية استخدمها برمجيا بشكل مجموعة من المراحل المترابطة (سأقوم بإضافة تعليق باللغة الإنجليزية على كل سطر من اسطر المثال لتسهيل تتبع الكود):

1-التعامل مع الـSound Card لعملية تسجيل الصوت من المايكروفون والتعامل مع الـ WAVE Format:

المرحلة الأولى تعريف الـClasses الخاصة بالـDirect Sound وكما تم شرحها في الأعلى:

كود
private CaptureBufferDescription captureBufferDescription;
private AutoResetEvent autoResetEvent;
private Notify notify;
private WaveFormat waveFormat;
private Capture capture;
private CaptureBuffer captureBuffer;
private Device device;
private SecondaryBuffer playbackBuffer;
private BufferDescription playbackBufferDescription;




المرحلة الثانية سنقوم بإنشاء دالة لتعريف الـSound Card الذي سيستخدم في عملية تسجيل الصوت وكذلك هي نفسها عند المستقبل:
كود
public void SetVoiceDevices(System.Windows.Forms.Control AppForm_TypeThis)
{
// Use The Recommended settings For Sound Devices
SetVoiceDevices(
0, // Device Number (First Device)
1, // Channels (2 if Stereo)
AppForm_TypeThis, // Application Form Pointer
16, // BitsPerSample
22050); // SamplesPerSecond
}
public void SetVoiceDevices(int deviceID, short channels, System.Windows.Forms.Control AppForm_TypeThis, short bitsPerSample, int samplesPerSecond)
{
// Installization Voice Devices
device = new Device(); // Sound Input Device
device.SetCooperativeLevel(AppForm_TypeThis, CooperativeLevel.Normal); // Set The Application Form and Priority
CaptureDevicesCollection captureDeviceCollection = new CaptureDevicesCollection(); // To Get Available Devices (Input Sound Card)
DeviceInformation deviceInfo = captureDeviceCollection[deviceID]; // Set Device Number
capture = new Capture(deviceInfo.DriverGuid); // Get The Selected Device Driver Information

//Set up the wave format to be captured.
waveFormat = new WaveFormat(); // Wave Format declaration
waveFormat.Channels = channels; // Channels (2 if Stereo)
waveFormat.FormatTag = WaveFormatTag.Pcm; // PCM - Pulse Code Modulation
waveFormat.SamplesPerSecond = samplesPerSecond; // The Number of Samples Peer One Second
waveFormat.BitsPerSample = bitsPerSample; // The Number of bits for each sample
waveFormat.BlockAlign = (short)(channels * (bitsPerSample / (short)Cool); // Minimum atomic unit of data in one byte, Ex: 1 * (16/Cool = 2 bits
waveFormat.AverageBytesPerSecond = waveFormat.BlockAlign * samplesPerSecond; // required Bytes-Peer-Second Ex. 22050*2= 44100
captureBufferDescription = new CaptureBufferDescription();
captureBufferDescription.BufferBytes = waveFormat.AverageBytesPerSecond / 5; //Ex. 200 milliseconds of PCM data = 8820 Bytes (In Record)
captureBufferDescription.Format = waveFormat; // Using Wave Format

// Playback
playbackBufferDescription = new BufferDescription();
playbackBufferDescription.BufferBytes = waveFormat.AverageBytesPerSecond / 5; //Ex. 200 milliseconds of PCM data = 8820 Bytes (In Playback)
playbackBufferDescription.Format = waveFormat;
playbackBuffer = new SecondaryBuffer(playbackBufferDescription, device);
bufferSize = captureBufferDescription.BufferBytes;
}

************************
الرجوع الى أعلى الصفحة اذهب الى الأسفل
http://alhash-school.yoo7.com
Abdulbasit
عبدالباسط غرايبة
عبدالباسط غرايبة
avatar

ذكر عدد الرسائل : 1668
الموقع : alhash-school.yolasite.com
العمر : 34
العمل/الترفيه : فني مختبرات
نقاط التميز مسابقات : 130
نقاط التميز : 13767
السٌّمعَة : 48
الاوسمة :
الاوسمة2 : وسام ادارة
احترام قوانين المنتدى :
100 / 100100 / 100

الدولة :
تاريخ التسجيل : 28/11/2008

مُساهمةموضوع: رد: سلسلة دروس برمجة الـ Rtp In Voip & Video Conferencing, C# RTP VOIP Video In Multicasting Systems   الجمعة مايو 08, 2009 9:10 pm

المرحلة الثالثة إنشاء الدالة الخاصة بالتقاط الصوت لتجهيز الضغط والإرسال:

كود
private void StartRecordAndSend() // Send Recorded Voice
{
try
{
captureBuffer = new CaptureBuffer(captureBufferDescription, capture); // Set Buffer Size,Voice Recording Format & Input Voice Device
SetBufferEvents(); // Set the events Positions to Send While Recording
int halfBuffer = bufferSize / 2; // Take the half buffer size
captureBuffer.Start(true); // start capturing
bool readFirstBufferPart = true; // to know which part has been filled (the buufer has been divided into tow parts)
int offset = 0; // at point 0
MemoryStream memStream = new MemoryStream(halfBuffer); // set the half buffer size to the memory stream
bStop = false;

while (True)
{

//WaitOne() Blocks the current thread until the current WaitHandle receives a signal
//WaitHandle("Encapsulates operating system–specific objects that wait for exclusive access to shared resources")
autoResetEvent.WaitOne();

memStream.Seek(0, SeekOrigin.Begin); //Sets the position within the current stream to 0
captureBuffer.Read(offset, memStream, halfBuffer, LockFlag.None); // capturing and set to MemoryStream
readFirstBufferPart = !readFirstBufferPart; // reflecting the boolean value to set the new comming buffer to the other part
offset = readFirstBufferPart ? 0 : halfBuffer; // if readFirstBufferPart set to true then set the offset to 0 else set the offset to the half buffer

byte[] dataToWrite = memStream.GetBuffer;

// Here you can Compress the voice buffer
.
.

// Sending the compressed voice across Network
.
.

}
}
catch (Exception) { }
finally
{captureBuffer.Stop();}
}



2-إدارة الـBuffering وذلك بتجزيء الـBuffer إلى جزأين الأول يستخدم في عملية تخزين الصوت المسجل والثاني لتجهيزه لعملية المعالجة كإرساله أو ضغطه:

كود
protected void SetBufferEvents()
{
// Goal: To Send While Recording
// To Set The Buffer Size to get 200 milliseconds and divide it in half,
// so that when the first half is filled the data can be used to send,
// while the second half of the buffer is being filled with PCM Data

try
{
autoResetEvent = new AutoResetEvent(false); // To wait for notifications
notify = new Notify(captureBuffer); // The number of bytes that can trigger the notification event

// the first half
BufferPositionNotify bufferPositionNotify1 = new BufferPositionNotify(); // to describe the notification position
bufferPositionNotify1.Offset = bufferSize / 2 - 1; // (= At the Half of The Buffer) to know where the notify event will trigger
bufferPositionNotify1.EventNotifyHandle = autoResetEvent.SafeWaitHandle.DangerousGetHandle(); // Set The Event that will trigger after the offset reached

// the last half
BufferPositionNotify bufferPositionNotify2 = new BufferPositionNotify();
bufferPositionNotify2.Offset = bufferSize - 1; // (= At The Last Buffer)
bufferPositionNotify2.EventNotifyHandle = autoResetEvent.SafeWaitHandle.DangerousGetHandle();

notify.SetNotificationPositions(new BufferPositionNotify[] { bufferPositionNotify1, bufferPositionNotify2 }); // The Tow Positions (First & Last)
}
catch (Exception) { }
}




3-ضغط الـBuffer المستلم باستخدام معايير الضغط المتاحة: في هذه المرحلة فالخيار متاح لك في اختيار طريقة الضغط المناسبة ويمكنك أيضا في هذه المرحلة القيام بعملية Coding معينة على الـBuffer مثلا تشفيره ثم ضغطه لكن وجب في البداية دراسة أنواع الضغط والتشفير المناسبة لصوت بهدف المحافظة على الـQoS Quality Of Server والتي سيتم التطرق لها في دروس لاحقة من هذه السلسلة.

4-تغليف الـBuffering في RTP Packet وإرساله عبر الشبكة إلى Multicast RTP Session:
قمت سابقا بشرح كيفية استخدام الـRTP Protocol لعملية الانضمام إلى مجموعة وكذلك كيفية تغليف الـByte Data بالـRTP Packet لمزيد من المعلومات أنظر الدرس الثاني.

5-في الطرف المقابل (المستقبل) سيقوم بالانضمام إلى RTP Session ثم بدأ عملية الـListening على الـSession لاستقبال كما تم شرح هذه العملية في الدرس الثاني إذ أنه بعد الانضمام إلى RTP Session سيتم تنفيذ الـRTP Session Event والذي بدوره سيمكنك من استقبال البيانات الواردة من المرسل وبعد ذلك يمكننا تجميع الـBuffer ثم عرضه.

كود
private void RtpStreamAdded(object sender, RtpEvents.RtpStreamEventArgs ea)
{
ea.RtpStream.FrameReceived += new RtpStream.FrameReceivedEventHandler(FrameReceived);
}
private void FrameReceived(object sender, RtpStream.FrameReceivedEventArgs ea)
{
PlayReceivedVoice(ea.Frame.Buffer);
}



6-بعد عملية الاستقبال يتم تجميع الـBytes المستقبلة في Buffer لإجراء عملية فك الضغط ومن ثم عرضه على Sound Device لديك.

كود
private void PlayReceivedVoice(byte[] VoiceBuffer)
{

//Decompress the received data
// byte[] byteDecodedData = Decompress(VoiceBuffer);

//Play it on the speaker device.
playbackBuffer = new SecondaryBuffer(playbackBufferDescription, device);
playbackBuffer.Write(0, byteDecodedData, LockFlag.None); // 0= is the Starting Point (the offset)
playbackBuffer.Play(0, BufferPlayFlags.Default); // 0 = is The Priority of Sound for hardware that mixing the voice resources

}

************************
الرجوع الى أعلى الصفحة اذهب الى الأسفل
http://alhash-school.yoo7.com
Abdulbasit
عبدالباسط غرايبة
عبدالباسط غرايبة
avatar

ذكر عدد الرسائل : 1668
الموقع : alhash-school.yolasite.com
العمر : 34
العمل/الترفيه : فني مختبرات
نقاط التميز مسابقات : 130
نقاط التميز : 13767
السٌّمعَة : 48
الاوسمة :
الاوسمة2 : وسام ادارة
احترام قوانين المنتدى :
100 / 100100 / 100

الدولة :
تاريخ التسجيل : 28/11/2008

مُساهمةموضوع: رد: سلسلة دروس برمجة الـ Rtp In Voip & Video Conferencing, C# RTP VOIP Video In Multicasting Systems   الجمعة مايو 08, 2009 9:13 pm

ثالثا: دراسة حجم الـBuffer وتأثره بسرعة الشبكة وعلاقة ذلك بالـJitter Loss And Delay:

سنقدم في هذا الدرس كيفية حساب حجم الـBuffer و التحكم به بناء على عوامل قدرة الشبكة وكذلك الجودة.
بينا سابقا أن الزيادة في حجم الـBuffer يساعد المرسل على تقسيم البيانات المراد إرسالها وبالتالي إمكانية إرسال إحجام اكبر من البيانات على سرعات شبكة أقل لكن كما وذكرنا إذ أن ذلك يساعد على أمرين:
الأول: إمكانية ضياع Frames إثناء الإرسال بسبب زيادة عدد تلك الـFrames.
الثاني: حاجة المرسل إلى وقت أكثر لتقسيم تلك الـFrames وحاجة المستقبل لوقت و Buffer أكبر لإعادة ترتيب تلك الـFrames وبالمحصلة زيادة الـDelay.
في البداية سنقوم بتعريف أهم المصطلحات والتي سنستخدمها في عملية إدارة الـBuffer والتي قمنا بتخصيصها بدرس السابق في الدالة SetVoiceDevices:
Channels : وهو عدد القنوات التي يتم من خلالها تسجيل الصوت وعرضه وكمثال فإن نظام الـStereo يستخدم قناتين ويضاعف عدد القنوات المستخدمة حجم الـBuffer بحيث أنه يضرب بعدد القنوات التي يتم استخدامها.
Sample Peer Second: ويسمى أيضا Sampling rate وهي تعبير عن عدد الـSamples بالثانية الواحدة ومن المعروف أن الـSample هو قيمة لموقع معين من الموجة الصوتية في زمن محدد وأما الـSampling فهو عملية تحويل الـcontinuous signal إلى discrete signal بهدف تحويل تلك الـSignal إلى النظام الثنائي.
Bits Peer Sample : ويعبر عنه بالـ bit depth وهو عدد الـBits التي ستحتاجها لتحويل Wave Sample واحدة من النظام التناظري إلى الرقمي وكلما زاد عدد الـbits كلما زادت جودة الصوت وزاد الاحتياج إلى حجم Buffer أكبر. وبالتالي لحساب حجم الـBuffer الذي سنحتاجه في عمليات الإرسال والاستقبال ومن خلال المعادلة التالية يمكننا معرفة الحد الأدنى لحجم الـBuffer الذي سنحتاجه لإجراء عملية الإرسال:

كود
Bit rate = (bit depth) x (sampling rate) x (number of channels).
The Minimum Size Of The Buffer in Bytes = Channels X (BitsPerSample/Cool.
Example: 2 X (16 bits /Cool = 4 Bytes

The Minimum Size Of The Buffer in One Second = (The Minimum Size Of The Buffer in Bytes) X (Number of Samples Peer One Second)
Example: 4Bytes * 22050 = 88200 Bytes For each Second.



وهذا يعني أننا سنحتاج إلى Buffer لا يقل عن 88200 Bytes لتخزين ثانية واحدة من الصوت قبل عملية الضغط أو الإرسال وبتالي ولحساب السرعة المطلوبة من قناة الاتصال في الثانية الواحدة والذي إذا تحقق فسيكون هنالك مزامنة في عملية التحدث وبالتالي وصول الصوت بشكل مستمر وغير متقطع سنطبق الخطوات التالية:
أولا حساب عدد الـFrames المحتمل والذي سنحتاجها لإرسال 88200 Bytes في الثانية الواحدة:

كود
(88200 the size of the buffer for each second) / (1500 Bytes the minimum size of the frame In Ethernet as example - 40 Bytes The Minimum Size of The Empty RTP Frame) = 61 Frames


ثانيا حساب حجم الـFrames الفارغة:
كود
61 Frames X 40 Bytes = 2440 Bytes


ثالثا جمع كافة القيم وضربها بـ8 لتحويلها إلى Bits وتقسيمها على 1024 لمعرفة السرعة المطلوبة بالـ KB :
كود
(88200 + 2240) (Cool / 1024 = 706 K bit/Second


وهذا يعني أننا سنحتاج إلى شبكة بسرعة لا تقل عن 706Kb/S لنقل ثانية واحدة من الـWave Voice بمواصفات: قناتين اتصال و 22050 Sampling Rate و 16 Bits لجودة الصوت.

ولمزامنة عملية التسجيل و الإرسال قمنا بتنفيذ الدالة SetBufferEvents وذلك لتقسيم الـBuffer إلى جزأين الأول سيستخدم في تسجيل الصوت القادم من المايكروفون والثاني سيستخدم في عملية الإرسال, ولتنفيذ ذلك قمنا بإنشاء اثنين من الـNotifications الأول سينفذ عندما يصل تعبئة الـBuffer إلى النصف بحيث يعلن فيه عن امتلاء الجزء المخصص لتخزين الصوت وبالتالي إضافته إلى الجزء التالي من الـBuffer المخصص للإرسال وفي حالة امتلاء الجزء الثاني سيتم إرسال الـBuffer ومن ثم تنظيفه من جديد لتكرار العملية.

يمكن التحكم أيضا بزمن الإرسال ويعتمد ذلك على سرعة الشبكة من جهة وحجم الـBuffer من جهة أخرى وقد قمنا في المثال السابق بإرسال كامل الـBuffer عند كل 200 milliseconds وذلك بعد ضغطه باستخدام المعيار G.711 وهو ITU Standard ويعتبر من إحدى معايير الضغط المخصصة لصوت ويمكن باستخدام ذلك المعيار تقليل حجم الـVoice In Wave Format إلى النصف تقريبا.

************************
الرجوع الى أعلى الصفحة اذهب الى الأسفل
http://alhash-school.yoo7.com
eh_rh
مراقب عام
مراقب عام
avatar

ذكر عدد الرسائل : 1974
العمر : 43
نقاط التميز مسابقات : 20
نقاط التميز : 7424
السٌّمعَة : 33
الاوسمة :
الاوسمة2 : ادارة
احترام قوانين المنتدى :
100 / 100100 / 100

الدولة :
تاريخ التسجيل : 28/11/2008

مُساهمةموضوع: رد: سلسلة دروس برمجة الـ Rtp In Voip & Video Conferencing, C# RTP VOIP Video In Multicasting Systems   الجمعة مايو 08, 2009 10:15 pm

مشكووووووووووووووووووووور

على هذه السلسله نامل الفائده للجميع

************************
الرجوع الى أعلى الصفحة اذهب الى الأسفل
zgol
عضو خبير
عضو خبير
avatar

ذكر عدد الرسائل : 557
الموقع : alhash-shool.yoo7.com
العمر : 21
العمل/الترفيه : طالب
المزاج : من الاخر
نقاط التميز : 4746
السٌّمعَة : 0
الاوسمة :
احترام قوانين المنتدى :
100 / 100100 / 100

الدولة :
تاريخ التسجيل : 29/03/2009

مُساهمةموضوع: رد: سلسلة دروس برمجة الـ Rtp In Voip & Video Conferencing, C# RTP VOIP Video In Multicasting Systems   الإثنين يوليو 06, 2009 9:49 pm

الرجوع الى أعلى الصفحة اذهب الى الأسفل
 
سلسلة دروس برمجة الـ Rtp In Voip & Video Conferencing, C# RTP VOIP Video In Multicasting Systems
استعرض الموضوع السابق استعرض الموضوع التالي الرجوع الى أعلى الصفحة 
صفحة 1 من اصل 1
 مواضيع مماثلة
-
» وسائل الإتصالات
» تفسير القران كامل لامام الشيخ محمد متوالى الشعراوى
» دورة مصغرة فى برنامج تحرير الافلام العملاق Honestech Video Editor 7.0
» برنامج ( Xilisoft 3GP Video Converter ) لتحويل صيغ الفيديو كامل بالسريل
» برنامج محول الصيغ Any Video Converter Professional

صلاحيات هذا المنتدى:لاتستطيع الرد على المواضيع في هذا المنتدى
منتدى مدرسة الهاشمية الثانوية للبنين :: الحاسوب و تكنولوجيا المعلومات :: علوم الحاسوب-
انتقل الى: