winlin

adjust the api, move audio and h264 after rtmp

@@ -858,231 +858,622 @@ int srs_rtmp_write_packet(srs_rtmp_t rtmp, char type, u_int32_t timestamp, char* @@ -858,231 +858,622 @@ int srs_rtmp_write_packet(srs_rtmp_t rtmp, char type, u_int32_t timestamp, char*
858 return ret; 858 return ret;
859 } 859 }
860 860
861 -struct FlvContext  
862 -{  
863 - SrsFileReader reader;  
864 - SrsFileWriter writer;  
865 - SrsFlvEncoder enc;  
866 - SrsFlvDecoder dec;  
867 -}; 861 +/**
  862 +* write audio raw frame to SRS.
  863 +*/
  864 +int srs_audio_write_raw_frame(srs_rtmp_t rtmp,
  865 + char sound_format, char sound_rate, char sound_size, char sound_type,
  866 + char aac_packet_type, char* frame, int frame_size, u_int32_t timestamp
  867 +) {
  868 + Context* context = (Context*)rtmp;
  869 + srs_assert(context);
868 870
869 -srs_flv_t srs_flv_open_read(const char* file)  
870 -{  
871 - int ret = ERROR_SUCCESS;  
872 -  
873 - FlvContext* flv = new FlvContext();  
874 -  
875 - if ((ret = flv->reader.open(file)) != ERROR_SUCCESS) {  
876 - srs_freep(flv);  
877 - return NULL;  
878 - } 871 + // TODO: FIXME: for aac, must send the sequence header first.
879 872
880 - if ((ret = flv->dec.initialize(&flv->reader)) != ERROR_SUCCESS) {  
881 - srs_freep(flv);  
882 - return NULL; 873 + // for audio frame, there is 1 or 2 bytes header:
  874 + // 1bytes, SoundFormat|SoundRate|SoundSize|SoundType
  875 + // 1bytes, AACPacketType for SoundFormat == 10
  876 + int size = frame_size + 1;
  877 + if (aac_packet_type == SrsCodecAudioAAC) {
  878 + size += 1;
883 } 879 }
  880 + char* data = new char[size];
  881 + char* p = data;
884 882
885 - return flv;  
886 -}  
887 -  
888 -srs_flv_t srs_flv_open_write(const char* file)  
889 -{  
890 - int ret = ERROR_SUCCESS; 883 + u_int8_t audio_header = sound_type & 0x01;
  884 + audio_header |= (sound_size << 1) & 0x02;
  885 + audio_header |= (sound_rate << 2) & 0x0c;
  886 + audio_header |= (sound_format << 4) & 0xf0;
891 887
892 - FlvContext* flv = new FlvContext(); 888 + *p++ = audio_header;
893 889
894 - if ((ret = flv->writer.open(file)) != ERROR_SUCCESS) {  
895 - srs_freep(flv);  
896 - return NULL; 890 + if (aac_packet_type == SrsCodecAudioAAC) {
  891 + *p++ = aac_packet_type;
897 } 892 }
898 893
899 - if ((ret = flv->enc.initialize(&flv->writer)) != ERROR_SUCCESS) {  
900 - srs_freep(flv);  
901 - return NULL;  
902 - } 894 + memcpy(p, frame, frame_size);
903 895
904 - return flv;  
905 -}  
906 -  
907 -void srs_flv_close(srs_flv_t flv)  
908 -{  
909 - FlvContext* context = (FlvContext*)flv;  
910 - srs_freep(context); 896 + return srs_rtmp_write_packet(context, SRS_RTMP_TYPE_AUDIO, timestamp, data, size);
911 } 897 }
912 898
913 -int srs_flv_read_header(srs_flv_t flv, char header[9])  
914 -{  
915 - int ret = ERROR_SUCCESS; 899 +/**
  900 +* write h264 packet, with rtmp header.
  901 +* @param frame_type, SrsCodecVideoAVCFrameKeyFrame or SrsCodecVideoAVCFrameInterFrame.
  902 +* @param avc_packet_type, SrsCodecVideoAVCTypeSequenceHeader or SrsCodecVideoAVCTypeNALU.
  903 +* @param h264_raw_data the h.264 raw data, user must free it.
  904 +*/
  905 +int __srs_write_h264_packet(Context* context,
  906 + int8_t frame_type, int8_t avc_packet_type,
  907 + char* h264_raw_data, int h264_raw_size, u_int32_t dts, u_int32_t pts
  908 +) {
  909 + // the timestamp in rtmp message header is dts.
  910 + u_int32_t timestamp = dts;
916 911
917 - FlvContext* context = (FlvContext*)flv;  
918 -  
919 - if (!context->reader.is_open()) {  
920 - return ERROR_SYSTEM_IO_INVALID;  
921 - } 912 + // for h264 in RTMP video payload, there is 5bytes header:
  913 + // 1bytes, FrameType | CodecID
  914 + // 1bytes, AVCPacketType
  915 + // 3bytes, CompositionTime, the cts.
  916 + // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
  917 + int size = h264_raw_size + 5;
  918 + char* data = new char[size];
  919 + char* p = data;
922 920
923 - if ((ret = context->dec.read_header(header)) != ERROR_SUCCESS) {  
924 - return ret;  
925 - } 921 + // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
  922 + // Frame Type, Type of video frame.
  923 + // CodecID, Codec Identifier.
  924 + // set the rtmp header
  925 + *p++ = (frame_type << 4) | SrsCodecVideoAVC;
926 926
927 - char ts[4]; // tag size  
928 - if ((ret = context->dec.read_previous_tag_size(ts)) != ERROR_SUCCESS) {  
929 - return ret;  
930 - } 927 + // AVCPacketType
  928 + *p++ = avc_packet_type;
  929 +
  930 + // CompositionTime
  931 + // pts = dts + cts, or
  932 + // cts = pts - dts.
  933 + // where cts is the header in rtmp video packet payload header.
  934 + u_int32_t cts = pts - dts;
  935 + char* pp = (char*)&cts;
  936 + *p++ = pp[2];
  937 + *p++ = pp[1];
  938 + *p++ = pp[0];
931 939
932 - return ret; 940 + // h.264 raw data.
  941 + memcpy(p, h264_raw_data, h264_raw_size);
  942 +
  943 + return srs_rtmp_write_packet(context, SRS_RTMP_TYPE_VIDEO, timestamp, data, size);
933 } 944 }
934 945
935 -int srs_flv_read_tag_header(srs_flv_t flv, char* ptype, int32_t* pdata_size, u_int32_t* ptime) 946 +/**
  947 +* write the h264 sps/pps in context over RTMP.
  948 +*/
  949 +int __srs_write_h264_sps_pps(Context* context, u_int32_t dts, u_int32_t pts)
