التقاط الفيديو من كاميرات USB على أجهزة Linux

خلفية


منذ بعض الوقت ، كنت أميل إلى "تحسين" دبابة من مجموعة "معركة دبابات" المعروفة ، وإضافة القدرة على اللعب كما لو كنت سائق دبابة. ظهرت الفكرة بعد قراءة عدة مقالات عن حبري (على سبيل المثال ، هنا: geektimes.ru/post/257528) ، وجدت فيها كيف يمكن القيام بذلك باستخدام موجه WiFi صغير وكاميرا USB. بدا الحل بسيطًا بشكل جذاب: يتم تشغيل جهاز التوجيه ببرنامج ثابت خاص ، والكاميرا متصلة به ، ويتم التحكم في الخزان بواسطة جهاز التحكم عن بعد الأصلي ، ويتم عرض الفيديو في المتصفح. بعد أن جمعت النموذج الأولي بسرعة ، وجدت أن الفيديو تم التقاطه بجودة مقرفة. كانت إما 320 × 440 × 30 أو 640 × 480 × 30. عندما تم تشغيل وضع 1280x720 ، في أفضل الأحوال كان هناك مقطع فيديو ممزق يحتوي على قطع أثرية ، في أسوأ الأحوال لم يكن على الإطلاق. لم يعمل وضع 1920x1080 من حيث المبدأ. لقد أزعجني هذا كثيرًا ، حيث دعمت الكاميرا على جهاز كمبيوتر أوضاعًا تصل إلى 1920x1080x30 وكان لديها ضغط MJPG للأجهزة. اقترح حدسي أن التنفيذ أبعد ما يكون عن الكمال.

الأهداف


  1. الفيديو بدقة FullHD (1920X1080) أو HD (1280x720) ومعدل الإطارات العادي (حتى تتمكن من اللعب).
  2. خططت لإعطاء اللعبة للأطفال ، لذلك كنت بحاجة إلى بدء تلقائي ودعم لتوصيل / فصل الكاميرا.

بشكل عام ، أردت شيئًا مثل هذا:



محددات


لم أكن لأبحث عن حل يعمل دائمًا وفي كل مكان. يناسبني القيود التالية تماما:

  1. إشارة wifi جيدة.
  2. عدد محدود من الاتصالات ، تم إعطاء الأولوية للحالة عندما يكون هناك عميل واحد فقط.
  3. تدعم الكاميرا وضع MJPG.

