落鹤生:我之前曾做过一个RTMP视频直播(相关介绍及相关下载文件可浏览此处:http://rg4.net/easyrtmp)的小东西,可支持直接从摄像头采集编码,也可直接采集视频采集卡采集视频,,然后发布到FMS/Red5。刚刚发现有人也做了类似的东西。呵呵。以下为其文章。
需要从硬压卡上获取的NALU封装成RTMP协议格式发送给RED5/FMS进行实时发布.
RTMP中传送 H.264使用的视频封装格式既是 FLV规范 中的 VideoTag
Frame Type UB [4]
Type of video frame. The following values are defined:
- 1 = key frame (for AVC, a seekable frame)
- 2 = inter frame (for AVC, a non-seekable frame)
- 3 = disposable inter frame (H.263 only)
- 4 = generated key frame (reserved for server use only)
- 5 = video info/command frame
CodecID UB [4]
Codec Identifier. The following values are defined:
- 2 = Sorenson H.263
- 3 = Screen video
- 4 = On2 VP6
- 5 = On2 VP6 with alpha channel
- 6 = Screen video version 2
- 7 = AVC
AVCPacketType F UI8
The following values are defined:
- 0 = AVC sequence header
- 1 = AVC NALU
- 2 = AVC end of sequence(lower level NALU sequence ender is not required or supported)
CompositionTime SI24
- IF AVCPacketType == 1
- Composition time offset
- ELSE
- 0
See ISO 14496-12, 8.15.3 for an explanation of composition
times. The offset in an FLV file is always in milliseconds.
在第一个RTMP Message的数据包中,需要发送 AVC sequence header , 也就是AVCDecoderConfigurationRecord
其中就包含有Profile / Level / SPS / PPS 等解码需要的信息
然后就开始发送NALU了。
NALU在一个RTMP Message可以发送1个或者多个。
根据 NALU的 reference idc 可以得出 帧类型
- typedef enum {
- NALU_PRIORITY_HIGHEST = 3,
- NALU_PRIORITY_HIGH = 2,
- NALU_PRIORITY_LOW = 1,
- NALU_PRIORITY_DISPOSABLE = 0
- } NaluRefIdc;
-
- typedef enum {
- NALU_PRIORITY_HIGHEST = 3,
- NALU_PRIORITY_HIGH = 2,
- NALU_PRIORITY_LOW = 1,
- NALU_PRIORITY_DISPOSABLE = 0
- } NaluRefIdc;
如果这个 VideoTag中含有 NALU_PRIORITY_HIGHEST 的NALU, 那么它的VideoTag的 Frame Type 应该是 FrameType_KeyFrame
- enum FrameType
- {
- FrameType_KeyFrame = 1,
- FrameType_InterFrame = 2,
- FrameType_DisposableInterFrame = 3,
- FrameType_GeneratedKeyFrame = 4,
- FrameType_VideoInfo = 5,
- };
(wangjia184) |