【发布时间】: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 单元:
- 仅限初始 SPS 和 PPS 配置。
- 直接来自编码器的每个原始 h264 NAL 单元。
- 对双方。
我做错了什么?通过一些 RTMP 库的来源,如rtmp-rtsp-stream-client-java,似乎在创建 FLV 标签时删除了 SEI 消息。
非常感谢您的帮助。
【问题讨论】:
标签: android video-streaming h.264 rtmp