【问题标题】:Does RTMP support the Display Orientation SEI Message in h264 streams?RTMP 是否支持 h264 流中的显示方向 SEI 消息?
【发布时间】:2020-09-17 05:25:33
【问题描述】:

我正在使用原生 MediaCodec API 在 Android 上通过 RTMP 流式传输视频 h264 视频和 AAC 音频。视频和音频看起来很棒,但是当视频以纵向模式拍摄时,在网络上或使用 VLC 播放时始终是横向的。

通读 h264 规范后,我发现这种额外的元数据可以在补充增强信息 (SEI) 中指定,并且我已经着手将其添加到原始 h264 比特流中。我的 SEI NAL 单元遵循这种基本格式,我计划稍后进行优化:

val displayOrientationSEI = {
    val prefix = byteArrayOf(0, 0, 0, 1)
    val nalHeader = byteArrayOf(6) // forbidden_zero_bit:0; nal_ref_idc:0; nal_unit_type:6 

    val display = byteArrayOf(47 /* Display orientation type*/, 3 /*payload size*/)

    val displayOrientationCancelFlag = "0" // u(1); Rotation information follows
    val horFlip = "1" // hor_flip; u(1); Flip horizontally
    val verFlip = "1" // ver_flip; u(1); Flip vertically
    val anticlockwiseRotation = "0100000000000000" // u(16); value / 2^16 -> 90 degrees
    val displayOrientationRepetitionPeriod = "010" // ue(v); Persistent till next video sequence
    val displayOrientationExtensionFlag = "0" // u(1); No other value is permitted by the spec atm
    val byteAlignment = "1"

    val bitString = displayOrientationCancelFlag +
            horFlip +
            verFlip +
            anticlockwiseRotation +
            displayOrientationRepetitionPeriod +
            displayOrientationExtensionFlag +
            byteAlignment

    prefix + nalHeader + display + BigInteger(bitString, 2).toByteArray()
}()

使用Jcodec's SEI class,我可以看到我的 SEI 消息被正确解析。我使用Android JNI wrapper for LibRtmp 将这些数据包写入 RTMP 流。

尽管如此,ffprobe 不显示方向元数据,并且播放时的视频仍然是横向的。

在这一点上,我想我错过了一个非常小的细节,即当 LibRtmp 写出原始 h264 单元时,FLV 标头如何工作。我试过附加这个displayOrientationSEI NAL 单元:

  1. 仅限初始 SPS 和 PPS 配置。
  2. 直接来自编码器的每个原始 h264 NAL 单元。
  3. 对双方。

我做错了什么?通过一些 RTMP 库的来源,如rtmp-rtsp-stream-client-java,似乎在创建 FLV 标签时删除了 SEI 消息。

非常感谢您的帮助。

【问题讨论】:

    标签: android video-streaming h.264 rtmp


    【解决方案1】:

    RTMP 是否支持 h264 流中的 Display Orientation SEI 消息?

    RTMP 不知道这个概念。从 RTMP 的角度来看,SEI 只是它复制的一系列字节。它从不查看它们,从不解析它们。

    需要支持的是 h.264 解码器(RTMP 也不知道)和播放器软件。如果它不适合您,您必须检查播放器,或编码 SEI 的有效性,而不是传输。

    【讨论】:

    • 明白了,谢谢。似乎将原始 h264 和 AAC 单元复用到 FLV 以用于 RTMP 的库无论出于何种原因都会剥离 SEI。鉴于您的专长,您之前是否曾通过 RMTP 发送过 Display Orientation SEI?通过查看两个用于 Android 的 RTMP 多路复用库的源代码,他们都选择删除 SEI 并在发送视频帧之前手动旋转视频帧。想知道这是否是因为它们是在添加显示方向 SEI 之前编写的。
    • 我现在看到我的问题标题是错误的。我的意思是,FLV 容器格式,尤其是用于通过 RTMP 流式传输的格式,是否支持从它复用的 h264 视频中编码 SEI 消息?我见过的库实现似乎只保留 NAL 单元类型 SPS、PPS、IDR 和 NonIDR;无论出于何种原因,其余的都会被忽略。
    • 再次强调,FLV 没有 SEI 的概念。规范中有注释。 Flv 只是包装了 es。
    • 没有 FLV 容器限制。图书馆不应该改变这一点。我对您正在使用的库一无所知,或者我什至不知道您正在使用什么库。
    • 查看代码,该库也会破坏带有 B 帧的流。这是垃圾代码,不要使用它。
    猜你喜欢
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多