Compartir tecnología

¿Cómo reproducen los auriculares VR transmisiones 8K RTSP|RTMP con baja latencia?

2024-07-12

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

experiencia técnica

Cuando estábamos fabricando reproductores RTSP y RTMP para la plataforma Unity, algunas empresas presentaron tales requisitos técnicos, con la esperanza de reproducir transmisiones en vivo panorámicas 8K RTSP|RTMP y datos 8K en los auriculares, lo que propuso nuevas ideas para los auriculares y el reproductor. los requisitos, analizaremos cómo los dispositivos VR montados en la cabeza reproducen datos de transmisión 8K RTSP|RTMP desde varios aspectos:

1. Soporte al jugador

  1. compatibilidad : En primer lugar, el reproductor RTSP|RTMP debe admitir la transmisión de vídeo con resolución de 8K. Esto significa que el reproductor debe poder decodificar videos de 8K y reproducirlos en un dispositivo de visualización que admita una resolución de 8K. No hace falta decir que ya lo admitimos.
  2. capacidad de decodificación : El reproductor debe tener potentes capacidades de decodificación para manejar la gran cantidad de datos en la transmisión de video de 8K. Esto generalmente requiere que el reproductor utilice algoritmos de decodificación eficientes y haga un uso completo de las funciones de aceleración de hardware (como la aceleración de GPU), lo que requiere que los auriculares admitan la decodificación física de 8K.

2. Requisitos de red

  1. banda ancha : La transmisión de vídeo de 8K requiere un ancho de banda de red extremadamente alto para admitir la transmisión en tiempo real. Asegúrese de que el ancho de banda de la red sea lo suficientemente grande para evitar problemas como retrasos, demoras o almacenamiento en búfer durante la reproducción. Si se trata de un entorno de intranet, básicamente no se preocupe por los problemas de ancho de banda.
  2. estabilidad : La estabilidad de la conexión de red también es muy importante. Una conexión de red inestable puede provocar que la transmisión de vídeo se interrumpa o se degrade su calidad.

3. Requisitos de hardware

  1. Procesador y memoria: Los cascos de realidad virtual reproducen transmisiones de video de 8K, lo que impone requisitos muy altos en el rendimiento de los cascos de realidad virtual. Por ejemplo, quest3 es una buena opción.

4. Pasos de reproducción

  1. Seleccionar reproductor RTSP: Nuestro enfoque es utilizar el reproductor RTSP|RTMP nativo de Daniu Live SDK en modo de decodificación dura para devolver los datos YUV o RGB decodificados a la unidad. Cabe señalar que debido a la transmisión 8K RTSP|RTMP, la cantidad de datos. Datos muy grandes, especialmente datos decodificados, es necesario reducir las copias lo menos posible si las condiciones lo permiten.

Realización técnica

Este artículo toma como ejemplo el módulo de reproducción Unity3D RTSP|RTMP de la plataforma Android de Daniu Live SDK:

Empieza a jugar:

  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. }

La implementación correspondiente de OpenPlayer() es la siguiente:

  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. }

Cerrar jugador:

  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. }

Actualizar datos de actualización:

  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. }

Resumir

Si un visor de realidad virtual necesita reproducir transmisiones RTSP o RTSP de 8K, tiene requisitos muy altos de hardware y red, por lo que puede encontrar algunos desafíos en las aplicaciones prácticas. A través de pruebas reales, los auriculares quest3, combinados con nuestro reproductor RTSP|RTMP, pueden lograr un retraso de milisegundos en la reproducción de datos de video de 8K en Unity para cumplir con escenarios de uso con requisitos de tiempo real muy altos, como el control de equilibrio. Los desarrolladores interesados ​​pueden discutir esto. conmigo individualmente.