الممارسة FFmpeg DXVA2 فك الأجهزة

تحية! هذه المقالة هي استمرار لمقالتي FFmpeg للبدء في استخدام Visual Studio. نحن هنا نصل إلى فك تشفير الأجهزة لتيار FULL HD RTSP. سأقول مقدمًا أنه حتى Intel ATOM Z8350 يمكنه التعامل بسهولة مع هذه المهمة.

الهدف: فك تشفير الأجهزة وتسجيل ما يصل إلى 4 إطارات في ذاكرة الوصول العشوائي للمعالجة المتوازية اللاحقة (أربعة نوى للمعالج) من كاميرا IP RTSP h.264. أقوم بعرض الإطارات التي تمت معالجتها باستخدام وظائف WinAPI. نتيجة لذلك ، نحصل على نظام عالي السرعة لمعالجة الكمبيوتر لتيار RTSP في الوضع المتوازي. بعد ذلك ، يمكنك توصيل خوارزميات رؤية الكمبيوتر لمعالجة إطارات الوقت الفعلي .

صورة

دخول


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

DirectX Video Acceleration (DXVA) عبارة عن واجهة برمجة تطبيقات لاستخدام تسريع الأجهزة لتسريع معالجة الفيديو باستخدام وحدات معالجة الرسومات. يتيح لك DXVA 2.0 إعادة توجيه المزيد من العمليات إلى وحدة معالجة الرسومات ، بما في ذلك عمليات التقاط الفيديو ومعالجة الفيديو.

بعد كتابة المقال السابق ، سُئلت بعض الأسئلة: "لماذا يستخدم FFmpeg؟" سأبدأ مع المشاكل. الصعوبة الرئيسية لفك تشفير الأجهزة هي كتابة إطار فك الشفرة إلى RAM. بالنسبة إلى الوضوح العالي الكامل ، تبلغ هذه النسبة 1920 × 1080 × 3 = 6،220،800 بايت. حتى مع الأخذ في الاعتبار حقيقة أن الإطار تم تخزينه بتنسيق NV12 ، فإن هذا أيضًا كثير من 1920 × 1080 × 1.5 = 3 110 400 بايت. تعد الكتابة فوق 75 ميجابايت في الثانية مهمة خطيرة لأي معالج. لحل هذه المشكلة ، أضافت Intel أوامر SSE 4 ، والتي تتيح لك إعادة كتابة البيانات دون معالج. لسوء الحظ ، ليس كل المكتبات تنفذ هذا. لقد اختبرت المكتبات التالية:

  1. FFMPEG
  2. VLC
  3. مكتبة برمجية مفتوحة للرؤية الحاسوبية

VLC - يعمل مع كاميرات IP من خلال فك تشفير الأجهزة (تحميل منخفض للغاية للمعالج) ، يمكن بناء مشغل دفق RTSP بدائي في 10 سطور فقط من التعليمات البرمجية ، لكن تلقي إطارات فك الشفرة في ذاكرة الوصول العشوائي (RAM) يستغرق وقتًا طويلاً للغاية من المعالج.

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

FFmpeg - أظهرت جيدة ، في رأيي ، النتائج ، وأنها تعمل بشكل مستقر. لا يتم تطبيق العائق الوحيد الذي يعمل مع كاميرات WEB للإصدار X86 (يبدو أن X64 يسمح لك بالعمل) في Windows.

أجهزة فك تشفير الفيديو سهلة


في الواقع ، فك تشفير الأجهزة باستخدام مكتبة FFmpeg ليس أكثر تعقيدًا من البرامج. إعدادات المشروع هي نفسها لتنفيذ البرنامج ، ظل الرسم البياني للكتل دون تغيير.

يمكنك عرض قائمة FFmpeg أساليب دعم الأجهزة فك التشفير.

fprintf(stderr, " %s", av_hwdevice_get_type_name(type)); 

أول شيء نحتاج إلى فعله هو إخبار FFmpeg بأي جهاز فك تشفير للأجهزة تريد فك تشفير الفيديو. في حالتي ، يترك Windows10 + Intel Atom Z8350 DXVA2 فقط:

 type = av_hwdevice_find_type_by_name("dxva2"); 

