winlin

fix #133, support push rtsp to srs. 2.0.120.

1 #Simple-RTMP-Server 1 #Simple-RTMP-Server
2 2
3 -<<<<<<< HEAD  
4 SRS/2.0,开发代号:[ZhouGuowen](https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_Product#release20) 3 SRS/2.0,开发代号:[ZhouGuowen](https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_Product#release20)
5 -=======  
6 -SRS/1.0,开发代号:[HuKaiqun](https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_Product#release10)  
7 ->>>>>>> 1.0release  
8 4
9 SRS定位是运营级的互联网直播服务器集群,追求更好的概念完整性和最简单实现的代码。 5 SRS定位是运营级的互联网直播服务器集群,追求更好的概念完整性和最简单实现的代码。
10 6
@@ -493,6 +489,8 @@ Supported operating systems and hardware: @@ -493,6 +489,8 @@ Supported operating systems and hardware:
493 [#250](https://github.com/winlinvip/simple-rtmp-server/issues/250). 489 [#250](https://github.com/winlinvip/simple-rtmp-server/issues/250).
494 1. Rewrite HLS(h.264+aac/mp3) streaming, read 490 1. Rewrite HLS(h.264+aac/mp3) streaming, read
495 [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304). 491 [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304).
  492 +1. Support push RTSP to SRS, read
  493 +[#133](https://github.com/winlinvip/simple-rtmp-server/issues/133).
496 1. [no-plan] Support <500ms latency, FRSC(Fast RTMP-compatible Stream Channel tech). 494 1. [no-plan] Support <500ms latency, FRSC(Fast RTMP-compatible Stream Channel tech).
497 1. [no-plan] Support RTMP 302 redirect [#92](https://github.com/winlinvip/simple-rtmp-server/issues/92). 495 1. [no-plan] Support RTMP 302 redirect [#92](https://github.com/winlinvip/simple-rtmp-server/issues/92).
498 1. [no-plan] Support multiple processes, for both origin and edge 496 1. [no-plan] Support multiple processes, for both origin and edge
@@ -531,6 +529,7 @@ Supported operating systems and hardware: @@ -531,6 +529,7 @@ Supported operating systems and hardware:
531 529
532 ### SRS 2.0 history 530 ### SRS 2.0 history
533 531
  532 +* v2.0, 2015-02-18, fix [#133](https://github.com/winlinvip/simple-rtmp-server/issues/133), support push rtsp to srs. 2.0.120.
534 * v2.0, 2015-02-17, the join maybe failed, should use a variable to ensure thread terminated. 2.0.119. 533 * v2.0, 2015-02-17, the join maybe failed, should use a variable to ensure thread terminated. 2.0.119.
535 * v2.0, 2015-02-15, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), support config default acodec/vcodec. 2.0.118. 534 * v2.0, 2015-02-15, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), support config default acodec/vcodec. 2.0.118.
536 * v2.0, 2015-02-15, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), rewrite hls/ts code, support h.264+mp3 for hls. 2.0.117. 535 * v2.0, 2015-02-15, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), rewrite hls/ts code, support h.264+mp3 for hls. 2.0.117.
@@ -629,7 +629,6 @@ int SrsMpegtsOverUdp::connect() @@ -629,7 +629,6 @@ int SrsMpegtsOverUdp::connect()
629 return ret; 629 return ret;
630 } 630 }
631 631
632 -  
633 return ret; 632 return ret;
634 } 633 }
635 634
@@ -35,6 +35,12 @@ using namespace std; @@ -35,6 +35,12 @@ using namespace std;
35 #include <srs_core_autofree.hpp> 35 #include <srs_core_autofree.hpp>
36 #include <srs_kernel_stream.hpp> 36 #include <srs_kernel_stream.hpp>
37 #include <srs_kernel_buffer.hpp> 37 #include <srs_kernel_buffer.hpp>
  38 +#include <srs_rtmp_sdk.hpp>
  39 +#include <srs_rtmp_amf0.hpp>
  40 +#include <srs_rtmp_utility.hpp>
  41 +#include <srs_kernel_utility.hpp>
  42 +#include <srs_raw_avc.hpp>
  43 +#include <srs_kernel_codec.hpp>
38 44
39 #ifdef SRS_AUTO_STREAM_CASTER 45 #ifdef SRS_AUTO_STREAM_CASTER
40 46
@@ -100,15 +106,15 @@ int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf) @@ -100,15 +106,15 @@ int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)
100 } 106 }
101 } 107 }
102 108
103 - srs_trace("rtsp: rtp %dB, vt=%d/%u, sts=%u/%#x/%#x, paylod=%dB, chunked=%d",  
104 - nb_buf, cache->version, cache->payload_type, cache->sequence_number, cache->timestamp, cache->ssrc, 109 + srs_trace("rtsp: rtp #%d %dB, vt=%d/%u, sts=%u/%u/%#x, paylod=%dB, chunked=%d",
  110 + stream_id, nb_buf, cache->version, cache->payload_type, cache->sequence_number, cache->timestamp, cache->ssrc,
105 cache->payload->length(), cache->chunked 111 cache->payload->length(), cache->chunked
106 ); 112 );
107 113
108 // always free it. 114 // always free it.
109 SrsAutoFree(SrsRtpPacket, cache); 115 SrsAutoFree(SrsRtpPacket, cache);
110 116
111 - if ((ret = rtsp->on_rtp_packet(cache)) != ERROR_SUCCESS) { 117 + if ((ret = rtsp->on_rtp_packet(cache, stream_id)) != ERROR_SUCCESS) {
112 srs_error("rtsp: process rtp packet failed. ret=%d", ret); 118 srs_error("rtsp: process rtp packet failed. ret=%d", ret);
113 return ret; 119 return ret;
114 } 120 }
@@ -116,9 +122,59 @@ int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf) @@ -116,9 +122,59 @@ int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)
116 return ret; 122 return ret;
117 } 123 }
118 124
  125 +SrsRtspAudioCache::SrsRtspAudioCache()
  126 +{
  127 + dts = NULL;
  128 + audio_samples = NULL;
  129 + payload = NULL;
  130 +}
  131 +
  132 +SrsRtspAudioCache::~SrsRtspAudioCache()
  133 +{
  134 + srs_freep(audio_samples);
  135 + srs_freep(payload);
  136 +}
  137 +
  138 +SrsRtspJitter::SrsRtspJitter()
  139 +{
  140 + delta = 0;
  141 + previous_timestamp = 0;
  142 + pts = 0;
  143 +}
  144 +
  145 +SrsRtspJitter::~SrsRtspJitter()
  146 +{
  147 +}
  148 +
  149 +int64_t SrsRtspJitter::timestamp()
  150 +{
  151 + return pts;
  152 +}
  153 +
  154 +int SrsRtspJitter::correct(int64_t& ts)
  155 +{
  156 + int ret = ERROR_SUCCESS;
  157 +
  158 + if (previous_timestamp == 0) {
  159 + previous_timestamp = ts;
  160 + }
  161 +
  162 + delta = srs_max(0, ts - previous_timestamp);
  163 + if (delta > 90000) {
  164 + delta = 0;
  165 + }
  166 +
  167 + previous_timestamp = ts;
  168 +
  169 + ts = pts + delta;
  170 + pts = ts;
  171 +
  172 + return ret;
  173 +}
  174 +
