1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

For #913, KAFKA, RTSP support complex error.

This commit is contained in:
winlin 2018-01-01 10:30:31 +08:00
parent 70a20ffadb
commit 15aea686c3
6 changed files with 508 additions and 713 deletions

File diff suppressed because it is too large Load diff

View file

@ -80,8 +80,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
/** /**
@ -109,8 +109,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
/** /**
@ -177,50 +177,44 @@ public:
return s; return s;
} }
virtual int encode(SrsBuffer* buf) virtual srs_error_t encode(SrsBuffer* buf)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
if (!buf->require(4)) { if (!buf->require(4)) {
ret = ERROR_KAFKA_CODEC_ARRAY; return srs_error_new(ERROR_KAFKA_CODEC_ARRAY, "requires 4 only %d bytes", buf->left());
srs_error("kafka encode array failed. ret=%d", ret);
return ret;
} }
buf->write_4bytes(length); buf->write_4bytes(length);
for (SrsIterator it = elems.begin(); it != elems.end(); ++it) { for (SrsIterator it = elems.begin(); it != elems.end(); ++it) {
T* elem = *it; T* elem = *it;
if ((ret = elem->encode(buf)) != ERROR_SUCCESS) { if ((err = elem->encode(buf)) != srs_success) {
srs_error("kafka encode array elem failed. ret=%d", ret); return srs_error_wrap(err, "encode elem");
return ret;
} }
} }
return ret; return err;
} }
virtual int decode(SrsBuffer* buf) virtual srs_error_t decode(SrsBuffer* buf)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
if (!buf->require(4)) { if (!buf->require(4)) {
ret = ERROR_KAFKA_CODEC_ARRAY; return srs_error_new(ERROR_KAFKA_CODEC_ARRAY, "requires 4 only %d bytes", buf->left());
srs_error("kafka decode array failed. ret=%d", ret);
return ret;
} }
length = buf->read_4bytes(); length = buf->read_4bytes();
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
T* elem = new T(); T* elem = new T();
if ((ret = elem->decode(buf)) != ERROR_SUCCESS) { if ((err = elem->decode(buf)) != srs_success) {
srs_error("kafka decode array elem failed. ret=%d", ret);
srs_freep(elem); srs_freep(elem);
return ret; return srs_error_wrap(err, "decode elem");
} }
elems.push_back(elem); elems.push_back(elem);
} }
return ret; return err;
} }
}; };
template<> template<>
@ -263,14 +257,13 @@ public:
{ {
return 4 + 4 * (int)elems.size(); return 4 + 4 * (int)elems.size();
} }
virtual int encode(SrsBuffer* buf) virtual srs_error_t encode(SrsBuffer* buf)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
if (!buf->require(4 + sizeof(int32_t) * (int)elems.size())) { int nb_required = 4 + sizeof(int32_t) * (int)elems.size();
ret = ERROR_KAFKA_CODEC_ARRAY; if (!buf->require(nb_required)) {
srs_error("kafka encode array failed. ret=%d", ret); return srs_error_new(ERROR_KAFKA_CODEC_ARRAY, "requires %d only %d bytes", nb_required, buf->left());
return ret;
} }
buf->write_4bytes(length); buf->write_4bytes(length);
@ -279,24 +272,20 @@ public:
buf->write_4bytes(elem); buf->write_4bytes(elem);
} }
return ret; return err;
} }
virtual int decode(SrsBuffer* buf) virtual srs_error_t decode(SrsBuffer* buf)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
if (!buf->require(4)) { if (!buf->require(4)) {
ret = ERROR_KAFKA_CODEC_ARRAY; return srs_error_new(ERROR_KAFKA_CODEC_ARRAY, "requires 4 only %d bytes", buf->left());
srs_error("kafka decode array failed. ret=%d", ret);
return ret;
} }
length = buf->read_4bytes(); length = buf->read_4bytes();
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
if (!buf->require(sizeof(int32_t))) { if (!buf->require(sizeof(int32_t))) {
ret = ERROR_KAFKA_CODEC_ARRAY; return srs_error_new(ERROR_KAFKA_CODEC_ARRAY, "requires %d only %d bytes", sizeof(int32_t), buf->left());
srs_error("kafka decode array elem failed. ret=%d", ret);
return ret;
} }
@ -304,7 +293,7 @@ public:
elems.push_back(elem); elems.push_back(elem);
} }
return ret; return err;
} }
}; };
@ -414,8 +403,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
/** /**
@ -480,8 +469,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
/** /**
@ -538,7 +527,7 @@ public:
/** /**
* create message from json object. * create message from json object.
*/ */
virtual int create(SrsJsonObject* obj); virtual srs_error_t create(SrsJsonObject* obj);
private: private:
/** /**
* get the raw message, bytes after the message_size. * get the raw message, bytes after the message_size.
@ -547,8 +536,8 @@ private:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
/** /**
@ -568,8 +557,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
/** /**
@ -599,8 +588,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
/** /**
@ -622,8 +611,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
/** /**
@ -652,8 +641,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
/** /**
@ -672,8 +661,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
struct SrsKafkaPartitionMetadata : public ISrsCodec struct SrsKafkaPartitionMetadata : public ISrsCodec
{ {
@ -689,8 +678,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
struct SrsKafkaTopicMetadata : public ISrsCodec struct SrsKafkaTopicMetadata : public ISrsCodec
{ {
@ -704,8 +693,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
/** /**
@ -727,8 +716,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
@ -754,8 +743,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
struct SrsKafkaProducerTopicMessages : public ISrsCodec struct SrsKafkaProducerTopicMessages : public ISrsCodec
{ {
@ -771,8 +760,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
/** /**
@ -815,8 +804,8 @@ public:
// interface ISrsCodec // interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual int encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf); virtual srs_error_t decode(SrsBuffer* buf);
}; };
/** /**
@ -875,26 +864,25 @@ public:
* write the message to kafka server. * write the message to kafka server.
* @param msg the msg to send. user must not free it again. * @param msg the msg to send. user must not free it again.
*/ */
virtual int send_and_free_message(SrsKafkaRequest* msg); virtual srs_error_t send_and_free_message(SrsKafkaRequest* msg);
/** /**
* read the message from kafka server. * read the message from kafka server.
* @param pmsg output the received message. user must free it. * @param pmsg output the received message. user must free it.
*/ */
virtual int recv_message(SrsKafkaResponse** pmsg); virtual srs_error_t recv_message(SrsKafkaResponse** pmsg);
public: public:
/** /**
* expect specified message. * expect specified message.
*/ */
template<typename T> template<typename T>
int expect_message(T** pmsg) srs_error_t expect_message(T** pmsg)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
while (true) { while (true) {
SrsKafkaResponse* res = NULL; SrsKafkaResponse* res = NULL;
if ((ret = recv_message(&res)) != ERROR_SUCCESS) { if ((err = recv_message(&res)) != srs_success) {
srs_error("recv response failed. ret=%d", ret); return srs_error_wrap(err, "recv message");
return ret;
} }
// drop not matched. // drop not matched.
@ -909,7 +897,7 @@ public:
break; break;
} }
return ret; return err;
} }
}; };
@ -927,11 +915,11 @@ public:
/** /**
* fetch the metadata from broker for topic. * fetch the metadata from broker for topic.
*/ */
virtual int fetch_metadata(std::string topic, SrsKafkaTopicMetadataResponse** pmsg); virtual srs_error_t fetch_metadata(std::string topic, SrsKafkaTopicMetadataResponse** pmsg);
/** /**
* write the messages to partition of topic. * write the messages to partition of topic.
*/ */
virtual int write_messages(std::string topic, int32_t partition, std::vector<SrsJsonObject*>& msgs); virtual srs_error_t write_messages(std::string topic, int32_t partition, std::vector<SrsJsonObject*>& msgs);
}; };
// convert kafka array[string] to vector[string] // convert kafka array[string] to vector[string]

View file

@ -41,9 +41,9 @@ SrsRawH264Stream::~SrsRawH264Stream()
{ {
} }
int SrsRawH264Stream::annexb_demux(SrsBuffer* stream, char** pframe, int* pnb_frame) srs_error_t SrsRawH264Stream::annexb_demux(SrsBuffer* stream, char** pframe, int* pnb_frame)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
*pframe = NULL; *pframe = NULL;
*pnb_frame = 0; *pnb_frame = 0;
@ -53,7 +53,7 @@ int SrsRawH264Stream::annexb_demux(SrsBuffer* stream, char** pframe, int* pnb_fr
// about annexb, @see ISO_IEC_14496-10-AVC-2003.pdf, page 211. // about annexb, @see ISO_IEC_14496-10-AVC-2003.pdf, page 211.
int pnb_start_code = 0; int pnb_start_code = 0;
if (!srs_avc_startswith_annexb(stream, &pnb_start_code)) { if (!srs_avc_startswith_annexb(stream, &pnb_start_code)) {
return ERROR_H264_API_NO_PREFIXED; return srs_error_new(ERROR_H264_API_NO_PREFIXED, "annexb start code");
} }
int start = stream->pos() + pnb_start_code; int start = stream->pos() + pnb_start_code;
@ -72,7 +72,7 @@ int SrsRawH264Stream::annexb_demux(SrsBuffer* stream, char** pframe, int* pnb_fr
break; break;
} }
return ret; return err;
} }
bool SrsRawH264Stream::is_sps(char* frame, int nb_frame) bool SrsRawH264Stream::is_sps(char* frame, int nb_frame)
@ -99,13 +99,13 @@ bool SrsRawH264Stream::is_pps(char* frame, int nb_frame)
return nal_unit_type == 8; return nal_unit_type == 8;
} }
int SrsRawH264Stream::sps_demux(char* frame, int nb_frame, string& sps) srs_error_t SrsRawH264Stream::sps_demux(char* frame, int nb_frame, string& sps)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// atleast 1bytes for SPS to decode the type, profile, constrain and level. // atleast 1bytes for SPS to decode the type, profile, constrain and level.
if (nb_frame < 4) { if (nb_frame < 4) {
return ret; return err;
} }
sps = ""; sps = "";
@ -115,15 +115,15 @@ int SrsRawH264Stream::sps_demux(char* frame, int nb_frame, string& sps)
// should never be empty. // should never be empty.
if (sps.empty()) { if (sps.empty()) {
return ERROR_STREAM_CASTER_AVC_SPS; return srs_error_new(ERROR_STREAM_CASTER_AVC_SPS, "no sps");
} }
return ret; return err;
} }
int SrsRawH264Stream::pps_demux(char* frame, int nb_frame, string& pps) srs_error_t SrsRawH264Stream::pps_demux(char* frame, int nb_frame, string& pps)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
pps = ""; pps = "";
if (nb_frame > 0) { if (nb_frame > 0) {
@ -132,15 +132,15 @@ int SrsRawH264Stream::pps_demux(char* frame, int nb_frame, string& pps)
// should never be empty. // should never be empty.
if (pps.empty()) { if (pps.empty()) {
return ERROR_STREAM_CASTER_AVC_PPS; return srs_error_new(ERROR_STREAM_CASTER_AVC_PPS, "no pps");
} }
return ret; return err;
} }
int SrsRawH264Stream::mux_sequence_header(string sps, string pps, uint32_t dts, uint32_t pts, string& sh) srs_error_t SrsRawH264Stream::mux_sequence_header(string sps, string pps, uint32_t dts, uint32_t pts, string& sh)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// 5bytes sps/pps header: // 5bytes sps/pps header:
// configurationVersion, AVCProfileIndication, profile_compatibility, // configurationVersion, AVCProfileIndication, profile_compatibility,
@ -160,10 +160,7 @@ int SrsRawH264Stream::mux_sequence_header(string sps, string pps, uint32_t dts,
SrsAutoFreeA(char, packet); SrsAutoFreeA(char, packet);
// use stream to generate the h264 packet. // use stream to generate the h264 packet.
SrsBuffer stream; SrsBuffer stream(packet, nb_packet);
if ((ret = stream.initialize(packet, nb_packet)) != ERROR_SUCCESS) {
return ret;
}
// decode the SPS: // decode the SPS:
// @see: 7.3.2.1.1, ISO_IEC_14496-10-AVC-2012.pdf, page 62 // @see: 7.3.2.1.1, ISO_IEC_14496-10-AVC-2012.pdf, page 62
@ -223,12 +220,12 @@ int SrsRawH264Stream::mux_sequence_header(string sps, string pps, uint32_t dts,
sh = ""; sh = "";
sh.append(packet, nb_packet); sh.append(packet, nb_packet);
return ret; return err;
} }
int SrsRawH264Stream::mux_ipb_frame(char* frame, int nb_frame, string& ibp) srs_error_t SrsRawH264Stream::mux_ipb_frame(char* frame, int nb_frame, string& ibp)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// 4bytes size of nalu: // 4bytes size of nalu:
// NALUnitLength // NALUnitLength
@ -239,10 +236,7 @@ int SrsRawH264Stream::mux_ipb_frame(char* frame, int nb_frame, string& ibp)
SrsAutoFreeA(char, packet); SrsAutoFreeA(char, packet);
// use stream to generate the h264 packet. // use stream to generate the h264 packet.
SrsBuffer stream; SrsBuffer stream(packet, nb_packet);
if ((ret = stream.initialize(packet, nb_packet)) != ERROR_SUCCESS) {
return ret;
}
// 5.3.4.2.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 16 // 5.3.4.2.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 16
// lengthSizeMinusOne, or NAL_unit_length, always use 4bytes size // lengthSizeMinusOne, or NAL_unit_length, always use 4bytes size
@ -258,12 +252,12 @@ int SrsRawH264Stream::mux_ipb_frame(char* frame, int nb_frame, string& ibp)
ibp = ""; ibp = "";
ibp.append(packet, nb_packet); ibp.append(packet, nb_packet);
return ret; return err;
} }
int SrsRawH264Stream::mux_avc2flv(string video, int8_t frame_type, int8_t avc_packet_type, uint32_t dts, uint32_t pts, char** flv, int* nb_flv) srs_error_t SrsRawH264Stream::mux_avc2flv(string video, int8_t frame_type, int8_t avc_packet_type, uint32_t dts, uint32_t pts, char** flv, int* nb_flv)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// for h264 in RTMP video payload, there is 5bytes header: // for h264 in RTMP video payload, there is 5bytes header:
// 1bytes, FrameType | CodecID // 1bytes, FrameType | CodecID
@ -299,7 +293,7 @@ int SrsRawH264Stream::mux_avc2flv(string video, int8_t frame_type, int8_t avc_pa
*flv = data; *flv = data;
*nb_flv = size; *nb_flv = size;
return ret; return err;
} }
SrsRawAacStream::SrsRawAacStream() SrsRawAacStream::SrsRawAacStream()
@ -310,9 +304,9 @@ SrsRawAacStream::~SrsRawAacStream()
{ {
} }
int SrsRawAacStream::adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec) srs_error_t SrsRawAacStream::adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
while (!stream->empty()) { while (!stream->empty()) {
int adts_header_start = stream->pos(); int adts_header_start = stream->pos();
@ -337,12 +331,12 @@ int SrsRawAacStream::adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame
// else // else
// require(9bytes)=72bits // require(9bytes)=72bits
if (!stream->require(7)) { if (!stream->require(7)) {
return ERROR_AAC_ADTS_HEADER; return srs_error_new(ERROR_AAC_ADTS_HEADER, "requires 7 only %d bytes", stream->left());
} }
// for aac, the frame must be ADTS format. // for aac, the frame must be ADTS format.
if (!srs_aac_startswith_adts(stream)) { if (!srs_aac_startswith_adts(stream)) {
return ERROR_AAC_REQUIRED_ADTS; return srs_error_new(ERROR_AAC_REQUIRED_ADTS, "not adts");
} }
// syncword 12 bslbf // syncword 12 bslbf
@ -362,8 +356,6 @@ int SrsRawAacStream::adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame
* and set to '0' if the audio data are MPEG-4. See also ISO/IEC 11172-3, subclause 2.4.2.3. * and set to '0' if the audio data are MPEG-4. See also ISO/IEC 11172-3, subclause 2.4.2.3.
*/ */
if (id != 0x01) { if (id != 0x01) {
srs_info("adts: id must be 1(aac), actual 0(mp4a). ret=%d", ret);
// well, some system always use 0, but actually is aac format. // well, some system always use 0, but actually is aac format.
// for example, houjian vod ts always set the aac id to 0, actually 1. // for example, houjian vod ts always set the aac id to 0, actually 1.
// we just ignore it, and alwyas use 1(aac) to demux. // we just ignore it, and alwyas use 1(aac) to demux.
@ -406,7 +398,7 @@ int SrsRawAacStream::adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame
// adts_error_check(), 1.A.2.2.3 Error detection // adts_error_check(), 1.A.2.2.3 Error detection
if (!protection_absent) { if (!protection_absent) {
if (!stream->require(2)) { if (!stream->require(2)) {
return ERROR_AAC_ADTS_HEADER; return srs_error_new(ERROR_AAC_ADTS_HEADER, "requires 2 only %d bytes", stream->left());
} }
// crc_check 16 Rpchof // crc_check 16 Rpchof
/*int16_t crc_check = */stream->read_2bytes(); /*int16_t crc_check = */stream->read_2bytes();
@ -419,7 +411,7 @@ int SrsRawAacStream::adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame
int adts_header_size = stream->pos() - adts_header_start; int adts_header_size = stream->pos() - adts_header_start;
int raw_data_size = frame_length - adts_header_size; int raw_data_size = frame_length - adts_header_size;
if (!stream->require(raw_data_size)) { if (!stream->require(raw_data_size)) {
return ERROR_AAC_ADTS_HEADER; return srs_error_new(ERROR_AAC_ADTS_HEADER, "requires %d only %d bytes", raw_data_size, stream->left());
} }
// the codec info. // the codec info.
@ -456,16 +448,16 @@ int SrsRawAacStream::adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame
break; break;
} }
return ret; return err;
} }
int SrsRawAacStream::mux_sequence_header(SrsRawAacStreamCodec* codec, string& sh) srs_error_t SrsRawAacStream::mux_sequence_header(SrsRawAacStreamCodec* codec, string& sh)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// only support aac profile 1-4. // only support aac profile 1-4.
if (codec->aac_object == SrsAacObjectTypeReserved) { if (codec->aac_object == SrsAacObjectTypeReserved) {
return ERROR_AAC_DATA_INVALID; return srs_error_new(ERROR_AAC_DATA_INVALID, "invalid aac object");
} }
SrsAacObjectType audioObjectType = codec->aac_object; SrsAacObjectType audioObjectType = codec->aac_object;
@ -500,7 +492,7 @@ int SrsRawAacStream::mux_sequence_header(SrsRawAacStreamCodec* codec, string& sh
sh += ch; sh += ch;
ch = (samplingFrequencyIndex << 7) & 0x80; ch = (samplingFrequencyIndex << 7) & 0x80;
if (samplingFrequencyIndex == 0x0f) { if (samplingFrequencyIndex == 0x0f) {
return ERROR_AAC_DATA_INVALID; return srs_error_new(ERROR_AAC_DATA_INVALID, "invalid sampling frequency index");
} }
// 7bits left. // 7bits left.
@ -515,12 +507,12 @@ int SrsRawAacStream::mux_sequence_header(SrsRawAacStreamCodec* codec, string& sh
// extensionFlag; 1 bslbf // extensionFlag; 1 bslbf
sh += ch; sh += ch;
return ret; return err;
} }
int SrsRawAacStream::mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec* codec, uint32_t dts, char** flv, int* nb_flv) srs_error_t SrsRawAacStream::mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec* codec, uint32_t dts, char** flv, int* nb_flv)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
char sound_format = codec->sound_format; char sound_format = codec->sound_format;
char sound_type = codec->sound_type; char sound_type = codec->sound_type;
@ -554,6 +546,6 @@ int SrsRawAacStream::mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec
*flv = data; *flv = data;
*nb_flv = size; *nb_flv = size;
return ret; return err;
} }

