正在显示
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. |
-
请 注册 或 登录 后发表评论