936 { 950 {
937 int ret = ERROR_SUCCESS; 951 int ret = ERROR_SUCCESS;
938 952
939 - FlvContext* context = (FlvContext*)flv;  
940 -  
941 - if (!context->reader.is_open()) {  
942 - return ERROR_SYSTEM_IO_INVALID; 953 + // only send when both sps and pps changed.
  954 + if (!context->h264_sps_changed || !context->h264_pps_changed) {
  955 + return ret;
943 } 956 }
944 957
945 - if ((ret = context->dec.read_tag_header(ptype, pdata_size, ptime)) != ERROR_SUCCESS) { 958 + // 5bytes sps/pps header:
  959 + // configurationVersion, AVCProfileIndication, profile_compatibility,
  960 + // AVCLevelIndication, lengthSizeMinusOne
  961 + // 3bytes size of sps:
  962 + // numOfSequenceParameterSets, sequenceParameterSetLength(2B)
  963 + // Nbytes of sps.
  964 + // sequenceParameterSetNALUnit
  965 + // 3bytes size of pps:
  966 + // numOfPictureParameterSets, pictureParameterSetLength
  967 + // Nbytes of pps:
  968 + // pictureParameterSetNALUnit
  969 + int nb_packet = 5
  970 + + 3 + (int)context->h264_sps.length()
  971 + + 3 + (int)context->h264_pps.length();
  972 + char* packet = new char[nb_packet];
  973 + SrsAutoFree(char, packet);
  974 +
  975 + // use stream to generate the h264 packet.
  976 + SrsStream stream;
  977 + if ((ret = stream.initialize(packet, nb_packet)) != ERROR_SUCCESS) {
946 return ret; 978 return ret;
947 } 979 }
948 980
949 - return ret;  
950 -}  
951 -  
952 -int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size)  
953 -{  
954 - int ret = ERROR_SUCCESS; 981 + // decode the SPS:
  982 + // @see: 7.3.2.1.1, H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 62
  983 + if (true) {
  984 + srs_assert((int)context->h264_sps.length() >= 4);
  985 + char* frame = (char*)context->h264_sps.data();
955 986
956 - FlvContext* context = (FlvContext*)flv;  
957 -  
958 - if (!context->reader.is_open()) {  
959 - return ERROR_SYSTEM_IO_INVALID; 987 + // @see: Annex A Profiles and levels, H.264-AVC-ISO_IEC_14496-10.pdf, page 205
  988 + // Baseline profile profile_idc is 66(0x42).
  989 + // Main profile profile_idc is 77(0x4d).
  990 + // Extended profile profile_idc is 88(0x58).
  991 + u_int8_t profile_idc = frame[1];
  992 + //u_int8_t constraint_set = frame[2];
  993 + u_int8_t level_idc = frame[3];
  994 +
  995 + // generate the sps/pps header
  996 + // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
  997 + // configurationVersion
  998 + stream.write_1bytes(0x01);
  999 + // AVCProfileIndication
  1000 + stream.write_1bytes(profile_idc);
  1001 + // profile_compatibility
  1002 + stream.write_1bytes(0x00);
  1003 + // AVCLevelIndication
  1004 + stream.write_1bytes(level_idc);
  1005 + // lengthSizeMinusOne, or NAL_unit_length, always use 4bytes size,
  1006 + // so we always set it to 0x03.
  1007 + stream.write_1bytes(0x03);
960 } 1008 }
961 1009
962 - if ((ret = context->dec.read_tag_data(data, size)) != ERROR_SUCCESS) {  
963 - return ret; 1010 + // sps
  1011 + if (true) {
  1012 + // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
  1013 + // numOfSequenceParameterSets, always 1
  1014 + stream.write_1bytes(0x01);
  1015 + // sequenceParameterSetLength
  1016 + stream.write_2bytes(context->h264_sps.length());
  1017 + // sequenceParameterSetNALUnit
  1018 + stream.write_string(context->h264_sps);
964 } 1019 }
965 1020
966 - char ts[4]; // tag size  
967 - if ((ret = context->dec.read_previous_tag_size(ts)) != ERROR_SUCCESS) {  
968 - return ret; 1021 + // pps
  1022 + if (true) {
  1023 + // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
  1024 + // numOfPictureParameterSets, always 1
  1025 + stream.write_1bytes(0x01);
  1026 + // pictureParameterSetLength
  1027 + stream.write_2bytes(context->h264_pps.length());
  1028 + // pictureParameterSetNALUnit
  1029 + stream.write_string(context->h264_pps);
969 } 1030 }
970 1031
971 - return ret;  
972 -}  
973 -  
974 -int srs_flv_write_header(srs_flv_t flv, char header[9])  
975 -{  
976 - int ret = ERROR_SUCCESS;  
977 -  
978 - FlvContext* context = (FlvContext*)flv;  
979 -  
980 - if (!context->writer.is_open()) {  
981 - return ERROR_SYSTEM_IO_INVALID;  
982 - } 1032 + // reset sps and pps.
  1033 + context->h264_sps_changed = false;
  1034 + context->h264_pps_changed = false;
  1035 + context->h264_sps_pps_sent = true;
983 1036
984 - if ((ret = context->enc.write_header(header)) != ERROR_SUCCESS) {  
985 - return ret;  
986 - } 1037 + // TODO: FIXME: for more profile.
  1038 + // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
  1039 + // profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 144
987 1040
988 - return ret; 1041 + // send out h264 packet.
  1042 + int8_t frame_type = SrsCodecVideoAVCFrameKeyFrame;
  1043 + int8_t avc_packet_type = SrsCodecVideoAVCTypeSequenceHeader;
  1044 + return __srs_write_h264_packet(
  1045 + context, frame_type, avc_packet_type,
  1046 + packet, nb_packet, dts, pts
  1047 + );
989 } 1048 }
990 1049
991 -int srs_flv_write_tag(srs_flv_t flv, char type, int32_t time, char* data, int size)  
992 -{ 1050 +/**
  1051 +* write h264 IPB-frame.
  1052 +*/
  1053 +int __srs_write_h264_ipb_frame(Context* context,
  1054 + char* data, int size, u_int32_t dts, u_int32_t pts
  1055 +) {
993 int ret = ERROR_SUCCESS; 1056 int ret = ERROR_SUCCESS;
994 1057
995 - FlvContext* context = (FlvContext*)flv; 1058 + // when sps or pps not sent, ignore the packet.
  1059 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/203
  1060 + if (!context->h264_sps_pps_sent) {
  1061 + return ERROR_H264_DROP_BEFORE_SPS_PPS;
  1062 + }
  1063 +
  1064 + // 5bits, 7.3.1 NAL unit syntax,
  1065 + // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
  1066 + // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
  1067 + u_int8_t nal_unit_type = (char)data[0] & 0x1f;
  1068 +
  1069 + // 4bytes size of nalu:
  1070 + // NALUnitLength
  1071 + // Nbytes of nalu.
  1072 + // NALUnit
  1073 + int nb_packet = 4 + size;
  1074 + char* packet = new char[nb_packet];
  1075 + SrsAutoFree(char, packet);
  1076 +
  1077 + // use stream to generate the h264 packet.
  1078 + SrsStream stream;
  1079 + if ((ret = stream.initialize(packet, nb_packet)) != ERROR_SUCCESS) {
  1080 + return ret;
  1081 + }
996 1082
997 - if (!context->writer.is_open()) {  
998 - return ERROR_SYSTEM_IO_INVALID; 1083 + // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
  1084 + // lengthSizeMinusOne, or NAL_unit_length, always use 4bytes size
  1085 + u_int32_t NAL_unit_length = size;
  1086 +
  1087 + // mux the avc NALU in "ISO Base Media File Format"
  1088 + // from H.264-AVC-ISO_IEC_14496-15.pdf, page 20
  1089 + // NALUnitLength
  1090 + stream.write_4bytes(NAL_unit_length);
  1091 + // NALUnit
  1092 + stream.write_bytes(data, size);
  1093 +
  1094 + // send out h264 packet.
  1095 + int8_t frame_type = SrsCodecVideoAVCFrameInterFrame;
  1096 + if (nal_unit_type != 1) {
  1097 + frame_type = SrsCodecVideoAVCFrameKeyFrame;
999 } 1098 }
  1099 + int8_t avc_packet_type = SrsCodecVideoAVCTypeNALU;
  1100 + return __srs_write_h264_packet(
  1101 + context, frame_type, avc_packet_type,
  1102 + packet, nb_packet, dts, pts
  1103 + );
1000 1104
1001 - if (type == SRS_RTMP_TYPE_AUDIO) {  
1002 - return context->enc.write_audio(time, data, size);  
1003 - } else if (type == SRS_RTMP_TYPE_VIDEO) {  
1004 - return context->enc.write_video(time, data, size); 1105 + return ret;
  1106 +}
  1107 +
  1108 +/**
  1109 +* write h264 raw frame, maybe sps/pps/IPB-frame.
  1110 +*/
  1111 +int __srs_write_h264_raw_frame(Context* context,
  1112 + char* frame, int frame_size, u_int32_t dts, u_int32_t pts
  1113 +) {
  1114 + int ret = ERROR_SUCCESS;
  1115 +
  1116 + // ignore invalid frame,
  1117 + // atleast 1bytes for SPS to decode the type
  1118 + if (frame_size < 1) {
  1119 + return ret;
  1120 + }
  1121 +
  1122 + // 5bits, 7.3.1 NAL unit syntax,
  1123 + // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
  1124 + // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
  1125 + u_int8_t nal_unit_type = (char)frame[0] & 0x1f;
  1126 +
  1127 + if (nal_unit_type == 7) {
  1128 + // atleast 1bytes for SPS to decode the type, profile, constrain and level.
  1129 + if (frame_size < 4) {
  1130 + return ret;
  1131 + }
  1132 +
  1133 + std::string sps;
  1134 + sps.append(frame, frame_size);
  1135 +
  1136 + if (context->h264_sps == sps) {
  1137 + return ERROR_H264_DUPLICATED_SPS;
  1138 + }
  1139 + context->h264_sps_changed = true;
  1140 + context->h264_sps = sps;
  1141 +
  1142 + return __srs_write_h264_sps_pps(context, dts, pts);
  1143 + } else if (nal_unit_type == 8) {
  1144 +
  1145 + std::string pps;
  1146 + pps.append(frame, frame_size);
  1147 +
  1148 + if (context->h264_pps == pps) {
  1149 + return ERROR_H264_DUPLICATED_PPS;
  1150 + }
  1151 + context->h264_pps_changed = true;
  1152 + context->h264_pps = pps;
  1153 +
  1154 + return __srs_write_h264_sps_pps(context, dts, pts);
1005 } else { 1155 } else {
1006 - return context->enc.write_metadata(data, size); 1156 + return __srs_write_h264_ipb_frame(context, frame, frame_size, dts, pts);
1007 } 1157 }
1008 - 1158 +
1009 return ret; 1159 return ret;
1010 } 1160 }
1011 1161
1012 -int srs_flv_size_tag(int data_size)  
1013 -{  
1014 - return SrsFlvEncoder::size_tag(data_size); 1162 +/**
  1163 +* write h264 multiple frames, in annexb format.
  1164 +*/
  1165 +int srs_h264_write_raw_frames(srs_rtmp_t rtmp,
  1166 + char* frames, int frames_size, u_int32_t dts, u_int32_t pts
  1167 +) {
  1168 + int ret = ERROR_SUCCESS;
  1169 +
  1170 + srs_assert(frames != NULL);
  1171 + srs_assert(frames_size > 0);
  1172 +
  1173 + srs_assert(rtmp != NULL);
  1174 + Context* context = (Context*)rtmp;
  1175 +
  1176 + if ((ret = context->h264_raw_stream.initialize(frames, frames_size)) != ERROR_SUCCESS) {
  1177 + return ret;
  1178 + }
  1179 +
  1180 + // use the last error
  1181 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/203
  1182 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/204
  1183 + int error_code_return = ret;
  1184 +
  1185 + // send each frame.
  1186 + while (!context->h264_raw_stream.empty()) {
  1187 + // each frame must prefixed by annexb format.
  1188 + // about annexb, @see H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
  1189 + int pnb_start_code = 0;
  1190 + if (!srs_avc_startswith_annexb(&context->h264_raw_stream, &pnb_start_code)) {
  1191 + return ERROR_H264_API_NO_PREFIXED;
  1192 + }
  1193 + int start = context->h264_raw_stream.pos() + pnb_start_code;
  1194 +
  1195 + // find the last frame prefixed by annexb format.
  1196 + context->h264_raw_stream.skip(pnb_start_code);
  1197 + while (!context->h264_raw_stream.empty()) {
  1198 + if (srs_avc_startswith_annexb(&context->h264_raw_stream, NULL)) {
  1199 + break;
  1200 + }
  1201 + context->h264_raw_stream.skip(1);
  1202 + }
  1203 + int size = context->h264_raw_stream.pos() - start;
  1204 +
  1205 + // send out the frame.
  1206 + char* frame = context->h264_raw_stream.data() + start;
  1207 +
  1208 + // it may be return error, but we must process all packets.
  1209 + if ((ret = __srs_write_h264_raw_frame(context, frame, size, dts, pts)) != ERROR_SUCCESS) {
  1210 + error_code_return = ret;
  1211 +
  1212 + // ignore known error, process all packets.
  1213 + if (srs_h264_is_dvbsp_error(ret)
  1214 + || srs_h264_is_duplicated_sps_error(ret)
  1215 + || srs_h264_is_duplicated_pps_error(ret)
  1216 + ) {
  1217 + continue;
  1218 + }
  1219 +
  1220 + return ret;
  1221 + }
  1222 + }
  1223 +
  1224 + return error_code_return;
1015 } 1225 }
1016 1226
1017 -int64_t srs_flv_tellg(srs_flv_t flv) 1227 +srs_h264_bool srs_h264_is_dvbsp_error(int error_code)
1018 { 1228 {
1019 - FlvContext* context = (FlvContext*)flv;  
1020 - return context->reader.tellg(); 1229 + return error_code == ERROR_H264_DROP_BEFORE_SPS_PPS;
1021 } 1230 }
1022 1231
1023 -void srs_flv_lseek(srs_flv_t flv, int64_t offset) 1232 +srs_h264_bool srs_h264_is_duplicated_sps_error(int error_code)
1024 { 1233 {
1025 - FlvContext* context = (FlvContext*)flv;  
1026 - context->reader.lseek(offset); 1234 + return error_code == ERROR_H264_DUPLICATED_SPS;
1027 } 1235 }
1028 1236
1029 -srs_flv_bool srs_flv_is_eof(int error_code) 1237 +srs_h264_bool srs_h264_is_duplicated_pps_error(int error_code)
1030 { 1238 {
1031 - return error_code == ERROR_SYSTEM_FILE_EOF; 1239 + return error_code == ERROR_H264_DUPLICATED_PPS;
1032 } 1240 }
1033 1241
1034 -srs_flv_bool srs_flv_is_sequence_header(char* data, int32_t size) 1242 +int srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int* pnb_start_code)
1035 { 1243 {
1036 - return SrsFlvCodec::video_is_sequence_header(data, (int)size); 1244 + SrsStream stream;
  1245 + if (stream.initialize(h264_raw_data, h264_raw_size) != ERROR_SUCCESS) {
  1246 + return false;
  1247 + }
  1248 +
  1249 + return srs_avc_startswith_annexb(&stream, pnb_start_code);
1037 } 1250 }
1038 1251
1039 -srs_flv_bool srs_flv_is_keyframe(char* data, int32_t size) 1252 +struct FlvContext
1040 { 1253 {
1041 - return SrsFlvCodec::video_is_keyframe(data, (int)size);  
1042 -} 1254 + SrsFileReader reader;
  1255 + SrsFileWriter writer;
  1256 + SrsFlvEncoder enc;
  1257 + SrsFlvDecoder dec;
  1258 +};