119 SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o) 175 SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o)
120 { 176 {
121 - output = o; 177 + output_template = o;
122 178
123 session = ""; 179 session = "";
124 video_rtp = NULL; 180 video_rtp = NULL;
@@ -129,6 +185,18 @@ SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o) @@ -129,6 +185,18 @@ SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o)
129 skt = new SrsStSocket(fd); 185 skt = new SrsStSocket(fd);
130 rtsp = new SrsRtspStack(skt); 186 rtsp = new SrsRtspStack(skt);
131 trd = new SrsThread("rtsp", this, 0, false); 187 trd = new SrsThread("rtsp", this, 0, false);
  188 +
  189 + req = NULL;
  190 + io = NULL;
  191 + client = NULL;
  192 + stream_id = 0;
  193 + vjitter = new SrsRtspJitter();
  194 + ajitter = new SrsRtspJitter();
  195 +
  196 + avc = new SrsRawH264Stream();
  197 + aac = new SrsRawAacStream();
  198 + acodec = new SrsRawAacStreamCodec();
  199 + acache = new SrsRtspAudioCache();
132 } 200 }
133 201
134 SrsRtspConn::~SrsRtspConn() 202 SrsRtspConn::~SrsRtspConn()
@@ -142,6 +210,13 @@ SrsRtspConn::~SrsRtspConn() @@ -142,6 +210,13 @@ SrsRtspConn::~SrsRtspConn()
142 srs_freep(trd); 210 srs_freep(trd);
143 srs_freep(skt); 211 srs_freep(skt);
144 srs_freep(rtsp); 212 srs_freep(rtsp);
  213 +
  214 + close();
  215 +
  216 + srs_freep(vjitter);
  217 + srs_freep(ajitter);
  218 + srs_freep(acodec);
  219 + srs_freep(acache);
