mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Merge branch 'srs.master'
This commit is contained in:
commit
a48ce99a31
3 changed files with 43 additions and 46 deletions
|
@ -37,26 +37,30 @@ gcc srs_h264_raw_publish.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_h
|
||||||
|
|
||||||
#define srs_trace(msg, ...) printf(msg, ##__VA_ARGS__);printf("\n")
|
#define srs_trace(msg, ...) printf(msg, ##__VA_ARGS__);printf("\n")
|
||||||
|
|
||||||
int read_h264_frame(char* data, int size, char** p, int fps,
|
int read_h264_frame(char* data, int size, char** pp, int fps,
|
||||||
char** frame, int* frame_size, int* dts, int* pts)
|
char** frame, int* frame_size, int* dts, int* pts)
|
||||||
{
|
{
|
||||||
|
char* p = *pp;
|
||||||
|
|
||||||
// @remark, for this demo, to publish h264 raw file to SRS,
|
// @remark, for this demo, to publish h264 raw file to SRS,
|
||||||
// we search the h264 frame from the buffer which cached the h264 data.
|
// we search the h264 frame from the buffer which cached the h264 data.
|
||||||
// please get h264 raw data from device, it always a encoded frame.
|
// please get h264 raw data from device, it always a encoded frame.
|
||||||
int pnb_start_code = 0;
|
int pnb_start_code = 0;
|
||||||
if (!srs_h264_startswith_annexb(*p, size - (*p - data), &pnb_start_code)) {
|
if (!srs_h264_startswith_annexb(p, size - (p - data), &pnb_start_code)) {
|
||||||
srs_trace("h264 raw data invalid.");
|
srs_trace("h264 raw data invalid.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*p += pnb_start_code;
|
p += pnb_start_code;
|
||||||
|
|
||||||
*frame = *p;
|
*frame = p;
|
||||||
for (;*p < data + size; *p = *p + 1) {
|
for (;p < data + size; p++) {
|
||||||
if (srs_h264_startswith_annexb(*p, size - (*p - data), &pnb_start_code)) {
|
if (srs_h264_startswith_annexb(p, size - (p - data), &pnb_start_code)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*frame_size = *p - *frame;
|
|
||||||
|
*pp = p;
|
||||||
|
*frame_size = p - *frame;
|
||||||
if (*frame_size <= 0) {
|
if (*frame_size <= 0) {
|
||||||
srs_trace("h264 raw data invalid.");
|
srs_trace("h264 raw data invalid.");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -157,18 +161,9 @@ int main(int argc, char** argv)
|
||||||
goto rtmp_destroy;
|
goto rtmp_destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert the h264 packet to rtmp packet.
|
// send out the h264 packet over RTMP
|
||||||
char* rtmp_data = NULL;
|
if (srs_write_h264_raw_frame(rtmp, data, size, dts, pts) != 0) {
|
||||||
int rtmp_size = 0;
|
srs_trace("send h264 raw data failed.");
|
||||||
u_int32_t timestamp = 0;
|
|
||||||
if (srs_h264_to_rtmp(data, size, dts, pts, &rtmp_data, &rtmp_size, ×tamp) != 0) {
|
|
||||||
srs_trace("h264 raw data to rtmp data failed.");
|
|
||||||
goto rtmp_destroy;
|
|
||||||
}
|
|
||||||
|
|
||||||
// send out the rtmp packet.
|
|
||||||
int type = SRS_RTMP_TYPE_VIDEO;
|
|
||||||
if (srs_write_packet(rtmp, type, timestamp, rtmp_data, rtmp_size) != 0) {
|
|
||||||
goto rtmp_destroy;
|
goto rtmp_destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +171,7 @@ int main(int argc, char** argv)
|
||||||
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
|
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
|
||||||
u_int8_t nut = (char)data[0] & 0x1f;
|
u_int8_t nut = (char)data[0] & 0x1f;
|
||||||
srs_trace("sent packet: type=%s, time=%d, size=%d, fps=%d, b[0]=%#x(%s)",
|
srs_trace("sent packet: type=%s, time=%d, size=%d, fps=%d, b[0]=%#x(%s)",
|
||||||
srs_type2string(type), timestamp, rtmp_size, fps, nut,
|
srs_type2string(SRS_RTMP_TYPE_VIDEO), dts, size, fps, (char)data[0],
|
||||||
(nut == 7? "SPS":(nut == 8? "PPS":(nut == 5? "I":(nut == 1? "P":"Unknown")))));
|
(nut == 7? "SPS":(nut == 8? "PPS":(nut == 5? "I":(nut == 1? "P":"Unknown")))));
|
||||||
|
|
||||||
// @remark, when use encode device, it not need to sleep.
|
// @remark, when use encode device, it not need to sleep.
|
||||||
|
|
|
@ -996,27 +996,31 @@ char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize)
|
||||||
return any->human_print(pdata, psize);
|
return any->human_print(pdata, psize);
|
||||||
}
|
}
|
||||||
|
|
||||||
int srs_h264_to_rtmp(char* h264_raw_data, int h264_raw_size, u_int32_t dts, u_int32_t pts, char** prtmp_data, int* prtmp_size, u_int32_t* ptimestamp)
|
int srs_write_h264_raw_frame(srs_rtmp_t rtmp, char* frame, int frame_size, u_int32_t dts, u_int32_t pts)
|
||||||
{
|
{
|
||||||
srs_assert(h264_raw_size > 0);
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
// the timestamp in rtmp message header is dts.
|
srs_assert(frame_size > 1);
|
||||||
*ptimestamp = dts;
|
|
||||||
|
srs_assert(rtmp != NULL);
|
||||||
|
Context* context = (Context*)rtmp;
|
||||||
|
|
||||||
|
// 5bits, 7.3.1 NAL unit syntax,
|
||||||
|
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
|
||||||
|
// 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
|
||||||
|
u_int8_t nal_unit_type = (char)frame[0] & 0x1f;
|
||||||
|
|
||||||
|
/*// the timestamp in rtmp message header is dts.
|
||||||
|
u_int32_t timestamp = dts;
|
||||||
|
|
||||||
// for h264 in RTMP video payload, there is 5bytes header:
|
// for h264 in RTMP video payload, there is 5bytes header:
|
||||||
// 1bytes, FrameType | CodecID
|
// 1bytes, FrameType | CodecID
|
||||||
// 1bytes, AVCPacketType
|
// 1bytes, AVCPacketType
|
||||||
// 3bytes, CompositionTime, the cts.
|
// 3bytes, CompositionTime, the cts.
|
||||||
// @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
|
// @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
|
||||||
*prtmp_size = h264_raw_size + 5;
|
int size = h264_raw_size + 5;
|
||||||
char* p = new char[*prtmp_size];
|
char* data = new char[size];
|
||||||
memcpy(p + 5, h264_raw_data, h264_raw_size);
|
memcpy(data + 5, h264_raw_data, h264_raw_size);
|
||||||
*prtmp_data = p;
|
|
||||||
|
|
||||||
// 5bits, 7.3.1 NAL unit syntax,
|
|
||||||
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
|
|
||||||
// 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
|
|
||||||
u_int8_t nal_unit_type = (char)h264_raw_data[0] & 0x1f;
|
|
||||||
|
|
||||||
// Frame Type, Type of video frame.
|
// Frame Type, Type of video frame.
|
||||||
// @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
|
// @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
|
||||||
|
@ -1044,9 +1048,9 @@ int srs_h264_to_rtmp(char* h264_raw_data, int h264_raw_size, u_int32_t dts, u_in
|
||||||
char* pp = (char*)&cts;
|
char* pp = (char*)&cts;
|
||||||
*p++ = pp[2];
|
*p++ = pp[2];
|
||||||
*p++ = pp[1];
|
*p++ = pp[1];
|
||||||
*p++ = pp[0];
|
*p++ = pp[0];*/
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int* pnb_start_code)
|
int srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int* pnb_start_code)
|
||||||
|
|
|
@ -337,24 +337,22 @@ extern char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize);
|
||||||
**************************************************************
|
**************************************************************
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
/**
|
/**
|
||||||
* convert h264 stream data to rtmp packet.
|
* write h.264 raw frame over RTMP to rtmp server.
|
||||||
* @param h264_raw_data the input h264 raw data, a encoded h.264 I/P/B frame data.
|
* @param frame the input h264 raw data, an encoded h.264 I/P/B frame data.
|
||||||
* @paam h264_raw_size the size of h264 raw data. assert > 0.
|
* the frame without h.264 annexb header, by N[00] 00 00 01, where N>=0,
|
||||||
|
* for instance, header(00 00 00 01) + frame(67 42 80 29 95 A0 14 01 6E 40)
|
||||||
|
* @paam frame_size the size of h264 raw data.
|
||||||
|
* assert frame_size > 1, at least has 1 bytes header.
|
||||||
* @param dts the dts of h.264 raw data.
|
* @param dts the dts of h.264 raw data.
|
||||||
* @param pts the pts of h.264 raw data.
|
* @param pts the pts of h.264 raw data.
|
||||||
* @param prtmp_data the output rtmp format packet, which can be send by srs_write_packet.
|
|
||||||
* @param prtmp_size the size of rtmp packet, for srs_write_packet.
|
|
||||||
* @param ptimestamp the timestamp of rtmp packet, for srs_write_packet.
|
|
||||||
*
|
*
|
||||||
* @remark, user should free the h264_raw_data.
|
* @remark, user should free the frame.
|
||||||
* @remark, user should free the prtmp_data if success.
|
|
||||||
* @remark, the tbn of dts/pts is 1/1000 for RTMP, that is, in ms.
|
* @remark, the tbn of dts/pts is 1/1000 for RTMP, that is, in ms.
|
||||||
*
|
*
|
||||||
* @return 0, success; otherswise, failed.
|
* @return 0, success; otherswise, failed.
|
||||||
*/
|
*/
|
||||||
extern int srs_h264_to_rtmp(
|
extern int srs_write_h264_raw_frame(srs_rtmp_t rtmp,
|
||||||
char* h264_raw_data, int h264_raw_size, u_int32_t dts, u_int32_t pts,
|
char* frame, int frame_size, u_int32_t dts, u_int32_t pts
|
||||||
char** prtmp_data, int* prtmp_size, u_int32_t* ptimestamp
|
|
||||||
);
|
);
|
||||||
/**
|
/**
|
||||||
* whether h264 raw data starts with the annexb,
|
* whether h264 raw data starts with the annexb,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue