Berbagi teknologi

Bagaimana headset VR memutar streaming 8K RTSP|RTMP dengan latensi rendah?

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

latar belakang teknis

Saat kami membuat pemutar RTSP dan RTMP untuk platform Unity, beberapa perusahaan mengajukan persyaratan teknis tersebut, berharap dapat memutar streaming langsung panorama 8K RTSP|RTMP dan data 8K di headset, yang mengusulkan ide-ide baru untuk headset dan pemutar persyaratannya, kita akan membahas bagaimana perangkat VR yang dipasang di kepala memutar data streaming 8K RTSP|RTMP dari beberapa aspek:

1. Dukungan pemain

  1. kesesuaian : Pertama, pemutar RTSP|RTMP harus mendukung streaming video resolusi 8K. Artinya, pemutar harus dapat memecahkan kode video 8K dan memutarnya di perangkat layar yang mendukung resolusi 8K.
  2. kemampuan decoding : Pemutar harus memiliki kemampuan decoding yang kuat untuk menangani data dalam jumlah besar dalam aliran video 8K. Hal ini biasanya mengharuskan pemain untuk menggunakan algoritme decoding yang efisien dan memanfaatkan sepenuhnya fungsi akselerasi perangkat keras (seperti akselerasi GPU), yang memerlukan headset untuk mendukung hard decoding 8K.

2. Persyaratan jaringan

  1. lebar pita : Streaming video 8K memerlukan bandwidth jaringan yang sangat tinggi untuk mendukung transmisi waktu nyata. Pastikan bandwidth jaringan cukup besar untuk menghindari masalah seperti kelambatan, penundaan, atau buffering selama pemutaran. Jika ini adalah lingkungan intranet, pada dasarnya jangan khawatir tentang masalah bandwidth.
  2. stabilitas : Stabilitas koneksi jaringan juga sangat penting. Koneksi jaringan yang tidak stabil dapat menyebabkan streaming video terganggu atau kualitasnya menurun.

3. Persyaratan perangkat keras

  1. Prosesor dan memori: Headset VR memutar streaming video 8K, yang memberikan persyaratan sangat tinggi pada kinerja headset VR, misalnya, quest3 adalah pilihan yang baik.

4. Langkah-langkah pemutaran

  1. Pilih pemutar RTSP: Pendekatan kami adalah menggunakan pemutar RTSP|RTMP asli dari Daniu Live SDK dalam mode decoding keras untuk memanggil kembali data YUV atau RGB yang didekode ke kesatuan. Perlu dicatat bahwa karena aliran 8K RTSP|RTMP, jumlah data Sangat besar, terutama data yang didekodekan, salinannya perlu dikurangi sesedikit mungkin jika kondisinya memungkinkan.

Realisasi teknis

Artikel ini mengambil modul pemutaran platform Android Unity3D RTSP|RTMP dari Daniu Live SDK sebagai contoh:

Mulai bermain:

  1. /*
  2. * SmartPlayerAndroidMono.cs
  3. * Author: daniusdk.com
  4. * QQ:89030985
  5. */
  6. public void Play()
  7. {
  8. if (is_running)
  9. {
  10. Debug.Log("已经在播放。。");
  11. return;
  12. }
  13. //获取输入框的url
  14. string url = input_url_.text.Trim();
  15. if (!url.StartsWith("rtmp://") && !url.StartsWith("rtsp://"))
  16. {
  17. videoUrl = "rtsp://admin:[email protected]:554/h264/ch1/main/av_stream";
  18. }
  19. else
  20. {
  21. videoUrl = url;
  22. }
  23. OpenPlayer();
  24. if ( player_handle_ == 0 )
  25. return;
  26. NT_U3D_Set_Game_Object(player_handle_, game_object_);
  27. /* ++ 播放前参数配置可加在此处 ++ */
  28. int is_using_tcp = 0; //TCP/UDP模式设置
  29. NT_U3D_SetRTSPTcpMode(player_handle_, is_using_tcp);
  30. int is_report = 0;
  31. int report_interval = 1;
  32. NT_U3D_SetReportDownloadSpeed(player_handle_, is_report, report_interval); //下载速度回调
  33. NT_U3D_SetBuffer(player_handle_, play_buffer_time_); //设置buffer time
  34. NT_U3D_SetPlayerLowLatencyMode(player_handle_, is_low_latency_ ? 1 : 0); //设置是否启用低延迟模式
  35. NT_U3D_SetMute(player_handle_, is_mute_ ? 1 : 0); //是否启动播放的时候静音
  36. NT_U3D_SetAudioVolume(player_handle_, cur_audio_volume_); //设置播放音量
  37. NT_U3D_SetVideoDecoderMode(player_handle_, is_hw_decode_ ? 1 : 0); //设置H.264软硬解模式
  38. NT_U3D_SetVideoHevcDecoderMode(player_handle_, is_hw_decode_ ? 1 : 0); //设置H.265软硬解模式
  39. int is_output = 1;
  40. int disable_use_image_planes = 0;
  41. bool is_supports_texture_format = SystemInfo.SupportsTextureFormat(TextureFormat.RG16);
  42. Debug.Log("is_supports_texture_format: " + is_supports_texture_format);
  43. int is_supported_multiple_format = is_supports_texture_format? 1:0;
  44. int max_images = 3;
  45. int buffer_pool_max_size = 0;
  46. NT_U3D_SetImageReaderOutput(player_handle_, is_output, disable_use_image_planes, is_supported_multiple_format, max_images, buffer_pool_max_size); //硬解码image reader
  47. int is_fast_startup = 1;
  48. NT_U3D_SetFastStartup(player_handle_, is_fast_startup); //设置快速启动模式
  49. int rtsp_timeout = 10;
  50. NT_U3D_SetRTSPTimeout(player_handle_, rtsp_timeout); //设置RTSP超时时间
  51. int is_auto_switch_tcp_udp = 1;
  52. NT_U3D_SetRTSPAutoSwitchTcpUdp(player_handle_, is_auto_switch_tcp_udp); //设置TCP/UDP模式自动切换
  53. int is_audiotrack = 1;
  54. NT_U3D_SetAudioOutputType(player_handle_, is_audiotrack); //设置音频输出模式: if 0: 自动选择; if with 1: audiotrack模式
  55. NT_U3D_SetUrl(player_handle_, videoUrl);
  56. /* -- 播放前参数配置可加在此处 -- */
  57. int flag = NT_U3D_StartPlay(player_handle_);
  58. if (flag == DANIULIVE_RETURN_OK)
  59. {
  60. is_need_get_frame_ = true;
  61. Debug.Log("播放成功");
  62. }
  63. else
  64. {
  65. is_need_get_frame_ = false;
  66. Debug.LogError("播放失败");
  67. }
  68. is_running = true;
  69. }

Implementasi OpenPlayer() yang sesuai adalah sebagai berikut:

  1. private void OpenPlayer()
  2. {
  3. if ( java_obj_cur_activity_ == null )
  4. {
  5. Debug.LogError("getApplicationContext is null");
  6. return;
  7. }
  8. player_handle_ = NT_U3D_Open();
  9. if (player_handle_ != 0)
  10. Debug.Log("open success");
  11. else
  12. Debug.LogError("open fail");
  13. }

Tutup Pemain:

  1. private void ClosePlayer()
  2. {
  3. is_need_get_frame_ = false;
  4. is_need_init_texture_ = false;
  5. int flag = NT_U3D_StopPlay(player_handle_);
  6. if (flag == DANIULIVE_RETURN_OK)
  7. {
  8. Debug.Log("停止成功");
  9. }
  10. else
  11. {
  12. Debug.LogError("停止失败");
  13. }
  14. flag = NT_U3D_Close(player_handle_);
  15. if (flag == DANIULIVE_RETURN_OK)
  16. {
  17. Debug.Log("关闭成功");
  18. }
  19. else
  20. {
  21. Debug.LogError("关闭失败");
  22. }
  23. player_handle_ = 0;
  24. NT_U3D_UnInit();
  25. is_running = false;
  26. video_format_ = VideoFrame.FORMAT_UNKNOWN;
  27. video_width_ = 0;
  28. video_height_ = 0;
  29. }

Perbarui data penyegaran:

  1. private void Update()
  2. {
  3. if (!is_need_get_frame_)
  4. return;
  5. if (player_handle_ == 0)
  6. return;
  7. AndroidJavaObject u3d_video_frame_obj = NT_U3D_GetVideoFrame(player_handle_);
  8. if (u3d_video_frame_obj == null)
  9. {
  10. return;
  11. }
  12. VideoFrame converted_video_frame = ConvertToVideoFrame(u3d_video_frame_obj);
  13. if (converted_video_frame == null)
  14. {
  15. u3d_video_frame_obj.Call("release");
  16. u3d_video_frame_obj = null;
  17. return;
  18. }
  19. if (!is_need_init_texture_)
  20. {
  21. if (converted_video_frame.format_ != video_format_)
  22. {
  23. is_need_init_texture_ = true;
  24. }
  25. else if (converted_video_frame.width_ != video_width_
  26. || converted_video_frame.height_ != video_height_
  27. || converted_video_frame.stride0_ != y_row_bytes_
  28. || converted_video_frame.stride1_ != u_row_bytes_
  29. || converted_video_frame.stride2_ != v_row_bytes_)
  30. {
  31. is_need_init_texture_ = true;
  32. }
  33. }
  34. if (is_need_init_texture_)
  35. {
  36. if (InitYUVTexture(converted_video_frame))
  37. {
  38. is_need_init_texture_ = false;
  39. }
  40. }
  41. UpdateYUVTexture(converted_video_frame);
  42. converted_video_frame.java_frame_obj_ = null;
  43. converted_video_frame = null;
  44. u3d_video_frame_obj.Call("release");
  45. u3d_video_frame_obj = null;
  46. }

Meringkaskan

Jika headset VR perlu memutar streaming 8K RTSP atau RTSP, headset tersebut memiliki persyaratan perangkat keras dan jaringan yang sangat tinggi, sehingga mungkin menghadapi beberapa tantangan dalam aplikasi praktis. Melalui pengujian sebenarnya, headset quest3, dikombinasikan dengan pemutar RTSP|RTMP kami, dapat mencapai penundaan pemutaran data video 8K tingkat milidetik di Unity untuk memenuhi skenario penggunaan dengan persyaratan waktu nyata yang sangat tinggi seperti kontrol keseimbangan dengan saya secara individu.