145 } 220 }
146 221
147 int SrsRtspConn::serve() 222 int SrsRtspConn::serve()
@@ -179,6 +254,18 @@ int SrsRtspConn::do_cycle() @@ -179,6 +254,18 @@ int SrsRtspConn::do_cycle()
179 return ret; 254 return ret;
180 } 255 }
181 } else if (req->is_announce()) { 256 } else if (req->is_announce()) {
  257 + if (rtsp_tcUrl.empty()) {
  258 + rtsp_tcUrl = req->uri;
  259 + }
  260 + size_t pos = string::npos;
  261 + if ((pos = rtsp_tcUrl.rfind(".sdp")) != string::npos) {
  262 + rtsp_tcUrl = rtsp_tcUrl.substr(0, pos);
  263 + }
  264 + if ((pos = rtsp_tcUrl.rfind("/")) != string::npos) {
  265 + rtsp_stream = rtsp_tcUrl.substr(pos + 1);
  266 + rtsp_tcUrl = rtsp_tcUrl.substr(0, pos);
  267 + }
  268 +
182 srs_assert(req->sdp); 269 srs_assert(req->sdp);
183 video_id = ::atoi(req->sdp->video_stream_id.c_str()); 270 video_id = ::atoi(req->sdp->video_stream_id.c_str());
184 audio_id = ::atoi(req->sdp->audio_stream_id.c_str()); 271 audio_id = ::atoi(req->sdp->audio_stream_id.c_str());
@@ -186,13 +273,13 @@ int SrsRtspConn::do_cycle() @@ -186,13 +273,13 @@ int SrsRtspConn::do_cycle()
186 audio_codec = req->sdp->audio_codec; 273 audio_codec = req->sdp->audio_codec;
187 audio_sample_rate = ::atoi(req->sdp->audio_sample_rate.c_str()); 274 audio_sample_rate = ::atoi(req->sdp->audio_sample_rate.c_str());
188 audio_channel = ::atoi(req->sdp->audio_channel.c_str()); 275 audio_channel = ::atoi(req->sdp->audio_channel.c_str());
189 - sps = req->sdp->video_sps;  
190 - pps = req->sdp->video_pps;  
191 - asc = req->sdp->audio_sh;  
192 - srs_trace("rtsp: video(#%d, %s, %s/%s), audio(#%d, %s, %s/%s, %dHZ %dchannels)", 276 + h264_sps = req->sdp->video_sps;
  277 + h264_pps = req->sdp->video_pps;
  278 + aac_specific_config = req->sdp->audio_sh;
  279 + srs_trace("rtsp: video(#%d, %s, %s/%s), audio(#%d, %s, %s/%s, %dHZ %dchannels), %s/%s",
193 video_id, video_codec.c_str(), req->sdp->video_protocol.c_str(), req->sdp->video_transport_format.c_str(), 280 video_id, video_codec.c_str(), req->sdp->video_protocol.c_str(), req->sdp->video_transport_format.c_str(),
194 audio_id, audio_codec.c_str(), req->sdp->audio_protocol.c_str(), req->sdp->audio_transport_format.c_str(), 281 audio_id, audio_codec.c_str(), req->sdp->audio_protocol.c_str(), req->sdp->audio_transport_format.c_str(),
195 - audio_sample_rate, audio_channel 282 + audio_sample_rate, audio_channel, rtsp_tcUrl.c_str(), rtsp_stream.c_str()
196 ); 283 );
197 284
198 SrsRtspResponse* res = new SrsRtspResponse(req->seq); 285 SrsRtspResponse* res = new SrsRtspResponse(req->seq);
@@ -262,9 +349,38 @@ int SrsRtspConn::do_cycle() @@ -262,9 +349,38 @@ int SrsRtspConn::do_cycle()
262 return ret; 349 return ret;
263 } 350 }
264 351
265 -int SrsRtspConn::on_rtp_packet(SrsRtpPacket* pkt) 352 +int SrsRtspConn::on_rtp_packet(SrsRtpPacket* pkt, int stream_id)
266 { 353 {
267 int ret = ERROR_SUCCESS; 354 int ret = ERROR_SUCCESS;
  355 +
  356 + // ensure rtmp connected.
  357 + if ((ret = connect()) != ERROR_SUCCESS) {
  358 + return ret;
  359 + }
  360 +
  361 + if (stream_id == video_id) {
  362 + // rtsp tbn is ts tbn.
  363 + int64_t pts = pkt->timestamp;
  364 + if ((ret = vjitter->correct(pts)) != ERROR_SUCCESS) {
  365 + srs_error("rtsp: correct by jitter failed. ret=%d", ret);
  366 + return ret;
  367 + }
  368 +
  369 + // TODO: FIXME: set dts to pts, please finger out the right dts.
  370 + int64_t dts = pts;
  371 +
  372 + return on_rtp_video(pkt, dts, pts);
  373 + } else {
  374 + // rtsp tbn is ts tbn.
  375 + int64_t pts = pkt->timestamp;
  376 + if ((ret = ajitter->correct(pts)) != ERROR_SUCCESS) {
  377 + srs_error("rtsp: correct by jitter failed. ret=%d", ret);
  378 + return ret;
  379 + }
  380 +
  381 + return on_rtp_audio(pkt, pts);
  382 + }
  383 +
268 return ret; 384 return ret;
269 } 385 }
270 386
@@ -307,6 +423,336 @@ void SrsRtspConn::on_thread_stop() @@ -307,6 +423,336 @@ void SrsRtspConn::on_thread_stop()
307 caster->remove(this); 423 caster->remove(this);
308 } 424 }
309 425
  426 +int SrsRtspConn::on_rtp_video(SrsRtpPacket* pkt, int64_t dts, int64_t pts)
  427 +{
  428 + int ret = ERROR_SUCCESS;
  429 +
  430 + if ((ret = kickoff_audio_cache(pkt, dts)) != ERROR_SUCCESS) {
  431 + return ret;
  432 + }
  433 +
  434 + if ((ret = write_h264_ipb_frame(pkt->payload->bytes(), pkt->payload->length(), dts / 90, pts / 90)) != ERROR_SUCCESS) {
  435 + return ret;
  436 + }
  437 +
  438 + return ret;
  439 +}
  440 +
  441 +int SrsRtspConn::on_rtp_audio(SrsRtpPacket* pkt, int64_t dts)
  442 +{
  443 + int ret = ERROR_SUCCESS;
  444 +
  445 + if ((ret = kickoff_audio_cache(pkt, dts)) != ERROR_SUCCESS) {
  446 + return ret;
  447 + }
  448 +
  449 + // cache current audio to kickoff.
  450 + acache->dts = dts;
  451 + acache->audio_samples = pkt->audio_samples;
  452 + acache->payload = pkt->payload;
  453 +
  454 + pkt->audio_samples = NULL;
  455 + pkt->payload = NULL;
  456 +
  457 + return ret;
  458 +}
  459 +
  460 +int SrsRtspConn::kickoff_audio_cache(SrsRtpPacket* pkt, int64_t dts)
  461 +{
  462 + int ret = ERROR_SUCCESS;
  463 +
  464 + // nothing to kick off.
  465 + if (!acache->payload) {
  466 + return ret;
  467 + }
  468 +
  469 + if (dts - acache->dts > 0 && acache->audio_samples->nb_sample_units > 0) {
  470 + int64_t delta = (dts - acache->dts) / acache->audio_samples->nb_sample_units;
  471 + for (int i = 0; i < acache->audio_samples->nb_sample_units; i++) {
  472 + char* frame = acache->audio_samples->sample_units[i].bytes;
  473 + int nb_frame = acache->audio_samples->sample_units[i].size;
  474 + int64_t timestamp = (acache->dts + delta * i) / 90;
  475 + acodec->aac_packet_type = 1;
  476 + if ((ret = write_audio_raw_frame(frame, nb_frame, acodec, timestamp)) != ERROR_SUCCESS) {
  477 + return ret;
  478 + }
  479 + }
  480 + }
  481 +
  482 + acache->dts = 0;
  483 + srs_freep(acache->audio_samples);
  484 + srs_freep(acache->payload);
  485 +
  486 + return ret;
  487 +}
  488 +
  489 +int SrsRtspConn::write_sequence_header()
  490 +{
  491 + int ret = ERROR_SUCCESS;
  492 +
  493 + // use the current dts.
  494 + int64_t dts = vjitter->timestamp() / 90;
  495 +
  496 + // send video sps/pps
  497 + if ((ret = write_h264_sps_pps(dts, dts)) != ERROR_SUCCESS) {
  498 + return ret;
  499 + }
  500 +
  501 + // generate audio sh by audio specific config.
  502 + if (true) {
  503 + std::string sh = aac_specific_config;
  504 +
  505 + SrsAvcAacCodec dec;
  506 + if ((ret = dec.audio_aac_sequence_header_demux((char*)sh.c_str(), (int)sh.length())) != ERROR_SUCCESS) {
  507 + return ret;
  508 + }
  509 +
  510 + acodec->sound_format = SrsCodecAudioAAC;
  511 + acodec->sound_type = (dec.aac_channels == 2)? SrsCodecAudioSoundTypeStereo : SrsCodecAudioSoundTypeMono;
  512 + acodec->sound_size = SrsCodecAudioSampleSize16bit;
  513 + acodec->aac_packet_type = 0;
  514 +
  515 + static int aac_sample_rates[] = {
  516 + 96000, 88200, 64000, 48000,
  517 + 44100, 32000, 24000, 22050,
  518 + 16000, 12000, 11025, 8000,
  519 + 7350, 0, 0, 0
  520 + };
  521 + switch (aac_sample_rates[dec.aac_sample_rate]) {
  522 + case 11025:
  523 + acodec->sound_rate = SrsCodecAudioSampleRate11025;
  524 + break;
  525 + case 22050:
  526 + acodec->sound_rate = SrsCodecAudioSampleRate22050;
  527 + break;
  528 + case 44100:
  529 + acodec->sound_rate = SrsCodecAudioSampleRate44100;
  530 + break;
  531 + default:
  532 + break;
  533 + };
  534 +
  535 + if ((ret = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), acodec, dts)) != ERROR_SUCCESS) {
  536 + return ret;
  537 + }
  538 + }
  539 +
  540 + return ret;
  541 +}
  542 +
  543 +int SrsRtspConn::write_h264_sps_pps(u_int32_t dts, u_int32_t pts)
  544 +{
  545 + int ret = ERROR_SUCCESS;
  546 +
  547 + // h264 raw to h264 packet.
  548 + std::string sh;
  549 + if ((ret = avc->mux_sequence_header(h264_sps, h264_pps, dts, pts, sh)) != ERROR_SUCCESS) {
  550 + return ret;
  551 + }
  552 +
  553 + // h264 packet to flv packet.
  554 + int8_t frame_type = SrsCodecVideoAVCFrameKeyFrame;
  555 + int8_t avc_packet_type = SrsCodecVideoAVCTypeSequenceHeader;
  556 + char* flv = NULL;
  557 + int nb_flv = 0;
  558 + if ((ret = avc->mux_avc2flv(sh, frame_type, avc_packet_type, dts, pts, &flv, &nb_flv)) != ERROR_SUCCESS) {
  559 + return ret;
  560 + }
  561 +
  562 + // the timestamp in rtmp message header is dts.
  563 + u_int32_t timestamp = dts;
  564 + if ((ret = rtmp_write_packet(SrsCodecFlvTagVideo, timestamp, flv, nb_flv)) != ERROR_SUCCESS) {
  565 + return ret;
  566 + }
  567 +
  568 + return ret;
  569 +}
  570 +
  571 +int SrsRtspConn::write_h264_ipb_frame(char* frame, int frame_size, u_int32_t dts, u_int32_t pts)
  572 +{
  573 + int ret = ERROR_SUCCESS;
  574 +
  575 + std::string ibp;
  576 + int8_t frame_type;
  577 + if ((ret = avc->mux_ipb_frame(frame, frame_size, dts, pts, ibp, frame_type)) != ERROR_SUCCESS) {
  578 + return ret;
  579 + }
  580 +
  581 + int8_t avc_packet_type = SrsCodecVideoAVCTypeNALU;
  582 + char* flv = NULL;
  583 + int nb_flv = 0;
  584 + if ((ret = avc->mux_avc2flv(ibp, frame_type, avc_packet_type, dts, pts, &flv, &nb_flv)) != ERROR_SUCCESS) {
  585 + return ret;
  586 + }
  587 +
  588 + // the timestamp in rtmp message header is dts.
  589 + u_int32_t timestamp = dts;
  590 + return rtmp_write_packet(SrsCodecFlvTagVideo, timestamp, flv, nb_flv);
  591 +}
  592 +
  593 +int SrsRtspConn::write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, u_int32_t dts)
  594 +{
  595 + int ret = ERROR_SUCCESS;
  596 +
  597 + char* data = NULL;
  598 + int size = 0;
  599 + if ((ret = aac->mux_aac2flv(frame, frame_size, codec, dts, &data, &size)) != ERROR_SUCCESS) {
  600 + return ret;
  601 + }
  602 +
  603 + return rtmp_write_packet(SrsCodecFlvTagAudio, dts, data, size);
  604 +}
  605 +
  606 +int SrsRtspConn::rtmp_write_packet(char type, u_int32_t timestamp, char* data, int size)
  607 +{
  608 + int ret = ERROR_SUCCESS;
  609 +
  610 + SrsSharedPtrMessage* msg = NULL;
  611 +
  612 + if ((ret = srs_rtmp_create_msg(type, timestamp, data, size, stream_id, &msg)) != ERROR_SUCCESS) {
  613 + srs_error("rtsp: create shared ptr msg failed. ret=%d", ret);
  614 + return ret;
  615 + }
  616 + srs_assert(msg);
  617 +
  618 + // send out encoded msg.
  619 + if ((ret = client->send_and_free_message(msg, stream_id)) != ERROR_SUCCESS) {
  620 + return ret;
  621 + }
  622 +
  623 + return ret;
  624 +}
  625 +
  626 +// TODO: FIXME: merge all client code.
  627 +int SrsRtspConn::connect()
  628 +{
  629 + int ret = ERROR_SUCCESS;
  630 +
  631 + // when ok, ignore.
  632 + if (io || client) {
  633 + return ret;
  634 + }
  635 +
  636 + // parse uri
  637 + if (!req) {
  638 + req = new SrsRequest();
  639 +
  640 + std::string schema, host, vhost, app, port, param;
  641 + srs_discovery_tc_url(rtsp_tcUrl, schema, host, vhost, app, port, param);
  642 +
  643 + // generate output by template.
  644 + std::string output = output_template;
  645 + output = srs_string_replace(output, "[app]", app);
  646 + output = srs_string_replace(output, "[stream]", rtsp_stream);
  647 +
  648 + size_t pos = string::npos;
  649 + string uri = req->tcUrl = output;
  650 +
  651 + // tcUrl, stream
  652 + if ((pos = uri.rfind("/")) != string::npos) {
  653 + req->stream = uri.substr(pos + 1);
  654 + req->tcUrl = uri = uri.substr(0, pos);
  655 + }
  656 +
  657 + srs_discovery_tc_url(req->tcUrl,
  658 + req->schema, req->host, req->vhost, req->app, req->port,
  659 + req->param);
  660 + }
  661 +
  662 + // connect host.
  663 + if ((ret = srs_socket_connect(req->host, ::atoi(req->port.c_str()), ST_UTIME_NO_TIMEOUT, &stfd)) != ERROR_SUCCESS) {
  664 + srs_error("rtsp: connect server %s:%s failed. ret=%d", req->host.c_str(), req->port.c_str(), ret);
  665 + return ret;
  666 + }
  667 + io = new SrsStSocket(stfd);
  668 + client = new SrsRtmpClient(io);
  669 +
  670 + client->set_recv_timeout(SRS_CONSTS_RTMP_RECV_TIMEOUT_US);
  671 + client->set_send_timeout(SRS_CONSTS_RTMP_SEND_TIMEOUT_US);
  672 +
  673 + // connect to vhost/app
  674 + if ((ret = client->handshake()) != ERROR_SUCCESS) {
  675 + srs_error("rtsp: handshake with server failed. ret=%d", ret);
  676 + return ret;
  677 + }
  678 + if ((ret = connect_app(req->host, req->port)) != ERROR_SUCCESS) {
  679 + srs_error("rtsp: connect with server failed. ret=%d", ret);
  680 + return ret;
  681 + }
  682 + if ((ret = client->create_stream(stream_id)) != ERROR_SUCCESS) {
  683 + srs_error("rtsp: connect with server failed, stream_id=%d. ret=%d", stream_id, ret);
  684 + return ret;
  685 + }
  686 +
  687 + // publish.
  688 + if ((ret = client->publish(req->stream, stream_id)) != ERROR_SUCCESS) {
  689 + srs_error("rtsp: publish failed, stream=%s, stream_id=%d. ret=%d",
  690 + req->stream.c_str(), stream_id, ret);
  691 + return ret;
  692 + }
  693 +
  694 + return write_sequence_header();
  695 +}
  696 +
  697 +// TODO: FIXME: refine the connect_app.
  698 +int SrsRtspConn::connect_app(string ep_server, string ep_port)
  699 +{
  700 + int ret = ERROR_SUCCESS;
  701 +
  702 + // args of request takes the srs info.
  703 + if (req->args == NULL) {
  704 + req->args = SrsAmf0Any::object();
  705 + }
  706 +
  707 + // notify server the edge identity,
  708 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/147
  709 + SrsAmf0Object* data = req->args;
  710 + data->set("srs_sig", SrsAmf0Any::str(RTMP_SIG_SRS_KEY));
  711 + data->set("srs_server", SrsAmf0Any::str(RTMP_SIG_SRS_KEY" "RTMP_SIG_SRS_VERSION" ("RTMP_SIG_SRS_URL_SHORT")"));
  712 + data->set("srs_license", SrsAmf0Any::str(RTMP_SIG_SRS_LICENSE));
  713 + data->set("srs_role", SrsAmf0Any::str(RTMP_SIG_SRS_ROLE));
  714 + data->set("srs_url", SrsAmf0Any::str(RTMP_SIG_SRS_URL));
  715 + data->set("srs_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION));
  716 + data->set("srs_site", SrsAmf0Any::str(RTMP_SIG_SRS_WEB));
  717 + data->set("srs_email", SrsAmf0Any::str(RTMP_SIG_SRS_EMAIL));
  718 + data->set("srs_copyright", SrsAmf0Any::str(RTMP_SIG_SRS_COPYRIGHT));
  719 + data->set("srs_primary", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY));
  720 + data->set("srs_authors", SrsAmf0Any::str(RTMP_SIG_SRS_AUTHROS));
  721 + // for edge to directly get the id of client.
  722 + data->set("srs_pid", SrsAmf0Any::number(getpid()));
  723 + data->set("srs_id", SrsAmf0Any::number(_srs_context->get_id()));
  724 +
  725 + // local ip of edge
  726 + std::vector<std::string> ips = srs_get_local_ipv4_ips();
  727 + assert(_srs_config->get_stats_network() < (int)ips.size());
  728 + std::string local_ip = ips[_srs_config->get_stats_network()];
  729 + data->set("srs_server_ip", SrsAmf0Any::str(local_ip.c_str()));
  730 +
  731 + // generate the tcUrl
  732 + std::string param = "";
  733 + std::string tc_url = srs_generate_tc_url(ep_server, req->vhost, req->app, ep_port, param);
  734 +
  735 + // upnode server identity will show in the connect_app of client.
  736 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/160
  737 + // the debug_srs_upnode is config in vhost and default to true.
  738 + bool debug_srs_upnode = _srs_config->get_debug_srs_upnode(req->vhost);
  739 + if ((ret = client->connect_app(req->app, tc_url, req, debug_srs_upnode)) != ERROR_SUCCESS) {
  740 + srs_error("rtsp: connect with server failed, tcUrl=%s, dsu=%d. ret=%d",
  741 + tc_url.c_str(), debug_srs_upnode, ret);
  742 + return ret;
  743 + }
  744 +
  745 + return ret;
  746 +}
  747 +
  748 +void SrsRtspConn::close()
  749 +{
  750 + srs_freep(client);
  751 + srs_freep(io);
  752 + srs_freep(req);
  753 + srs_close_stfd(stfd);
  754 +}
  755 +