يمكنك اختيار CUDA أو D3D11VA أو QSV أو VAAPI (Linux فقط) كجهاز فك تشفير للأجهزة. وفقًا لذلك ، يجب أن يكون لديك حل الأجهزة هذا ويجب إنشاء FFmpeg بدعمه.

افتح دفق الفيديو:

 avformat_open_input(&input_ctx, filename, NULL, NULL; 

نحصل على معلومات حول دفق الفيديو:

 av_find_best_stream(input_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0); 

تخصيص الذاكرة:

 frame = av_frame_alloc(); //       sw_frame = av_frame_alloc(); //        

تقوم هذه الوظيفة بالكتابة فوق الملف الذي تم فك تشفيره في RAM:

 av_hwframe_transfer_data(sw_frame, frame, 0); 

قليلا عن تنسيق NV12


لذلك ، حصلنا على إطار في بنية sw_frame. يتم تخزين الإطار المستلم بتنسيق NV12. تم اختراع هذا التنسيق بواسطة Microsoft. يسمح لك بتخزين معلومات البكسل في 12 بت. عندما تكون الكثافة 8 بتات ، وتصف 4 بتات اللون (أو بالأحرى ، يتم وصف اللون فورًا بأربعة بكسلات مجاورة 2 × 2 بكسل). علاوة على ذلك ، sw_frame.data [0] - يتم تخزين الكثافة ، وفي sw_frame.data [1] - يتم تخزين اللون. للتحويل من NV-12 إلى RGB ، يمكنك استخدام الوظيفة التالية:

ترجمة C ++ من NV12 إلى RGB
 void SaveFrame(uint8_t * f1, uint8_t * f2, int iFrame) { FILE *pFile; char szFilename[32]; int x, i, j; // char buff[1920 * 1080 * 3]; uint8_t *buff = new uint8_t(1920*3*2); int u=0, v=0, y=0; // Open file sprintf(szFilename, "frame%d.ppm", iFrame); pFile = fopen(szFilename, "wb"); if (pFile == NULL) return; //    fprintf(pFile, "P6\n%d %d\n255\n", 1920, 1080); for (j = 0; j < 1080 / 2; j++) { for (i = 0; i < 1920; i +=2) { // 1  rgb y = *(f1 + j * 1920 * 2 + i); v = *(f2 + j * 1920 + i) - 128; u = *(f2 + j * 1920 + i + 1) - 128; x = round(y + 1.370705 * v); if (x < 0) x = 0; if (x > 255) x = 255; // if (j > 34) printf("%i, ",(j * 1920 * 2 + i) * 3); buff[i * 3 + 2] = x; x = round(y - 0.698001 * v - 0.337633 * u); if (x < 0) x = 0; if (x > 255) x = 255; buff[i * 3 + 1] = x; x = round(y + 1.732446 * u); if (x < 0) x = 0; if (x > 255) x = 255; buff[i * 3] = x; // 2  rgb y = *(f1 + j * 1920 * 2 + i + 1); x = y + 1.370705 * v; if (x < 0) x = 0; if (x > 255) x = 255; buff[i * 3 + 5] = x; x = y - 0.698001 * v - 0.337633 * u; if (x < 0) x = 0; if (x > 255) x = 255; buff[i * 3 + 4] = x; x = y + 1.732446 * u; if (x < 0) x = 0; if (x > 255) x = 255; buff[i * 3 + 3] = x; // 3  rgb y = *(f1 + j * 1920 * 2 + 1920 + i); x = y + 1.370705 * v; if (x < 0) x = 0; if (x > 255) x = 255; buff[(1920 + i) * 3 + 2] = x; x = y - 0.698001 * v - 0.337633 * u; if (x < 0) x = 0; if (x > 255) x = 255; buff[(1920 + i) * 3 + 1] = x; x = y + 1.732446 * u; if (x < 0) x = 0; if (x > 255) x = 255; buff[(1920 + i) * 3 + 0] = x; // 4  rgb y = *(f1 + j * 1920 * 2 + 1920 + i + 1); x = y + 1.370705 * v; if (x < 0) x = 0; if (x > 255) x = 255; buff[(1920 + i) * 3 + 5] = x; x = y - 0.698001 * v - 0.337633 * u; if (x < 0) x = 0; if (x > 255) x = 255; buff[(1920 + i) * 3 + 4] = x; x = y + 1.732446 * u; if (x < 0) x = 0; if (x > 255) x = 255; buff[(1920 + i) * 3 + 3] = x; // printf("%i, ", i); } // for i fwrite(buff, 1, 1920 * 3 * 2, pFile); printf("\n %i\n", j); } // for j // printf("Save4\n"); // Write pixel data // fwrite(buff, 1, 1920*1080*3, pFile); // Close file printf("close\n"); fclose(pFile); printf("exit\n"); delete buff; // return; } 


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

وهكذا تعلمنا كيفية فك تشفير ملفات الفيديو في الأجهزة وعرضها في نافذة. التقينا بتنسيق NV12 وكيفية تحويله إلى RGB مألوف.

دلل فك التشفير الأجهزة


يصدر FFmpeg الإطارات بعد 40 مللي ثانية (بمعدل 25 إطارًا في الثانية). كقاعدة عامة ، تستغرق معالجة إطار HD كامل وقتًا أطول بكثير. وهذا يتطلب تعدد مؤشرات ترابط لتعظيم الحمل من جميع النوى المعالج 4. في الممارسة العملية ، أبدأ 6 خيوط مرة واحدة ولا أزالها بعد الآن ، مما يبسط العمل إلى حد كبير ويزيد من موثوقية البرنامج. يظهر مخطط التشغيل في الشكل. 1

صورة
الشكل 1 مخطط بناء برنامج متعدد الخيوط مع FFmpeg

كتبت وحدة فك الترميز الخاصة بي كـ * .dll (FFmpegD.DLL) لإدراجها في مشاريعي. يسمح لك هذا بتقليل رمز المشروع ، مما يزيد من فهم الكود وإدراجه في أي لغة برمجة ، حتى Assembler (verified :)). باستخدامه ، سوف نكتب مشغل دفق RTSP من كاميرا IP.

لبدء العمل باستخدام DLL ، تحتاج إلى تمرير مؤشر إلى مصفوفة int [13] ، ومعالجة حدث وصول إطار جديد ، و HANDLE لبدء معالجة حزمة بيانات جديدة من الكاميرا ، ومصفوفة char لعنوان الكاميرا.

ويرد هيكل مجموعة في الجدول 1.

صورة

قبل الاتصال ، يجب عليك إعادة تعيين أرقام الإطارات 1-4.

ستتخذ مكتبة الارتباط الحيوي (DLL) كافة الخطوات اللازمة لتهيئة FFmpeg وستقوم بتسجيل المؤشرات وأرقام الإطارات. بعد أن يحدد الحدث "وصول إطار جديد". من الضروري فقط معالجة الإطارات الواردة والكتابة 0 بدلاً من رقم الإطار (وهذا يعني أنه تمت معالجة الإطار ولم يعد يستخدم).

ستجد أدناه مثالاً للاعب مزود برمز المصدر. المثال هو ShowDib3 Charles Petzold.

الأرشيف مع المشروع
أرشيف FFmpegD.dll

النتائج: FFmpeg كاشف حركة الأجهزة حتى على Intel Atom Z8350 يترجم h264 Full HD في الوقت الحقيقي مع ما يصل إلى 20 ٪ من تحميل المعالج مع كاشف الحركة المتصل.


مثال عملية تشغيل كاشف الحركة على Intel ATOM Z8350. أول 30 ثانية هي حساب الخلفية. بعد ذلك ، يعمل كاشف الحركة بطريقة طرح الخلفية.

ملاحظة: يمكنك أيضًا فك تشفير ملفات الفيديو (h.264 المضغوطة) !!!

المراجع:

  1. معلومات مفيدة متنوعة على FFmpeg
  2. معلومات حول استخدام المكتبات المختلفة التي تقدمها FFmpeg
  3. معلومات عن الأشكال والتحويل إلى RGB

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


All Articles