mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
For #299, refine code.
This commit is contained in:
parent
62b7204514
commit
f32aab3d92
175 changed files with 15529 additions and 15935 deletions
|
@ -1,25 +1,25 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2017 SRS(ossrs)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2017 SRS(ossrs)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <srs_rtsp_stack.hpp>
|
||||
|
||||
|
@ -48,50 +48,50 @@ string srs_generate_rtsp_status_text(int status)
|
|||
{
|
||||
static std::map<int, std::string> _status_map;
|
||||
if (_status_map.empty()) {
|
||||
_status_map[SRS_CONSTS_RTSP_Continue] = SRS_CONSTS_RTSP_Continue_str;
|
||||
_status_map[SRS_CONSTS_RTSP_OK] = SRS_CONSTS_RTSP_OK_str;
|
||||
_status_map[SRS_CONSTS_RTSP_Created] = SRS_CONSTS_RTSP_Created_str;
|
||||
_status_map[SRS_CONSTS_RTSP_LowOnStorageSpace] = SRS_CONSTS_RTSP_LowOnStorageSpace_str;
|
||||
_status_map[SRS_CONSTS_RTSP_MultipleChoices] = SRS_CONSTS_RTSP_MultipleChoices_str;
|
||||
_status_map[SRS_CONSTS_RTSP_MovedPermanently] = SRS_CONSTS_RTSP_MovedPermanently_str;
|
||||
_status_map[SRS_CONSTS_RTSP_MovedTemporarily] = SRS_CONSTS_RTSP_MovedTemporarily_str;
|
||||
_status_map[SRS_CONSTS_RTSP_SeeOther] = SRS_CONSTS_RTSP_SeeOther_str;
|
||||
_status_map[SRS_CONSTS_RTSP_NotModified] = SRS_CONSTS_RTSP_NotModified_str;
|
||||
_status_map[SRS_CONSTS_RTSP_UseProxy] = SRS_CONSTS_RTSP_UseProxy_str;
|
||||
_status_map[SRS_CONSTS_RTSP_BadRequest] = SRS_CONSTS_RTSP_BadRequest_str;
|
||||
_status_map[SRS_CONSTS_RTSP_Unauthorized] = SRS_CONSTS_RTSP_Unauthorized_str;
|
||||
_status_map[SRS_CONSTS_RTSP_PaymentRequired] = SRS_CONSTS_RTSP_PaymentRequired_str;
|
||||
_status_map[SRS_CONSTS_RTSP_Forbidden] = SRS_CONSTS_RTSP_Forbidden_str;
|
||||
_status_map[SRS_CONSTS_RTSP_NotFound] = SRS_CONSTS_RTSP_NotFound_str;
|
||||
_status_map[SRS_CONSTS_RTSP_MethodNotAllowed] = SRS_CONSTS_RTSP_MethodNotAllowed_str;
|
||||
_status_map[SRS_CONSTS_RTSP_NotAcceptable] = SRS_CONSTS_RTSP_NotAcceptable_str;
|
||||
_status_map[SRS_CONSTS_RTSP_ProxyAuthenticationRequired] = SRS_CONSTS_RTSP_ProxyAuthenticationRequired_str;
|
||||
_status_map[SRS_CONSTS_RTSP_RequestTimeout] = SRS_CONSTS_RTSP_RequestTimeout_str;
|
||||
_status_map[SRS_CONSTS_RTSP_Gone] = SRS_CONSTS_RTSP_Gone_str;
|
||||
_status_map[SRS_CONSTS_RTSP_LengthRequired] = SRS_CONSTS_RTSP_LengthRequired_str;
|
||||
_status_map[SRS_CONSTS_RTSP_PreconditionFailed] = SRS_CONSTS_RTSP_PreconditionFailed_str;
|
||||
_status_map[SRS_CONSTS_RTSP_RequestEntityTooLarge] = SRS_CONSTS_RTSP_RequestEntityTooLarge_str;
|
||||
_status_map[SRS_CONSTS_RTSP_RequestURITooLarge] = SRS_CONSTS_RTSP_RequestURITooLarge_str;
|
||||
_status_map[SRS_CONSTS_RTSP_UnsupportedMediaType] = SRS_CONSTS_RTSP_UnsupportedMediaType_str;
|
||||
_status_map[SRS_CONSTS_RTSP_ParameterNotUnderstood] = SRS_CONSTS_RTSP_ParameterNotUnderstood_str;
|
||||
_status_map[SRS_CONSTS_RTSP_ConferenceNotFound] = SRS_CONSTS_RTSP_ConferenceNotFound_str;
|
||||
_status_map[SRS_CONSTS_RTSP_NotEnoughBandwidth] = SRS_CONSTS_RTSP_NotEnoughBandwidth_str;
|
||||
_status_map[SRS_CONSTS_RTSP_SessionNotFound] = SRS_CONSTS_RTSP_SessionNotFound_str;
|
||||
_status_map[SRS_CONSTS_RTSP_MethodNotValidInThisState] = SRS_CONSTS_RTSP_MethodNotValidInThisState_str;
|
||||
_status_map[SRS_CONSTS_RTSP_HeaderFieldNotValidForResource] = SRS_CONSTS_RTSP_HeaderFieldNotValidForResource_str;
|
||||
_status_map[SRS_CONSTS_RTSP_InvalidRange] = SRS_CONSTS_RTSP_InvalidRange_str;
|
||||
_status_map[SRS_CONSTS_RTSP_ParameterIsReadOnly] = SRS_CONSTS_RTSP_ParameterIsReadOnly_str;
|
||||
_status_map[SRS_CONSTS_RTSP_AggregateOperationNotAllowed] = SRS_CONSTS_RTSP_AggregateOperationNotAllowed_str;
|
||||
_status_map[SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed] = SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed_str;
|
||||
_status_map[SRS_CONSTS_RTSP_UnsupportedTransport] = SRS_CONSTS_RTSP_UnsupportedTransport_str;
|
||||
_status_map[SRS_CONSTS_RTSP_DestinationUnreachable] = SRS_CONSTS_RTSP_DestinationUnreachable_str;
|
||||
_status_map[SRS_CONSTS_RTSP_InternalServerError] = SRS_CONSTS_RTSP_InternalServerError_str;
|
||||
_status_map[SRS_CONSTS_RTSP_NotImplemented] = SRS_CONSTS_RTSP_NotImplemented_str;
|
||||
_status_map[SRS_CONSTS_RTSP_BadGateway] = SRS_CONSTS_RTSP_BadGateway_str;
|
||||
_status_map[SRS_CONSTS_RTSP_ServiceUnavailable] = SRS_CONSTS_RTSP_ServiceUnavailable_str;
|
||||
_status_map[SRS_CONSTS_RTSP_GatewayTimeout] = SRS_CONSTS_RTSP_GatewayTimeout_str;
|
||||
_status_map[SRS_CONSTS_RTSP_RTSPVersionNotSupported] = SRS_CONSTS_RTSP_RTSPVersionNotSupported_str;
|
||||
_status_map[SRS_CONSTS_RTSP_OptionNotSupported] = SRS_CONSTS_RTSP_OptionNotSupported_str;
|
||||
_status_map[SRS_CONSTS_RTSP_Continue] = SRS_CONSTS_RTSP_Continue_str;
|
||||
_status_map[SRS_CONSTS_RTSP_OK] = SRS_CONSTS_RTSP_OK_str;
|
||||
_status_map[SRS_CONSTS_RTSP_Created] = SRS_CONSTS_RTSP_Created_str;
|
||||
_status_map[SRS_CONSTS_RTSP_LowOnStorageSpace] = SRS_CONSTS_RTSP_LowOnStorageSpace_str;
|
||||
_status_map[SRS_CONSTS_RTSP_MultipleChoices] = SRS_CONSTS_RTSP_MultipleChoices_str;
|
||||
_status_map[SRS_CONSTS_RTSP_MovedPermanently] = SRS_CONSTS_RTSP_MovedPermanently_str;
|
||||
_status_map[SRS_CONSTS_RTSP_MovedTemporarily] = SRS_CONSTS_RTSP_MovedTemporarily_str;
|
||||
_status_map[SRS_CONSTS_RTSP_SeeOther] = SRS_CONSTS_RTSP_SeeOther_str;
|
||||
_status_map[SRS_CONSTS_RTSP_NotModified] = SRS_CONSTS_RTSP_NotModified_str;
|
||||
_status_map[SRS_CONSTS_RTSP_UseProxy] = SRS_CONSTS_RTSP_UseProxy_str;
|
||||
_status_map[SRS_CONSTS_RTSP_BadRequest] = SRS_CONSTS_RTSP_BadRequest_str;
|
||||
_status_map[SRS_CONSTS_RTSP_Unauthorized] = SRS_CONSTS_RTSP_Unauthorized_str;
|
||||
_status_map[SRS_CONSTS_RTSP_PaymentRequired] = SRS_CONSTS_RTSP_PaymentRequired_str;
|
||||
_status_map[SRS_CONSTS_RTSP_Forbidden] = SRS_CONSTS_RTSP_Forbidden_str;
|
||||
_status_map[SRS_CONSTS_RTSP_NotFound] = SRS_CONSTS_RTSP_NotFound_str;
|
||||
_status_map[SRS_CONSTS_RTSP_MethodNotAllowed] = SRS_CONSTS_RTSP_MethodNotAllowed_str;
|
||||
_status_map[SRS_CONSTS_RTSP_NotAcceptable] = SRS_CONSTS_RTSP_NotAcceptable_str;
|
||||
_status_map[SRS_CONSTS_RTSP_ProxyAuthenticationRequired] = SRS_CONSTS_RTSP_ProxyAuthenticationRequired_str;
|
||||
_status_map[SRS_CONSTS_RTSP_RequestTimeout] = SRS_CONSTS_RTSP_RequestTimeout_str;
|
||||
_status_map[SRS_CONSTS_RTSP_Gone] = SRS_CONSTS_RTSP_Gone_str;
|
||||
_status_map[SRS_CONSTS_RTSP_LengthRequired] = SRS_CONSTS_RTSP_LengthRequired_str;
|
||||
_status_map[SRS_CONSTS_RTSP_PreconditionFailed] = SRS_CONSTS_RTSP_PreconditionFailed_str;
|
||||
_status_map[SRS_CONSTS_RTSP_RequestEntityTooLarge] = SRS_CONSTS_RTSP_RequestEntityTooLarge_str;
|
||||
_status_map[SRS_CONSTS_RTSP_RequestURITooLarge] = SRS_CONSTS_RTSP_RequestURITooLarge_str;
|
||||
_status_map[SRS_CONSTS_RTSP_UnsupportedMediaType] = SRS_CONSTS_RTSP_UnsupportedMediaType_str;
|
||||
_status_map[SRS_CONSTS_RTSP_ParameterNotUnderstood] = SRS_CONSTS_RTSP_ParameterNotUnderstood_str;
|
||||
_status_map[SRS_CONSTS_RTSP_ConferenceNotFound] = SRS_CONSTS_RTSP_ConferenceNotFound_str;
|
||||
_status_map[SRS_CONSTS_RTSP_NotEnoughBandwidth] = SRS_CONSTS_RTSP_NotEnoughBandwidth_str;
|
||||
_status_map[SRS_CONSTS_RTSP_SessionNotFound] = SRS_CONSTS_RTSP_SessionNotFound_str;
|
||||
_status_map[SRS_CONSTS_RTSP_MethodNotValidInThisState] = SRS_CONSTS_RTSP_MethodNotValidInThisState_str;
|
||||
_status_map[SRS_CONSTS_RTSP_HeaderFieldNotValidForResource] = SRS_CONSTS_RTSP_HeaderFieldNotValidForResource_str;
|
||||
_status_map[SRS_CONSTS_RTSP_InvalidRange] = SRS_CONSTS_RTSP_InvalidRange_str;
|
||||
_status_map[SRS_CONSTS_RTSP_ParameterIsReadOnly] = SRS_CONSTS_RTSP_ParameterIsReadOnly_str;
|
||||
_status_map[SRS_CONSTS_RTSP_AggregateOperationNotAllowed] = SRS_CONSTS_RTSP_AggregateOperationNotAllowed_str;
|
||||
_status_map[SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed] = SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed_str;
|
||||
_status_map[SRS_CONSTS_RTSP_UnsupportedTransport] = SRS_CONSTS_RTSP_UnsupportedTransport_str;
|
||||
_status_map[SRS_CONSTS_RTSP_DestinationUnreachable] = SRS_CONSTS_RTSP_DestinationUnreachable_str;
|
||||
_status_map[SRS_CONSTS_RTSP_InternalServerError] = SRS_CONSTS_RTSP_InternalServerError_str;
|
||||
_status_map[SRS_CONSTS_RTSP_NotImplemented] = SRS_CONSTS_RTSP_NotImplemented_str;
|
||||
_status_map[SRS_CONSTS_RTSP_BadGateway] = SRS_CONSTS_RTSP_BadGateway_str;
|
||||
_status_map[SRS_CONSTS_RTSP_ServiceUnavailable] = SRS_CONSTS_RTSP_ServiceUnavailable_str;
|
||||
_status_map[SRS_CONSTS_RTSP_GatewayTimeout] = SRS_CONSTS_RTSP_GatewayTimeout_str;
|
||||
_status_map[SRS_CONSTS_RTSP_RTSPVersionNotSupported] = SRS_CONSTS_RTSP_RTSPVersionNotSupported_str;
|
||||
_status_map[SRS_CONSTS_RTSP_OptionNotSupported] = SRS_CONSTS_RTSP_OptionNotSupported_str;
|
||||
}
|
||||
|
||||
std::string status_text;
|
||||
|
@ -104,7 +104,7 @@ string srs_generate_rtsp_status_text(int status)
|
|||
return status_text;
|
||||
}
|
||||
|
||||
std::string srs_generate_rtsp_method_str(SrsRtspMethod method)
|
||||
std::string srs_generate_rtsp_method_str(SrsRtspMethod method)
|
||||
{
|
||||
switch (method) {
|
||||
case SrsRtspMethodDescribe: return SRS_METHOD_DESCRIBE;
|
||||
|
@ -129,12 +129,12 @@ SrsRtpPacket::SrsRtpPacket()
|
|||
extension = 0;
|
||||
csrc_count = 0;
|
||||
marker = 1;
|
||||
|
||||
|
||||
payload_type = 0;
|
||||
sequence_number = 0;
|
||||
timestamp = 0;
|
||||
ssrc = 0;
|
||||
|
||||
|
||||
payload = new SrsSimpleStream();
|
||||
audio = new SrsAudioFrame();
|
||||
chunked = false;
|
||||
|
@ -158,7 +158,7 @@ void SrsRtpPacket::copy(SrsRtpPacket* src)
|
|||
sequence_number = src->sequence_number;
|
||||
timestamp = src->timestamp;
|
||||
ssrc = src->ssrc;
|
||||
|
||||
|
||||
chunked = src->chunked;
|
||||
completed = src->completed;
|
||||
|
||||
|
@ -169,7 +169,7 @@ void SrsRtpPacket::copy(SrsRtpPacket* src)
|
|||
void SrsRtpPacket::reap(SrsRtpPacket* src)
|
||||
{
|
||||
copy(src);
|
||||
|
||||
|
||||
srs_freep(payload);
|
||||
payload = src->payload;
|
||||
src->payload = NULL;
|
||||
|
@ -182,112 +182,112 @@ void SrsRtpPacket::reap(SrsRtpPacket* src)
|
|||
int SrsRtpPacket::decode(SrsBuffer* stream)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
||||
// 12bytes header
|
||||
if (!stream->require(12)) {
|
||||
ret = ERROR_RTP_HEADER_CORRUPT;
|
||||
srs_error("rtsp: rtp header corrupt. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int8_t vv = stream->read_1bytes();
|
||||
version = (vv >> 6) & 0x03;
|
||||
padding = (vv >> 5) & 0x01;
|
||||
extension = (vv >> 4) & 0x01;
|
||||
csrc_count = vv & 0x0f;
|
||||
|
||||
|
||||
int8_t mv = stream->read_1bytes();
|
||||
marker = (mv >> 7) & 0x01;
|
||||
payload_type = mv & 0x7f;
|
||||
|
||||
|
||||
sequence_number = stream->read_2bytes();
|
||||
timestamp = stream->read_4bytes();
|
||||
ssrc = stream->read_4bytes();
|
||||
|
||||
|
||||
// TODO: FIXME: check sequence number.
|
||||
|
||||
|
||||
// video codec.
|
||||
if (payload_type == 96) {
|
||||
return decode_96(stream);
|
||||
} else if (payload_type == 97) {
|
||||
return decode_97(stream);
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsRtpPacket::decode_97(SrsBuffer* stream)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
||||
// atleast 2bytes content.
|
||||
if (!stream->require(2)) {
|
||||
ret = ERROR_RTP_TYPE97_CORRUPT;
|
||||
srs_error("rtsp: rtp type97 corrupt. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int8_t hasv = stream->read_1bytes();
|
||||
int8_t lasv = stream->read_1bytes();
|
||||
uint16_t au_size = ((hasv << 5) & 0xE0) | ((lasv >> 3) & 0x1f);
|
||||
|
||||
|
||||
if (!stream->require(au_size)) {
|
||||
ret = ERROR_RTP_TYPE97_CORRUPT;
|
||||
srs_error("rtsp: rtp type97 au_size corrupt. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int required_size = 0;
|
||||
|
||||
|
||||
// append left bytes to payload.
|
||||
payload->append(
|
||||
stream->data() + stream->pos() + au_size,
|
||||
stream->size() - stream->pos() - au_size
|
||||
);
|
||||
stream->data() + stream->pos() + au_size,
|
||||
stream->size() - stream->pos() - au_size
|
||||
);
|
||||
char* p = payload->bytes();
|
||||
|
||||
|
||||
for (int i = 0; i < au_size; i += 2) {
|
||||
hasv = stream->read_1bytes();
|
||||
lasv = stream->read_1bytes();
|
||||
|
||||
|
||||
uint16_t sample_size = ((hasv << 5) & 0xE0) | ((lasv >> 3) & 0x1f);
|
||||
// TODO: FIXME: finger out how to parse the size of sample.
|
||||
if (sample_size < 0x100 && stream->require(required_size + sample_size + 0x100)) {
|
||||
sample_size = sample_size | 0x100;
|
||||
}
|
||||
|
||||
|
||||
char* sample = p + required_size;
|
||||
required_size += sample_size;
|
||||
|
||||
|
||||
if (!stream->require(required_size)) {
|
||||
ret = ERROR_RTP_TYPE97_CORRUPT;
|
||||
srs_error("rtsp: rtp type97 samples corrupt. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if ((ret = audio->add_sample(sample, sample_size)) != ERROR_SUCCESS) {
|
||||
srs_error("rtsp: rtp type97 add sample failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// parsed ok.
|
||||
completed = true;
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsRtpPacket::decode_96(SrsBuffer* stream)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
||||
// atleast 2bytes content.
|
||||
if (!stream->require(2)) {
|
||||
ret = ERROR_RTP_TYPE96_CORRUPT;
|
||||
srs_error("rtsp: rtp type96 corrupt. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// frame type
|
||||
// 0... .... reserverd
|
||||
// .11. .... NALU[0]&0x60
|
||||
|
@ -296,7 +296,7 @@ int SrsRtpPacket::decode_96(SrsBuffer* stream)
|
|||
int8_t ftv = stream->read_1bytes();
|
||||
int8_t nalu_0x60 = ftv & 0x60;
|
||||
int8_t fu_indicator = ftv & 0x1c;
|
||||
|
||||
|
||||
// nri, whatever
|
||||
// 10.. .... first chunk.
|
||||
// 00.. .... continous chunk.
|
||||
|
@ -307,12 +307,12 @@ int SrsRtpPacket::decode_96(SrsBuffer* stream)
|
|||
bool last_chunk = (nriv & 0xC0) == 0x40;
|
||||
bool contious_chunk = (nriv & 0xC0) == 0x00;
|
||||
int8_t nalu_0x1f = nriv & 0x1f;
|
||||
|
||||
|
||||
// chunked, generate the first byte NALU.
|
||||
if (fu_indicator == 0x1c && (first_chunk || last_chunk || contious_chunk)) {
|
||||
chunked = true;
|
||||
completed = last_chunk;
|
||||
|
||||
|
||||
// generate and append the first byte NALU.
|
||||
if (first_chunk) {
|
||||
int8_t nalu_byte0 = nalu_0x60 | nalu_0x1f;
|
||||
|
@ -322,12 +322,12 @@ int SrsRtpPacket::decode_96(SrsBuffer* stream)
|
|||
payload->append(stream->data() + stream->pos(), stream->size() - stream->pos());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// no chunked, append to payload.
|
||||
stream->skip(-2);
|
||||
payload->append(stream->data() + stream->pos(), stream->size() - stream->pos());
|
||||
completed = true;
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -343,18 +343,18 @@ SrsRtspSdp::~SrsRtspSdp()
|
|||
int SrsRtspSdp::parse(string token)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
||||
if (token.empty()) {
|
||||
srs_info("rtsp: ignore empty token.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t pos = string::npos;
|
||||
|
||||
|
||||
char* start = (char*)token.data();
|
||||
char* end = start + (int)token.length();
|
||||
char* p = start;
|
||||
|
||||
|
||||
// key, first 2bytes.
|
||||
// v=0
|
||||
// o=- 0 0 IN IP4 127.0.0.1
|
||||
|
@ -374,13 +374,13 @@ int SrsRtspSdp::parse(string token)
|
|||
// a=control:streamid=1
|
||||
char key = p[0];
|
||||
p += 2;
|
||||
|
||||
|
||||
// left bytes as attr string.
|
||||
std::string attr_str;
|
||||
if (end - p) {
|
||||
attr_str.append(p, end - p);
|
||||
}
|
||||
|
||||
|
||||
// parse the attributes from left bytes.
|
||||
std::vector<std::string> attrs;
|
||||
while (p < end) {
|
||||
|
@ -395,7 +395,7 @@ int SrsRtspSdp::parse(string token)
|
|||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
|
||||
// parse the first attr as desc, update the first elem for desc.
|
||||
// for example, the value can be "tool", "AS", "rtpmap", "fmtp", "control"
|
||||
std::string desc_key;
|
||||
|
@ -410,7 +410,7 @@ int SrsRtspSdp::parse(string token)
|
|||
desc_key = attr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// interpret the attribute according by key.
|
||||
switch (key) {
|
||||
case 'v': version = attr_str; break;
|
||||
|
@ -492,7 +492,7 @@ int SrsRtspSdp::parse(string token)
|
|||
case 't':
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -502,7 +502,7 @@ int SrsRtspSdp::parse_fmtp_attribute(string attr)
|
|||
|
||||
size_t pos = string::npos;
|
||||
std::string token = attr;
|
||||
|
||||
|
||||
while (!token.empty()) {
|
||||
std::string item = token;
|
||||
if ((pos = item.find(";")) != string::npos) {
|
||||
|
@ -511,13 +511,13 @@ int SrsRtspSdp::parse_fmtp_attribute(string attr)
|
|||
} else {
|
||||
token = "";
|
||||
}
|
||||
|
||||
|
||||
std::string item_key = item, item_value;
|
||||
if ((pos = item.find("=")) != string::npos) {
|
||||
item_key = item.substr(0, pos);
|
||||
item_value = item.substr(pos + 1);
|
||||
}
|
||||
|
||||
|
||||
if (state == SrsRtspSdpStateVideo) {
|
||||
if (item_key == "packetization-mode") {
|
||||
video_packetization_mode = item_value;
|
||||
|
@ -548,7 +548,7 @@ int SrsRtspSdp::parse_fmtp_attribute(string attr)
|
|||
srs_error("rtsp: audio config failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
char* tmp_sh = new char[item_value.length()];
|
||||
SrsAutoFreeA(char, tmp_sh);
|
||||
int nb_tmp_sh = ff_hex_to_data((uint8_t*)tmp_sh, item_value.c_str());
|
||||
|
@ -557,7 +557,7 @@ int SrsRtspSdp::parse_fmtp_attribute(string attr)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -567,7 +567,7 @@ int SrsRtspSdp::parse_control_attribute(string attr)
|
|||
|
||||
size_t pos = string::npos;
|
||||
std::string token = attr;
|
||||
|
||||
|
||||
while (!token.empty()) {
|
||||
std::string item = token;
|
||||
if ((pos = item.find(";")) != string::npos) {
|
||||
|
@ -576,13 +576,13 @@ int SrsRtspSdp::parse_control_attribute(string attr)
|
|||
} else {
|
||||
token = "";
|
||||
}
|
||||
|
||||
|
||||
std::string item_key = item, item_value;
|
||||
if ((pos = item.find("=")) != string::npos) {
|
||||
item_key = item.substr(0, pos);
|
||||
item_value = item.substr(pos + 1);
|
||||
}
|
||||
|
||||
|
||||
if (state == SrsRtspSdpStateVideo) {
|
||||
if (item_key == "streamid") {
|
||||
video_stream_id = item_value;
|
||||
|
@ -593,7 +593,7 @@ int SrsRtspSdp::parse_control_attribute(string attr)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -602,16 +602,16 @@ string SrsRtspSdp::base64_decode(string value)
|
|||
if (value.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
int nb_output = (int)(value.length() * 2);
|
||||
uint8_t* output = new uint8_t[nb_output];
|
||||
SrsAutoFreeA(uint8_t, output);
|
||||
|
||||
|
||||
int ret = srs_av_base64_decode(output, (char*)value.c_str(), nb_output);
|
||||
if (ret <= 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
std::string plaintext;
|
||||
plaintext.append((char*)output, ret);
|
||||
return plaintext;
|
||||
|
@ -633,7 +633,7 @@ int SrsRtspTransport::parse(string attr)
|
|||
|
||||
size_t pos = string::npos;
|
||||
std::string token = attr;
|
||||
|
||||
|
||||
while (!token.empty()) {
|
||||
std::string item = token;
|
||||
if ((pos = item.find(";")) != string::npos) {
|
||||
|
@ -642,13 +642,13 @@ int SrsRtspTransport::parse(string attr)
|
|||
} else {
|
||||
token = "";
|
||||
}
|
||||
|
||||
|
||||
std::string item_key = item, item_value;
|
||||
if ((pos = item.find("=")) != string::npos) {
|
||||
item_key = item.substr(0, pos);
|
||||
item_value = item.substr(pos + 1);
|
||||
}
|
||||
|
||||
|
||||
if (transport.empty()) {
|
||||
transport = item_key;
|
||||
if ((pos = transport.find("/")) != string::npos) {
|
||||
|
@ -660,7 +660,7 @@ int SrsRtspTransport::parse(string attr)
|
|||
profile = profile.substr(0, pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (item_key == "unicast" || item_key == "multicast") {
|
||||
cast_type = item_key;
|
||||
} else if (item_key == "mode") {
|
||||
|
@ -676,7 +676,7 @@ int SrsRtspTransport::parse(string attr)
|
|||
client_port_max = ::atoi(eport.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -728,33 +728,33 @@ SrsRtspResponse::~SrsRtspResponse()
|
|||
int SrsRtspResponse::encode(stringstream& ss)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
||||
// status line
|
||||
ss << SRS_RTSP_VERSION << SRS_RTSP_SP
|
||||
<< status << SRS_RTSP_SP
|
||||
<< srs_generate_rtsp_status_text(status) << SRS_RTSP_CRLF;
|
||||
|
||||
ss << SRS_RTSP_VERSION << SRS_RTSP_SP
|
||||
<< status << SRS_RTSP_SP
|
||||
<< srs_generate_rtsp_status_text(status) << SRS_RTSP_CRLF;
|
||||
|
||||
// cseq
|
||||
ss << SRS_RTSP_TOKEN_CSEQ << ":" << SRS_RTSP_SP << seq << SRS_RTSP_CRLF;
|
||||
|
||||
|
||||
// others.
|
||||
ss << "Cache-Control: no-store" << SRS_RTSP_CRLF
|
||||
<< "Pragma: no-cache" << SRS_RTSP_CRLF
|
||||
<< "Server: " << RTMP_SIG_SRS_SERVER << SRS_RTSP_CRLF;
|
||||
|
||||
<< "Pragma: no-cache" << SRS_RTSP_CRLF
|
||||
<< "Server: " << RTMP_SIG_SRS_SERVER << SRS_RTSP_CRLF;
|
||||
|
||||
// session if specified.
|
||||
if (!session.empty()) {
|
||||
ss << SRS_RTSP_TOKEN_SESSION << ":" << session << SRS_RTSP_CRLF;
|
||||
}
|
||||
|
||||
|
||||
if ((ret = encode_header(ss)) != ERROR_SUCCESS) {
|
||||
srs_error("rtsp: encode header failed. ret=%d", ret);
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
// header EOF.
|
||||
ss << SRS_RTSP_CRLF;
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -765,7 +765,7 @@ int SrsRtspResponse::encode_header(std::stringstream& ss)
|
|||
|
||||
SrsRtspOptionsResponse::SrsRtspOptionsResponse(int cseq) : SrsRtspResponse(cseq)
|
||||
{
|
||||
methods = (SrsRtspMethod)(SrsRtspMethodDescribe | SrsRtspMethodOptions
|
||||
methods = (SrsRtspMethod)(SrsRtspMethodDescribe | SrsRtspMethodOptions
|
||||
| SrsRtspMethodPause | SrsRtspMethodPlay | SrsRtspMethodSetup | SrsRtspMethodTeardown
|
||||
| SrsRtspMethodAnnounce | SrsRtspMethodRecord);
|
||||
}
|
||||
|
@ -789,9 +789,9 @@ int SrsRtspOptionsResponse::encode_header(stringstream& ss)
|
|||
SrsRtspMethodSetParameter,
|
||||
SrsRtspMethodTeardown,
|
||||
};
|
||||
|
||||
|
||||
ss << SRS_RTSP_TOKEN_PUBLIC << ":" << SRS_RTSP_SP;
|
||||
|
||||
|
||||
bool appended = false;
|
||||
int nb_methods = (int)(sizeof(rtsp_methods) / sizeof(SrsRtspMethod));
|
||||
for (int i = 0; i < nb_methods; i++) {
|
||||
|
@ -799,7 +799,7 @@ int SrsRtspOptionsResponse::encode_header(stringstream& ss)
|
|||
if (((int)methods & (int)method) != (int)method) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (appended) {
|
||||
ss << ", ";
|
||||
}
|
||||
|
@ -807,7 +807,7 @@ int SrsRtspOptionsResponse::encode_header(stringstream& ss)
|
|||
appended = true;
|
||||
}
|
||||
ss << SRS_RTSP_CRLF;
|
||||
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -824,10 +824,10 @@ SrsRtspSetupResponse::~SrsRtspSetupResponse()
|
|||
int SrsRtspSetupResponse::encode_header(stringstream& ss)
|
||||
{
|
||||
ss << SRS_RTSP_TOKEN_SESSION << ":" << SRS_RTSP_SP << session << SRS_RTSP_CRLF;
|
||||
ss << SRS_RTSP_TOKEN_TRANSPORT << ":" << SRS_RTSP_SP
|
||||
<< "RTP/AVP;unicast;client_port=" << client_port_min << "-" << client_port_max << ";"
|
||||
<< "server_port=" << local_port_min << "-" << local_port_max
|
||||
<< SRS_RTSP_CRLF;
|
||||
ss << SRS_RTSP_TOKEN_TRANSPORT << ":" << SRS_RTSP_SP
|
||||
<< "RTP/AVP;unicast;client_port=" << client_port_min << "-" << client_port_max << ";"
|
||||
<< "server_port=" << local_port_min << "-" << local_port_max
|
||||
<< SRS_RTSP_CRLF;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -845,29 +845,29 @@ SrsRtspStack::~SrsRtspStack()
|
|||
int SrsRtspStack::recv_message(SrsRtspRequest** preq)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
||||
SrsRtspRequest* req = new SrsRtspRequest();
|
||||
if ((ret = do_recv_message(req)) != ERROR_SUCCESS) {
|
||||
srs_freep(req);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
*preq = req;
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsRtspStack::send_message(SrsRtspResponse* res)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
||||
std::stringstream ss;
|
||||
// encode the message to string.
|
||||
res->encode(ss);
|
||||
|
||||
|
||||
std::string str = ss.str();
|
||||
srs_assert(!str.empty());
|
||||
|
||||
|
||||
if ((ret = skt->write((char*)str.c_str(), (int)str.length(), NULL)) != ERROR_SUCCESS) {
|
||||
if (!srs_is_client_gracefully_close(ret)) {
|
||||
srs_error("rtsp: send response failed. ret=%d", ret);
|
||||
|
@ -875,14 +875,14 @@ int SrsRtspStack::send_message(SrsRtspResponse* res)
|
|||
return ret;
|
||||
}
|
||||
srs_info("rtsp: send response ok");
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsRtspStack::do_recv_message(SrsRtspRequest* req)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
||||
// parse request line.
|
||||
if ((ret = recv_token_normal(req->method)) != ERROR_SUCCESS) {
|
||||
if (!srs_is_client_gracefully_close(ret)) {
|
||||
|
@ -890,21 +890,21 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if ((ret = recv_token_normal(req->uri)) != ERROR_SUCCESS) {
|
||||
if (!srs_is_client_gracefully_close(ret)) {
|
||||
srs_error("rtsp: parse uri failed. ret=%d", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if ((ret = recv_token_eof(req->version)) != ERROR_SUCCESS) {
|
||||
if (!srs_is_client_gracefully_close(ret)) {
|
||||
srs_error("rtsp: parse version failed. ret=%d", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// parse headers.
|
||||
for (;;) {
|
||||
// parse the header name
|
||||
|
@ -920,7 +920,7 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// parse the header value according by header name
|
||||
if (token == SRS_RTSP_TOKEN_CSEQ) {
|
||||
std::string seq;
|
||||
|
@ -986,7 +986,7 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// for setup, parse the stream id from uri.
|
||||
if (req->is_setup()) {
|
||||
size_t pos = string::npos;
|
||||
|
@ -997,14 +997,14 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req)
|
|||
req->stream_id = ::atoi(stream_id.c_str());
|
||||
srs_info("rtsp: setup stream id=%d", req->stream_id);
|
||||
}
|
||||
|
||||
|
||||
// parse rdp body.
|
||||
long consumed = 0;
|
||||
while (consumed < req->content_length) {
|
||||
if (!req->sdp) {
|
||||
req->sdp = new SrsRtspSdp();
|
||||
}
|
||||
|
||||
|
||||
int nb_token = 0;
|
||||
std::string token;
|
||||
if ((ret = recv_token_util_eof(token, &nb_token)) != ERROR_SUCCESS) {
|
||||
|
@ -1014,7 +1014,7 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req)
|
|||
return ret;
|
||||
}
|
||||
consumed += nb_token;
|
||||
|
||||
|
||||
if ((ret = req->sdp->parse(token)) != ERROR_SUCCESS) {
|
||||
srs_error("rtsp: sdp parse token failed, token=%s. ret=%d", token.c_str(), ret);
|
||||
return ret;
|
||||
|
@ -1022,16 +1022,16 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req)
|
|||
srs_info("rtsp: %s", token.c_str());
|
||||
}
|
||||
srs_info("rtsp: sdp parsed, size=%d", consumed);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsRtspStack::recv_token_normal(std::string& token)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
||||
SrsRtspTokenState state;
|
||||
|
||||
|
||||
if ((ret = recv_token(token, state)) != ERROR_SUCCESS) {
|
||||
if (ret == ERROR_RTSP_REQUEST_HEADER_EOF) {
|
||||
return ret;
|
||||
|
@ -1041,22 +1041,22 @@ int SrsRtspStack::recv_token_normal(std::string& token)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if (state != SrsRtspTokenStateNormal) {
|
||||
ret = ERROR_RTSP_TOKEN_NOT_NORMAL;
|
||||
srs_error("rtsp: parse normal token failed, state=%d. ret=%d", state, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsRtspStack::recv_token_eof(std::string& token)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
||||
SrsRtspTokenState state;
|
||||
|
||||
|
||||
if ((ret = recv_token(token, state)) != ERROR_SUCCESS) {
|
||||
if (ret == ERROR_RTSP_REQUEST_HEADER_EOF) {
|
||||
return ret;
|
||||
|
@ -1066,22 +1066,22 @@ int SrsRtspStack::recv_token_eof(std::string& token)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if (state != SrsRtspTokenStateEOF) {
|
||||
ret = ERROR_RTSP_TOKEN_NOT_NORMAL;
|
||||
srs_error("rtsp: parse eof token failed, state=%d. ret=%d", state, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsRtspStack::recv_token_util_eof(std::string& token, int* pconsumed)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
||||
SrsRtspTokenState state;
|
||||
|
||||
|
||||
// use 0x00 as ignore the normal token flag.
|
||||
if ((ret = recv_token(token, state, 0x00, pconsumed)) != ERROR_SUCCESS) {
|
||||
if (ret == ERROR_RTSP_REQUEST_HEADER_EOF) {
|
||||
|
@ -1092,32 +1092,32 @@ int SrsRtspStack::recv_token_util_eof(std::string& token, int* pconsumed)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if (state != SrsRtspTokenStateEOF) {
|
||||
ret = ERROR_RTSP_TOKEN_NOT_NORMAL;
|
||||
srs_error("rtsp: parse eof token failed, state=%d. ret=%d", state, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch, int* pconsumed)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
||||
// whatever, default to error state.
|
||||
state = SrsRtspTokenStateError;
|
||||
|
||||
|
||||
// when buffer is empty, append bytes first.
|
||||
bool append_bytes = buf->length() == 0;
|
||||
|
||||
|
||||
// parse util token.
|
||||
for (;;) {
|
||||
// append bytes if required.
|
||||
if (append_bytes) {
|
||||
append_bytes = false;
|
||||
|
||||
|
||||
char buffer[SRS_RTSP_BUFFER];
|
||||
ssize_t nb_read = 0;
|
||||
if ((ret = skt->read(buffer, SRS_RTSP_BUFFER, &nb_read)) != ERROR_SUCCESS) {
|
||||
|
@ -1127,19 +1127,19 @@ int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char
|
|||
return ret;
|
||||
}
|
||||
srs_info("rtsp: io read %d bytes", nb_read);
|
||||
|
||||
|
||||
buf->append(buffer, nb_read);
|
||||
}
|
||||
|
||||
|
||||
// parse one by one.
|
||||
char* start = buf->bytes();
|
||||
char* end = start + buf->length();
|
||||
char* p = start;
|
||||
|
||||
|
||||
// find util SP/CR/LF, max 2 EOF, to finger out the EOF of message.
|
||||
for (; p < end && p[0] != normal_ch && p[0] != SRS_RTSP_CR && p[0] != SRS_RTSP_LF; p++) {
|
||||
}
|
||||
|
||||
|
||||
// matched.
|
||||
if (p < end) {
|
||||
// finger out the state.
|
||||
|
@ -1160,11 +1160,11 @@ int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char
|
|||
} else {
|
||||
ret = ERROR_RTSP_REQUEST_HEADER_EOF;
|
||||
}
|
||||
|
||||
|
||||
// ignore SP/CR/LF
|
||||
for (int i = 0; i < 2 && p < end && (p[0] == normal_ch || p[0] == SRS_RTSP_CR || p[0] == SRS_RTSP_LF); p++, i++) {
|
||||
}
|
||||
|
||||
|
||||
// consume the token bytes.
|
||||
srs_assert(p - start);
|
||||
buf->erase(p - start);
|
||||
|
@ -1173,11 +1173,11 @@ int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// append more and parse again.
|
||||
append_bytes = true;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue