Meluncurkan Netflix di TV dan dekoder. Ekstra 40 milidetik

Aplikasi Netflix berjalan di ratusan smart TV, stick, dan dekoder. Saya adalah salah satu teknisi yang membantu produsen menjalankan aplikasi kami di perangkat mereka. Pada artikel ini, kita akan membahas masalah yang sangat sulit yang mencegah satu set-top box memasuki pasar Eropa.



Masalah misterius



Pada akhir 2017, saya mendapat telepon untuk membahas masalah aplikasi Netflix di dekoder baru. Itu adalah TV Android berkemampuan 4K baru berdasarkan Android Open Source Project (AOSP) versi 5.0, Lollipop. Saya bekerja di Netflix selama beberapa tahun dan membantu meluncurkan beberapa perangkat, tetapi ini adalah TV Android pertama saya.



Keempat pihak saling berhubungan: sebuah perusahaan TV berbayar Eropa yang besar yang meluncurkan perangkat (operator), integrator firmware (integrator), pemasok system-on-a-chip (pemasok chip), dan saya sendiri (Netflix).



Integrator dan Netflix telah menyelesaikan proses sertifikasi ketat Netflix, tetapi selama pengujian internal dengan operator, seorang eksekutif perusahaan melaporkan masalah serius: Pemutaran Netflix terlambat, artinya video diputar dalam waktu yang sangat singkat, lalu dijeda, lalu dijeda, lalu dijeda. Ini tidak selalu terjadi, tetapi mulai lambat beberapa hari setelah menyalakan konsol. Mereka menunjukkan videonya, terlihat mengerikan.



Integrator menemukan cara untuk mereproduksi masalah: meluncurkan Netflix beberapa kali, memulai pemutaran, lalu kembali ke UI. Mereka menyediakan skrip untuk mengotomatiskan proses tersebut. Terkadang butuh waktu hingga lima menit, tetapi skrip selalu mereproduksi bug dengan andal.



Sementara itu, seorang insinyur di pemasok chip mendiagnosis penyebab utama: aplikasi Netflix Android TV bernama Ninja tidak dapat mengirimkan data audio. Kelambatan disebabkan oleh kekurangan produksi pada pipeline audio hardware. Pemutaran berhenti saat decoder menunggu sebagian dari streaming audio dari Ninja, lalu dilanjutkan saat data baru tiba. Integrator, pemasok chip, dan operator semuanya menganggap masalahnya sudah jelas. Dan mereka semua menatap saya: Netflix, ada bug di aplikasi Anda dan Anda harus memperbaikinya. Saya mendengar ketegangan dalam suara perwakilan operator. Rilis perangkat ditunda dan melebihi anggaran, dan mereka mengharapkan hasil dari saya.



Penyelidikan



Saya skeptis. Aplikasi Ninja yang sama ini berjalan di jutaan perangkat Android TV, termasuk smart TV dan dekoder lainnya. Jika ada bug di Ninja, mengapa hanya terjadi di perangkat ini?



Saya mulai dengan mereplikasi masalah sendiri menggunakan skrip dari integrator. Saya menghubungi seorang kolega dari produsen chip dan bertanya apakah dia telah melihat yang seperti ini (tidak terlihat). Kemudian saya mulai mempelajari kode sumber Ninja. Itu perlu untuk menemukan kode yang tepat yang bertanggung jawab untuk pengiriman data audio. Saya menemukan banyak hal, tetapi saya mulai tersesat dalam kode yang bertanggung jawab untuk bermain, dan saya membutuhkan bantuan.



Saya naik ke atas dan menemukan insinyur yang menulis pipa audio dan video Ninja, dia memperkenalkan saya pada kodenya. Setelah itu, saya sendiri mempelajarinya beberapa lama untuk akhirnya memahami bagian utama dan menambahkan log saya sendiri. Aplikasi Netflix rumit, tetapi dengan cara yang disederhanakan, aplikasi ini mengambil data dari server Netflix, menyangga data video dan audio di perangkat selama beberapa detik, lalu mengirimkan bingkai video dan audio satu per satu ke dekoder perangkat keras.





Angka: 1. Saluran pemutaran yang disederhanakan



Mari kita bahas sejenak tentang saluran audio / video di aplikasi Netflix. Sebelum "buffer dekoder", ini persis sama di setiap dekoder dan TV, tetapi memindahkan data A / V ke buffer dekoder perangkat adalah prosedur khusus perangkat. Ini berjalan di utasnya sendiri. Tujuan dari prosedur ini adalah untuk menjaga buffer dekoder tetap penuh dengan memanggil frame berikutnya dari data audio atau video melalui Netflix API. Di Ninja, pekerjaan ini dilakukan dengan seutas benangAndroid. Ada mesin status sederhana dan beberapa logika untuk menangani berbagai status pemutaran, tetapi pada pemutaran normal, streaming menyalin satu frame data ke API pemutaran Android, lalu memberi tahu penjadwal thread untuk menunggu 15 md sebelum panggilan penangan berikutnya. Saat Anda membuat utas Android, Anda bisa meminta utas untuk memulai ulang seperti putaran, tetapi penjadwal utas Android-lah yang memanggil penangan, bukan aplikasi Anda sendiri.



