لماذا يستخدم استخدام H264 في خطوط أنابيب المرسل/المستقبل تأخيرًا كبيرًا؟

StackOverflow https://stackoverflow.com/questions/2893407

سؤال

عندما أحاول إنشاء خط أنابيب يستخدم H264 لنقل الفيديو ، أحصل على بعض التأخير الهائل ، حتى 10 ثوانٍ لنقل الفيديو من الجهاز إلى ... جهاز بلدي! هذا أمر غير مقبول لأهدافي وأرغب في استشارة Stackoverflow حول ما أخطأ فيه (أو أي شخص آخر).

أخذت خطوط الأنابيب من صفحة توثيق GSTRTPBIN وقمت بتعديلها قليلاً لاستخدام speex:

هذا خط أنابيب المرسل: #!/bin/sh

gst-launch -v gstrtpbin name=rtpbin \
        v4l2src ! ffmpegcolorspace ! ffenc_h263 ! rtph263ppay ! rtpbin.send_rtp_sink_0 \
                  rtpbin.send_rtp_src_0 ! udpsink host=127.0.0.1 port=5000                            \
                  rtpbin.send_rtcp_src_0 ! udpsink host=127.0.0.1 port=5001 sync=false async=false    \
                  udpsrc port=5005 ! rtpbin.recv_rtcp_sink_0                           \
        pulsesrc ! audioconvert ! audioresample  ! audio/x-raw-int,rate=16000 !    \
                  speexenc bitrate=16000 ! rtpspeexpay ! rtpbin.send_rtp_sink_1                   \
                  rtpbin.send_rtp_src_1 ! udpsink host=127.0.0.1 port=5002                            \
                  rtpbin.send_rtcp_src_1 ! udpsink host=127.0.0.1 port=5003 sync=false async=false    \
                  udpsrc port=5007 ! rtpbin.recv_rtcp_sink_1

خط أنابيب المتلقي:

!/بن/ش

gst-launch -v\
    gstrtpbin name=rtpbin                                          \
    udpsrc caps="application/x-rtp,media=(string)video, clock-rate=(int)90000, encoding-name=(string)H263-1998" \
            port=5000 ! rtpbin.recv_rtp_sink_0                                \
        rtpbin. ! rtph263pdepay ! ffdec_h263 ! xvimagesink                    \
     udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0                               \
     rtpbin.send_rtcp_src_0 ! udpsink port=5005 sync=false async=false        \
    udpsrc caps="application/x-rtp,media=(string)audio, clock-rate=(int)16000, encoding-name=(string)SPEEX, encoding-params=(string)1, payload=(int)110" \
            port=5002 ! rtpbin.recv_rtp_sink_1                                \
        rtpbin. ! rtpspeexdepay ! speexdec ! audioresample ! audioconvert ! alsasink \
     udpsrc port=5003 ! rtpbin.recv_rtcp_sink_1                               \
     rtpbin.send_rtcp_src_1 ! udpsink host=127.0.0.1 port=5007 sync=false async=false

هذه خطوط الأنابيب ، مزيج من H263 و Speex ، تعمل بشكل جيد بما فيه الكفاية. ألتقط أصابعي بالقرب من الكاميرا و micropohne ثم أرى حركة وأسمع الصوت في نفس الوقت.

ثم قمت بتغيير خطوط الأنابيب لاستخدام H264 على طول مسار الفيديو.

يصبح المرسل: #!/bin/sh

gst-launch -v gstrtpbin name=rtpbin \
        v4l2src ! ffmpegcolorspace ! x264enc bitrate=300 ! rtph264pay ! rtpbin.send_rtp_sink_0 \
                  rtpbin.send_rtp_src_0 ! udpsink host=127.0.0.1 port=5000                            \
                  rtpbin.send_rtcp_src_0 ! udpsink host=127.0.0.1 port=5001 sync=false async=false    \
                  udpsrc port=5005 ! rtpbin.recv_rtcp_sink_0                           \
        pulsesrc ! audioconvert ! audioresample  ! audio/x-raw-int,rate=16000 !    \
                  speexenc bitrate=16000 ! rtpspeexpay ! rtpbin.send_rtp_sink_1                   \
                  rtpbin.send_rtp_src_1 ! udpsink host=127.0.0.1 port=5002                            \
                  rtpbin.send_rtcp_src_1 ! udpsink host=127.0.0.1 port=5003 sync=false async=false    \
                  udpsrc port=5007 ! rtpbin.recv_rtcp_sink_1

