RTMP 是否支持 h264 流中的 Display Orientation SEI Message?
Does RTMP support the Display Orientation SEI Message in h264 streams?
我正在 Android 使用本机 MediaCodec API 通过 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, I can see that my SEI message is parsed properly. I write out these packets to the RTMP stream using an Android JNI wrapper for LibRtmp.
尽管如此,ffprobe 不会显示方向元数据,并且播放时的视频仍然是横向的。
在这一点上,我想我遗漏了一个非常小的细节,即当原始 h264 单元由 LibRtmp 写出时,FLV headers 是如何工作的。我试过附加这个 displayOrientationSEI
NAL 单元:
- 仅限初始 SPS 和 PPS 配置。
- 每个原始的 h264 NAL 单元直接来自编码器。
- 对两者。
我做错了什么?查看一些 RTMP 库的源代码,例如 rtmp-rtsp-stream-client-java,似乎在创建 FLV 标签时删除了 SEI 消息。
非常感谢您的帮助。
Does RTMP support the Display Orientation SEI Message in h264 streams?
RTMP 并不知道这个概念。从 RTMP 的角度来看,SEI 只是它复制的一系列字节。它从不查看它们,从不解析它们。
需要支持的是h.264解码器(RTMP也不知道)和播放器软件。如果它不适合您,您必须检查播放器或编码的 SEI 的有效性,而不是传输。
我正在 Android 使用本机 MediaCodec API 通过 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, I can see that my SEI message is parsed properly. I write out these packets to the RTMP stream using an Android JNI wrapper for LibRtmp.
尽管如此,ffprobe 不会显示方向元数据,并且播放时的视频仍然是横向的。
在这一点上,我想我遗漏了一个非常小的细节,即当原始 h264 单元由 LibRtmp 写出时,FLV headers 是如何工作的。我试过附加这个 displayOrientationSEI
NAL 单元:
- 仅限初始 SPS 和 PPS 配置。
- 每个原始的 h264 NAL 单元直接来自编码器。
- 对两者。
我做错了什么?查看一些 RTMP 库的源代码,例如 rtmp-rtsp-stream-client-java,似乎在创建 FLV 标签时删除了 SEI 消息。
非常感谢您的帮助。
Does RTMP support the Display Orientation SEI Message in h264 streams?
RTMP 并不知道这个概念。从 RTMP 的角度来看,SEI 只是它复制的一系列字节。它从不查看它们,从不解析它们。
需要支持的是h.264解码器(RTMP也不知道)和播放器软件。如果它不适合您,您必须检查播放器或编码的 SEI 的有效性,而不是传输。