Pada maksimum 60 FPS, perangkat harus menampilkan bingkai baru setiap 16,66 md, jadi memeriksa setelah 15 md sudah cukup. Karena integrator menentukan bahwa masalahnya ada di aliran audio, saya fokus pada penangan khusus yang mengirimkan sampel audio ke layanan audio Android.



Perlu dipahami dari mana datangnya kelambanan, yaitu keterlambatan. Saya berasumsi bahwa beberapa fungsi yang dipanggil oleh handler adalah penyebabnya, jadi saya menyebarkan pesan log ke seluruh handler dan akan dengan mudah menemukan kode yang menyebabkan lag. Segera menjadi jelas bahwa tidak ada yang salah dengan penangan, dan itu berjalan selama beberapa milidetik bahkan saat pemutaran lambat.



Ya, wawasan



Pada akhirnya, saya fokus pada tiga angka: baud rate, waktu panggilan handler, dan waktu untuk mentransfer kontrol dari handler kembali ke Android. Saya menulis skrip untuk mengurai output log dan menghasilkan grafik di bawah ini yang menunjukkan responsnya. Angka: 2. Visualisasi bandwidth streaming audio dan pengaturan waktu penangan Garis oranye adalah kecepatan perjalanan data dari buffering streaming ke sistem audio Android (byte per milidetik). Ada tiga skenario berbeda dalam diagram ini:













  1. Dua area dengan puncak tinggi, di mana kecepatan data mencapai 500 byte per milidetik. Fase ini melakukan buffering sebelum memulai pemutaran. Pawang menyalin data secepat mungkin.

  2. — . 45 .

  3. , 10 . .


Kesimpulan yang tak terhindarkan: Garis oranye menegaskan kesimpulan insinyur dari perusahaan chip. Memang, Ninja tidak cukup cepat untuk mengirimkan data audio.



Untuk memahami alasannya, mari kita lihat lebih dekat garis kuning dan abu-abu.



Garis kuning menunjukkan waktu yang dihabiskan dalam prosedur penangan itu sendiri, dihitung dari stempel waktu yang tercatat di awal dan di akhir prosedur. Di area normal dan tertinggal, waktu di pawang sama: sekitar 2 md. Beruntun menunjukkan kasus saat waktu lebih lambat karena tugas lain yang dilakukan di perangkat.



Akar penyebab sebenarnya



Garis abu-abu - waktu antara panggilan ke pawang - menceritakan kisah yang berbeda. Pada pemutaran normal, penangan dipanggil kira-kira setiap 15 md. Dalam kasus kelambatan di sebelah kanan, penangan dipanggil kira-kira setiap 55 md. Ada tambahan 40 md di antara panggilan, dan dalam situasi seperti itu ia tidak dapat mengikuti pemutaran. Tapi kenapa?



Saya melaporkan penemuan saya ke integrator dan pemasok chip (lihat, penjadwal utas Android yang harus disalahkan!), Tetapi mereka tetap bersikeras bahwa Netflix harus menyelesaikan masalah. Mengapa tidak menyalin lebih banyak data setiap kali penangan dipanggil? Itu adalah kritik yang adil, tetapi menerapkan perilaku ini akan memerlukan perubahan besar yang tidak ingin saya lakukan, jadi saya terus mencari akar masalahnya. Saya menyelami kode sumber Android dan menemukan bahwa utas Android adalah konstruksi ruang pengguna dan penjadwal utas menggunakan panggilan sistem untuk menyinkronkan epoll()



. Saya tahu kinerja epoll()



tidak dijamin, jadi saya curiga ada sesuatu yang secara sistematis memengaruhinya.



Pada titik ini, saya diselamatkan oleh teknisi lain dari pemasok chip yang menemukan bug yang telah diperbaiki di versi Android berikutnya (Marshmallow). Ternyata penjadwal utas Android mengubah perilaku utas bergantung pada apakah aplikasi berjalan di latar depan atau di latar belakang. Untaian latar belakang diberi tambahan latensi 40 mdtk (40.000.000 ns).



Bug jauh di dalam kernel Android berarti bahwa nilai timer tambahan ini bertahan saat utas dikedepankan. Biasanya, utas prosesor audio dibuat saat aplikasi berada di latar depan, tetapi terkadang sedikit lebih awal saat Ninja masih di latar belakang. Jika ini terjadi, pemutaran akan mulai lambat.



Pelajaran



Ini bukan bug terakhir yang kami perbaiki di platform Android, tetapi yang paling sulit dilacak. Itu di luar aplikasi Netflix dan bahkan di luar jalur pemutaran, dan semua data mentah menunjukkan kesalahan di aplikasi Netflix itu sendiri.



Ceritanya menggambarkan aspek pekerjaan saya yang saya sukai: tidak mungkin untuk memprediksi semua masalah yang akan dilontarkan mitra kami kepada saya. Dan saya tahu bahwa menyelesaikannya membutuhkan pemahaman banyak sistem, bekerja dengan kolega yang hebat, dan terus mendorong diri Anda sendiri untuk mempelajari hal-hal baru. Apa yang saya lakukan berdampak langsung pada orang-orang nyata dan kesenangan mereka terhadap produk hebat. Ketika orang-orang menikmati menonton Netflix di ruang tamu mereka, saya tahu saya adalah bagian dari tim yang mewujudkannya.



All Articles