- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如何正确地将 H264 字节流打包到 RTP 数据包中,以便我可以使用 FFMPEG 接收帧?
当我启动 FFMPEG 接收器时,它会输出大量如下错误:
Invalid UE golomb code
[h264 @ 0xd63060] pps_id 3199971767 out of range
[h264 @ 0xd63060] slice type 32 too large at -1
[h264 @ 0xd63060] decode_slice_header error
[h264 @ 0xd63060] non-existing PPS 0 referenced
[h264 @ 0xd63060] decode_slice_header error
[h264 @ 0xd63060] no frame!
[h264 @ 0xd63060] decode_slice_header error
[h264 @ 0xd63060] Unknown NAL code: 0 (0 bits)
[h264 @ 0xd63060] no frame!
[h264 @ 0xd63060] non-existing PPS 0 referenced
这是我使用的 SDP 文件:
c=IN IP4 192.168.2.30
t=0 0
m=video 51372 RTP/AVP 96
a=rtpmap:96 H264/90000
a=recv only
pps_id 错误很奇怪,它好像在寻找下一个 PPS,但找不到它,尽管我尝试将 PPS 嵌入到每个 NALU 中。
我一直在阅读 RFC 6184并试图理解它。但是我觉得我还是不太明白H264和RTP是如何交互的。目前我正在尝试对来自相机的像素进行编码,并通过 RTP 在网络上传输 1920x1080 H264 编码帧,然后由 FFMPEG 接收并解码。我正在用 Java 组装 RTP 和 FU-A header ,并在它们对于 MTU 来说太大时对 NALU 进行分段。
我一直在 Wireshark 中密切关注流,这是我的第一个数据包的输出:
Real-Time Transport Protocol
10.. .... = Version: RFC 1889 Version (2)
..0. .... = Padding: False
...0 .... = Extension: False
.... 0000 = Contributing source identifiers count: 0
1... .... = Marker: True
Payload type: DynamicRTP-Type-96 (96)
Sequence number: 0
Timestamp: 2727179012
Synchronization Source identifier: 0x00000000 (0)
H.264
NAL unit header or first byte of the payload
0... .... = F bit: No bit errors or other syntax violations
.00. .... = Nal_ref_idc (NRI): 0
...0 0000 = Type: Undefined (0)
H264 NAL Unit Payload
我不明白为什么第一个有效负载的 NALU 类型为 0。不过,这是我的第二个数据包:
Real-Time Transport Protocol
10.. .... = Version: RFC 1889 Version (2)
..0. .... = Padding: False
...0 .... = Extension: False
.... 0000 = Contributing source identifiers count: 0
0... .... = Marker: False
Payload type: DynamicRTP-Type-96 (96)
Sequence number: 1
Timestamp: 2727179019
Synchronization Source identifier: 0x00000000 (0)
H.264
FU identifier
0... .... = F bit: No bit errors or other syntax violations
.11. .... = Nal_ref_idc (NRI): 3
...1 1100 = Type: Fragmentation unit A (FU-A) (28)
FU Header
1... .... = Start bit: the first packet of FU-A picture
.0.. .... = End bit: Not the last packet of FU-A picture
..0. .... = Forbidden bit: 0
...0 0101 = Nal_unit_type: Coded slice of an IDR picture (5)
H264 NAL Unit Payload
0000 0000 0000 0000 0000 0000 0000 0001 0110 0101 1011 1000 0000 0100 0000 010. = first_mb_in_slice: 3000762881
.... ...1 = slice_type: P (P slice) (0)
0011 1... = pic_parameter_set_id: 6
所以我认为最后一个数据包是一个 I 帧?这是开始 fragment 和结束 fragment 之间的 fragment :
Real-Time Transport Protocol
10.. .... = Version: RFC 1889 Version (2)
..0. .... = Padding: False
...0 .... = Extension: False
.... 0000 = Contributing source identifiers count: 0
0... .... = Marker: False
Payload type: DynamicRTP-Type-96 (96)
Sequence number: 1
Timestamp: 2727179019
Synchronization Source identifier: 0x00000000 (0)
H.264
FU identifier
0... .... = F bit: No bit errors or other syntax violations
.11. .... = Nal_ref_idc (NRI): 3
...1 1100 = Type: Fragmentation unit A (FU-A) (28)
FU Header
0... .... = Start bit: Not the first packet of FU-A picture
.0.. .... = End bit: Not the last packet of FU-A picture
..0. .... = Forbidden bit: 0
...0 0101 = Nal_unit_type: Coded slice of an IDR picture (5)
当然这里是假定的 I-Frame 的最后一个数据包:
Real-Time Transport Protocol
10.. .... = Version: RFC 1889 Version (2)
..0. .... = Padding: False
...0 .... = Extension: False
.... 0000 = Contributing source identifiers count: 0
1... .... = Marker: True
Payload type: DynamicRTP-Type-96 (96)
Sequence number: 1
Timestamp: 2727179019
Synchronization Source identifier: 0x00000000 (0)
H.264
FU identifier
0... .... = F bit: No bit errors or other syntax violations
.11. .... = Nal_ref_idc (NRI): 3
...1 1100 = Type: Fragmentation unit A (FU-A) (28)
FU Header
0... .... = Start bit: Not the first packet of FU-A picture
.1.. .... = End bit: the last packet of FU-A picture
..0. .... = Forbidden bit: 0
...0 0101 = Nal_unit_type: Coded slice of an IDR picture (5)
现在这是编码器给我的下一个字节的数据包:
Real-Time Transport Protocol
10.. .... = Version: RFC 1889 Version (2)
..0. .... = Padding: False
...0 .... = Extension: False
.... 0000 = Contributing source identifiers count: 0
0... .... = Marker: False
Payload type: DynamicRTP-Type-96 (96)
Sequence number: 2
Timestamp: 2727179089
Synchronization Source identifier: 0x00000000 (0)
H.264
FU identifier
0... .... = F bit: No bit errors or other syntax violations
.11. .... = Nal_ref_idc (NRI): 3
...1 1100 = Type: Fragmentation unit A (FU-A) (28)
FU Header
1... .... = Start bit: the first packet of FU-A picture
.0.. .... = End bit: Not the last packet of FU-A picture
..0. .... = Forbidden bit: 0
...0 0001 = Nal_unit_type: Coded slice of a non-IDR picture (1)
H264 NAL Unit Payload
0000 0000 0000 0000 0000 0000 0000 0001 0110 0001 1110 0000 0010 0000 0001 100. = first_mb_in_slice: 2968522763
.... ...0 0111 .... = slice_type: B (B slice) (6)
.... 0001 110. .... = pic_parameter_set_id: 13
这部分让我感到困惑,当相机静止时,编码器给我越来越小的 NALU 和未定义的类型,我不完全确定为什么下面的数据包会作为一个完整的 NALU 发送到 FFMPEG。
Real-Time Transport Protocol
10.. .... = Version: RFC 1889 Version (2)
..0. .... = Padding: False
...0 .... = Extension: False
.... 0000 = Contributing source identifiers count: 0
1... .... = Marker: True
Payload type: DynamicRTP-Type-96 (96)
Sequence number: 36
Timestamp: 2727180258
Synchronization Source identifier: 0x00000000 (0)
H.264
NAL unit header or first byte of the payload
0... .... = F bit: No bit errors or other syntax violations
.00. .... = Nal_ref_idc (NRI): 0
...0 0000 = Type: Undefined (0)
H264 NAL Unit Payload
我正在使用 Android MediaCodec 编码器,这里是我配置编码器的一些代码:
mediaCodec = MediaCodec.createByCodecName("OMX.Nvidia.h264.encoder");
mediaFormat = MediaFormat.createVideoFormat("video/avc", 1920, 1080);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 125000);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 0);
mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 1920 * 1080);
编码器是给我整个访问单元还是只给我 NALU?
这是我的逻辑:
我觉得我很接近,但它显然不适用于任何 RTP 接收器。我很欣赏关于此事的任何想法或想法。
谢谢,
最佳答案
我终于设法解决了,我的数据包配置不正确。
我什至可以在流的中间启动 FFmpeg,它可以工作!
关于android - 如何将Android MediaCodec编码的H264打包成RTP包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39928847/
我是一名优秀的程序员,十分优秀!