将h.264裸码流推送到RTMP服务器

将h.264裸码流推送到RTMP服务器
// SPS
000000016742802995A014016E40
JI液灌溉系统做任务// PPS
0000000168CE3880
// IFrame
<
// PFrame
<
⼀般可以从IP摄像头的sdk中拿到这种数据,⼀般sdk会使⽤如下接⼝:
int device_read(char** pdata, int* psize, int* pdts, int* ppts);
也有的摄像头没有B帧,所以dts和pts是⼀致的,所以后⾯的时间戳合并成⼀个:
int device_read(char** pdata, int* psize, int* timestamp);
辣椒红素的提取
或者,使⽤回调函数,当摄像头编码出h.264数据时回调这个函数,格式和上⾯的也差不多。
本⽂描述了如何将拿到的h.264数据,通过RTMP协议发布到RTMP服务器,然后使⽤RTMP或者HLS播放。
srs-librtmp
显然发送h.264的数据得使⽤RTMP库,rtmpdump提供的librtmp要求是flv/RTMP格式的数据,⽽srs-librtmp提供了接⼝直接发送h.264数据。
例如:
git clone github/winlinvip/simple-rtmp-server.git
SRS⽬前有两个分⽀,只有SRS2(即master分⽀)提供了h.264裸码流发送的功能,git clone之后要切换到这个分⽀:
cd simple-rtmp-server/trunk
git checkout master
如果你可以使⽤.h和.a库,就可以直接编译srs,可以看到⽣成了.h和.a⽂件:
./configure --disable-all --with-librtmp && make &&
ls -lh objs/include/srs_librtmp.h objs/lib/srs_librtmp.a
如果是需要将srs-librtmp导出成⼀个.h和.cpp⽂件,执⾏下⾯的命令,可以看到⽣成了.h和.cpp⽂件:
./configure --export-librtmp-single=objs/srs-librtmp &&
ls -lh objs/srs-librtmp/srs_librtmp.h objs/srs-librtmp/srs_librtmp.cpp
下⾯就可以编写程序,读取h.264裸码流,然后调⽤srs-librtmp发送出去了。
srs_h264_raw_publish
// SPS
000000016742802995A014016E40
// PPS
0000000168CE3880
// IFrame
<
// PFrame
<
下载这个h.264裸码流⽂件和实例⽂件:
wget raw.githubusercontent/winlinvip/simple-rtmp-server/master/trunk/research/librtmp/srs_h264_raw_publish.c -O objs/srs-librtmp/srs_h264_ wget lease/3rdparty/720p.h264.raw -O objs/srs-librtmp/720p.h264.raw
查看srs-librtmp⽬录,应该是下⾯的结构:
[winlin@dev6 trunk]$ ls -lh  objs/srs-librtmp
total 5.8M
-rw-rw-r-- 1 winlin winlin 5.1M Nov  8 12:39 720p.h264.raw
-rw-rw-r-- 1 winlin winlin  633 Nov 16 10:32 example.c
-rw-rw-r-- 1 winlin winlin  87K Nov 16 10:36 srs_h264_raw_publish.c
-rw-rw-r-- 1 winlin winlin 557K Nov 16 10:32 srs_librtmp.cpp
-rw-rw-r-- 1 winlin winlin  20K Nov 16 10:32 srs_librtmp.h
srs_h264_raw_publish.c读取h.264裸码流后,基本上读取到的就是⼀个⼀个的h.264 annexb格式的包,参考read_h264_frame():
// SPS
000000016742802995A014016E40
// PPS
0000000168CE3880
// IFrame
<
// PFrame
钻孔电视<
连接RTMP和发送的主要函数是:
srs_rtmp_t rtmp = srs_rtmp_create(rtmp_url);
srs_simple_handshake(rtmp);
srs_connect_app("rtmp://127.0.0.1/live/livestream");
srs_publish_stream(rtmp);
while (!EOF) {
read_h264_frame(&data, &size, &dts, &pts);
srs_h264_write_raw_frames(rtmp, data, size, dts, pts);
}
这⼏个函数就可以把h.264裸码流发出去了。
编译和运⾏
若使⽤srs-librtmp导出的单个.h和.cpp⽂件,编译和运⾏命令是:
cd objs/srs-librtmp &&
gcc -g -O0 srs_h264_raw_publish.c srs_librtmp.cpp -o publisher -lstdc++ &&
./publisher ./720p.h264.raw rtmp://ossrs/live/h264.raw
播放的RTMP地址为:rtmp://ossrs/live/h264.raw,打开下⾯的链接即可观看流:
接⼝
其中有⼏个错误可以忽略:
srs_h264_is_dvbsp_error:这个是因为IP摄像头在每个I帧前都插⼊了SPS和PPS,所以在服务器断开重连时,重新调⽤srslibrtmp 的连接和publish函数,不⽤考虑接下来的帧是否是sps和pps。但是RTMP要求第⼀个video包是sps/pps,所以srs-librtmp的srs_h264_write_raw_frame()会忽略sps和pps之前的video包,然后返回⼀个错误码,⽤户只要忽略这个错误码即可。
维夫饼干
srs_h264_is_duplicated_sps_error:这个因为IP摄像头在每个I帧前都插⼊sps和pps,这些重复的sps和pps会导致hls频繁的插⼊discontinue信息,所以srs-librtmp只有在sps和pps都变化时才发送新的sequence header包,⽽不是每次都发送。所以sps重复时会返回⼀个错误码,⽤户忽略这个错误即可。
srs_h264_is_duplicated_pps_error:这个和上⾯的错误⼀样,是pps重复,⽤户忽略即可。
⽬前的接⼝声明如下,最新的接⼝声明以代码为准:
/**
* write h.264 raw frame over RTMP to rtmp server.
* @param frames the input h264 raw data, encoded h.264 I/P/B frames data.
*      frames can be one or more than one frame,
*      each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0,
*      for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40)
*      about annexb, @see H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
* @paam frames_size the size of h264 raw data.
*      assert frames_size > 0, at least has 1 bytes header.
* @param dts the dts of h.264 raw data.
* @param pts the pts of h.264 raw data.
*
* @remark, user should free the frames.
* @remark, the tbn of dts/pts is 1/1000 for RTMP, that is, in ms.
* @remark, cts = pts - dts
* @remark, use srs_h264_startswith_annexb to check whether frame is annexb format.
* @example /trunk/research/librtmp/srs_h264_raw_publish.c
* @see github/winlinvip/simple-rtmp-server/issues/66
*
* @return 0, success; otherswise, failed.
*      for dvbsp error, @see srs_h264_is_dvbsp_error().
*      for duplictated sps error, @see srs_h264_is_duplicated_sps_error().
*      for duplictated pps error, @see srs_h264_is_duplicated_pps_error().
*/
/**
For the example file:
winlinvip.github.lease/3rdparty/720p.h264.raw
The data sequence is:
// SPS混合辅助肢体
000000016742802995A014016E40
// PPS
0000000168CE3880
// IFrame
<
// PFrame
<
User can send the SPS+PPS, then each frame:
// SPS+PPS
srs_h264_write_raw_frames('000000016742802995A014016E400000000168CE3880', size, dts, pts)    // IFrame
srs_h264_write_raw_frames('', size, dts, pts)
// PFrame
srs_h264_write_raw_frames('', size, dts, pts) User also can send one by one:
// SPS
srs_h264_write_raw_frames('000000016742802995A014016E4', size, dts, pts)
// PPS
srs_h264_write_raw_frames('00000000168CE3880', size, dts, pts)
// IFrame
srs_h264_write_raw_frames('', size, dts, pts)
// PFrame
srs_h264_write_raw_frames('', size, dts, pts)
*/
extern int srs_h264_write_raw_frames(srs_rtmp_t rtmp,
char* frames, int frames_size, u_int32_t dts, u_int32_t pts
);
/**
* whether error_code is dvbsp(drop video before sps/pps/sequence-header) error.
储物盒
*
* @see github/winlinvip/simple-rtmp-server/issues/203
* @example /trunk/research/librtmp/srs_h264_raw_publish.c
* @remark why drop video?
*      some encoder, for example, ipcamera, will send sps/pps before each IFrame,
*      so, when error and reconnect the rtmp, the first video is not sps/pps(sequence header),
*      this will cause SRS server to disable HLS.
*/
extern srs_h264_bool srs_h264_is_dvbsp_error(int error_code);
/**
* whether error_code is duplicated sps error.
*
* @see github/winlinvip/simple-rtmp-server/issues/204
* @example /trunk/research/librtmp/srs_h264_raw_publish.c
*/
extern srs_h264_bool srs_h264_is_duplicated_sps_error(int error_code);
/**
* whether error_code is duplicated pps error.
*
* @see github/winlinvip/simple-rtmp-server/issues/204
* @example /trunk/research/librtmp/srs_h264_raw_publish.c
*/
extern srs_h264_bool srs_h264_is_duplicated_pps_error(int error_code);
srs-librtmp会将h.264包打包成RTMP包,不⽤⽤户每次都要处理。

本文发布于:2024-09-23 08:26:04,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/2/174950.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:码流   发送   函数
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议