310 SrsRtspCaster::SrsRtspCaster(SrsConfDirective* c) 756 SrsRtspCaster::SrsRtspCaster(SrsConfDirective* c)
311 { 757 {
312 // TODO: FIXME: support reload. 758 // TODO: FIXME: support reload.
@@ -46,6 +46,15 @@ class SrsRtspStack; @@ -46,6 +46,15 @@ class SrsRtspStack;
46 class SrsRtspCaster; 46 class SrsRtspCaster;
47 class SrsConfDirective; 47 class SrsConfDirective;
48 class SrsRtpPacket; 48 class SrsRtpPacket;
  49 +class SrsRequest;
  50 +class SrsStSocket;
  51 +class SrsRtmpClient;
  52 +class SrsRawH264Stream;
  53 +class SrsRawAacStream;
  54 +class SrsRawAacStreamCodec;
  55 +class SrsSharedPtrMessage;
  56 +class SrsCodecSample;
  57 +class SrsSimpleBuffer;
49 58
50 /** 59 /**
51 * a rtp connection which transport a stream. 60 * a rtp connection which transport a stream.
@@ -70,12 +79,45 @@ public: @@ -70,12 +79,45 @@ public:
70 }; 79 };
71 80
72 /** 81 /**
  82 +* audio is group by frames.
  83 +*/
  84 +struct SrsRtspAudioCache
  85 +{
  86 + int64_t dts;
  87 + SrsCodecSample* audio_samples;
  88 + SrsSimpleBuffer* payload;
  89 +
  90 + SrsRtspAudioCache();
  91 + virtual ~SrsRtspAudioCache();
  92 +};
  93 +
  94 +/**
  95 +* the time jitter correct for rtsp.
  96 +*/
  97 +class SrsRtspJitter
  98 +{
  99 +private:
  100 + int64_t previous_timestamp;
  101 + int64_t pts;
  102 + int delta;
  103 +public:
  104 + SrsRtspJitter();
  105 + virtual ~SrsRtspJitter();
  106 +public:
  107 + virtual int64_t timestamp();
  108 + virtual int correct(int64_t& ts);
  109 +};
  110 +
  111 +/**
73 * the rtsp connection serve the fd. 112 * the rtsp connection serve the fd.
74 */ 113 */
75 class SrsRtspConn : public ISrsThreadHandler 114 class SrsRtspConn : public ISrsThreadHandler
76 { 115 {
77 private: 116 private:
78 - std::string output; 117 + std::string output_template;
  118 + std::string rtsp_tcUrl;
  119 + std::string rtsp_stream;
  120 +
79 private: 121 private:
80 std::string session; 122 std::string session;
81 // video stream. 123 // video stream.
@@ -88,17 +130,28 @@ private: @@ -88,17 +130,28 @@ private:
88 int audio_sample_rate; 130 int audio_sample_rate;
89 int audio_channel; 131 int audio_channel;
90 SrsRtpConn* audio_rtp; 132 SrsRtpConn* audio_rtp;
91 - // video sequence header.  
92 - std::string sps;  
93 - std::string pps;  
94 - // audio sequence header.  
95 - std::string asc;  
96 private: 133 private:
97 st_netfd_t stfd; 134 st_netfd_t stfd;
98 SrsStSocket* skt; 135 SrsStSocket* skt;
99 SrsRtspStack* rtsp; 136 SrsRtspStack* rtsp;
100 SrsRtspCaster* caster; 137 SrsRtspCaster* caster;
101 SrsThread* trd; 138 SrsThread* trd;
  139 +private:
  140 + SrsRequest* req;
  141 + SrsStSocket* io;
  142 + SrsRtmpClient* client;
  143 + SrsRtspJitter* vjitter;
  144 + SrsRtspJitter* ajitter;
  145 + int stream_id;
  146 +private:
  147 + SrsRawH264Stream* avc;
  148 + std::string h264_sps;
  149 + std::string h264_pps;
  150 +private:
  151 + SrsRawAacStream* aac;
  152 + SrsRawAacStreamCodec* acodec;
  153 + std::string aac_specific_config;
  154 + SrsRtspAudioCache* acache;
102 public: 155 public:
103 SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o); 156 SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o);
104 virtual ~SrsRtspConn(); 157 virtual ~SrsRtspConn();
@@ -108,11 +161,28 @@ private: @@ -108,11 +161,28 @@ private:
108 virtual int do_cycle(); 161 virtual int do_cycle();
109 // internal methods 162 // internal methods
110 public: 163 public:
111 - virtual int on_rtp_packet(SrsRtpPacket* pkt); 164 + virtual int on_rtp_packet(SrsRtpPacket* pkt, int stream_id);
112 // interface ISrsThreadHandler 165 // interface ISrsThreadHandler
113 public: 166 public:
114 virtual int cycle(); 167 virtual int cycle();
115 virtual void on_thread_stop(); 168 virtual void on_thread_stop();
  169 +private:
  170 + virtual int on_rtp_video(SrsRtpPacket* pkt, int64_t dts, int64_t pts);
  171 + virtual int on_rtp_audio(SrsRtpPacket* pkt, int64_t dts);
  172 + virtual int kickoff_audio_cache(SrsRtpPacket* pkt, int64_t dts);
  173 +private:
  174 + virtual int write_sequence_header();
  175 + virtual int write_h264_sps_pps(u_int32_t dts, u_int32_t pts);
  176 + virtual int write_h264_ipb_frame(char* frame, int frame_size, u_int32_t dts, u_int32_t pts);
  177 + virtual int write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, u_int32_t dts);
  178 + virtual int rtmp_write_packet(char type, u_int32_t timestamp, char* data, int size);
  179 +private:
  180 + // connect to rtmp output url.
  181 + // @remark ignore when not connected, reconnect when disconnected.
  182 + virtual int connect();
  183 + virtual int connect_app(std::string ep_server, std::string ep_port);
  184 + // close the connected io and rtmp to ready to be re-connect.
  185 + virtual void close();
116 }; 186 };
117 187
118 /** 188 /**
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 119 34 +#define VERSION_REVISION 120
35 35
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "SRS" 37 #define RTMP_SIG_SRS_KEY "SRS"
@@ -279,58 +279,12 @@ int SrsAvcAacCodec::audio_aac_demux(char* data, int size, SrsCodecSample* sample @@ -279,58 +279,12 @@ int SrsAvcAacCodec::audio_aac_demux(char* data, int size, SrsCodecSample* sample
279 srs_freep(aac_extra_data); 279 srs_freep(aac_extra_data);
280 aac_extra_data = new char[aac_extra_size]; 280 aac_extra_data = new char[aac_extra_size];
281 memcpy(aac_extra_data, stream->data() + stream->pos(), aac_extra_size); 281 memcpy(aac_extra_data, stream->data() + stream->pos(), aac_extra_size);
282 - }  
283 -  
284 - // only need to decode the first 2bytes:  
285 - // audioObjectType, aac_profile, 5bits.  
286 - // samplingFrequencyIndex, aac_sample_rate, 4bits.  
287 - // channelConfiguration, aac_channels, 4bits  
288 - if (!stream->require(2)) {  
289 - ret = ERROR_HLS_DECODE_ERROR;  
290 - srs_error("audio codec decode aac sequence header failed. ret=%d", ret);  
291 - return ret;  
292 - }  
293 - u_int8_t profile_ObjectType = stream->read_1bytes();  
294 - u_int8_t samplingFrequencyIndex = stream->read_1bytes();  
295 -  
296 - aac_channels = (samplingFrequencyIndex >> 3) & 0x0f;  
297 - samplingFrequencyIndex = ((profile_ObjectType << 1) & 0x0e) | ((samplingFrequencyIndex >> 7) & 0x01);  
298 - profile_ObjectType = (profile_ObjectType >> 3) & 0x1f;  
299 -  
300 - // set the aac sample rate.  
301 - aac_sample_rate = samplingFrequencyIndex;  
302 282
303 - // the profile = object_id + 1  
304 - // @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,  
305 - // Table 1. A.9 ¨C MPEG-2 Audio profiles and MPEG-4 Audio object types  
306 - aac_profile = profile_ObjectType + 1;  
307 -  
308 - // the valid aac profile:  
309 - // MPEG-2 profile  
310 - // Main profile (ID == 1)  
311 - // Low Complexity profile (LC) (ID == 2)  
312 - // Scalable Sampling Rate profile (SSR) (ID == 3)  
313 - // (reserved) (ID == 4)  
314 - // @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,  
315 - // Table 1. A.9 ¨C MPEG-2 Audio profiles and MPEG-4 Audio object types  
316 - if (aac_profile > 4) {  
317 - ret = ERROR_HLS_DECODE_ERROR;  
318 - srs_error("audio codec decode aac sequence header failed, "  
319 - "adts object=%d invalid. ret=%d", profile_ObjectType, ret);  
320 - return ret; 283 + // demux the sequence header.
  284 + if ((ret = audio_aac_sequence_header_demux(aac_extra_data, aac_extra_size)) != ERROR_SUCCESS) {
  285 + return ret;
  286 + }
321 } 287 }
322 -  
323 - // TODO: FIXME: to support aac he/he-v2, see: ngx_rtmp_codec_parse_aac_header  
324 - // @see: https://github.com/winlinvip/nginx-rtmp-module/commit/3a5f9eea78fc8d11e8be922aea9ac349b9dcbfc2  
325 - //  
326 - // donot force to LC, @see: https://github.com/winlinvip/simple-rtmp-server/issues/81  
327 - // the source will print the sequence header info.  
328 - //if (aac_profile > 3) {  
329 - // Mark all extended profiles as LC  
330 - // to make Android as happy as possible.  
331 - // @see: ngx_rtmp_hls_parse_aac_header  
332 - //aac_profile = 1;  
333 - //}  
334 } else if (aac_packet_type == SrsCodecAudioTypeRawData) { 288 } else if (aac_packet_type == SrsCodecAudioTypeRawData) {
335 // ensure the sequence header demuxed 289 // ensure the sequence header demuxed
336 if (aac_extra_size <= 0 || !aac_extra_data) { 290 if (aac_extra_size <= 0 || !aac_extra_data) {
@@ -403,6 +357,68 @@ int SrsAvcAacCodec::audio_mp3_demux(char* data, int size, SrsCodecSample* sample @@ -403,6 +357,68 @@ int SrsAvcAacCodec::audio_mp3_demux(char* data, int size, SrsCodecSample* sample
403 return ret; 357 return ret;
404 } 358 }
405 359
  360 +int SrsAvcAacCodec::audio_aac_sequence_header_demux(char* data, int size)
  361 +{
  362 + int ret = ERROR_SUCCESS;
  363 +
  364 + if ((ret = stream->initialize(data, size)) != ERROR_SUCCESS) {
  365 + return ret;
  366 + }
  367 +
  368 + // only need to decode the first 2bytes:
  369 + // audioObjectType, aac_profile, 5bits.
  370 + // samplingFrequencyIndex, aac_sample_rate, 4bits.
  371 + // channelConfiguration, aac_channels, 4bits
  372 + if (!stream->require(2)) {
  373 + ret = ERROR_HLS_DECODE_ERROR;
  374 + srs_error("audio codec decode aac sequence header failed. ret=%d", ret);
  375 + return ret;
  376 + }
  377 + u_int8_t profile_ObjectType = stream->read_1bytes();
  378 + u_int8_t samplingFrequencyIndex = stream->read_1bytes();
  379 +
  380 + aac_channels = (samplingFrequencyIndex >> 3) & 0x0f;
  381 + samplingFrequencyIndex = ((profile_ObjectType << 1) & 0x0e) | ((samplingFrequencyIndex >> 7) & 0x01);
  382 + profile_ObjectType = (profile_ObjectType >> 3) & 0x1f;
  383 +
  384 + // set the aac sample rate.
  385 + aac_sample_rate = samplingFrequencyIndex;
  386 +
  387 + // the profile = object_id + 1
  388 + // @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,
  389 + // Table 1. A.9 ¨C MPEG-2 Audio profiles and MPEG-4 Audio object types
  390 + aac_profile = profile_ObjectType + 1;
  391 +
  392 + // the valid aac profile:
  393 + // MPEG-2 profile
  394 + // Main profile (ID == 1)
  395 + // Low Complexity profile (LC) (ID == 2)
  396 + // Scalable Sampling Rate profile (SSR) (ID == 3)
  397 + // (reserved) (ID == 4)
  398 + // @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,
  399 + // Table 1. A.9 ¨C MPEG-2 Audio profiles and MPEG-4 Audio object types
  400 + if (aac_profile > 4) {
  401 + ret = ERROR_HLS_DECODE_ERROR;
  402 + srs_error("audio codec decode aac sequence header failed, "
  403 + "adts object=%d invalid. ret=%d", profile_ObjectType, ret);
  404 + return ret;
  405 + }
  406 +
  407 + // TODO: FIXME: to support aac he/he-v2, see: ngx_rtmp_codec_parse_aac_header
  408 + // @see: https://github.com/winlinvip/nginx-rtmp-module/commit/3a5f9eea78fc8d11e8be922aea9ac349b9dcbfc2
  409 + //
  410 + // donot force to LC, @see: https://github.com/winlinvip/simple-rtmp-server/issues/81
  411 + // the source will print the sequence header info.
  412 + //if (aac_profile > 3) {
  413 + // Mark all extended profiles as LC
  414 + // to make Android as happy as possible.
  415 + // @see: ngx_rtmp_hls_parse_aac_header
  416 + //aac_profile = 1;
  417 + //}
  418 +
  419 + return ret;
  420 +}
  421 +
406 int SrsAvcAacCodec::video_avc_demux(char* data, int size, SrsCodecSample* sample) 422 int SrsAvcAacCodec::video_avc_demux(char* data, int size, SrsCodecSample* sample)
407 { 423 {
408 int ret = ERROR_SUCCESS; 424 int ret = ERROR_SUCCESS;
@@ -475,6 +475,11 @@ public: @@ -475,6 +475,11 @@ public:
475 * demux the h.264 NALUs to sampe units. 475 * demux the h.264 NALUs to sampe units.
476 */ 476 */
477 virtual int video_avc_demux(char* data, int size, SrsCodecSample* sample); 477 virtual int video_avc_demux(char* data, int size, SrsCodecSample* sample);
  478 +public:
  479 + /**
  480 + * directly demux the sequence header, without RTMP packet header.
  481 + */
  482 + virtual int audio_aac_sequence_header_demux(char* data, int size);
