Hai Artikel ini merupakan kelanjutan dari
artikel FFmpeg saya yang memulai dengan Visual Studio. Di sini kita menuju ke decoding perangkat keras dari aliran FULL HD RTSP. Saya akan mengatakan sebelumnya bahwa bahkan Intel ATOM Z8350 dapat dengan mudah mengatasi tugas ini.
Tugas: decoding perangkat keras dan merekam hingga 4 frame dalam RAM untuk pemrosesan paralel berikutnya (empat core prosesor) dari kamera IP RTSP h.264. Saya menampilkan frame yang diproses menggunakan fungsi WinAPI. Hasilnya, kami mendapatkan sistem kecepatan tinggi untuk pemrosesan komputer dari aliran RTSP dalam mode paralel. Selanjutnya, Anda dapat menghubungkan algoritma
visi komputer untuk memproses frame
Real Time .
Entri
Mengapa saya perlu mendekode perangkat keras? Anda ingin men-decode video real-time dengan prosesor yang lemah dan murah atau Anda ingin menurunkan prosesor sebanyak mungkin, maka sekarang saatnya untuk berkenalan dengan decoding perangkat keras.
DirectX Video Acceleration (DXVA) adalah API untuk menggunakan akselerasi perangkat keras untuk mempercepat pemrosesan video dengan GPU. DXVA 2.0 memungkinkan Anda mengarahkan lebih banyak operasi ke GPU, termasuk menangkap video dan operasi pemrosesan video.
Setelah menulis artikel sebelumnya, saya ditanya beberapa pertanyaan: "Mengapa FFMPeg digunakan?" Saya akan mulai dengan masalah. Kesulitan utama dari decoding perangkat keras adalah untuk menulis frame yang diterjemahkan ke RAM. Untuk Full HD, ini adalah 1920 x 1080 x 3 = 6.220.800 byte. Bahkan dengan mempertimbangkan fakta bahwa frame disimpan dalam format NV12, ini juga banyak 1920 x 1080 x 1,5 = 3 110 400 byte. Menimpa 75 MB per detik adalah tugas serius untuk prosesor apa pun. Untuk mengatasi masalah ini, Intel telah menambahkan perintah SSE 4, yang memungkinkan Anda menulis ulang data tanpa prosesor. Sayangnya, tidak semua perpustakaan menerapkan ini. Saya telah menguji perpustakaan berikut:
- Ffmpeg
- VLC
- Opencv
VLC - bekerja dengan kamera IP melalui decoding perangkat keras (beban prosesor sangat rendah), pemutar aliran RTSP primitif dapat dibangun hanya dalam 10 baris kode, tetapi menerima bingkai yang diterjemahkan dalam RAM membutuhkan terlalu banyak waktu prosesor.
OpenCV - RTSP menggunakan FFmpeg untuk bekerja dengan aliran, jadi diputuskan untuk bekerja tanpa perantara, yaitu gunakan perpustakaan FFmpeg. Selain itu, FFmpeg, yang diinstal secara default, dibangun di OpenCV tanpa decoding perangkat keras.
FFmpeg - menunjukkan baik, menurut pendapat saya, hasil, itu bekerja secara stabil. Satu-satunya kelemahan tidak diimplementasikan bekerja dengan WEB-kamera untuk versi X86 (X64 tampaknya memungkinkan Anda untuk bekerja) di Windows.
Penguraian video perangkat keras itu mudah
Bahkan, decoding perangkat keras menggunakan perpustakaan FFmpeg tidak lebih rumit daripada perangkat lunak. Pengaturan proyek sama seperti untuk implementasi perangkat lunak, diagram blok tetap tidak berubah.
Anda dapat menampilkan daftar metode decoding perangkat keras yang didukung FFmpeg.
fprintf(stderr, " %s", av_hwdevice_get_type_name(type));
Hal pertama yang perlu kita lakukan adalah memberi tahu FFmpeg dengan dekoder perangkat keras mana yang ingin Anda dekode videonya. Dalam kasus saya, Windows10 + Intel Atom Z8350 hanya menyisakan DXVA2:
type = av_hwdevice_find_type_by_name("dxva2");
Anda dapat memilih CUDA, D3D11VA, QSV atau VAAPI (hanya Linux) sebagai dekoder perangkat keras. Oleh karena itu, Anda harus memiliki solusi perangkat keras ini dan FFmpeg harus dibangun dengan dukungannya.
Buka aliran video:
avformat_open_input(&input_ctx, filename, NULL, NULL;
Kami mendapatkan informasi tentang aliran video:
av_find_best_stream(input_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
Alokasikan memori:
frame = av_frame_alloc();
Fungsi ini menimpa file yang diterjemahkan dalam RAM:
av_hwframe_transfer_data(sw_frame, frame, 0);
Sedikit tentang format NV12
Jadi, kami mendapat bingkai dalam struktur sw_frame. Bingkai yang diterima disimpan dalam format NV12. Format ini ditemukan oleh Microsoft. Ini memungkinkan Anda untuk menyimpan informasi piksel dalam 12 bit. Di mana 8 bit adalah intensitas, dan 4 bit menggambarkan warna (atau lebih tepatnya, warna segera dijelaskan untuk 4 piksel 2x2 yang berdekatan). Selain itu, sw_frame.data [0] - intensitas disimpan, dan dalam sw_frame.data [1] - warnanya disimpan. Untuk mengkonversi dari NV-12 ke RGB, Anda dapat menggunakan fungsi berikut:
Terjemahan C ++ dari NV12 ke RGB void SaveFrame(uint8_t * f1, uint8_t * f2, int iFrame) { FILE *pFile; char szFilename[32]; int x, i, j;
Meskipun bekerja dengan NV12 memungkinkan Anda untuk mempercepat implementasi prosedur seperti kabur, Retinex dan mendapatkan gambar dalam skala abu-abu (hanya dengan membuang warnanya). Dalam tugas saya, saya tidak menerjemahkan format NV12 ke RGB, karena ini membutuhkan waktu ekstra.
Jadi kami belajar cara memecahkan kode file video di perangkat keras dan menampilkannya di jendela. Kami bertemu dalam format NV12 dan bagaimana mengubahnya menjadi RGB yang sudah dikenal.
Decoding hardware Dll
FFmpeg mengeluarkan frame setelah 40 ms (pada 25 frame per detik). Sebagai aturan, memproses bingkai Full HD membutuhkan waktu lebih lama. Ini membutuhkan multithreading untuk memaksimalkan beban keempat inti prosesor. Dalam praktiknya, saya memulai 6 utas sekali dan tidak menghapusnya lagi, yang sangat menyederhanakan pekerjaan dan meningkatkan keandalan program. Skema operasi ditunjukkan pada Gambar. 1
Gambar. 1 Skema membangun program multi-berulir dengan FFmpegSaya menulis dekoder saya sebagai
* .dll (FFmpegD.DLL) untuk dimasukkan dalam proyek saya. Ini memungkinkan Anda untuk mengurangi kode proyek, yang meningkatkan pemahaman kode dan memasukkannya ke dalam bahasa pemrograman apa pun, hingga Assembler (diverifikasi :)). Dengan menggunakannya, kami akan menulis stream player RTSP kami dari kamera IP.
Untuk mulai bekerja dengan DLL, Anda perlu meneruskan pointer ke array [13] int, HANDLE dari acara kedatangan bingkai baru, HANDLE untuk mulai memproses paket data baru dari kamera, dan array array kamera.
Struktur array diberikan dalam tabel 1.

Sebelum menelepon, Anda harus mengatur ulang nomor bingkai 1-4.
DLL akan mengambil semua langkah yang diperlukan untuk menginisialisasi FFmpeg dan akan merekam pointer dan nomor bingkai. Setelah itu menetapkan acara "Kedatangan bingkai baru". Anda hanya perlu memproses frame yang masuk dan menulis 0 alih-alih nomor frame (ini berarti frame telah diproses dan tidak lagi digunakan).
Di bawah ini Anda akan menemukan contoh pemain dengan kode sumber. Contohnya adalah ShowDib3 Charles Petzold.
→
Arsipkan dengan proyek→
Arsip FFmpegD.dllHASIL: Detektor gerak perangkat keras FFmpeg bahkan pada Intel Atom Z8350 mendekodekan h264 Full HD secara real time dengan pemuatan prosesor hingga 20% dengan detektor gerakan yang terhubung.
Contoh Pengoperasian Motion Detector pada Intel ATOM Z8350. 30 detik pertama adalah perhitungan latar belakang. Setelah itu, detektor gerak bekerja dengan metode pengurangan latar belakang.PS Anda juga dapat mendekode file video (terkompresi h.264) !!!
Referensi:
- Informasi bermanfaat lain-lain tentang FFmpeg
- Informasi tentang penggunaan berbagai perpustakaan yang disediakan oleh FFmpeg
- Informasi tentang format dan konversi ke RGB