Skip to content

Commit

Permalink
for ossrs#133, rtsp parse aac from rtp packet.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Feb 18, 2015
1 parent 0cc693a commit a954040
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 2 deletions.
2 changes: 2 additions & 0 deletions trunk/src/kernel/srs_kernel_error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
99 changes: 97 additions & 2 deletions trunk/src/protocol/srs_rtsp_stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -133,13 +134,15 @@ SrsRtpPacket::SrsRtpPacket()
ssrc = 0;

payload = new SrsSimpleBuffer();
audio_samples = new SrsCodecSample();
chunked = false;
completed = false;
}

SrsRtpPacket::~SrsRtpPacket()
{
srs_freep(payload);
srs_freep(audio_samples);
}

void SrsRtpPacket::copy(SrsRtpPacket* src)
Expand All @@ -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;
Expand All @@ -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
Expand Down
9 changes: 9 additions & 0 deletions trunk/src/protocol/srs_rtsp_stack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -292,6 +293,11 @@ class SrsRtpPacket
// 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();
Expand All @@ -308,6 +314,9 @@ class SrsRtpPacket
* decode rtp packet from stream.
*/
virtual int decode(SrsStream* stream);
private:
virtual int decode_97(SrsStream* stream);
virtual int decode_96(SrsStream* stream);
};

/**
Expand Down

0 comments on commit a954040

Please sign in to comment.