ويصبح جهاز الاستقبال: #!/bin/sh

gst-launch -v\
    gstrtpbin name=rtpbin                                          \
    udpsrc caps="application/x-rtp,media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264" \
            port=5000 ! rtpbin.recv_rtp_sink_0                                \
        rtpbin. ! rtph264depay ! ffdec_h264 ! xvimagesink                    \
     udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0                               \
     rtpbin.send_rtcp_src_0 ! udpsink port=5005 sync=false async=false        \
    udpsrc caps="application/x-rtp,media=(string)audio, clock-rate=(int)16000, encoding-name=(string)SPEEX, encoding-params=(string)1, payload=(int)110" \
            port=5002 ! rtpbin.recv_rtp_sink_1                                \
        rtpbin. ! rtpspeexdepay ! speexdec ! audioresample ! audioconvert ! alsasink \
     udpsrc port=5003 ! rtpbin.recv_rtcp_sink_1                               \
     rtpbin.send_rtcp_src_1 ! udpsink host=127.0.0.1 port=5007 sync=false async=false

هذا ما يحدث تحت أوبونتو 10.04. لم ألاحظ مثل هذه التأخيرات الضخمة على Ubuntu 9.04 - كانت التأخيرات هناك في المدى 2-3 ثوان ، Afair.

هل كانت مفيدة؟

المحلول

مع بعض المساعدة من "Sharktooth" في #x264 على Freenode ، اكتشفت أن إصدار GIT من GST-Plugins-Augly يدعم الإعداد المسبق "Zero-Latency".

http://cgit.freedesktop.org/gstreamer/gst-plugins-ugly

لقد قمت بتعديل مثالك لتعيين "X264enc pass = Qualizer = 20 Tune = Zerolatency" ، ويبدو أن الكمون يبقى عند 0.7 - 0.9 ثانية. لا يمكنني معرفة كيفية الحصول عليه أقل.

نصائح أخرى

شيء ما هناك هو التخزين المؤقت ، على الأرجح المشفر. كلما زاد عدد البيانات التي يجب أن تعمل معها ، زاد الضغط أكثر فعالية. لست على دراية بهذا التشفير ، ولكن عادة ما يكون هناك إعداد لكمية التخزين المؤقت.

x264 بشكل افتراضي ، تقوم الإدخال بإدخال المزيد من البيانات للعمل معها. زيادة التأخير من Ubuntu 10.04 على الأرجح لأنه كان عالقًا في إصدار X264 قديم ، قبل إدخال-MBTree و-RC-Slowahead.

في هذه الصفحة من Mewiki يمكنك أن ترى كيفية حساب الكمون ، وعدد الإطارات ، وما يلي ، على ما يجب تعطيله أولاً لتقليل الكمون:

من الممكن تقليل الكمون في X264 ، ولكنه يقلل من الجودة. إذا كنت لا تريد زمن انتقال ، فقم بتعيين Zerolatency. إذا تمكنت من التعامل مع زمن انتقال صغير (أي أقل من ثانية واحدة) ، فهذا يستحق ضبط الخيارات للسماح بذلك. فيما يلي سلسلة من الخطوات التي يمكنك متابعتها لتقليل الكمون بشكل متزايد. توقف عندما يكون الكمون منخفضًا بدرجة كافية:

  1. ابدأ بالتخلف عن السداد
  2. اقتل Sync-Slowahead
  3. إسقاط RC-Slowahead إلى ما لا يقل عن 10 ~
  4. إسقاط المواضيع إلى قيمة أقل (أي قل 6 بدلاً من 12)
  5. استخدام شرائح المواضيع
  6. تعطيل RC-Slowahead
  7. تعطيل الأطر B.
  8. أنت الآن في -تون Zerolatency

لذا ، يجب عليك أولاً محاولة إضافة شيء مثل سطر الأوامر الخاص بك

sync-slowahead = 0 ، rc-slowahead = 10 (لست متأكدًا من تنسيق سطر الأوامر في التطبيق الخاص بك)

هذا يجب أن يحلق معظم الكمون ، بتكلفة كفاءة ضغط منخفضة. إذا كان لديك العديد من النوى (Quadcore مع HT ، على سبيل المثال) ، فقد يكون من المفيد أيضًا القيام بالرقم 4. ، بتكلفة سرعة صغيرة.

استخدم Tune = Zerolatency ، وفقًا لنصيحة Sharktooth ، إذا كان هذا لا يزال غير كافٍ.

المزيد عن الموضوع: http://x264dev.multimedia.cx/archives/249

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top