View file

@ -47,7 +47,7 @@ public:
* @param pframe the output h.264 frame in stream. user should never free it. * @param pframe the output h.264 frame in stream. user should never free it.
* @param pnb_frame the output h.264 frame size. * @param pnb_frame the output h.264 frame size.
*/ */
virtual int annexb_demux(SrsBuffer* stream, char** pframe, int* pnb_frame); virtual srs_error_t annexb_demux(SrsBuffer* stream, char** pframe, int* pnb_frame);
/** /**
* whether the frame is sps or pps. * whether the frame is sps or pps.
*/ */
@ -57,22 +57,22 @@ public:
* demux the sps or pps to string. * demux the sps or pps to string.
* @param sps/pps output the sps/pps. * @param sps/pps output the sps/pps.
*/ */
virtual int sps_demux(char* frame, int nb_frame, std::string& sps); virtual srs_error_t sps_demux(char* frame, int nb_frame, std::string& sps);
virtual int pps_demux(char* frame, int nb_frame, std::string& pps); virtual srs_error_t pps_demux(char* frame, int nb_frame, std::string& pps);
public: public:
/** /**
* h264 raw data to h264 packet, without flv payload header. * h264 raw data to h264 packet, without flv payload header.
* mux the sps/pps to flv sequence header packet. * mux the sps/pps to flv sequence header packet.
* @param sh output the sequence header. * @param sh output the sequence header.
*/ */
virtual int mux_sequence_header(std::string sps, std::string pps, uint32_t dts, uint32_t pts, std::string& sh); virtual srs_error_t mux_sequence_header(std::string sps, std::string pps, uint32_t dts, uint32_t pts, std::string& sh);
/** /**
* h264 raw data to h264 packet, without flv payload header. * h264 raw data to h264 packet, without flv payload header.
* mux the ibp to flv ibp packet. * mux the ibp to flv ibp packet.
* @param ibp output the packet. * @param ibp output the packet.
* @param frame_type output the frame type. * @param frame_type output the frame type.
*/ */
virtual int mux_ipb_frame(char* frame, int nb_frame, std::string& ibp); virtual srs_error_t mux_ipb_frame(char* frame, int nb_frame, std::string& ibp);
/** /**
* mux the avc video packet to flv video packet. * mux the avc video packet to flv video packet.
* @param frame_type, SrsVideoAvcFrameTypeKeyFrame or SrsVideoAvcFrameTypeInterFrame. * @param frame_type, SrsVideoAvcFrameTypeKeyFrame or SrsVideoAvcFrameTypeInterFrame.
@ -81,7 +81,7 @@ public:
* @param flv output the muxed flv packet. * @param flv output the muxed flv packet.
* @param nb_flv output the muxed flv size. * @param nb_flv output the muxed flv size.
*/ */
virtual int mux_avc2flv(std::string video, int8_t frame_type, int8_t avc_packet_type, uint32_t dts, uint32_t pts, char** flv, int* nb_flv); virtual srs_error_t mux_avc2flv(std::string video, int8_t frame_type, int8_t avc_packet_type, uint32_t dts, uint32_t pts, char** flv, int* nb_flv);
}; };
/** /**
@ -119,13 +119,13 @@ public:
* @param pnb_frame the output aac frame size. * @param pnb_frame the output aac frame size.
* @param codec the output codec info. * @param codec the output codec info.
*/ */
virtual int adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec); virtual srs_error_t adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec);
/** /**
* aac raw data to aac packet, without flv payload header. * aac raw data to aac packet, without flv payload header.
* mux the aac specific config to flv sequence header packet. * mux the aac specific config to flv sequence header packet.
* @param sh output the sequence header. * @param sh output the sequence header.
*/ */
virtual int mux_sequence_header(SrsRawAacStreamCodec* codec, std::string& sh); virtual srs_error_t mux_sequence_header(SrsRawAacStreamCodec* codec, std::string& sh);
/** /**
* mux the aac audio packet to flv audio packet. * mux the aac audio packet to flv audio packet.
* @param frame the aac raw data. * @param frame the aac raw data.
@ -134,7 +134,7 @@ public:
* @param flv output the muxed flv packet. * @param flv output the muxed flv packet.
* @param nb_flv output the muxed flv size. * @param nb_flv output the muxed flv size.
*/ */
virtual int mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec* codec, uint32_t dts, char** flv, int* nb_flv); virtual srs_error_t mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec* codec, uint32_t dts, char** flv, int* nb_flv);
}; };
#endif #endif

