mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
for #133, rtsp parse aac from rtp packet.
This commit is contained in:
parent
0cc693a3b8
commit
a954040d29
3 changed files with 108 additions and 2 deletions
|
@ -145,6 +145,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define ERROR_RTSP_TOKEN_NOT_NORMAL 2042
|
||||
#define ERROR_RTSP_REQUEST_HEADER_EOF 2043
|
||||
#define ERROR_RTP_HEADER_CORRUPT 2044
|
||||
#define ERROR_RTP_TYPE96_CORRUPT 2045
|
||||
#define ERROR_RTP_TYPE97_CORRUPT 2046
|
||||
//
|
||||
// system control message,
|
||||
// not an error, but special control logic.
|
||||
|
|
|
@ -35,6 +35,7 @@ using namespace std;
|
|||
#include <srs_core_autofree.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_kernel_stream.hpp>
|
||||
#include <srs_kernel_codec.hpp>
|
||||
|
||||
#ifdef SRS_AUTO_STREAM_CASTER
|
||||
|
||||
|
@ -133,6 +134,7 @@ SrsRtpPacket::SrsRtpPacket()
|
|||
ssrc = 0;
|
||||
|
||||
payload = new SrsSimpleBuffer();
|
||||
audio_samples = new SrsCodecSample();
|
||||
chunked = false;
|
||||
completed = false;
|
||||
}
|
||||
|
@ -140,6 +142,7 @@ SrsRtpPacket::SrsRtpPacket()
|
|||
SrsRtpPacket::~SrsRtpPacket()
|
||||
{
|
||||
srs_freep(payload);
|
||||
srs_freep(audio_samples);
|
||||
}
|
||||
|
||||
void SrsRtpPacket::copy(SrsRtpPacket* src)
|
||||
|
@ -156,22 +159,28 @@ void SrsRtpPacket::copy(SrsRtpPacket* src)
|
|||
|
||||
chunked = src->chunked;
|
||||
completed = src->completed;
|
||||
audio_samples = new SrsCodecSample();
|
||||
}
|
||||
|
||||
void SrsRtpPacket::reap(SrsRtpPacket* src)
|
||||
{
|
||||
copy(src);
|
||||
|
||||
srs_freep(payload);
|
||||
payload = src->payload;
|
||||
src->payload = NULL;
|
||||
|
||||
srs_freep(audio_samples);
|
||||
audio_samples = src->audio_samples;
|
||||
src->audio_samples = NULL;
|
||||
}
|
||||
|
||||
int SrsRtpPacket::decode(SrsStream* stream)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
// 12bytes header, atleast 2bytes content.
|
||||
if (!stream->require(14)) {
|
||||
// 12bytes header
|
||||
if (!stream->require(12)) {
|
||||
ret = ERROR_RTP_HEADER_CORRUPT;
|
||||
srs_error("rtsp: rtp header corrupt. ret=%d", ret);
|
||||
return ret;
|
||||
|
@ -191,6 +200,92 @@ int SrsRtpPacket::decode(SrsStream* stream)
|
|||
timestamp = stream->read_4bytes();
|
||||
ssrc = stream->read_4bytes();
|
||||
|
||||
// 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(SrsStream* 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();
|
||||
u_int16_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 nb_samples = au_size / 2;
|
||||
int guess_sample_size = (stream->size() - stream->pos() - au_size) / nb_samples;
|
||||
int required_size = 0;
|
||||
|
||||
// append left bytes to payload.
|
||||
payload->append(
|
||||
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();
|
||||
|
||||
u_int16_t sample_size = ((hasv << 5) & 0xE0) | ((lasv >> 3) & 0x1f);
|
||||
if (sample_size != guess_sample_size) {
|
||||
// guess the size lost 0x100.
|
||||
if (guess_sample_size == (sample_size | 0x100)) {
|
||||
sample_size = guess_sample_size;
|
||||
}
|
||||
}
|
||||
|
||||
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_samples->add_sample_unit(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(SrsStream* 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
|
||||
|
|
|
@ -39,6 +39,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
class SrsStream;
|
||||
class SrsSimpleBuffer;
|
||||
class SrsCodecSample;
|
||||
class ISrsProtocolReaderWriter;
|
||||
|
||||
// rtsp specification
|
||||
|
@ -292,6 +293,11 @@ public:
|
|||
// normal message always completed.
|
||||
// while chunked completed when the last chunk arriaved.
|
||||
bool completed;
|
||||
|
||||
/**
|
||||
* the audio samples, one rtp packets may contains multiple audio samples.
|
||||
*/
|
||||
SrsCodecSample* audio_samples;
|
||||
public:
|
||||
SrsRtpPacket();
|
||||
virtual ~SrsRtpPacket();
|
||||
|
@ -308,6 +314,9 @@ public:
|
|||
* decode rtp packet from stream.
|
||||
*/
|
||||
virtual int decode(SrsStream* stream);
|
||||
private:
|
||||
virtual int decode_97(SrsStream* stream);
|
||||
virtual int decode_96(SrsStream* stream);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue