我正在使用本机的h264 API在Android上通过RTMP播放视频、MediaCodec视频和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的SEI类,我可以看到我的SEI消息被正确地解析了。我使用用于LibRtmp的Android包装器将这些数据包写入RTMP流。
尽管如此,ff探头并没有显示方位元数据,而且播放时的视频仍然在风景中。
在这一点上,我想我遗漏了一个非常小的细节,当原始的h264单元由LibRtmp写出时,FLV头是如何工作的。我尝试过附加这个displayOrientationSEI NAL单元:
我做错了什么?通过一些RTMP库的源代码,如rtmp-rtsp流-客户端-java,似乎在创建FLV标记时删除了SEI消息。
帮助是非常非常感谢的。
发布于 2020-05-29 20:24:27
RTMP是否支持h264流中的显示方向SEI消息?
RTMP不知道这个概念。从RTMPs的角度来看,SEI只是它所处理的一系列字节。它从不看他们,也不解析他们。
需要支持它的是h.264解码器( RTMP也不知道)和播放器软件。如果它不适合您,您必须检查播放机,或编码SEI的有效性,而不是传输。
https://stackoverflow.com/questions/62089397
复制相似问题