478 private: 483 private:
479 /** 484 /**
480 * when avc packet type is SrsCodecVideoAVCTypeSequenceHeader, 485 * when avc packet type is SrsCodecVideoAVCTypeSequenceHeader,
@@ -147,6 +147,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -147,6 +147,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
147 #define ERROR_RTP_HEADER_CORRUPT 2044 147 #define ERROR_RTP_HEADER_CORRUPT 2044
148 #define ERROR_RTP_TYPE96_CORRUPT 2045 148 #define ERROR_RTP_TYPE96_CORRUPT 2045
149 #define ERROR_RTP_TYPE97_CORRUPT 2046 149 #define ERROR_RTP_TYPE97_CORRUPT 2046
  150 +#define ERROR_RTSP_AUDIO_CONFIG 2047
150 // 151 //
151 // system control message, 152 // system control message,
152 // not an error, but special control logic. 153 // not an error, but special control logic.
@@ -621,3 +621,41 @@ char* srs_av_base64_encode(char* out, int out_size, const u_int8_t* in, int in_s @@ -621,3 +621,41 @@ char* srs_av_base64_encode(char* out, int out_size, const u_int8_t* in, int in_s
621 return ret; 621 return ret;
622 } 622 }
623 623
  624 +#define SPACE_CHARS " \t\r\n"
  625 +
  626 +int av_toupper(int c)
  627 +{
  628 + if (c >= 'a' && c <= 'z') {
  629 + c ^= 0x20;
  630 + }
  631 + return c;
  632 +}
  633 +
  634 +int ff_hex_to_data(u_int8_t* data, const char* p)
  635 +{
  636 + int c, len, v;
  637 +
  638 + len = 0;
  639 + v = 1;
  640 + for (;;) {
  641 + p += strspn(p, SPACE_CHARS);
  642 + if (*p == '\0')
  643 + break;
  644 + c = av_toupper((unsigned char) *p++);
  645 + if (c >= '0' && c <= '9')
  646 + c = c - '0';
  647 + else if (c >= 'A' && c <= 'F')
  648 + c = c - 'A' + 10;
  649 + else
  650 + break;
  651 + v = (v << 4) | c;
  652 + if (v & 0x100) {
  653 + if (data)
  654 + data[len] = v;
  655 + len++;
  656 + v = 1;
  657 + }
  658 + }
  659 + return len;
  660 +}
  661 +
@@ -115,5 +115,12 @@ extern char* srs_av_base64_encode(char* out, int out_size, const u_int8_t* in, i @@ -115,5 +115,12 @@ extern char* srs_av_base64_encode(char* out, int out_size, const u_int8_t* in, i
115 */ 115 */
116 #define SRS_AV_BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1) 116 #define SRS_AV_BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1)
117 117
  118 +/**
  119 +* convert hex string to data.
  120 +* for example, p=config='139056E5A0'
  121 +* output hex to data={0x13, 0x90, 0x56, 0xe5, 0xa0}
  122 +*/
  123 +extern int ff_hex_to_data(u_int8_t* data, const char* p);
  124 +
118 #endif 125 #endif
119 126
@@ -200,6 +200,8 @@ int SrsRtpPacket::decode(SrsStream* stream) @@ -200,6 +200,8 @@ int SrsRtpPacket::decode(SrsStream* stream)
200 timestamp = stream->read_4bytes(); 200 timestamp = stream->read_4bytes();
201 ssrc = stream->read_4bytes(); 201 ssrc = stream->read_4bytes();
202 202
  203 + // TODO: FIXME: check sequence number.
  204 +
203 // video codec. 205 // video codec.
204 if (payload_type == 96) { 206 if (payload_type == 96) {
205 return decode_96(stream); 207 return decode_96(stream);
@@ -232,7 +234,6 @@ int SrsRtpPacket::decode_97(SrsStream* stream) @@ -232,7 +234,6 @@ int SrsRtpPacket::decode_97(SrsStream* stream)
232 } 234 }
233 235
234 int nb_samples = au_size / 2; 236 int nb_samples = au_size / 2;
235 - int guess_sample_size = (stream->size() - stream->pos() - au_size) / nb_samples;  
236 int required_size = 0; 237 int required_size = 0;
237 238
238 // append left bytes to payload. 239 // append left bytes to payload.
@@ -247,11 +248,9 @@ int SrsRtpPacket::decode_97(SrsStream* stream) @@ -247,11 +248,9 @@ int SrsRtpPacket::decode_97(SrsStream* stream)
247 lasv = stream->read_1bytes(); 248 lasv = stream->read_1bytes();
248 249
249 u_int16_t sample_size = ((hasv << 5) & 0xE0) | ((lasv >> 3) & 0x1f); 250 u_int16_t sample_size = ((hasv << 5) & 0xE0) | ((lasv >> 3) & 0x1f);
250 - if (sample_size != guess_sample_size) {  
251 - // guess the size lost 0x100.  
252 - if (guess_sample_size == (sample_size | 0x100)) {  
253 - sample_size = guess_sample_size;  
254 - } 251 + // TODO: FIXME: finger out how to parse the size of sample.
  252 + if (sample_size < 0x100 && stream->require(required_size + sample_size + 0x100)) {
  253 + sample_size = sample_size | 0x100;
255 } 254 }
256 255
257 char* sample = p + required_size; 256 char* sample = p + required_size;
@@ -541,7 +540,17 @@ int SrsRtspSdp::parse_fmtp_attribute(string attr) @@ -541,7 +540,17 @@ int SrsRtspSdp::parse_fmtp_attribute(string attr)
541 } else if (item_key == "indexdeltalength") { 540 } else if (item_key == "indexdeltalength") {
542 audio_index_delta_length = item_value; 541 audio_index_delta_length = item_value;
543 } else if (item_key == "config") { 542 } else if (item_key == "config") {
544 - audio_sh = base64_decode(item_value); 543 + if (item_value.length() <= 0) {
  544 + ret = ERROR_RTSP_AUDIO_CONFIG;
  545 + srs_error("rtsp: audio config failed. ret=%d", ret);
  546 + return ret;
  547 + }
  548 +
  549 + char* tmp_sh = new char[item_value.length()];
  550 + SrsAutoFree(char, tmp_sh);
  551 + int nb_tmp_sh = ff_hex_to_data((u_int8_t*)tmp_sh, item_value.c_str());
  552 + srs_assert(nb_tmp_sh > 0);
  553 + audio_sh.append(tmp_sh, nb_tmp_sh);
545 } 554 }
546 } 555 }
547 } 556 }