complete the h264 to rtmp, but the sps and pps should send in a rtmp packet. for bug #66
正在显示
2 个修改的文件
包含
50 行增加
和
5 行删除
| @@ -998,10 +998,53 @@ char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize) | @@ -998,10 +998,53 @@ char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize) | ||
| 998 | 998 | ||
| 999 | 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) | 999 | 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) |
| 1000 | { | 1000 | { |
| 1001 | - *prtmp_data = new char[h264_raw_size]; | ||
| 1002 | - memcpy(*prtmp_data, h264_raw_data, h264_raw_size); | ||
| 1003 | - | ||
| 1004 | - *prtmp_size = h264_raw_size; | 1001 | + srs_assert(h264_raw_size > 0); |
| 1002 | + | ||
| 1003 | + // the timestamp in rtmp message header is dts. | ||
| 1004 | + *ptimestamp = dts; | ||
| 1005 | + | ||
| 1006 | + // for h264 in RTMP video payload, there is 5bytes header: | ||
| 1007 | + // 1bytes, FrameType | CodecID | ||
| 1008 | + // 1bytes, AVCPacketType | ||
| 1009 | + // 3bytes, CompositionTime, the cts. | ||
| 1010 | + // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78 | ||
| 1011 | + *prtmp_size = h264_raw_size + 5; | ||
| 1012 | + char* p = new char[*prtmp_size]; | ||
| 1013 | + memcpy(p + 5, h264_raw_data, h264_raw_size); | ||
| 1014 | + *prtmp_data = p; | ||
| 1015 | + | ||
| 1016 | + // 5bits, 7.3.1 NAL unit syntax, | ||
| 1017 | + // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. | ||
| 1018 | + // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame | ||
| 1019 | + u_int8_t nal_unit_type = (char)h264_raw_data[0] & 0x1f; | ||
| 1020 | + | ||
| 1021 | + // Frame Type, Type of video frame. | ||
| 1022 | + // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78 | ||
| 1023 | + int8_t frame_type = SrsCodecVideoAVCFrameInterFrame; | ||
| 1024 | + if (nal_unit_type != 1) { | ||
| 1025 | + frame_type = SrsCodecVideoAVCFrameKeyFrame; | ||
| 1026 | + } | ||
| 1027 | + // CodecID, Codec Identifier. | ||
| 1028 | + int8_t codec_id = SrsCodecVideoAVC; | ||
| 1029 | + // set the rtmp header | ||
| 1030 | + *p++ = (frame_type << 4) | codec_id; | ||
| 1031 | + | ||
| 1032 | + // AVCPacketType | ||
| 1033 | + if (nal_unit_type == 7 || nal_unit_type == 8) { | ||
| 1034 | + *p++ = SrsCodecVideoAVCTypeSequenceHeader; | ||
| 1035 | + } else { | ||
| 1036 | + *p++ = SrsCodecVideoAVCTypeNALU; | ||
| 1037 | + } | ||
| 1038 | + | ||
| 1039 | + // CompositionTime | ||
| 1040 | + // pts = dts + cts, or | ||
| 1041 | + // cts = pts - dts. | ||
| 1042 | + // where cts is the header in rtmp video packet payload header. | ||
| 1043 | + u_int32_t cts = pts - dts; | ||
| 1044 | + char* pp = (char*)&cts; | ||
| 1045 | + *p++ = pp[2]; | ||
| 1046 | + *p++ = pp[1]; | ||
| 1047 | + *p++ = pp[0]; | ||
| 1005 | 1048 | ||
| 1006 | return 0; | 1049 | return 0; |
| 1007 | } | 1050 | } |
| @@ -339,14 +339,16 @@ extern char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize); | @@ -339,14 +339,16 @@ extern char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize); | ||
| 339 | /** | 339 | /** |
| 340 | * convert h264 stream data to rtmp packet. | 340 | * convert h264 stream data to rtmp packet. |
| 341 | * @param h264_raw_data the input h264 raw data, a encoded h.264 I/P/B frame data. | 341 | * @param h264_raw_data the input h264 raw data, a encoded h.264 I/P/B frame data. |
| 342 | -* @paam h264_raw_size the size of h264 raw data. | 342 | +* @paam h264_raw_size the size of h264 raw data. assert > 0. |
| 343 | * @param dts the dts of h.264 raw data. | 343 | * @param dts the dts of h.264 raw data. |
| 344 | * @param pts the pts of h.264 raw data. | 344 | * @param pts the pts of h.264 raw data. |
| 345 | * @param prtmp_data the output rtmp format packet, which can be send by srs_write_packet. | 345 | * @param prtmp_data the output rtmp format packet, which can be send by srs_write_packet. |
| 346 | * @param prtmp_size the size of rtmp packet, for srs_write_packet. | 346 | * @param prtmp_size the size of rtmp packet, for srs_write_packet. |
| 347 | * @param ptimestamp the timestamp of rtmp packet, for srs_write_packet. | 347 | * @param ptimestamp the timestamp of rtmp packet, for srs_write_packet. |
| 348 | +* | ||
| 348 | * @remark, user should free the h264_raw_data. | 349 | * @remark, user should free the h264_raw_data. |
| 349 | * @remark, user should free the prtmp_data if success. | 350 | * @remark, user should free the prtmp_data if success. |
| 351 | +* @remark, the tbn of dts/pts is 1/1000 for RTMP, that is, in ms. | ||
| 350 | * | 352 | * |
| 351 | * @return 0, success; otherswise, failed. | 353 | * @return 0, success; otherswise, failed. |
| 352 | */ | 354 | */ |
-
请 注册 或 登录 后发表评论