الأب و SW


  1. كاميرا الفيديو Logitech B910 HD ( http://www.logitech.com/en-us/product/b910-hd-webcam ).
  2. جهاز التوجيه TP-LINK TL-MR3020. يحتوي هذا الطفل على الأجهزة التالية: CPU MIPS 24K 400MHz و RAM 32 MiB و Flash 4 MiB و Ethernet 100 Mbit و USB 2.0 ( http://wiki.openwrt.org/en/toh/tp-link/tl-mr3020 ).
  3. . OR-WRT (http://roboforum.ru/wiki/OR-WRT), OpenWRT (http://openwrt.org/, 12.07 15.05).
  4. . , .
  5. “ ”.


بشكل عام ، هذا تكوين ضعيف حقًا ، خاصة إذا كنت تتذكر أن إطارًا بتنسيق YUV420 بحجم 1920X1080 يأخذ 4 MiB (2 بايت لكل بكسل). لقد شجعتني أن الكاميرا تدعم ضغط MJPG للأجهزة. أظهرت التجارب أن إطار FullHD المضغوط يكون عادة أقل من 500 كيلوبايت. لذلك قررت مواصلة البحث. اتضح أنه لالتقاط الفيديو وبثه عبر HTTP ، يتم استخدام mjpg-streamer (http://sourceforge.net/projects/mjpg-streamer/). أظهر تحليل رمزه أنه يستخدم 1 دفق لالتقاط الفيديو + دفق منفصل لكل عميل. هذا ليس الحل الأفضل لنظام أحادي النواة ، لأنه يتطلب تزامن مؤشر ترابط وذاكرة للمكدس لكل مؤشر ترابط. كما نسخ الإطارات الملتقطة. بشكل عام ، أصبح mjpg-streamer مشتبهًا فيه # 1.

اكتشاف مثير للاهتمام


أثناء دراسة mjpg-streamer ، اكتشفت أن التقاط الفيديو على Linux يتم باستخدام مكتبة v4l2 ويتم استخدام قائمة انتظار المخزن المؤقت لالتقاطه. أثناء تصحيح أخطاء تهيئة هذه المخازن المؤقتة في mjpg-streamer ، وجدت أنه حتى بالنسبة لوضع MJPG ، فإن حجمها كبير جدًا ويتزامن بشكل غير متوقع مع حجم الإطار غير المضغوط. لذلك بدأت أشك في أنه سيتعين علي الدخول إلى كود برنامج تشغيل UVC ، المسؤول عن دعم الكاميرات.

تحليل رمز السائق والنجاح الأول


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

انضغاط صغير.
, JPG. . , .

كان رمز مشغل UVC جاهزًا لإضافة أنواع مختلفة من الحلول "الخاصة" ، ووجدت بسهولة مكانًا لضبط حجم المخزن المؤقت (الوظيفة uvc_fixup_video_ctrl ()). علاوة على ذلك ، يدعم برنامج التشغيل مجموعة من المراوغات التي تسمح لك بدعم الكاميرات بانحرافات مختلفة عن معيار UVC. بشكل عام ، بذل مطورو السائق أفضل ما يمكن لدعم كاميرات حديقة الحيوان.

بإضافة تصحيح حجم المخزن المؤقت ، حصلت على تشغيل مستقر في وضع 1280x720 وحتى في وضع 1920x1080. مرحى! تم حل نصف المشكلة!

تبحث عن مغامرات جديدة


سعيدًا قليلاً بالنجاح الأول ، تذكرت أن mjpg-streamer أبعد ما يكون عن الكمال. بالتأكيد يمكنك القيام بشيء بسيط ، ليس عالميًا مثل mjpg-streamer ، ولكنه أكثر ملاءمة لظروفي. لذلك قررت أن أجعل uvc2http.

في mjpg-streamer ، لم يعجبني استخدام تيارات متعددة ونسخ المخازن المؤقتة. هذا حدد بنية الحل: 1 دفق ولا نسخة. باستخدام IO غير المحجوب ، يتم ذلك ببساطة: التقاط الإطار وإرساله إلى العميل دون نسخ. هناك مشكلة صغيرة: أثناء إرسال البيانات من المخزن المؤقت ، لا يمكننا إعادة المخزن المؤقت إلى قائمة الانتظار. وبينما لا يوجد المخزن المؤقت في قائمة الانتظار ، لا يمكن للسائق وضع إطار جديد فيه. ولكن إذا كان حجم قائمة الانتظار> 1 ، يصبح ذلك ممكنًا. يحدد عدد المخازن المؤقتة الحد الأقصى لعدد الاتصالات التي يمكن ضمان خدمتها. بمعنى ، إذا كنت أرغب في دعم عميل واحد بشكل مضمون ، فإن 3 مخازن مؤقتة كافية (يكتب برنامج التشغيل إلى مخزن مؤقت واحد ، ويتم إرسال البيانات من الثاني ، والثالث في المخزون لتجنب التنافس مع برنامج التشغيل للمخزن المؤقت عند محاولة الحصول على إطار جديد).

Uvc2http


يتكون Uvc2http من مكونين: UvcGrabber و HttpStreamer. الأول مسؤول عن تلقي المخازن المؤقتة (الإطارات) من قائمة الانتظار وإعادتها إلى قائمة الانتظار. والثاني هو المسؤول عن خدمة العملاء عبر HTTP. هناك المزيد من التعليمات البرمجية التي تربط هذه المكونات. يمكن العثور على التفاصيل في المصدر.

مشكلة غير متوقعة


كان كل شيء رائعًا: عمل التطبيق وبدقة 1280 × 720 أنتجت 20 إطارًا / ثانية. لقد أجريت تغييرات تجميلية على الرمز. بعد دفعة أخرى من التغييرات ، قمت بقياس معدل الإطار. كانت النتيجة محبطة - أقل من 15 إطارًا. هرعت للبحث عن ما أدى إلى التدهور. ربما أمضيت ساعتين انخفض خلالها التردد مع كل قياس بقيمة 7 إطارات / ثانية. دخلت أفكار مختلفة في رأسي حول التدهور بسبب العمل الطويل للموجه ، بسبب ارتفاع درجة حرارته. كان شيئًا غير مفهوم. في مرحلة ما ، أوقفت البث ورأيت أن التقاطًا واحدًا فقط (بدون البث) أعطى نفس الإطارات 7. حتى أنني بدأت أشك في وجود مشاكل في الكاميرا. بشكل عام ، بعض الهراء. كان ذلك في المساء ، وأظهرت الكاميرا النافذة ، وأظهرت شيئًا رماديًا. لتغيير الصورة القاتمة ، أدرت الكاميرا داخل الغرفة. والصغرى!ارتفع معدل الإطار إلى 15 وفهمت كل شيء. قامت الكاميرا تلقائيًا بتعديل وقت التعرض وأصبحت هذه المرة أطول من مدة الإطار عند تردد معين. خلال هاتين الساعتين ، حدث ما يلي: في البداية كان الظلام يزداد تدريجيًا (كان المساء) ، ثم أدرت الكاميرا داخل الغرفة المضاءة. بتوجيه الكاميرا إلى الثريا ، حصلت على 20 إطارًا / ثانية. مرحى.


  1. . 1-1.5 .
  2. . , , qv4l2, . : - . .
  3. . USB , ( ) ( ). USB ( ).
  4. يحتوي جهاز التوجيه على ذاكرة ومساحة قرص قليلة جدًا. لهذا السبب ، رفضت OR-WRT وقمت بتجميع صورة OpenWRT الخاصة بي ، وأزلت كل شيء غير ضروري منه.

النتائج


فيما يلي لوحة مع نتائج مقارنة mjpg-streamer و uvc2http. باختصار ، هناك زيادة كبيرة في استهلاك الذاكرة وكسب صغير في معدل الإطارات واستخدام وحدة المعالجة المركزية.
1280 × 7201920 × 1080
VSZ ، كيلوبايت ، عميل واحدVSZ ، KB ، 2 عملاءوحدة المعالجة المركزية ،٪ ، عميل واحدوحدة المعالجة المركزية ،٪ ، 2 عملاءFPS ، f / s ، عميل واحدFPS ، f / s ، 2 عملاءVSZ ، كيلوبايت ، عميل واحدVSZ ، KB ، 2 عملاءوحدة المعالجة المركزية ،٪ ، عميل واحدوحدة المعالجة المركزية ،٪ ، 2 عملاءFPS ، f / s ، عميل واحدFPS ، f / s ، 2 عملاء
Mjpg- غاسل1686019040264317.6خمسة عشر254562581228خمسون13.810
uvc2http3960396026432219.675767576284315.512.2

وبالطبع الفيديو الذي صنعته مع الأطفال:



صورة للدبابة الناتجة (اتضح شيء مثل عربة غجرية):



باستخدام


المصادر هنا . للاستخدام على كمبيوتر Linux ، تحتاج فقط إلى الترجمة (بشرط ألا ترغب في تصحيح برنامج تشغيل UVC). تم بناء الأداة المساعدة باستخدام CMake بالطريقة القياسية. إذا كنت بحاجة إلى استخدامه في OpenWRT ، فأنت بحاجة إلى اتخاذ خطوات إضافية:

  1. انسخ محتويات دليل OpenWrt-15.05 إلى جذر مستودع OpenWRT. هذه الملفات هي لـ OpenWRT 15.05 فقط. يصفون حزمة جديدة لـ OpenWRT وتصحيحا لبرنامج تشغيل UVC.
  2. , quirk UVC_QUIRK_COMPRESSION_RATE uvc_driver.c. UVC. , wiki.openwrt.org/doc/devel/patches. uvc_ids. :

    /* Logitech B910 HD Webcam */
    	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
    				| USB_DEVICE_ID_MATCH_INT_INFO,
    	  .idVendor		= 0x046d,
    	  .idProduct		= 0x0823,
    	  .bInterfaceClass	= USB_CLASS_VIDEO,
    	  .bInterfaceSubClass	= 1,
    	  .bInterfaceProtocol	= 0,
    	  .driver_info		= UVC_QUIRK_RESTORE_CTRLS_ON_INIT
    				| UVC_QUIRK_COMPRESSION_RATE }, // Enable buffer correction for compressed modes
    

  3. OpenWRT (http://wiki.openwrt.org/doc/howto/build). uvc2http Multimedia.
  4. uvc2http ( ) . , .
  5. قم بتثبيت الحزمة على الجهاز / تحديث النظام

ماذا بعد


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

يمكن تحسين خوارزمية الدفق نظرًا لوجود هامش على تحميل وحدة المعالجة المركزية وعرض القناة (تلقيت بسهولة 50+ ميغابت من جهاز التوجيه الذي يربط عشرة عملاء). يمكنك أيضًا إضافة دعم صوتي.

Source: https://habr.com/ru/post/ar386273/


All Articles