View file

@ -179,15 +179,13 @@ void SrsRtpPacket::reap(SrsRtpPacket* src)
src->audio = NULL; src->audio = NULL;
} }
int SrsRtpPacket::decode(SrsBuffer* stream) srs_error_t SrsRtpPacket::decode(SrsBuffer* stream)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// 12bytes header // 12bytes header
if (!stream->require(12)) { if (!stream->require(12)) {
ret = ERROR_RTP_HEADER_CORRUPT; return srs_error_new(ERROR_RTP_HEADER_CORRUPT, "requires 12 only %d bytes", stream->left());
srs_error("rtsp: rtp header corrupt. ret=%d", ret);
return ret;
} }
int8_t vv = stream->read_1bytes(); int8_t vv = stream->read_1bytes();
@ -213,19 +211,16 @@ int SrsRtpPacket::decode(SrsBuffer* stream)
return decode_97(stream); return decode_97(stream);
} }
return ret; return err;
} }
int SrsRtpPacket::decode_97(SrsBuffer* stream) srs_error_t SrsRtpPacket::decode_97(SrsBuffer* stream)
{ {
int ret = ERROR_SUCCESS;
srs_error_t err = srs_success; srs_error_t err = srs_success;
// atleast 2bytes content. // atleast 2bytes content.
if (!stream->require(2)) { if (!stream->require(2)) {
ret = ERROR_RTP_TYPE97_CORRUPT; return srs_error_new(ERROR_RTP_TYPE97_CORRUPT, "requires 2 only %d bytes", stream->left());
srs_error("rtsp: rtp type97 corrupt. ret=%d", ret);
return ret;
} }
int8_t hasv = stream->read_1bytes(); int8_t hasv = stream->read_1bytes();
@ -233,9 +228,7 @@ int SrsRtpPacket::decode_97(SrsBuffer* stream)
uint16_t au_size = ((hasv << 5) & 0xE0) | ((lasv >> 3) & 0x1f); uint16_t au_size = ((hasv << 5) & 0xE0) | ((lasv >> 3) & 0x1f);
if (!stream->require(au_size)) { if (!stream->require(au_size)) {
ret = ERROR_RTP_TYPE97_CORRUPT; return srs_error_new(ERROR_RTP_TYPE97_CORRUPT, "requires %d only %d bytes", au_size, stream->left());
srs_error("rtsp: rtp type97 au_size corrupt. ret=%d", ret);
return ret;
} }
int required_size = 0; int required_size = 0;
@ -261,35 +254,28 @@ int SrsRtpPacket::decode_97(SrsBuffer* stream)
required_size += sample_size; required_size += sample_size;
if (!stream->require(required_size)) { if (!stream->require(required_size)) {
ret = ERROR_RTP_TYPE97_CORRUPT; return srs_error_new(ERROR_RTP_TYPE97_CORRUPT, "requires %d only %d bytes", required_size, stream->left());
srs_error("rtsp: rtp type97 samples corrupt. ret=%d", ret);
return ret;
} }
if ((err = audio->add_sample(sample, sample_size)) != srs_success) { if ((err = audio->add_sample(sample, sample_size)) != srs_success) {
// TODO: FIXME: Use error
ret = srs_error_code(err);
srs_freep(err); srs_freep(err);
srs_error("rtsp: rtp type97 add sample failed. ret=%d", ret); return srs_error_wrap(err, "add sample");
return ret;
} }
} }
// parsed ok. // parsed ok.
completed = true; completed = true;
return ret; return err;
} }
int SrsRtpPacket::decode_96(SrsBuffer* stream) srs_error_t SrsRtpPacket::decode_96(SrsBuffer* stream)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// atleast 2bytes content. // atleast 2bytes content.
if (!stream->require(2)) { if (!stream->require(2)) {
ret = ERROR_RTP_TYPE96_CORRUPT; return srs_error_new(ERROR_RTP_TYPE96_CORRUPT, "requires 2 only %d bytes", stream->left());
srs_error("rtsp: rtp type96 corrupt. ret=%d", ret);
return ret;
} }
// frame type // frame type
@ -324,7 +310,7 @@ int SrsRtpPacket::decode_96(SrsBuffer* stream)
} }
payload->append(stream->data() + stream->pos(), stream->size() - stream->pos()); payload->append(stream->data() + stream->pos(), stream->size() - stream->pos());
return ret; return err;
} }
// no chunked, append to payload. // no chunked, append to payload.
@ -332,7 +318,7 @@ int SrsRtpPacket::decode_96(SrsBuffer* stream)
payload->append(stream->data() + stream->pos(), stream->size() - stream->pos()); payload->append(stream->data() + stream->pos(), stream->size() - stream->pos());
completed = true; completed = true;
return ret; return err;
} }
SrsRtspSdp::SrsRtspSdp() SrsRtspSdp::SrsRtspSdp()
@ -344,13 +330,13 @@ SrsRtspSdp::~SrsRtspSdp()
{ {
} }
int SrsRtspSdp::parse(string token) srs_error_t SrsRtspSdp::parse(string token)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
if (token.empty()) { if (token.empty()) {
srs_info("rtsp: ignore empty token."); // ignore empty token
return ret; return err;
} }
size_t pos = string::npos; size_t pos = string::npos;
@ -456,17 +442,15 @@ int SrsRtspSdp::parse(string token)
} else if (desc_key == "fmtp") { } else if (desc_key == "fmtp") {
for (int i = 1; i < (int)attrs.size(); i++) { for (int i = 1; i < (int)attrs.size(); i++) {
std::string attr = attrs.at(i); std::string attr = attrs.at(i);
if ((ret = parse_fmtp_attribute(attr)) != ERROR_SUCCESS) { if ((err = parse_fmtp_attribute(attr)) != srs_success) {
srs_error("rtsp: parse fmtp failed, attr=%s. ret=%d", attr.c_str(), ret); return srs_error_wrap(err, "parse fmtp attr=%s", attr.c_str());
return ret;
} }
} }
} else if (desc_key == "control") { } else if (desc_key == "control") {
for (int i = 0; i < (int)attrs.size(); i++) { for (int i = 0; i < (int)attrs.size(); i++) {
std::string attr = attrs.at(i); std::string attr = attrs.at(i);
if ((ret = parse_control_attribute(attr)) != ERROR_SUCCESS) { if ((err = parse_control_attribute(attr)) != srs_success) {
srs_error("rtsp: parse control failed, attr=%s. ret=%d", attr.c_str(), ret); return srs_error_wrap(err, "parse control attr=%s", attr.c_str());
return ret;
} }
} }
} }
@ -497,12 +481,12 @@ int SrsRtspSdp::parse(string token)
default: break; default: break;
} }
return ret; return err;
} }
int SrsRtspSdp::parse_fmtp_attribute(string attr) srs_error_t SrsRtspSdp::parse_fmtp_attribute(string attr)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
size_t pos = string::npos; size_t pos = string::npos;
std::string token = attr; std::string token = attr;
@ -548,9 +532,7 @@ int SrsRtspSdp::parse_fmtp_attribute(string attr)
audio_index_delta_length = item_value; audio_index_delta_length = item_value;
} else if (item_key == "config") { } else if (item_key == "config") {
if (item_value.length() <= 0) { if (item_value.length() <= 0) {
ret = ERROR_RTSP_AUDIO_CONFIG; return srs_error_new(ERROR_RTSP_AUDIO_CONFIG, "audio config");
srs_error("rtsp: audio config failed. ret=%d", ret);
return ret;
} }
char* tmp_sh = new char[item_value.length()]; char* tmp_sh = new char[item_value.length()];
@ -562,12 +544,12 @@ int SrsRtspSdp::parse_fmtp_attribute(string attr)
} }
} }
return ret; return err;
} }
int SrsRtspSdp::parse_control_attribute(string attr) srs_error_t SrsRtspSdp::parse_control_attribute(string attr)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
size_t pos = string::npos; size_t pos = string::npos;
std::string token = attr; std::string token = attr;
@ -598,7 +580,7 @@ int SrsRtspSdp::parse_control_attribute(string attr)
} }
} }
return ret; return err;
} }
string SrsRtspSdp::base64_decode(string value) string SrsRtspSdp::base64_decode(string value)
@ -631,9 +613,9 @@ SrsRtspTransport::~SrsRtspTransport()
{ {
} }
int SrsRtspTransport::parse(string attr) srs_error_t SrsRtspTransport::parse(string attr)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
size_t pos = string::npos; size_t pos = string::npos;
std::string token = attr; std::string token = attr;
@ -681,7 +663,7 @@ int SrsRtspTransport::parse(string attr)
} }
} }
return ret; return err;
} }
SrsRtspRequest::SrsRtspRequest() SrsRtspRequest::SrsRtspRequest()
@ -729,9 +711,9 @@ SrsRtspResponse::~SrsRtspResponse()
{ {
} }
int SrsRtspResponse::encode(stringstream& ss) srs_error_t SrsRtspResponse::encode(stringstream& ss)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// status line // status line
ss << SRS_RTSP_VERSION << SRS_RTSP_SP ss << SRS_RTSP_VERSION << SRS_RTSP_SP
@ -751,20 +733,19 @@ int SrsRtspResponse::encode(stringstream& ss)
ss << SRS_RTSP_TOKEN_SESSION << ":" << session << SRS_RTSP_CRLF; ss << SRS_RTSP_TOKEN_SESSION << ":" << session << SRS_RTSP_CRLF;
} }
if ((ret = encode_header(ss)) != ERROR_SUCCESS) { if ((err = encode_header(ss)) != srs_success) {
srs_error("rtsp: encode header failed. ret=%d", ret); return srs_error_wrap(err, "encode header");
return ret;
}; };
// header EOF. // header EOF.
ss << SRS_RTSP_CRLF; ss << SRS_RTSP_CRLF;
return ret; return err;
} }
int SrsRtspResponse::encode_header(std::stringstream& ss) srs_error_t SrsRtspResponse::encode_header(std::stringstream& ss)
{ {
return ERROR_SUCCESS; return srs_success;
} }
SrsRtspOptionsResponse::SrsRtspOptionsResponse(int cseq) : SrsRtspResponse(cseq) SrsRtspOptionsResponse::SrsRtspOptionsResponse(int cseq) : SrsRtspResponse(cseq)
@ -778,7 +759,7 @@ SrsRtspOptionsResponse::~SrsRtspOptionsResponse()
{ {
} }
int SrsRtspOptionsResponse::encode_header(stringstream& ss) srs_error_t SrsRtspOptionsResponse::encode_header(stringstream& ss)
{ {
SrsRtspMethod rtsp_methods[] = { SrsRtspMethod rtsp_methods[] = {
SrsRtspMethodDescribe, SrsRtspMethodDescribe,
@ -812,7 +793,7 @@ int SrsRtspOptionsResponse::encode_header(stringstream& ss)
} }
ss << SRS_RTSP_CRLF; ss << SRS_RTSP_CRLF;
return ERROR_SUCCESS; return srs_success;
} }
SrsRtspSetupResponse::SrsRtspSetupResponse(int seq) : SrsRtspResponse(seq) SrsRtspSetupResponse::SrsRtspSetupResponse(int seq) : SrsRtspResponse(seq)
@ -825,14 +806,14 @@ SrsRtspSetupResponse::~SrsRtspSetupResponse()
{ {
} }
int SrsRtspSetupResponse::encode_header(stringstream& ss) srs_error_t SrsRtspSetupResponse::encode_header(stringstream& ss)
{ {
ss << SRS_RTSP_TOKEN_SESSION << ":" << SRS_RTSP_SP << session << SRS_RTSP_CRLF; ss << SRS_RTSP_TOKEN_SESSION << ":" << SRS_RTSP_SP << session << SRS_RTSP_CRLF;
ss << SRS_RTSP_TOKEN_TRANSPORT << ":" << SRS_RTSP_SP ss << SRS_RTSP_TOKEN_TRANSPORT << ":" << SRS_RTSP_SP
<< "RTP/AVP;unicast;client_port=" << client_port_min << "-" << client_port_max << ";" << "RTP/AVP;unicast;client_port=" << client_port_min << "-" << client_port_max << ";"
<< "server_port=" << local_port_min << "-" << local_port_max << "server_port=" << local_port_min << "-" << local_port_max
<< SRS_RTSP_CRLF; << SRS_RTSP_CRLF;
return ERROR_SUCCESS; return srs_success;
} }
SrsRtspStack::SrsRtspStack(ISrsProtocolReaderWriter* s) SrsRtspStack::SrsRtspStack(ISrsProtocolReaderWriter* s)
@ -846,24 +827,24 @@ SrsRtspStack::~SrsRtspStack()
srs_freep(buf); srs_freep(buf);
} }
int SrsRtspStack::recv_message(SrsRtspRequest** preq) srs_error_t SrsRtspStack::recv_message(SrsRtspRequest** preq)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
SrsRtspRequest* req = new SrsRtspRequest(); SrsRtspRequest* req = new SrsRtspRequest();
if ((ret = do_recv_message(req)) != ERROR_SUCCESS) { if ((err = do_recv_message(req)) != srs_success) {
srs_freep(req); srs_freep(req);
return ret; return srs_error_wrap(err, "recv message");
} }
*preq = req; *preq = req;
return ret; return err;
} }
int SrsRtspStack::send_message(SrsRtspResponse* res) srs_error_t SrsRtspStack::send_message(SrsRtspResponse* res)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
std::stringstream ss; std::stringstream ss;
// encode the message to string. // encode the message to string.
@ -872,119 +853,83 @@ int SrsRtspStack::send_message(SrsRtspResponse* res)
std::string str = ss.str(); std::string str = ss.str();
srs_assert(!str.empty()); srs_assert(!str.empty());
if ((ret = skt->write((char*)str.c_str(), (int)str.length(), NULL)) != ERROR_SUCCESS) { if ((err = skt->write((char*)str.c_str(), (int)str.length(), NULL)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "write message");
srs_error("rtsp: send response failed. ret=%d", ret);
} }
return ret;
}
srs_info("rtsp: send response ok");
return ret; return err;
} }
int SrsRtspStack::do_recv_message(SrsRtspRequest* req) srs_error_t SrsRtspStack::do_recv_message(SrsRtspRequest* req)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// parse request line. // parse request line.
if ((ret = recv_token_normal(req->method)) != ERROR_SUCCESS) { if ((err = recv_token_normal(req->method)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "method");
srs_error("rtsp: parse method failed. ret=%d", ret);
}
return ret;
} }
if ((ret = recv_token_normal(req->uri)) != ERROR_SUCCESS) { if ((err = recv_token_normal(req->uri)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "uri");
srs_error("rtsp: parse uri failed. ret=%d", ret);
}
return ret;
} }
if ((ret = recv_token_eof(req->version)) != ERROR_SUCCESS) { if ((err = recv_token_eof(req->version)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "version");
srs_error("rtsp: parse version failed. ret=%d", ret);
}
return ret;
} }
// parse headers. // parse headers.
for (;;) { for (;;) {
// parse the header name // parse the header name
std::string token; std::string token;
if ((ret = recv_token_normal(token)) != ERROR_SUCCESS) { if ((err = recv_token_normal(token)) != srs_success) {
if (ret == ERROR_RTSP_REQUEST_HEADER_EOF) { if (srs_error_code(err) == ERROR_RTSP_REQUEST_HEADER_EOF) {
ret = ERROR_SUCCESS; srs_error_reset(err);
srs_info("rtsp: message header parsed");
break; break;
} }
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "recv token");
srs_error("rtsp: parse token failed. ret=%d", ret);
}
return ret;
} }
// parse the header value according by header name // parse the header value according by header name
if (token == SRS_RTSP_TOKEN_CSEQ) { if (token == SRS_RTSP_TOKEN_CSEQ) {
std::string seq; std::string seq;
if ((ret = recv_token_eof(seq)) != ERROR_SUCCESS) { if ((err = recv_token_eof(seq)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "seq");
srs_error("rtsp: parse %s failed. ret=%d", SRS_RTSP_TOKEN_CSEQ, ret);
}
return ret;
} }
req->seq = ::atol(seq.c_str()); req->seq = ::atol(seq.c_str());
} else if (token == SRS_RTSP_TOKEN_CONTENT_TYPE) { } else if (token == SRS_RTSP_TOKEN_CONTENT_TYPE) {
std::string ct; std::string ct;
if ((ret = recv_token_eof(ct)) != ERROR_SUCCESS) { if ((err = recv_token_eof(ct)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "ct");
srs_error("rtsp: parse %s failed. ret=%d", SRS_RTSP_TOKEN_CONTENT_TYPE, ret);
}
return ret;
} }
req->content_type = ct; req->content_type = ct;
} else if (token == SRS_RTSP_TOKEN_CONTENT_LENGTH) { } else if (token == SRS_RTSP_TOKEN_CONTENT_LENGTH) {
std::string cl; std::string cl;
if ((ret = recv_token_eof(cl)) != ERROR_SUCCESS) { if ((err = recv_token_eof(cl)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "cl");
srs_error("rtsp: parse %s failed. ret=%d", SRS_RTSP_TOKEN_CONTENT_LENGTH, ret);
}
return ret;
} }
req->content_length = ::atol(cl.c_str()); req->content_length = ::atol(cl.c_str());
} else if (token == SRS_RTSP_TOKEN_TRANSPORT) { } else if (token == SRS_RTSP_TOKEN_TRANSPORT) {
std::string transport; std::string transport;
if ((ret = recv_token_eof(transport)) != ERROR_SUCCESS) { if ((err = recv_token_eof(transport)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "transport");
srs_error("rtsp: parse %s failed. ret=%d", SRS_RTSP_TOKEN_TRANSPORT, ret);
}
return ret;
} }
if (!req->transport) { if (!req->transport) {
req->transport = new SrsRtspTransport(); req->transport = new SrsRtspTransport();
} }
if ((ret = req->transport->parse(transport)) != ERROR_SUCCESS) { if ((err = req->transport->parse(transport)) != srs_success) {
srs_error("rtsp: parse transport failed, transport=%s. ret=%d", transport.c_str(), ret); return srs_error_wrap(err, "parse transport=%s", transport.c_str());
return ret;
} }
} else if (token == SRS_RTSP_TOKEN_SESSION) { } else if (token == SRS_RTSP_TOKEN_SESSION) {
if ((ret = recv_token_eof(req->session)) != ERROR_SUCCESS) { if ((err = recv_token_eof(req->session)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "session");
srs_error("rtsp: parse %s failed. ret=%d", SRS_RTSP_TOKEN_SESSION, ret);
}
return ret;
} }
} else { } else {
// unknown header name, parse util EOF. // unknown header name, parse util EOF.
SrsRtspTokenState state = SrsRtspTokenStateNormal; SrsRtspTokenState state = SrsRtspTokenStateNormal;
while (state == SrsRtspTokenStateNormal) { while (state == SrsRtspTokenStateNormal) {
std::string value; std::string value;
if ((ret = recv_token(value, state)) != ERROR_SUCCESS) { if ((err = recv_token(value, state)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "state");
srs_error("rtsp: parse token failed. ret=%d", ret);
}
return ret;
} }
srs_trace("rtsp: ignore header %s=%s", token.c_str(), value.c_str()); srs_trace("rtsp: ignore header %s=%s", token.c_str(), value.c_str());
} }
@ -1011,104 +956,83 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req)
int nb_token = 0; int nb_token = 0;
std::string token; std::string token;
if ((ret = recv_token_util_eof(token, &nb_token)) != ERROR_SUCCESS) { if ((err = recv_token_util_eof(token, &nb_token)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "recv token");
srs_error("rtsp: parse sdp token failed. ret=%d", ret);
}
return ret;
} }
consumed += nb_token; consumed += nb_token;
if ((ret = req->sdp->parse(token)) != ERROR_SUCCESS) { if ((err = req->sdp->parse(token)) != srs_success) {
srs_error("rtsp: sdp parse token failed, token=%s. ret=%d", token.c_str(), ret); return srs_error_wrap(err, "parse token");
return ret;
} }
srs_info("rtsp: %s", token.c_str());
} }
srs_info("rtsp: sdp parsed, size=%d", consumed);
return ret; return err;
} }
int SrsRtspStack::recv_token_normal(std::string& token) srs_error_t SrsRtspStack::recv_token_normal(std::string& token)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
SrsRtspTokenState state; SrsRtspTokenState state;
if ((ret = recv_token(token, state)) != ERROR_SUCCESS) { if ((err = recv_token(token, state)) != srs_success) {
if (ret == ERROR_RTSP_REQUEST_HEADER_EOF) { if (srs_error_code(err) == ERROR_RTSP_REQUEST_HEADER_EOF) {
return ret; return srs_error_wrap(err, "EOF");
} }
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "recv token");
srs_error("rtsp: parse token failed. ret=%d", ret);
}
return ret;
} }
if (state != SrsRtspTokenStateNormal) { if (state != SrsRtspTokenStateNormal) {
ret = ERROR_RTSP_TOKEN_NOT_NORMAL; return srs_error_new(ERROR_RTSP_TOKEN_NOT_NORMAL, "invalid state=%d", state);
srs_error("rtsp: parse normal token failed, state=%d. ret=%d", state, ret);
return ret;
} }
return ret; return err;
} }
int SrsRtspStack::recv_token_eof(std::string& token) srs_error_t SrsRtspStack::recv_token_eof(std::string& token)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
SrsRtspTokenState state; SrsRtspTokenState state;
if ((ret = recv_token(token, state)) != ERROR_SUCCESS) { if ((err = recv_token(token, state)) != srs_success) {
if (ret == ERROR_RTSP_REQUEST_HEADER_EOF) { if (srs_error_code(err) == ERROR_RTSP_REQUEST_HEADER_EOF) {
return ret; return srs_error_wrap(err, "EOF");
} }
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "recv token");
srs_error("rtsp: parse token failed. ret=%d", ret);
}
return ret;
} }
if (state != SrsRtspTokenStateEOF) { if (state != SrsRtspTokenStateEOF) {
ret = ERROR_RTSP_TOKEN_NOT_NORMAL; return srs_error_new(ERROR_RTSP_TOKEN_NOT_NORMAL, "invalid state=%d", state);
srs_error("rtsp: parse eof token failed, state=%d. ret=%d", state, ret);
return ret;
} }
return ret; return err;
} }
int SrsRtspStack::recv_token_util_eof(std::string& token, int* pconsumed) srs_error_t SrsRtspStack::recv_token_util_eof(std::string& token, int* pconsumed)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
SrsRtspTokenState state; SrsRtspTokenState state;
// use 0x00 as ignore the normal token flag. // use 0x00 as ignore the normal token flag.
if ((ret = recv_token(token, state, 0x00, pconsumed)) != ERROR_SUCCESS) { if ((err = recv_token(token, state, 0x00, pconsumed)) != srs_success) {
if (ret == ERROR_RTSP_REQUEST_HEADER_EOF) { if (srs_error_code(err) == ERROR_RTSP_REQUEST_HEADER_EOF) {
return ret; return srs_error_wrap(err, "EOF");
} }
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "recv token");
srs_error("rtsp: parse token failed. ret=%d", ret);
}
return ret;
} }
if (state != SrsRtspTokenStateEOF) { if (state != SrsRtspTokenStateEOF) {
ret = ERROR_RTSP_TOKEN_NOT_NORMAL; return srs_error_new(ERROR_RTSP_TOKEN_NOT_NORMAL, "invalid state=%d", state);
srs_error("rtsp: parse eof token failed, state=%d. ret=%d", state, ret);
return ret;
} }
return ret; return err;
} }
int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch, int* pconsumed) srs_error_t SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch, int* pconsumed)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// whatever, default to error state. // whatever, default to error state.
state = SrsRtspTokenStateError; state = SrsRtspTokenStateError;
@ -1124,15 +1048,11 @@ int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char
char buffer[SRS_RTSP_BUFFER]; char buffer[SRS_RTSP_BUFFER];
ssize_t nb_read = 0; ssize_t nb_read = 0;
if ((ret = skt->read(buffer, SRS_RTSP_BUFFER, &nb_read)) != ERROR_SUCCESS) { if ((err = skt->read(buffer, SRS_RTSP_BUFFER, &nb_read)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "recv data");
srs_error("rtsp: io read failed. ret=%d", ret);
} }
return ret;
}
srs_info("rtsp: io read %d bytes", nb_read);
buf->append(buffer, nb_read); buf->append(buffer, (int)nb_read);
} }
// parse one by one. // parse one by one.
@ -1154,7 +1074,7 @@ int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char
} }
// got the token. // got the token.
int nb_token = p - start; int nb_token = (int)(p - start);
// trim last ':' character. // trim last ':' character.
if (nb_token && p[-1] == ':') { if (nb_token && p[-1] == ':') {
nb_token--; nb_token--;
@ -1162,7 +1082,7 @@ int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char
if (nb_token) { if (nb_token) {
token.append(start, nb_token); token.append(start, nb_token);
} else { } else {
ret = ERROR_RTSP_REQUEST_HEADER_EOF; err = srs_error_new(ERROR_RTSP_REQUEST_HEADER_EOF, "EOF");
} }
// ignore SP/CR/LF // ignore SP/CR/LF
@ -1171,9 +1091,9 @@ int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char
// consume the token bytes. // consume the token bytes.
srs_assert(p - start); srs_assert(p - start);
buf->erase(p - start); buf->erase((int)(p - start));
if (pconsumed) { if (pconsumed) {
*pconsumed = p - start; *pconsumed = (int)(p - start);
} }
break; break;
} }
@ -1182,7 +1102,7 @@ int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char
append_bytes = true; append_bytes = true;
} }
return ret; return err;
} }
#endif #endif

