正在显示
5 个修改的文件
包含
64 行增加
和
19 行删除
@@ -37,7 +37,7 @@ gcc srs_h264_raw_publish.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_h | @@ -37,7 +37,7 @@ gcc srs_h264_raw_publish.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_h | ||
37 | 37 | ||
38 | #define srs_trace(msg, ...) printf(msg, ##__VA_ARGS__);printf("\n") | 38 | #define srs_trace(msg, ...) printf(msg, ##__VA_ARGS__);printf("\n") |
39 | 39 | ||
40 | -int read_h264_frame(char* data, int size, char** pp, int fps, | 40 | +int read_h264_frame(char* data, int size, char** pp, int* pnb_start_code, int fps, |
41 | char** frame, int* frame_size, int* dts, int* pts) | 41 | char** frame, int* frame_size, int* dts, int* pts) |
42 | { | 42 | { |
43 | char* p = *pp; | 43 | char* p = *pp; |
@@ -45,8 +45,7 @@ int read_h264_frame(char* data, int size, char** pp, int fps, | @@ -45,8 +45,7 @@ int read_h264_frame(char* data, int size, char** pp, int fps, | ||
45 | // @remark, for this demo, to publish h264 raw file to SRS, | 45 | // @remark, for this demo, to publish h264 raw file to SRS, |
46 | // we search the h264 frame from the buffer which cached the h264 data. | 46 | // we search the h264 frame from the buffer which cached the h264 data. |
47 | // please get h264 raw data from device, it always a encoded frame. | 47 | // please get h264 raw data from device, it always a encoded frame. |
48 | - int pnb_start_code = 0; | ||
49 | - if (!srs_h264_startswith_annexb(p, size - (p - data), &pnb_start_code)) { | 48 | + if (!srs_h264_startswith_annexb(p, size - (p - data), pnb_start_code)) { |
50 | srs_trace("h264 raw data invalid."); | 49 | srs_trace("h264 raw data invalid."); |
51 | return -1; | 50 | return -1; |
52 | } | 51 | } |
@@ -55,10 +54,10 @@ int read_h264_frame(char* data, int size, char** pp, int fps, | @@ -55,10 +54,10 @@ int read_h264_frame(char* data, int size, char** pp, int fps, | ||
55 | // each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0, | 54 | // each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0, |
56 | // for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40) | 55 | // for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40) |
57 | *frame = p; | 56 | *frame = p; |
58 | - p += pnb_start_code; | 57 | + p += *pnb_start_code; |
59 | 58 | ||
60 | for (;p < data + size; p++) { | 59 | for (;p < data + size; p++) { |
61 | - if (srs_h264_startswith_annexb(p, size - (p - data), &pnb_start_code)) { | 60 | + if (srs_h264_startswith_annexb(p, size - (p - data), NULL)) { |
62 | break; | 61 | break; |
63 | } | 62 | } |
64 | } | 63 | } |
@@ -160,7 +159,10 @@ int main(int argc, char** argv) | @@ -160,7 +159,10 @@ int main(int argc, char** argv) | ||
160 | // @remark, read a frame from file buffer. | 159 | // @remark, read a frame from file buffer. |
161 | char* data = NULL; | 160 | char* data = NULL; |
162 | int size = 0; | 161 | int size = 0; |
163 | - if (read_h264_frame(h264_raw, file_size, &p, fps, &data, &size, &dts, &pts) < 0) { | 162 | + int nb_start_code = 0; |
163 | + if (read_h264_frame(h264_raw, file_size, &p, &nb_start_code, fps, | ||
164 | + &data, &size, &dts, &pts) < 0 | ||
165 | + ) { | ||
164 | srs_trace("read a frame from file buffer failed."); | 166 | srs_trace("read a frame from file buffer failed."); |
165 | goto rtmp_destroy; | 167 | goto rtmp_destroy; |
166 | } | 168 | } |
@@ -173,9 +175,9 @@ int main(int argc, char** argv) | @@ -173,9 +175,9 @@ int main(int argc, char** argv) | ||
173 | 175 | ||
174 | // 5bits, 7.3.1 NAL unit syntax, | 176 | // 5bits, 7.3.1 NAL unit syntax, |
175 | // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. | 177 | // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. |
176 | - u_int8_t nut = (char)data[0] & 0x1f; | ||
177 | - srs_trace("sent packet: type=%s, time=%d, size=%d, fps=%d, b[0]=%#x(%s)", | ||
178 | - srs_type2string(SRS_RTMP_TYPE_VIDEO), dts, size, fps, (char)data[0], | 178 | + u_int8_t nut = (char)data[nb_start_code] & 0x1f; |
179 | + srs_trace("sent packet: type=%s, time=%d, size=%d, fps=%d, b[%d]=%#x(%s)", | ||
180 | + srs_type2string(SRS_RTMP_TYPE_VIDEO), dts, size, fps, nb_start_code, (char)data[nb_start_code], | ||
179 | (nut == 7? "SPS":(nut == 8? "PPS":(nut == 5? "I":(nut == 1? "P":"Unknown"))))); | 181 | (nut == 7? "SPS":(nut == 8? "PPS":(nut == 5? "I":(nut == 1? "P":"Unknown"))))); |
180 | 182 | ||
181 | // @remark, when use encode device, it not need to sleep. | 183 | // @remark, when use encode device, it not need to sleep. |
@@ -531,7 +531,7 @@ int SrsAvcAacCodec::avc_demux_annexb_format(SrsStream* stream, SrsCodecSample* s | @@ -531,7 +531,7 @@ int SrsAvcAacCodec::avc_demux_annexb_format(SrsStream* stream, SrsCodecSample* s | ||
531 | 531 | ||
532 | // get the last matched NALU | 532 | // get the last matched NALU |
533 | while (!stream->empty()) { | 533 | while (!stream->empty()) { |
534 | - if (srs_avc_startswith_annexb(stream, &nb_start_code)) { | 534 | + if (srs_avc_startswith_annexb(stream, NULL)) { |
535 | break; | 535 | break; |
536 | } | 536 | } |
537 | 537 |
@@ -184,6 +184,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -184,6 +184,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
184 | #define ERROR_KERNEL_STREAM_INIT 3038 | 184 | #define ERROR_KERNEL_STREAM_INIT 3038 |
185 | #define ERROR_EDGE_VHOST_REMOVED 3039 | 185 | #define ERROR_EDGE_VHOST_REMOVED 3039 |
186 | #define ERROR_HLS_AVC_TRY_OTHERS 3040 | 186 | #define ERROR_HLS_AVC_TRY_OTHERS 3040 |
187 | +#define ERROR_H264_API_NO_PREFIXED 3041 | ||
187 | 188 | ||
188 | /** | 189 | /** |
189 | * whether the error code is an system control error. | 190 | * whether the error code is an system control error. |
@@ -70,6 +70,10 @@ struct Context | @@ -70,6 +70,10 @@ struct Context | ||
70 | SimpleSocketStream* skt; | 70 | SimpleSocketStream* skt; |
71 | int stream_id; | 71 | int stream_id; |
72 | 72 | ||
73 | + // for h264 raw stream, | ||
74 | + // see: https://github.com/winlinvip/simple-rtmp-server/issues/66#issuecomment-62240521 | ||
75 | + SrsStream raw_stream; | ||
76 | + | ||
73 | Context() { | 77 | Context() { |
74 | rtmp = NULL; | 78 | rtmp = NULL; |
75 | skt = NULL; | 79 | skt = NULL; |
@@ -995,15 +999,6 @@ char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize) | @@ -995,15 +999,6 @@ char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize) | ||
995 | 999 | ||
996 | return any->human_print(pdata, psize); | 1000 | return any->human_print(pdata, psize); |
997 | } | 1001 | } |
998 | - | ||
999 | -int srs_write_h264_raw_frames(srs_rtmp_t rtmp, char* frames, int frames_size, u_int32_t dts, u_int32_t pts) | ||
1000 | -{ | ||
1001 | - int ret = ERROR_SUCCESS; | ||
1002 | - | ||
1003 | - srs_assert(frames_size > 1); | ||
1004 | - | ||
1005 | - srs_assert(rtmp != NULL); | ||
1006 | - Context* context = (Context*)rtmp; | ||
1007 | 1002 | ||
1008 | /*// 5bits, 7.3.1 NAL unit syntax, | 1003 | /*// 5bits, 7.3.1 NAL unit syntax, |
1009 | // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. | 1004 | // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. |
@@ -1051,6 +1046,52 @@ int srs_write_h264_raw_frames(srs_rtmp_t rtmp, char* frames, int frames_size, u_ | @@ -1051,6 +1046,52 @@ int srs_write_h264_raw_frames(srs_rtmp_t rtmp, char* frames, int frames_size, u_ | ||
1051 | *p++ = pp[2]; | 1046 | *p++ = pp[2]; |
1052 | *p++ = pp[1]; | 1047 | *p++ = pp[1]; |
1053 | *p++ = pp[0];*/ | 1048 | *p++ = pp[0];*/ |
1049 | + | ||
1050 | +int srs_write_h264_raw_frame(Context* context, char* frame, int frame_size, u_int32_t dts, u_int32_t pts) | ||
1051 | +{ | ||
1052 | + int ret = ERROR_SUCCESS; | ||
1053 | + return ret; | ||
1054 | +} | ||
1055 | + | ||
1056 | +int srs_write_h264_raw_frames(srs_rtmp_t rtmp, char* frames, int frames_size, u_int32_t dts, u_int32_t pts) | ||
1057 | +{ | ||
1058 | + int ret = ERROR_SUCCESS; | ||
1059 | + | ||
1060 | + srs_assert(frames_size > 1); | ||
1061 | + | ||
1062 | + srs_assert(rtmp != NULL); | ||
1063 | + Context* context = (Context*)rtmp; | ||
1064 | + | ||
1065 | + if ((ret = context->raw_stream.initialize(frames, frames_size)) != ERROR_SUCCESS) { | ||
1066 | + return ret; | ||
1067 | + } | ||
1068 | + | ||
1069 | + // send each frame. | ||
1070 | + while (!context->raw_stream.empty()) { | ||
1071 | + // each frame must prefixed by annexb format. | ||
1072 | + // about annexb, @see H.264-AVC-ISO_IEC_14496-10.pdf, page 211. | ||
1073 | + int pnb_start_code = 0; | ||
1074 | + if (!srs_avc_startswith_annexb(&context->raw_stream, &pnb_start_code)) { | ||
1075 | + return ERROR_H264_API_NO_PREFIXED; | ||
1076 | + } | ||
1077 | + int start = context->raw_stream.pos() + pnb_start_code; | ||
1078 | + | ||
1079 | + // find the last frame prefixed by annexb format. | ||
1080 | + context->raw_stream.skip(pnb_start_code); | ||
1081 | + while (!context->raw_stream.empty()) { | ||
1082 | + if (srs_avc_startswith_annexb(&context->raw_stream, NULL)) { | ||
1083 | + break; | ||
1084 | + } | ||
1085 | + context->raw_stream.skip(1); | ||
1086 | + } | ||
1087 | + int size = context->raw_stream.pos() - start; | ||
1088 | + | ||
1089 | + // send out the frame. | ||
1090 | + char* frame = context->raw_stream.data() + start; | ||
1091 | + if ((ret = srs_write_h264_raw_frame(context, frame, size, dts, pts)) != ERROR_SUCCESS) { | ||
1092 | + return ret; | ||
1093 | + } | ||
1094 | + } | ||
1054 | 1095 | ||
1055 | return ret; | 1096 | return ret; |
1056 | } | 1097 | } |
@@ -342,6 +342,7 @@ extern char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize); | @@ -342,6 +342,7 @@ extern char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize); | ||
342 | * frames can be one or more than one frame, | 342 | * frames can be one or more than one frame, |
343 | * each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0, | 343 | * each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0, |
344 | * for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40) | 344 | * for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40) |
345 | +* about annexb, @see H.264-AVC-ISO_IEC_14496-10.pdf, page 211. | ||
345 | * @paam frames_size the size of h264 raw data. | 346 | * @paam frames_size the size of h264 raw data. |
346 | * assert frames_size > 1, at least has 1 bytes header. | 347 | * assert frames_size > 1, at least has 1 bytes header. |
347 | * @param dts the dts of h.264 raw data. | 348 | * @param dts the dts of h.264 raw data. |
-
请 注册 或 登录 后发表评论