正在显示
3 个修改的文件
包含
50 行增加
和
14 行删除
@@ -50,9 +50,13 @@ int read_h264_frame(char* data, int size, char** pp, int fps, | @@ -50,9 +50,13 @@ int read_h264_frame(char* data, int size, char** pp, int fps, | ||
50 | srs_trace("h264 raw data invalid."); | 50 | srs_trace("h264 raw data invalid."); |
51 | return -1; | 51 | return -1; |
52 | } | 52 | } |
53 | - p += pnb_start_code; | ||
54 | 53 | ||
54 | + // @see srs_write_h264_raw_frames | ||
55 | + // 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 | *frame = p; | 57 | *frame = p; |
58 | + p += pnb_start_code; | ||
59 | + | ||
56 | for (;p < data + size; p++) { | 60 | for (;p < data + size; p++) { |
57 | if (srs_h264_startswith_annexb(p, size - (p - data), &pnb_start_code)) { | 61 | if (srs_h264_startswith_annexb(p, size - (p - data), &pnb_start_code)) { |
58 | break; | 62 | break; |
@@ -162,7 +166,7 @@ int main(int argc, char** argv) | @@ -162,7 +166,7 @@ int main(int argc, char** argv) | ||
162 | } | 166 | } |
163 | 167 | ||
164 | // send out the h264 packet over RTMP | 168 | // send out the h264 packet over RTMP |
165 | - if (srs_write_h264_raw_frame(rtmp, data, size, dts, pts) != 0) { | 169 | + if (srs_write_h264_raw_frames(rtmp, data, size, dts, pts) != 0) { |
166 | srs_trace("send h264 raw data failed."); | 170 | srs_trace("send h264 raw data failed."); |
167 | goto rtmp_destroy; | 171 | goto rtmp_destroy; |
168 | } | 172 | } |
@@ -996,21 +996,23 @@ char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize) | @@ -996,21 +996,23 @@ char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize) | ||
996 | return any->human_print(pdata, psize); | 996 | return any->human_print(pdata, psize); |
997 | } | 997 | } |
998 | 998 | ||
999 | -int srs_write_h264_raw_frame(srs_rtmp_t rtmp, char* frame, int frame_size, u_int32_t dts, u_int32_t pts) | 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 | { | 1000 | { |
1001 | int ret = ERROR_SUCCESS; | 1001 | int ret = ERROR_SUCCESS; |
1002 | 1002 | ||
1003 | - srs_assert(frame_size > 1); | 1003 | + srs_assert(frames_size > 1); |
1004 | 1004 | ||
1005 | srs_assert(rtmp != NULL); | 1005 | srs_assert(rtmp != NULL); |
1006 | Context* context = (Context*)rtmp; | 1006 | Context* context = (Context*)rtmp; |
1007 | 1007 | ||
1008 | - // 5bits, 7.3.1 NAL unit syntax, | 1008 | + /*// 5bits, 7.3.1 NAL unit syntax, |
1009 | // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. | 1009 | // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. |
1010 | // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame | 1010 | // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame |
1011 | u_int8_t nal_unit_type = (char)frame[0] & 0x1f; | 1011 | u_int8_t nal_unit_type = (char)frame[0] & 0x1f; |
1012 | 1012 | ||
1013 | - /*// the timestamp in rtmp message header is dts. | 1013 | + // the RTMP packet header |
1014 | + | ||
1015 | + // the timestamp in rtmp message header is dts. | ||
1014 | u_int32_t timestamp = dts; | 1016 | u_int32_t timestamp = dts; |
1015 | 1017 | ||
1016 | // for h264 in RTMP video payload, there is 5bytes header: | 1018 | // for h264 in RTMP video payload, there is 5bytes header: |
@@ -338,21 +338,51 @@ extern char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize); | @@ -338,21 +338,51 @@ extern char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize); | ||
338 | *************************************************************/ | 338 | *************************************************************/ |
339 | /** | 339 | /** |
340 | * write h.264 raw frame over RTMP to rtmp server. | 340 | * write h.264 raw frame over RTMP to rtmp server. |
341 | -* @param frame the input h264 raw data, an encoded h.264 I/P/B frame data. | ||
342 | -* the frame without h.264 annexb header, by N[00] 00 00 01, where N>=0, | ||
343 | -* for instance, header(00 00 00 01) + frame(67 42 80 29 95 A0 14 01 6E 40) | ||
344 | -* @paam frame_size the size of h264 raw data. | ||
345 | -* assert frame_size > 1, at least has 1 bytes header. | 341 | +* @param frames the input h264 raw data, encoded h.264 I/P/B frames data. |
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, | ||
344 | +* for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40) | ||
345 | +* @paam frames_size the size of h264 raw data. | ||
346 | +* assert frames_size > 1, at least has 1 bytes header. | ||
346 | * @param dts the dts of h.264 raw data. | 347 | * @param dts the dts of h.264 raw data. |
347 | * @param pts the pts of h.264 raw data. | 348 | * @param pts the pts of h.264 raw data. |
348 | * | 349 | * |
349 | -* @remark, user should free the frame. | 350 | +* @remark, user should free the frames. |
350 | * @remark, the tbn of dts/pts is 1/1000 for RTMP, that is, in ms. | 351 | * @remark, the tbn of dts/pts is 1/1000 for RTMP, that is, in ms. |
351 | * | 352 | * |
352 | * @return 0, success; otherswise, failed. | 353 | * @return 0, success; otherswise, failed. |
353 | */ | 354 | */ |
354 | -extern int srs_write_h264_raw_frame(srs_rtmp_t rtmp, | ||
355 | - char* frame, int frame_size, u_int32_t dts, u_int32_t pts | 355 | +/** |
356 | +For the example file: | ||
357 | + http://winlinvip.github.io/srs.release/3rdparty/720p.h264.raw | ||
358 | +The data sequence is: | ||
359 | + // SPS | ||
360 | + 000000016742802995A014016E40 | ||
361 | + // PPS | ||
362 | + 0000000168CE3880 | ||
363 | + // IFrame | ||
364 | + 0000000165B8041014C038008B0D0D3A071..... | ||
365 | + // PFrame | ||
366 | + 0000000141E02041F8CDDC562BBDEFAD2F..... | ||
367 | +User can send the SPS+PPS, then each frame: | ||
368 | + // SPS+PPS | ||
369 | + srs_write_h264_raw_frame('000000016742802995A014016E400000000168CE3880', size, dts, pts) | ||
370 | + // IFrame | ||
371 | + srs_write_h264_raw_frame('0000000165B8041014C038008B0D0D3A071......', size, dts, pts) | ||
372 | + // PFrame | ||
373 | + srs_write_h264_raw_frame('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts) | ||
374 | +User also can send one by one: | ||
375 | + // SPS | ||
376 | + srs_write_h264_raw_frame('000000016742802995A014016E4', size, dts, pts) | ||
377 | + // PPS | ||
378 | + srs_write_h264_raw_frame('00000000168CE3880', size, dts, pts) | ||
379 | + // IFrame | ||
380 | + srs_write_h264_raw_frame('0000000165B8041014C038008B0D0D3A071......', size, dts, pts) | ||
381 | + // PFrame | ||
382 | + srs_write_h264_raw_frame('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts) | ||
383 | +*/ | ||
384 | +extern int srs_write_h264_raw_frames(srs_rtmp_t rtmp, | ||
385 | + char* frames, int frames_size, u_int32_t dts, u_int32_t pts | ||
356 | ); | 386 | ); |
357 | /** | 387 | /** |
358 | * whether h264 raw data starts with the annexb, | 388 | * whether h264 raw data starts with the annexb, |
-
请 注册 或 登录 后发表评论