1043 1259
1044 -srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed) 1260 +srs_flv_t srs_flv_open_read(const char* file)
1045 { 1261 {
1046 int ret = ERROR_SUCCESS; 1262 int ret = ERROR_SUCCESS;
1047 1263
1048 - srs_amf0_t amf0 = NULL; 1264 + FlvContext* flv = new FlvContext();
1049 1265
1050 - SrsStream stream;  
1051 - if ((ret = stream.initialize(data, size)) != ERROR_SUCCESS) {  
1052 - return amf0; 1266 + if ((ret = flv->reader.open(file)) != ERROR_SUCCESS) {
  1267 + srs_freep(flv);
  1268 + return NULL;
1053 } 1269 }
1054 1270
1055 - SrsAmf0Any* any = NULL;  
1056 - if ((ret = SrsAmf0Any::discovery(&stream, &any)) != ERROR_SUCCESS) {  
1057 - return amf0; 1271 + if ((ret = flv->dec.initialize(&flv->reader)) != ERROR_SUCCESS) {
  1272 + srs_freep(flv);
  1273 + return NULL;
1058 } 1274 }
1059 1275
1060 - stream.skip(-1 * stream.pos());  
1061 - if ((ret = any->read(&stream)) != ERROR_SUCCESS) {  
1062 - srs_freep(any);  
1063 - return amf0; 1276 + return flv;
  1277 +}
  1278 +
  1279 +srs_flv_t srs_flv_open_write(const char* file)
  1280 +{
  1281 + int ret = ERROR_SUCCESS;
  1282 +
  1283 + FlvContext* flv = new FlvContext();
  1284 +
  1285 + if ((ret = flv->writer.open(file)) != ERROR_SUCCESS) {
  1286 + srs_freep(flv);
  1287 + return NULL;
1064 } 1288 }
1065 1289
1066 - if (nparsed) {  
1067 - *nparsed = stream.pos(); 1290 + if ((ret = flv->enc.initialize(&flv->writer)) != ERROR_SUCCESS) {
  1291 + srs_freep(flv);
  1292 + return NULL;
1068 } 1293 }
1069 - amf0 = (srs_amf0_t)any;  
1070 1294
1071 - return amf0; 1295 + return flv;
1072 } 1296 }
1073 1297
1074 -srs_amf0_t srs_amf0_create_number(srs_amf0_number value) 1298 +void srs_flv_close(srs_flv_t flv)
1075 { 1299 {
1076 - return SrsAmf0Any::number(value); 1300 + FlvContext* context = (FlvContext*)flv;
  1301 + srs_freep(context);
1077 } 1302 }
1078 1303
1079 -srs_amf0_t srs_amf0_create_ecma_array() 1304 +int srs_flv_read_header(srs_flv_t flv, char header[9])
1080 { 1305 {
1081 - return SrsAmf0Any::ecma_array();  
1082 -} 1306 + int ret = ERROR_SUCCESS;
  1307 +
  1308 + FlvContext* context = (FlvContext*)flv;
1083 1309
1084 -srs_amf0_t srs_amf0_create_strict_array()  
1085 -{ 1310 + if (!context->reader.is_open()) {
  1311 + return ERROR_SYSTEM_IO_INVALID;
  1312 + }
  1313 +
  1314 + if ((ret = context->dec.read_header(header)) != ERROR_SUCCESS) {
  1315 + return ret;
  1316 + }
  1317 +
  1318 + char ts[4]; // tag size
  1319 + if ((ret = context->dec.read_previous_tag_size(ts)) != ERROR_SUCCESS) {
  1320 + return ret;
  1321 + }
  1322 +
  1323 + return ret;
  1324 +}
  1325 +
  1326 +int srs_flv_read_tag_header(srs_flv_t flv, char* ptype, int32_t* pdata_size, u_int32_t* ptime)
  1327 +{
  1328 + int ret = ERROR_SUCCESS;
  1329 +
  1330 + FlvContext* context = (FlvContext*)flv;
  1331 +
  1332 + if (!context->reader.is_open()) {
  1333 + return ERROR_SYSTEM_IO_INVALID;
  1334 + }
  1335 +
  1336 + if ((ret = context->dec.read_tag_header(ptype, pdata_size, ptime)) != ERROR_SUCCESS) {
  1337 + return ret;
  1338 + }
  1339 +
  1340 + return ret;
  1341 +}
  1342 +
  1343 +int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size)
  1344 +{
  1345 + int ret = ERROR_SUCCESS;
  1346 +
  1347 + FlvContext* context = (FlvContext*)flv;
  1348 +
  1349 + if (!context->reader.is_open()) {
  1350 + return ERROR_SYSTEM_IO_INVALID;
  1351 + }
  1352 +
  1353 + if ((ret = context->dec.read_tag_data(data, size)) != ERROR_SUCCESS) {
  1354 + return ret;
  1355 + }
  1356 +
  1357 + char ts[4]; // tag size
  1358 + if ((ret = context->dec.read_previous_tag_size(ts)) != ERROR_SUCCESS) {
  1359 + return ret;
  1360 + }
  1361 +
  1362 + return ret;
  1363 +}
  1364 +
  1365 +int srs_flv_write_header(srs_flv_t flv, char header[9])
  1366 +{
  1367 + int ret = ERROR_SUCCESS;
  1368 +
  1369 + FlvContext* context = (FlvContext*)flv;
  1370 +
  1371 + if (!context->writer.is_open()) {
  1372 + return ERROR_SYSTEM_IO_INVALID;
  1373 + }
  1374 +
  1375 + if ((ret = context->enc.write_header(header)) != ERROR_SUCCESS) {
  1376 + return ret;
  1377 + }
  1378 +
  1379 + return ret;
  1380 +}
  1381 +
  1382 +int srs_flv_write_tag(srs_flv_t flv, char type, int32_t time, char* data, int size)
  1383 +{
  1384 + int ret = ERROR_SUCCESS;
  1385 +
  1386 + FlvContext* context = (FlvContext*)flv;
  1387 +
  1388 + if (!context->writer.is_open()) {
  1389 + return ERROR_SYSTEM_IO_INVALID;
  1390 + }
  1391 +
  1392 + if (type == SRS_RTMP_TYPE_AUDIO) {
  1393 + return context->enc.write_audio(time, data, size);
  1394 + } else if (type == SRS_RTMP_TYPE_VIDEO) {
  1395 + return context->enc.write_video(time, data, size);
  1396 + } else {
  1397 + return context->enc.write_metadata(data, size);
  1398 + }
  1399 +
  1400 + return ret;
  1401 +}
  1402 +
  1403 +int srs_flv_size_tag(int data_size)
  1404 +{
  1405 + return SrsFlvEncoder::size_tag(data_size);
  1406 +}
  1407 +
  1408 +int64_t srs_flv_tellg(srs_flv_t flv)
  1409 +{
  1410 + FlvContext* context = (FlvContext*)flv;
  1411 + return context->reader.tellg();
  1412 +}
  1413 +
  1414 +void srs_flv_lseek(srs_flv_t flv, int64_t offset)
  1415 +{
  1416 + FlvContext* context = (FlvContext*)flv;
  1417 + context->reader.lseek(offset);
  1418 +}
  1419 +
  1420 +srs_flv_bool srs_flv_is_eof(int error_code)
  1421 +{
  1422 + return error_code == ERROR_SYSTEM_FILE_EOF;
  1423 +}
  1424 +
  1425 +srs_flv_bool srs_flv_is_sequence_header(char* data, int32_t size)
  1426 +{
  1427 + return SrsFlvCodec::video_is_sequence_header(data, (int)size);
  1428 +}
  1429 +
  1430 +srs_flv_bool srs_flv_is_keyframe(char* data, int32_t size)
  1431 +{
  1432 + return SrsFlvCodec::video_is_keyframe(data, (int)size);
  1433 +}
  1434 +
  1435 +srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed)
  1436 +{
  1437 + int ret = ERROR_SUCCESS;
  1438 +
  1439 + srs_amf0_t amf0 = NULL;
  1440 +
  1441 + SrsStream stream;
  1442 + if ((ret = stream.initialize(data, size)) != ERROR_SUCCESS) {
  1443 + return amf0;
  1444 + }
  1445 +
  1446 + SrsAmf0Any* any = NULL;
  1447 + if ((ret = SrsAmf0Any::discovery(&stream, &any)) != ERROR_SUCCESS) {
  1448 + return amf0;
  1449 + }
  1450 +
  1451 + stream.skip(-1 * stream.pos());
  1452 + if ((ret = any->read(&stream)) != ERROR_SUCCESS) {
  1453 + srs_freep(any);
  1454 + return amf0;
  1455 + }
  1456 +
  1457 + if (nparsed) {
  1458 + *nparsed = stream.pos();
  1459 + }
  1460 + amf0 = (srs_amf0_t)any;
  1461 +
  1462 + return amf0;
  1463 +}
  1464 +
  1465 +srs_amf0_t srs_amf0_create_number(srs_amf0_number value)
  1466 +{
  1467 + return SrsAmf0Any::number(value);
  1468 +}
  1469 +
  1470 +srs_amf0_t srs_amf0_create_ecma_array()
  1471 +{
  1472 + return SrsAmf0Any::ecma_array();
  1473 +}
  1474 +
  1475 +srs_amf0_t srs_amf0_create_strict_array()
  1476 +{
1086 return SrsAmf0Any::strict_array(); 1477 return SrsAmf0Any::strict_array();
1087 } 1478 }
1088 1479
@@ -1321,397 +1712,6 @@ void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value) @@ -1321,397 +1712,6 @@ void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value)
1321 obj->append(any); 1712 obj->append(any);
1322 } 1713 }
1323 1714
1324 -/**  
1325 -* write audio raw frame to SRS.  
1326 -*/  
1327 -int srs_audio_write_raw_frame(srs_rtmp_t rtmp,  
1328 - char sound_format, char sound_rate, char sound_size, char sound_type,  
1329 - char aac_packet_type, char* frame, int frame_size, u_int32_t timestamp  
1330 -) {  
1331 - Context* context = (Context*)rtmp;  
1332 - srs_assert(context);  
1333 -  
1334 - // TODO: FIXME: for aac, must send the sequence header first.  
1335 -  
1336 - // for audio frame, there is 1 or 2 bytes header:  
1337 - // 1bytes, SoundFormat|SoundRate|SoundSize|SoundType  
1338 - // 1bytes, AACPacketType for SoundFormat == 10  
1339 - int size = frame_size + 1;  
1340 - if (aac_packet_type == SrsCodecAudioAAC) {  
1341 - size += 1;  
1342 - }  
1343 - char* data = new char[size];  
1344 - char* p = data;  
1345 -  
1346 - u_int8_t audio_header = sound_type & 0x01;  
1347 - audio_header |= (sound_size << 1) & 0x02;  
1348 - audio_header |= (sound_rate << 2) & 0x0c;  
1349 - audio_header |= (sound_format << 4) & 0xf0;  
1350 -  
1351 - *p++ = audio_header;  
1352 -  
1353 - if (aac_packet_type == SrsCodecAudioAAC) {  
1354 - *p++ = aac_packet_type;  
1355 - }  
1356 -  
1357 - memcpy(p, frame, frame_size);  
1358 -  
1359 - return srs_rtmp_write_packet(context, SRS_RTMP_TYPE_AUDIO, timestamp, data, size);  
1360 -}  
1361 -  
1362 -/**  
1363 -* write h264 packet, with rtmp header.  
1364 -* @param frame_type, SrsCodecVideoAVCFrameKeyFrame or SrsCodecVideoAVCFrameInterFrame.  
1365 -* @param avc_packet_type, SrsCodecVideoAVCTypeSequenceHeader or SrsCodecVideoAVCTypeNALU.  
1366 -* @param h264_raw_data the h.264 raw data, user must free it.  
1367 -*/  
1368 -int __srs_write_h264_packet(Context* context,  
1369 - int8_t frame_type, int8_t avc_packet_type,  
1370 - char* h264_raw_data, int h264_raw_size, u_int32_t dts, u_int32_t pts  
1371 -) {  
1372 - // the timestamp in rtmp message header is dts.  
1373 - u_int32_t timestamp = dts;  
1374 -  
1375 - // for h264 in RTMP video payload, there is 5bytes header:  
1376 - // 1bytes, FrameType | CodecID  
1377 - // 1bytes, AVCPacketType  
1378 - // 3bytes, CompositionTime, the cts.  
1379 - // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78  
1380 - int size = h264_raw_size + 5;  
1381 - char* data = new char[size];  
1382 - char* p = data;  
1383 -  
1384 - // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78  
1385 - // Frame Type, Type of video frame.  
1386 - // CodecID, Codec Identifier.  
1387 - // set the rtmp header  
1388 - *p++ = (frame_type << 4) | SrsCodecVideoAVC;  
1389 -  
1390 - // AVCPacketType  
1391 - *p++ = avc_packet_type;  
1392 -  
1393 - // CompositionTime  
1394 - // pts = dts + cts, or  
1395 - // cts = pts - dts.  
1396 - // where cts is the header in rtmp video packet payload header.  
1397 - u_int32_t cts = pts - dts;  
1398 - char* pp = (char*)&cts;  
1399 - *p++ = pp[2];  
1400 - *p++ = pp[1];  
1401 - *p++ = pp[0];  
1402 -  
1403 - // h.264 raw data.  
1404 - memcpy(p, h264_raw_data, h264_raw_size);  
1405 -  
1406 - return srs_rtmp_write_packet(context, SRS_RTMP_TYPE_VIDEO, timestamp, data, size);  
1407 -}  
1408 -  
1409 -/**  
1410 -* write the h264 sps/pps in context over RTMP.  
1411 -*/  
1412 -int __srs_write_h264_sps_pps(Context* context, u_int32_t dts, u_int32_t pts)  
1413 -{  
1414 - int ret = ERROR_SUCCESS;  
1415 -  
1416 - // only send when both sps and pps changed.  
1417 - if (!context->h264_sps_changed || !context->h264_pps_changed) {  
1418 - return ret;  
1419 - }  
1420 -  
1421 - // 5bytes sps/pps header:  
1422 - // configurationVersion, AVCProfileIndication, profile_compatibility,  
1423 - // AVCLevelIndication, lengthSizeMinusOne  
1424 - // 3bytes size of sps:  
1425 - // numOfSequenceParameterSets, sequenceParameterSetLength(2B)  
1426 - // Nbytes of sps.  
1427 - // sequenceParameterSetNALUnit  
1428 - // 3bytes size of pps:  
1429 - // numOfPictureParameterSets, pictureParameterSetLength  
1430 - // Nbytes of pps:  
1431 - // pictureParameterSetNALUnit  
1432 - int nb_packet = 5  
1433 - + 3 + (int)context->h264_sps.length()  
1434 - + 3 + (int)context->h264_pps.length();  
1435 - char* packet = new char[nb_packet];  
1436 - SrsAutoFree(char, packet);  
1437 -  
1438 - // use stream to generate the h264 packet.  
1439 - SrsStream stream;  
1440 - if ((ret = stream.initialize(packet, nb_packet)) != ERROR_SUCCESS) {  
1441 - return ret;  
1442 - }  
1443 -  
1444 - // decode the SPS:  
1445 - // @see: 7.3.2.1.1, H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 62  
1446 - if (true) {  
1447 - srs_assert((int)context->h264_sps.length() >= 4);  
1448 - char* frame = (char*)context->h264_sps.data();  
1449 -  
1450 - // @see: Annex A Profiles and levels, H.264-AVC-ISO_IEC_14496-10.pdf, page 205  
1451 - // Baseline profile profile_idc is 66(0x42).  
1452 - // Main profile profile_idc is 77(0x4d).  
1453 - // Extended profile profile_idc is 88(0x58).  
1454 - u_int8_t profile_idc = frame[1];  
1455 - //u_int8_t constraint_set = frame[2];  
1456 - u_int8_t level_idc = frame[3];  
1457 -  
1458 - // generate the sps/pps header  
1459 - // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16  
1460 - // configurationVersion  
1461 - stream.write_1bytes(0x01);  
1462 - // AVCProfileIndication  
1463 - stream.write_1bytes(profile_idc);  
1464 - // profile_compatibility  
1465 - stream.write_1bytes(0x00);  
1466 - // AVCLevelIndication  
1467 - stream.write_1bytes(level_idc);  
1468 - // lengthSizeMinusOne, or NAL_unit_length, always use 4bytes size,  
1469 - // so we always set it to 0x03.  
1470 - stream.write_1bytes(0x03);  
1471 - }  
1472 -  
1473 - // sps  
1474 - if (true) {  
1475 - // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16  
1476 - // numOfSequenceParameterSets, always 1  
1477 - stream.write_1bytes(0x01);  
1478 - // sequenceParameterSetLength  
1479 - stream.write_2bytes(context->h264_sps.length());  
1480 - // sequenceParameterSetNALUnit  
1481 - stream.write_string(context->h264_sps);  
1482 - }  
1483 -  
1484 - // pps  
1485 - if (true) {  
1486 - // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16  
1487 - // numOfPictureParameterSets, always 1  
1488 - stream.write_1bytes(0x01);  
1489 - // pictureParameterSetLength  
1490 - stream.write_2bytes(context->h264_pps.length());  
1491 - // pictureParameterSetNALUnit  
1492 - stream.write_string(context->h264_pps);  
1493 - }  
1494 -  
1495 - // reset sps and pps.  
1496 - context->h264_sps_changed = false;  
1497 - context->h264_pps_changed = false;  
1498 - context->h264_sps_pps_sent = true;  
1499 -  
1500 - // TODO: FIXME: for more profile.  
1501 - // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16  
1502 - // profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 144  
1503 -  
1504 - // send out h264 packet.  
1505 - int8_t frame_type = SrsCodecVideoAVCFrameKeyFrame;  
1506 - int8_t avc_packet_type = SrsCodecVideoAVCTypeSequenceHeader;  
1507 - return __srs_write_h264_packet(  
1508 - context, frame_type, avc_packet_type,  
1509 - packet, nb_packet, dts, pts  
1510 - );  
1511 -}  
1512 -  
1513 -/**  
1514 -* write h264 IPB-frame.  
1515 -*/  
1516 -int __srs_write_h264_ipb_frame(Context* context,  
1517 - char* data, int size, u_int32_t dts, u_int32_t pts  
1518 -) {  
1519 - int ret = ERROR_SUCCESS;  
1520 -  
1521 - // when sps or pps not sent, ignore the packet.  
1522 - // @see https://github.com/winlinvip/simple-rtmp-server/issues/203  
1523 - if (!context->h264_sps_pps_sent) {  
1524 - return ERROR_H264_DROP_BEFORE_SPS_PPS;  
1525 - }  
1526 -  
1527 - // 5bits, 7.3.1 NAL unit syntax,  
1528 - // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.  
1529 - // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame  
1530 - u_int8_t nal_unit_type = (char)data[0] & 0x1f;  
1531 -  
1532 - // 4bytes size of nalu:  
1533 - // NALUnitLength  
1534 - // Nbytes of nalu.  
1535 - // NALUnit  
1536 - int nb_packet = 4 + size;  
1537 - char* packet = new char[nb_packet];  
1538 - SrsAutoFree(char, packet);  
1539 -  
1540 - // use stream to generate the h264 packet.  
1541 - SrsStream stream;  
1542 - if ((ret = stream.initialize(packet, nb_packet)) != ERROR_SUCCESS) {  
1543 - return ret;  
1544 - }  
1545 -  
1546 - // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16  
1547 - // lengthSizeMinusOne, or NAL_unit_length, always use 4bytes size  
1548 - u_int32_t NAL_unit_length = size;  
1549 -  
1550 - // mux the avc NALU in "ISO Base Media File Format"  
1551 - // from H.264-AVC-ISO_IEC_14496-15.pdf, page 20  
1552 - // NALUnitLength  
1553 - stream.write_4bytes(NAL_unit_length);  
1554 - // NALUnit  
1555 - stream.write_bytes(data, size);  
1556 -  
1557 - // send out h264 packet.  
1558 - int8_t frame_type = SrsCodecVideoAVCFrameInterFrame;  
1559 - if (nal_unit_type != 1) {  
1560 - frame_type = SrsCodecVideoAVCFrameKeyFrame;  
1561 - }  
1562 - int8_t avc_packet_type = SrsCodecVideoAVCTypeNALU;  
1563 - return __srs_write_h264_packet(  
1564 - context, frame_type, avc_packet_type,  
1565 - packet, nb_packet, dts, pts  
1566 - );  
1567 -  
1568 - return ret;  
1569 -}  
1570 -  
1571 -/**  
1572 -* write h264 raw frame, maybe sps/pps/IPB-frame.  
1573 -*/  
1574 -int __srs_write_h264_raw_frame(Context* context,  
1575 - char* frame, int frame_size, u_int32_t dts, u_int32_t pts  
1576 -) {  
1577 - int ret = ERROR_SUCCESS;  
1578 -  
1579 - // ignore invalid frame,  
1580 - // atleast 1bytes for SPS to decode the type  
1581 - if (frame_size < 1) {  
1582 - return ret;  
1583 - }  
1584 -  
1585 - // 5bits, 7.3.1 NAL unit syntax,  
1586 - // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.  
1587 - // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame  
1588 - u_int8_t nal_unit_type = (char)frame[0] & 0x1f;  
1589 -  
1590 - if (nal_unit_type == 7) {  
1591 - // atleast 1bytes for SPS to decode the type, profile, constrain and level.  
1592 - if (frame_size < 4) {  
1593 - return ret;  
1594 - }  
1595 -  
1596 - std::string sps;  
1597 - sps.append(frame, frame_size);  
1598 -  
1599 - if (context->h264_sps == sps) {  
1600 - return ERROR_H264_DUPLICATED_SPS;  
1601 - }  
1602 - context->h264_sps_changed = true;  
1603 - context->h264_sps = sps;  
1604 -  
1605 - return __srs_write_h264_sps_pps(context, dts, pts);  
1606 - } else if (nal_unit_type == 8) {  
1607 -  
1608 - std::string pps;  
1609 - pps.append(frame, frame_size);  
1610 -  
1611 - if (context->h264_pps == pps) {  
1612 - return ERROR_H264_DUPLICATED_PPS;  
1613 - }  
1614 - context->h264_pps_changed = true;  
1615 - context->h264_pps = pps;  
1616 -  
1617 - return __srs_write_h264_sps_pps(context, dts, pts);  
1618 - } else {  
1619 - return __srs_write_h264_ipb_frame(context, frame, frame_size, dts, pts);  
1620 - }  
1621 -  
1622 - return ret;  
1623 -}  
1624 -  
1625 -/**  
1626 -* write h264 multiple frames, in annexb format.  
1627 -*/  
1628 -int srs_h264_write_raw_frames(srs_rtmp_t rtmp,  
1629 - char* frames, int frames_size, u_int32_t dts, u_int32_t pts  
1630 -) {  
1631 - int ret = ERROR_SUCCESS;  
1632 -  
1633 - srs_assert(frames != NULL);  
1634 - srs_assert(frames_size > 0);  
1635 -  
1636 - srs_assert(rtmp != NULL);  
1637 - Context* context = (Context*)rtmp;  
1638 -  
1639 - if ((ret = context->h264_raw_stream.initialize(frames, frames_size)) != ERROR_SUCCESS) {  
1640 - return ret;  
1641 - }  
1642 -  
1643 - // use the last error  
1644 - // @see https://github.com/winlinvip/simple-rtmp-server/issues/203  
1645 - // @see https://github.com/winlinvip/simple-rtmp-server/issues/204  
1646 - int error_code_return = ret;  
1647 -  
1648 - // send each frame.  
1649 - while (!context->h264_raw_stream.empty()) {  
1650 - // each frame must prefixed by annexb format.  
1651 - // about annexb, @see H.264-AVC-ISO_IEC_14496-10.pdf, page 211.  
1652 - int pnb_start_code = 0;  
1653 - if (!srs_avc_startswith_annexb(&context->h264_raw_stream, &pnb_start_code)) {  
1654 - return ERROR_H264_API_NO_PREFIXED;  
1655 - }  
1656 - int start = context->h264_raw_stream.pos() + pnb_start_code;  
1657 -  
1658 - // find the last frame prefixed by annexb format.  
1659 - context->h264_raw_stream.skip(pnb_start_code);  
1660 - while (!context->h264_raw_stream.empty()) {  
1661 - if (srs_avc_startswith_annexb(&context->h264_raw_stream, NULL)) {  
1662 - break;  
1663 - }  
1664 - context->h264_raw_stream.skip(1);  
1665 - }  
1666 - int size = context->h264_raw_stream.pos() - start;  
1667 -  
1668 - // send out the frame.  
1669 - char* frame = context->h264_raw_stream.data() + start;  
1670 -  
1671 - // it may be return error, but we must process all packets.  
1672 - if ((ret = __srs_write_h264_raw_frame(context, frame, size, dts, pts)) != ERROR_SUCCESS) {  
1673 - error_code_return = ret;  
1674 -  
1675 - // ignore known error, process all packets.  
1676 - if (srs_h264_is_dvbsp_error(ret)  
1677 - || srs_h264_is_duplicated_sps_error(ret)  
1678 - || srs_h264_is_duplicated_pps_error(ret)  
1679 - ) {  
1680 - continue;  
1681 - }  
1682 -  
1683 - return ret;  
1684 - }  
1685 - }  
1686 -  
1687 - return error_code_return;  
1688 -}  
1689 -  
1690 -srs_h264_bool srs_h264_is_dvbsp_error(int error_code)  
1691 -{  
1692 - return error_code == ERROR_H264_DROP_BEFORE_SPS_PPS;  
1693 -}  
1694 -  
1695 -srs_h264_bool srs_h264_is_duplicated_sps_error(int error_code)  
1696 -{  
1697 - return error_code == ERROR_H264_DUPLICATED_SPS;  
1698 -}  
1699 -  
1700 -srs_h264_bool srs_h264_is_duplicated_pps_error(int error_code)  
1701 -{  
1702 - return error_code == ERROR_H264_DUPLICATED_PPS;  
1703 -}  
1704 -  
1705 -int srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int* pnb_start_code)  
1706 -{  
1707 - SrsStream stream;  
1708 - if (stream.initialize(h264_raw_data, h264_raw_size) != ERROR_SUCCESS) {  
1709 - return false;  
1710 - }  
1711 -  
1712 - return srs_avc_startswith_annexb(&stream, pnb_start_code);  
1713 -}  
1714 -  
1715 int64_t srs_utils_get_time_ms() 1715 int64_t srs_utils_get_time_ms()
1716 { 1716 {
1717 srs_update_system_time_ms(); 1717 srs_update_system_time_ms();
@@ -264,164 +264,6 @@ extern int srs_rtmp_write_packet(srs_rtmp_t rtmp, @@ -264,164 +264,6 @@ extern int srs_rtmp_write_packet(srs_rtmp_t rtmp,
264 264
265 /************************************************************* 265 /*************************************************************
266 ************************************************************** 266 **************************************************************
267 -* flv codec  
268 -* @example /trunk/research/librtmp/srs_flv_injecter.c  
269 -* @example /trunk/research/librtmp/srs_flv_parser.c  
270 -* @example /trunk/research/librtmp/srs_ingest_flv.c  
271 -* @example /trunk/research/librtmp/srs_ingest_rtmp.c  
272 -**************************************************************  
273 -*************************************************************/  
274 -typedef void* srs_flv_t;  
275 -typedef int srs_flv_bool;  
276 -/* open flv file for both read/write. */  
277 -extern srs_flv_t srs_flv_open_read(const char* file);  
278 -extern srs_flv_t srs_flv_open_write(const char* file);  
279 -extern void srs_flv_close(srs_flv_t flv);  
280 -/**  
281 -* read the flv header. 9bytes header.  
282 -* @param header, @see E.2 The FLV header, flv_v10_1.pdf in SRS doc.  
283 -* 3bytes, signature, "FLV",  
284 -* 1bytes, version, 0x01,  
285 -* 1bytes, flags, UB[5] 0, UB[1] audio present, UB[1] 0, UB[1] video present.  
286 -* 4bytes, dataoffset, 0x09, The length of this header in bytes  
287 -*  
288 -* @return 0, success; otherswise, failed.  
289 -* @remark, drop the 4bytes zero previous tag size.  
290 -*/  
291 -extern int srs_flv_read_header(srs_flv_t flv, char header[9]);  
292 -/**  
293 -* read the flv tag header, 1bytes tag, 3bytes data_size,  
294 -* 4bytes time, 3bytes stream id.  
295 -* @param ptype, output the type of tag, macros:  
296 -* SRS_RTMP_TYPE_AUDIO, FlvTagAudio  
297 -* SRS_RTMP_TYPE_VIDEO, FlvTagVideo  
298 -* SRS_RTMP_TYPE_SCRIPT, FlvTagScript  
299 -* @param pdata_size, output the size of tag data.  
300 -* @param ptime, output the time of tag, the dts in ms.  
301 -*  
302 -* @return 0, success; otherswise, failed.  
303 -* @remark, user must ensure the next is a tag, srs never check it.  
304 -*/  
305 -extern int srs_flv_read_tag_header(srs_flv_t flv,  
306 - char* ptype, int32_t* pdata_size, u_int32_t* ptime  
307 -);  
308 -/**  
309 -* read the tag data. drop the 4bytes previous tag size  
310 -* @param data, the data to read, user alloc and free it.  
311 -* @param size, the size of data to read, get by srs_flv_read_tag_header().  
312 -* @remark, srs will ignore and drop the 4bytes previous tag size.  
313 -*/  
314 -extern int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size);  
315 -/**  
316 -* write the flv header. 9bytes header.  
317 -* @param header, @see E.2 The FLV header, flv_v10_1.pdf in SRS doc.  
318 -* 3bytes, signature, "FLV",  
319 -* 1bytes, version, 0x01,  
320 -* 1bytes, flags, UB[5] 0, UB[1] audio present, UB[1] 0, UB[1] video present.  
321 -* 4bytes, dataoffset, 0x09, The length of this header in bytes  
322 -*  
323 -* @return 0, success; otherswise, failed.  
324 -* @remark, auto write the 4bytes zero previous tag size.  
325 -*/  
326 -extern int srs_flv_write_header(srs_flv_t flv, char header[9]);  
327 -/**  
328 -* write the flv tag to file.  
329 -*  
330 -* @return 0, success; otherswise, failed.  
331 -* @remark, auto write the 4bytes zero previous tag size.  
332 -*/  
333 -/* write flv tag to file, auto write the 4bytes previous tag size */  
334 -extern int srs_flv_write_tag(srs_flv_t flv,  
335 - char type, int32_t time, char* data, int size  
336 -);  
337 -/**  
338 -* get the tag size, for flv injecter to adjust offset,  
339 -* size = tag_header(11B) + data_size + previous_tag(4B)  
340 -* @return the size of tag.  
341 -*/  
342 -extern int srs_flv_size_tag(int data_size);  
343 -/* file stream */  
344 -/* file stream tellg to get offset */  
345 -extern int64_t srs_flv_tellg(srs_flv_t flv);  
346 -/* seek file stream, offset is form the start of file */  
347 -extern void srs_flv_lseek(srs_flv_t flv, int64_t offset);  
348 -/* error code */  
349 -/* whether the error code indicates EOF */  
350 -extern srs_flv_bool srs_flv_is_eof(int error_code);  
351 -/* media codec */  
352 -/**  
353 -* whether the video body is sequence header  
354 -* @param data, the data of tag, read by srs_flv_read_tag_data().  
355 -* @param size, the size of tag, read by srs_flv_read_tag_data().  
356 -*/  
357 -extern srs_flv_bool srs_flv_is_sequence_header(char* data, int32_t size);  
358 -/**  
359 -* whether the video body is keyframe  
360 -* @param data, the data of tag, read by srs_flv_read_tag_data().  
361 -* @param size, the size of tag, read by srs_flv_read_tag_data().  
362 -*/  
363 -extern srs_flv_bool srs_flv_is_keyframe(char* data, int32_t size);  
364 -  
365 -/*************************************************************  
366 -**************************************************************  
367 -* amf0 codec  
368 -* @example /trunk/research/librtmp/srs_ingest_flv.c  
369 -* @example /trunk/research/librtmp/srs_ingest_rtmp.c  
370 -**************************************************************  
371 -*************************************************************/  
372 -/* the output handler. */  
373 -typedef void* srs_amf0_t;  
374 -typedef int srs_amf0_bool;  
375 -typedef double srs_amf0_number;  
376 -/**  
377 -* parse amf0 from data.  
378 -* @param nparsed, the parsed size, NULL to ignore.  
379 -* @return the parsed amf0 object. NULL for error.  
380 -*/  
381 -extern srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed);  
382 -extern srs_amf0_t srs_amf0_create_number(srs_amf0_number value);  
383 -extern srs_amf0_t srs_amf0_create_ecma_array();  
384 -extern srs_amf0_t srs_amf0_create_strict_array();  
385 -extern srs_amf0_t srs_amf0_create_object();  
386 -extern void srs_amf0_free(srs_amf0_t amf0);  
387 -extern void srs_amf0_free_bytes(char* data);  
388 -/* size and to bytes */  
389 -extern int srs_amf0_size(srs_amf0_t amf0);  
390 -extern int srs_amf0_serialize(srs_amf0_t amf0, char* data, int size);  
391 -/* type detecter */  
392 -extern srs_amf0_bool srs_amf0_is_string(srs_amf0_t amf0);  
393 -extern srs_amf0_bool srs_amf0_is_boolean(srs_amf0_t amf0);  
394 -extern srs_amf0_bool srs_amf0_is_number(srs_amf0_t amf0);  
395 -extern srs_amf0_bool srs_amf0_is_null(srs_amf0_t amf0);  
396 -extern srs_amf0_bool srs_amf0_is_object(srs_amf0_t amf0);  
397 -extern srs_amf0_bool srs_amf0_is_ecma_array(srs_amf0_t amf0);  
398 -extern srs_amf0_bool srs_amf0_is_strict_array(srs_amf0_t amf0);  
399 -/* value converter */  
400 -extern const char* srs_amf0_to_string(srs_amf0_t amf0);  
401 -extern srs_amf0_bool srs_amf0_to_boolean(srs_amf0_t amf0);  
402 -extern srs_amf0_number srs_amf0_to_number(srs_amf0_t amf0);  
403 -/* value setter */  
404 -extern void srs_amf0_set_number(srs_amf0_t amf0, srs_amf0_number value);  
405 -/* object value converter */  
406 -extern int srs_amf0_object_property_count(srs_amf0_t amf0);  
407 -extern const char* srs_amf0_object_property_name_at(srs_amf0_t amf0, int index);  
408 -extern srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index);  
409 -extern srs_amf0_t srs_amf0_object_property(srs_amf0_t amf0, const char* name);  
410 -extern void srs_amf0_object_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value);  
411 -extern void srs_amf0_object_clear(srs_amf0_t amf0);  
412 -/* ecma array value converter */  
413 -extern int srs_amf0_ecma_array_property_count(srs_amf0_t amf0);  
414 -extern const char* srs_amf0_ecma_array_property_name_at(srs_amf0_t amf0, int index);  
415 -extern srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index);  
416 -extern srs_amf0_t srs_amf0_ecma_array_property(srs_amf0_t amf0, const char* name);  
417 -extern void srs_amf0_ecma_array_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value);  
418 -/* strict array value converter */  
419 -extern int srs_amf0_strict_array_property_count(srs_amf0_t amf0);  
420 -extern srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index);  
421 -extern void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value);  
422 -  
423 -/*************************************************************  
424 -**************************************************************  
425 * audio raw codec 267 * audio raw codec
426 ************************************************************** 268 **************************************************************
427 *************************************************************/ 269 *************************************************************/
@@ -585,6 +427,164 @@ extern int srs_h264_startswith_annexb( @@ -585,6 +427,164 @@ extern int srs_h264_startswith_annexb(
585 427
586 /************************************************************* 428 /*************************************************************
587 ************************************************************** 429 **************************************************************
  430 +* flv codec
  431 +* @example /trunk/research/librtmp/srs_flv_injecter.c
  432 +* @example /trunk/research/librtmp/srs_flv_parser.c
  433 +* @example /trunk/research/librtmp/srs_ingest_flv.c
  434 +* @example /trunk/research/librtmp/srs_ingest_rtmp.c
  435 +**************************************************************
  436 +*************************************************************/
  437 +typedef void* srs_flv_t;
  438 +typedef int srs_flv_bool;
  439 +/* open flv file for both read/write. */
  440 +extern srs_flv_t srs_flv_open_read(const char* file);
  441 +extern srs_flv_t srs_flv_open_write(const char* file);
  442 +extern void srs_flv_close(srs_flv_t flv);
  443 +/**
  444 +* read the flv header. 9bytes header.
  445 +* @param header, @see E.2 The FLV header, flv_v10_1.pdf in SRS doc.
  446 +* 3bytes, signature, "FLV",
  447 +* 1bytes, version, 0x01,
  448 +* 1bytes, flags, UB[5] 0, UB[1] audio present, UB[1] 0, UB[1] video present.
  449 +* 4bytes, dataoffset, 0x09, The length of this header in bytes
  450 +*
  451 +* @return 0, success; otherswise, failed.
  452 +* @remark, drop the 4bytes zero previous tag size.
  453 +*/
  454 +extern int srs_flv_read_header(srs_flv_t flv, char header[9]);
  455 +/**
  456 +* read the flv tag header, 1bytes tag, 3bytes data_size,
  457 +* 4bytes time, 3bytes stream id.
  458 +* @param ptype, output the type of tag, macros:
  459 +* SRS_RTMP_TYPE_AUDIO, FlvTagAudio
  460 +* SRS_RTMP_TYPE_VIDEO, FlvTagVideo
  461 +* SRS_RTMP_TYPE_SCRIPT, FlvTagScript
  462 +* @param pdata_size, output the size of tag data.
  463 +* @param ptime, output the time of tag, the dts in ms.
  464 +*
  465 +* @return 0, success; otherswise, failed.
  466 +* @remark, user must ensure the next is a tag, srs never check it.
  467 +*/
  468 +extern int srs_flv_read_tag_header(srs_flv_t flv,
  469 + char* ptype, int32_t* pdata_size, u_int32_t* ptime
  470 +);
  471 +/**
  472 +* read the tag data. drop the 4bytes previous tag size
  473 +* @param data, the data to read, user alloc and free it.
  474 +* @param size, the size of data to read, get by srs_flv_read_tag_header().
  475 +* @remark, srs will ignore and drop the 4bytes previous tag size.
  476 +*/
  477 +extern int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size);
  478 +/**
  479 +* write the flv header. 9bytes header.
  480 +* @param header, @see E.2 The FLV header, flv_v10_1.pdf in SRS doc.
  481 +* 3bytes, signature, "FLV",
  482 +* 1bytes, version, 0x01,
  483 +* 1bytes, flags, UB[5] 0, UB[1] audio present, UB[1] 0, UB[1] video present.
  484 +* 4bytes, dataoffset, 0x09, The length of this header in bytes
  485 +*
  486 +* @return 0, success; otherswise, failed.
  487 +* @remark, auto write the 4bytes zero previous tag size.
  488 +*/
  489 +extern int srs_flv_write_header(srs_flv_t flv, char header[9]);
  490 +/**
  491 +* write the flv tag to file.
  492 +*
  493 +* @return 0, success; otherswise, failed.
  494 +* @remark, auto write the 4bytes zero previous tag size.
  495 +*/
  496 +/* write flv tag to file, auto write the 4bytes previous tag size */
  497 +extern int srs_flv_write_tag(srs_flv_t flv,
  498 + char type, int32_t time, char* data, int size
  499 +);
  500 +/**
  501 +* get the tag size, for flv injecter to adjust offset,
  502 +* size = tag_header(11B) + data_size + previous_tag(4B)
  503 +* @return the size of tag.
  504 +*/
  505 +extern int srs_flv_size_tag(int data_size);
  506 +/* file stream */
  507 +/* file stream tellg to get offset */
  508 +extern int64_t srs_flv_tellg(srs_flv_t flv);
  509 +/* seek file stream, offset is form the start of file */
  510 +extern void srs_flv_lseek(srs_flv_t flv, int64_t offset);
  511 +/* error code */
  512 +/* whether the error code indicates EOF */
  513 +extern srs_flv_bool srs_flv_is_eof(int error_code);
  514 +/* media codec */
  515 +/**
  516 +* whether the video body is sequence header
  517 +* @param data, the data of tag, read by srs_flv_read_tag_data().
  518 +* @param size, the size of tag, read by srs_flv_read_tag_data().
  519 +*/
  520 +extern srs_flv_bool srs_flv_is_sequence_header(char* data, int32_t size);
  521 +/**
  522 +* whether the video body is keyframe
  523 +* @param data, the data of tag, read by srs_flv_read_tag_data().
  524 +* @param size, the size of tag, read by srs_flv_read_tag_data().
  525 +*/
  526 +extern srs_flv_bool srs_flv_is_keyframe(char* data, int32_t size);
  527 +
  528 +/*************************************************************
  529 +**************************************************************
  530 +* amf0 codec
  531 +* @example /trunk/research/librtmp/srs_ingest_flv.c
  532 +* @example /trunk/research/librtmp/srs_ingest_rtmp.c
  533 +**************************************************************
  534 +*************************************************************/
  535 +/* the output handler. */
  536 +typedef void* srs_amf0_t;
  537 +typedef int srs_amf0_bool;
  538 +typedef double srs_amf0_number;
  539 +/**
  540 +* parse amf0 from data.
  541 +* @param nparsed, the parsed size, NULL to ignore.
  542 +* @return the parsed amf0 object. NULL for error.
  543 +*/
  544 +extern srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed);
  545 +extern srs_amf0_t srs_amf0_create_number(srs_amf0_number value);
  546 +extern srs_amf0_t srs_amf0_create_ecma_array();
  547 +extern srs_amf0_t srs_amf0_create_strict_array();
  548 +extern srs_amf0_t srs_amf0_create_object();
  549 +extern void srs_amf0_free(srs_amf0_t amf0);
  550 +extern void srs_amf0_free_bytes(char* data);
  551 +/* size and to bytes */
  552 +extern int srs_amf0_size(srs_amf0_t amf0);
  553 +extern int srs_amf0_serialize(srs_amf0_t amf0, char* data, int size);
  554 +/* type detecter */
  555 +extern srs_amf0_bool srs_amf0_is_string(srs_amf0_t amf0);
  556 +extern srs_amf0_bool srs_amf0_is_boolean(srs_amf0_t amf0);
  557 +extern srs_amf0_bool srs_amf0_is_number(srs_amf0_t amf0);
  558 +extern srs_amf0_bool srs_amf0_is_null(srs_amf0_t amf0);
  559 +extern srs_amf0_bool srs_amf0_is_object(srs_amf0_t amf0);
  560 +extern srs_amf0_bool srs_amf0_is_ecma_array(srs_amf0_t amf0);
  561 +extern srs_amf0_bool srs_amf0_is_strict_array(srs_amf0_t amf0);
  562 +/* value converter */
  563 +extern const char* srs_amf0_to_string(srs_amf0_t amf0);
  564 +extern srs_amf0_bool srs_amf0_to_boolean(srs_amf0_t amf0);
  565 +extern srs_amf0_number srs_amf0_to_number(srs_amf0_t amf0);
  566 +/* value setter */
  567 +extern void srs_amf0_set_number(srs_amf0_t amf0, srs_amf0_number value);
  568 +/* object value converter */
  569 +extern int srs_amf0_object_property_count(srs_amf0_t amf0);
  570 +extern const char* srs_amf0_object_property_name_at(srs_amf0_t amf0, int index);
  571 +extern srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index);
  572 +extern srs_amf0_t srs_amf0_object_property(srs_amf0_t amf0, const char* name);
  573 +extern void srs_amf0_object_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value);
  574 +extern void srs_amf0_object_clear(srs_amf0_t amf0);
  575 +/* ecma array value converter */
  576 +extern int srs_amf0_ecma_array_property_count(srs_amf0_t amf0);
  577 +extern const char* srs_amf0_ecma_array_property_name_at(srs_amf0_t amf0, int index);
  578 +extern srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index);
  579 +extern srs_amf0_t srs_amf0_ecma_array_property(srs_amf0_t amf0, const char* name);
  580 +extern void srs_amf0_ecma_array_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value);
  581 +/* strict array value converter */
  582 +extern int srs_amf0_strict_array_property_count(srs_amf0_t amf0);
  583 +extern srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index);
  584 +extern void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value);
  585 +
  586 +/*************************************************************
  587 +**************************************************************
588 * utilities 588 * utilities
589 ************************************************************** 589 **************************************************************
590 *************************************************************/ 590 *************************************************************/