View file

@ -311,10 +311,10 @@ public:
/** /**
* decode rtp packet from stream. * decode rtp packet from stream.
*/ */
virtual int decode(SrsBuffer* stream); virtual srs_error_t decode(SrsBuffer* stream);
private: private:
virtual int decode_97(SrsBuffer* stream); virtual srs_error_t decode_97(SrsBuffer* stream);
virtual int decode_96(SrsBuffer* stream); virtual srs_error_t decode_96(SrsBuffer* stream);
}; };
/** /**
@ -394,16 +394,16 @@ public:
/** /**
* parse a line of token for sdp. * parse a line of token for sdp.
*/ */
virtual int parse(std::string token); virtual srs_error_t parse(std::string token);
private: private:
/** /**
* generally, the fmtp is the sequence header for video or audio. * generally, the fmtp is the sequence header for video or audio.
*/ */
virtual int parse_fmtp_attribute(std::string attr); virtual srs_error_t parse_fmtp_attribute(std::string attr);
/** /**
* generally, the control is the stream info for video or audio. * generally, the control is the stream info for video or audio.
*/ */
virtual int parse_control_attribute(std::string attr); virtual srs_error_t parse_control_attribute(std::string attr);
/** /**
* decode the string by base64. * decode the string by base64.
*/ */
@ -454,7 +454,7 @@ public:
/** /**
* parse a line of token for transport. * parse a line of token for transport.
*/ */
virtual int parse(std::string attr); virtual srs_error_t parse(std::string attr);
}; };
/** /**
@ -588,12 +588,12 @@ public:
/** /**
* encode message to string. * encode message to string.
*/ */
virtual int encode(std::stringstream& ss); virtual srs_error_t encode(std::stringstream& ss);
protected: protected:
/** /**
* sub classes override this to encode the headers. * sub classes override this to encode the headers.
*/ */
virtual int encode_header(std::stringstream& ss); virtual srs_error_t encode_header(std::stringstream& ss);
}; };
/** /**
@ -613,7 +613,7 @@ public:
SrsRtspOptionsResponse(int cseq); SrsRtspOptionsResponse(int cseq);
virtual ~SrsRtspOptionsResponse(); virtual ~SrsRtspOptionsResponse();
protected: protected:
virtual int encode_header(std::stringstream& ss); virtual srs_error_t encode_header(std::stringstream& ss);
}; };
/** /**
@ -643,7 +643,7 @@ public:
SrsRtspSetupResponse(int cseq); SrsRtspSetupResponse(int cseq);
virtual ~SrsRtspSetupResponse(); virtual ~SrsRtspSetupResponse();
protected: protected:
virtual int encode_header(std::stringstream& ss); virtual srs_error_t encode_header(std::stringstream& ss);
}; };
/** /**
@ -670,31 +670,31 @@ public:
* @return an int error code. * @return an int error code.
* ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF. * ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF.
*/ */
virtual int recv_message(SrsRtspRequest** preq); virtual srs_error_t recv_message(SrsRtspRequest** preq);
/** /**
* send rtsp message over underlayer io. * send rtsp message over underlayer io.
* @param res the rtsp response message, which user should never free it. * @param res the rtsp response message, which user should never free it.
* @return an int error code. * @return an int error code.
*/ */
virtual int send_message(SrsRtspResponse* res); virtual srs_error_t send_message(SrsRtspResponse* res);
private: private:
/** /**
* recv the rtsp message. * recv the rtsp message.
*/ */
virtual int do_recv_message(SrsRtspRequest* req); virtual srs_error_t do_recv_message(SrsRtspRequest* req);
/** /**
* read a normal token from io, error when token state is not normal. * read a normal token from io, error when token state is not normal.
*/ */
virtual int recv_token_normal(std::string& token); virtual srs_error_t recv_token_normal(std::string& token);
/** /**
* read a normal token from io, error when token state is not eof. * read a normal token from io, error when token state is not eof.
*/ */
virtual int recv_token_eof(std::string& token); virtual srs_error_t recv_token_eof(std::string& token);
/** /**
* read the token util got eof, for example, to read the response status Reason-Phrase * read the token util got eof, for example, to read the response status Reason-Phrase
* @param pconsumed, output the token parsed length. NULL to ignore. * @param pconsumed, output the token parsed length. NULL to ignore.
*/ */
virtual int recv_token_util_eof(std::string& token, int* pconsumed = NULL); virtual srs_error_t recv_token_util_eof(std::string& token, int* pconsumed = NULL);
/** /**
* read a token from io, split by SP, endswith CRLF: * read a token from io, split by SP, endswith CRLF:
* token1 SP token2 SP ... tokenN CRLF * token1 SP token2 SP ... tokenN CRLF
@ -705,7 +705,7 @@ private:
* the 0x00 use to ignore normal token flag. @see recv_token_util_eof * the 0x00 use to ignore normal token flag. @see recv_token_util_eof
* @param pconsumed, output the token parsed length. NULL to ignore. * @param pconsumed, output the token parsed length. NULL to ignore.
*/ */
virtual int recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch = SRS_RTSP_SP, int* pconsumed = NULL); virtual srs_error_t recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch = SRS_RTSP_SP, int* pconsumed = NULL);
}; };
#endif #endif