winlin

Merge branch '2.0release' into develop

@@ -348,7 +348,8 @@ Remark: @@ -348,7 +348,8 @@ Remark:
348 348
349 ### SRS 2.0 history 349 ### SRS 2.0 history
350 350
351 -* v2.0, 2015-05-30, fix [#420](https://github.com/simple-rtmp-server/srs/issues/420) remove ts for hls ram mode. 351 +* v2.0, 2015-06-06, fix [#421](https://github.com/simple-rtmp-server/srs/issues/421) drop video for unkown RTMP header.
  352 +* v2.0, 2015-06-05, fix [#420](https://github.com/simple-rtmp-server/srs/issues/420) remove ts for hls ram mode.
352 * v2.0, 2015-05-30, fix [#209](https://github.com/simple-rtmp-server/srs/issues/209) cleanup hls when stop and timeout. 2.0.173. 353 * v2.0, 2015-05-30, fix [#209](https://github.com/simple-rtmp-server/srs/issues/209) cleanup hls when stop and timeout. 2.0.173.
353 * v2.0, 2015-05-29, fix [#409](https://github.com/simple-rtmp-server/srs/issues/409) support pure video hls. 2.0.172. 354 * v2.0, 2015-05-29, fix [#409](https://github.com/simple-rtmp-server/srs/issues/409) support pure video hls. 2.0.172.
354 * v2.0, 2015-05-28, support [srs-dolphin][srs-dolphin], the multiple-process SRS. 355 * v2.0, 2015-05-28, support [srs-dolphin][srs-dolphin], the multiple-process SRS.
@@ -25,6 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -25,6 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 25
26 #ifdef SRS_AUTO_INGEST 26 #ifdef SRS_AUTO_INGEST
27 27
  28 +#include <stdlib.h>
28 using namespace std; 29 using namespace std;
29 30
30 #include <srs_kernel_error.hpp> 31 #include <srs_kernel_error.hpp>
@@ -39,11 +40,9 @@ using namespace std; @@ -39,11 +40,9 @@ using namespace std;
39 // ingest never sleep a long time, for we must start the stream ASAP. 40 // ingest never sleep a long time, for we must start the stream ASAP.
40 #define SRS_AUTO_INGESTER_SLEEP_US (int64_t)(3*1000*1000LL) 41 #define SRS_AUTO_INGESTER_SLEEP_US (int64_t)(3*1000*1000LL)
41 42
42 -SrsIngesterFFMPEG::SrsIngesterFFMPEG(SrsFFMPEG* _ffmpeg, string _vhost, string _id) 43 +SrsIngesterFFMPEG::SrsIngesterFFMPEG()
43 { 44 {
44 - ffmpeg = _ffmpeg;  
45 - vhost = _vhost;  
46 - id = _id; 45 + ffmpeg = NULL;
47 } 46 }
48 47
49 SrsIngesterFFMPEG::~SrsIngesterFFMPEG() 48 SrsIngesterFFMPEG::~SrsIngesterFFMPEG()
@@ -51,6 +50,53 @@ SrsIngesterFFMPEG::~SrsIngesterFFMPEG() @@ -51,6 +50,53 @@ SrsIngesterFFMPEG::~SrsIngesterFFMPEG()
51 srs_freep(ffmpeg); 50 srs_freep(ffmpeg);
52 } 51 }
53 52
  53 +int SrsIngesterFFMPEG::initialize(SrsFFMPEG* ff, string v, string i)
  54 +{
  55 + int ret = ERROR_SUCCESS;
  56 +
  57 + ffmpeg = ff;
  58 + vhost = v;
  59 + id = i;
  60 + starttime = srs_get_system_time_ms();
  61 +
  62 + return ret;
  63 +}
  64 +
  65 +string SrsIngesterFFMPEG::uri()
  66 +{
  67 + return vhost + "/" + id;
  68 +}
  69 +
  70 +int SrsIngesterFFMPEG::alive()
  71 +{
  72 + return (int)(srs_get_system_time_ms() - starttime);
  73 +}
  74 +
  75 +bool SrsIngesterFFMPEG::equals(string v)
  76 +{
  77 + return vhost == v;
  78 +}
  79 +
  80 +bool SrsIngesterFFMPEG::equals(string v, string i)
  81 +{
  82 + return vhost == v && id == i;
  83 +}
  84 +
  85 +int SrsIngesterFFMPEG::start()
  86 +{
  87 + return ffmpeg->start();
  88 +}
  89 +
  90 +void SrsIngesterFFMPEG::stop()
  91 +{
  92 + ffmpeg->stop();
  93 +}
  94 +
  95 +int SrsIngesterFFMPEG::cycle()
  96 +{
  97 + return ffmpeg->cycle();
  98 +}
  99 +
54 void SrsIngesterFFMPEG::fast_stop() 100 void SrsIngesterFFMPEG::fast_stop()
55 { 101 {
56 ffmpeg->fast_stop(); 102 ffmpeg->fast_stop();
@@ -129,6 +175,8 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest @@ -129,6 +175,8 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest
129 175
130 // get all engines. 176 // get all engines.
131 std::vector<SrsConfDirective*> engines = _srs_config->get_transcode_engines(ingest); 177 std::vector<SrsConfDirective*> engines = _srs_config->get_transcode_engines(ingest);
  178 +
  179 + // create ingesters without engines.
132 if (engines.empty()) { 180 if (engines.empty()) {
133 SrsFFMPEG* ffmpeg = new SrsFFMPEG(ffmpeg_bin); 181 SrsFFMPEG* ffmpeg = new SrsFFMPEG(ffmpeg_bin);
134 if ((ret = initialize_ffmpeg(ffmpeg, vhost, ingest, NULL)) != ERROR_SUCCESS) { 182 if ((ret = initialize_ffmpeg(ffmpeg, vhost, ingest, NULL)) != ERROR_SUCCESS) {
@@ -139,12 +187,17 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest @@ -139,12 +187,17 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest
139 return ret; 187 return ret;
140 } 188 }
141 189
142 - SrsIngesterFFMPEG* ingester = new SrsIngesterFFMPEG(ffmpeg, vhost->arg0(), ingest->arg0()); 190 + SrsIngesterFFMPEG* ingester = new SrsIngesterFFMPEG();
  191 + if ((ret = ingester->initialize(ffmpeg, vhost->arg0(), ingest->arg0())) != ERROR_SUCCESS) {
  192 + srs_freep(ingester);
  193 + return ret;
  194 + }
  195 +
143 ingesters.push_back(ingester); 196 ingesters.push_back(ingester);
144 return ret; 197 return ret;
145 } 198 }
146 199
147 - // create engine 200 + // create ingesters with engine
148 for (int i = 0; i < (int)engines.size(); i++) { 201 for (int i = 0; i < (int)engines.size(); i++) {
149 SrsConfDirective* engine = engines[i]; 202 SrsConfDirective* engine = engines[i];
150 SrsFFMPEG* ffmpeg = new SrsFFMPEG(ffmpeg_bin); 203 SrsFFMPEG* ffmpeg = new SrsFFMPEG(ffmpeg_bin);
@@ -157,7 +210,12 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest @@ -157,7 +210,12 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest
157 return ret; 210 return ret;
158 } 211 }
159 212
160 - SrsIngesterFFMPEG* ingester = new SrsIngesterFFMPEG(ffmpeg, vhost->arg0(), ingest->arg0()); 213 + SrsIngesterFFMPEG* ingester = new SrsIngesterFFMPEG();
  214 + if ((ret = ingester->initialize(ffmpeg, vhost->arg0(), ingest->arg0())) != ERROR_SUCCESS) {
  215 + srs_freep(ingester);
  216 + return ret;
  217 + }
  218 +
161 ingesters.push_back(ingester); 219 ingesters.push_back(ingester);
162 } 220 }
163 221
@@ -196,13 +254,13 @@ int SrsIngester::cycle() @@ -196,13 +254,13 @@ int SrsIngester::cycle()
196 SrsIngesterFFMPEG* ingester = *it; 254 SrsIngesterFFMPEG* ingester = *it;
197 255
198 // start all ffmpegs. 256 // start all ffmpegs.
199 - if ((ret = ingester->ffmpeg->start()) != ERROR_SUCCESS) { 257 + if ((ret = ingester->start()) != ERROR_SUCCESS) {
200 srs_error("ingest ffmpeg start failed. ret=%d", ret); 258 srs_error("ingest ffmpeg start failed. ret=%d", ret);
201 return ret; 259 return ret;
202 } 260 }
203 261
204 // check ffmpeg status. 262 // check ffmpeg status.
205 - if ((ret = ingester->ffmpeg->cycle()) != ERROR_SUCCESS) { 263 + if ((ret = ingester->cycle()) != ERROR_SUCCESS) {
206 srs_error("ingest ffmpeg cycle failed. ret=%d", ret); 264 srs_error("ingest ffmpeg cycle failed. ret=%d", ret);
207 return ret; 265 return ret;
208 } 266 }
@@ -376,11 +434,14 @@ void SrsIngester::show_ingest_log_message() @@ -376,11 +434,14 @@ void SrsIngester::show_ingest_log_message()
376 return; 434 return;
377 } 435 }
378 436
  437 + // random choose one ingester to report.
  438 + int index = rand() % (int)ingesters.size();
  439 + SrsIngesterFFMPEG* ingester = ingesters.at(index);
  440 +
379 // reportable 441 // reportable
380 if (pprint->can_print()) { 442 if (pprint->can_print()) {
381 - // TODO: FIXME: show more info.  
382 - srs_trace("-> "SRS_CONSTS_LOG_INGESTER  
383 - " time=%"PRId64", ingesters=%d", pprint->age(), (int)ingesters.size()); 443 + srs_trace("-> "SRS_CONSTS_LOG_INGESTER" time=%"PRId64", ingesters=%d, #%d(alive=%ds, %s)",
  444 + pprint->age(), (int)ingesters.size(), index, ingester->alive() / 1000, ingester->uri().c_str());
384 } 445 }
385 } 446 }
386 447
@@ -407,16 +468,15 @@ int SrsIngester::on_reload_vhost_removed(string vhost) @@ -407,16 +468,15 @@ int SrsIngester::on_reload_vhost_removed(string vhost)
407 for (it = ingesters.begin(); it != ingesters.end();) { 468 for (it = ingesters.begin(); it != ingesters.end();) {
408 SrsIngesterFFMPEG* ingester = *it; 469 SrsIngesterFFMPEG* ingester = *it;
409 470
410 - if (ingester->vhost != vhost) { 471 + if (!ingester->equals(vhost)) {
411 ++it; 472 ++it;
412 continue; 473 continue;
413 } 474 }
414 475
415 // stop the ffmpeg and free it. 476 // stop the ffmpeg and free it.
416 - ingester->ffmpeg->stop(); 477 + ingester->stop();
417 478
418 - srs_trace("reload stop ingester, "  
419 - "vhost=%s, id=%s", vhost.c_str(), ingester->id.c_str()); 479 + srs_trace("reload stop ingester, vhost=%s, id=%s", vhost.c_str(), ingester->uri().c_str());
420 480
421 srs_freep(ingester); 481 srs_freep(ingester);
422 482
@@ -436,16 +496,15 @@ int SrsIngester::on_reload_ingest_removed(string vhost, string ingest_id) @@ -436,16 +496,15 @@ int SrsIngester::on_reload_ingest_removed(string vhost, string ingest_id)
436 for (it = ingesters.begin(); it != ingesters.end();) { 496 for (it = ingesters.begin(); it != ingesters.end();) {
437 SrsIngesterFFMPEG* ingester = *it; 497 SrsIngesterFFMPEG* ingester = *it;
438 498
439 - if (ingester->vhost != vhost || ingester->id != ingest_id) { 499 + if (!ingester->equals(vhost, ingest_id)) {
440 ++it; 500 ++it;
441 continue; 501 continue;
442 } 502 }
443 503
444 // stop the ffmpeg and free it. 504 // stop the ffmpeg and free it.
445 - ingester->ffmpeg->stop(); 505 + ingester->stop();
446 506
447 - srs_trace("reload stop ingester, "  
448 - "vhost=%s, id=%s", vhost.c_str(), ingester->id.c_str()); 507 + srs_trace("reload stop ingester, vhost=%s, id=%s", vhost.c_str(), ingester->uri().c_str());
449 508
450 srs_freep(ingester); 509 srs_freep(ingester);
451 510
@@ -45,14 +45,26 @@ class SrsPithyPrint; @@ -45,14 +45,26 @@ class SrsPithyPrint;
45 */ 45 */
46 class SrsIngesterFFMPEG 46 class SrsIngesterFFMPEG
47 { 47 {
48 -public: 48 +private:
49 std::string vhost; 49 std::string vhost;
50 std::string id; 50 std::string id;
51 SrsFFMPEG* ffmpeg; 51 SrsFFMPEG* ffmpeg;
52 -  
53 - SrsIngesterFFMPEG(SrsFFMPEG* _ffmpeg, std::string _vhost, std::string _id); 52 + int64_t starttime;
  53 +public:
  54 + SrsIngesterFFMPEG();
54 virtual ~SrsIngesterFFMPEG(); 55 virtual ~SrsIngesterFFMPEG();
55 - 56 +public:
  57 + virtual int initialize(SrsFFMPEG* ff, std::string v, std::string i);
  58 + // the ingest uri, [vhost]/[ingest id]
  59 + virtual std::string uri();
  60 + // the alive in ms.
  61 + virtual int alive();
  62 + virtual bool equals(std::string v, std::string i);
  63 + virtual bool equals(std::string v);
  64 +public:
  65 + virtual int start();
  66 + virtual void stop();
  67 + virtual int cycle();
56 // @see SrsFFMPEG.fast_stop(). 68 // @see SrsFFMPEG.fast_stop().
57 virtual void fast_stop(); 69 virtual void fast_stop();
58 }; 70 };
@@ -62,6 +62,7 @@ public: @@ -62,6 +62,7 @@ public:
62 virtual bool can_handle() = 0; 62 virtual bool can_handle() = 0;
63 /** 63 /**
64 * process the received message. 64 * process the received message.
  65 + * @remark user must free this message.
65 */ 66 */
66 virtual int handle(SrsCommonMessage* msg) = 0; 67 virtual int handle(SrsCommonMessage* msg) = 0;
67 /** 68 /**
@@ -916,7 +916,6 @@ int SrsRtmpConn::handle_publish_message(SrsSource* source, SrsCommonMessage* msg @@ -916,7 +916,6 @@ int SrsRtmpConn::handle_publish_message(SrsSource* source, SrsCommonMessage* msg
916 srs_error("fmle decode unpublish message failed. ret=%d", ret); 916 srs_error("fmle decode unpublish message failed. ret=%d", ret);
917 return ret; 917 return ret;
918 } 918 }
919 -  
920 SrsAutoFree(SrsPacket, pkt); 919 SrsAutoFree(SrsPacket, pkt);
921 920
922 // for flash, any packet is republish. 921 // for flash, any packet is republish.
@@ -605,14 +605,14 @@ int SrsGopCache::cache(SrsSharedPtrMessage* shared_msg) @@ -605,14 +605,14 @@ int SrsGopCache::cache(SrsSharedPtrMessage* shared_msg)
605 // the gop cache know when to gop it. 605 // the gop cache know when to gop it.
606 SrsSharedPtrMessage* msg = shared_msg; 606 SrsSharedPtrMessage* msg = shared_msg;
607 607
608 - // disable gop cache when not h.264 608 + // got video, update the video count if acceptable
  609 + if (msg->is_video()) {
  610 + // drop video when not h.264
609 if (!SrsFlvCodec::video_is_h264(msg->payload, msg->size)) { 611 if (!SrsFlvCodec::video_is_h264(msg->payload, msg->size)) {
610 - srs_info("gop donot cache video for none h.264"); 612 + srs_info("gop cache drop video for none h.264");
611 return ret; 613 return ret;
612 } 614 }
613 615
614 - // got video, update the video count if acceptable  
615 - if (msg->is_video()) {  
616 cached_video_count++; 616 cached_video_count++;
617 audio_after_last_video_count = 0; 617 audio_after_last_video_count = 0;
618 } 618 }
@@ -1464,11 +1464,25 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) @@ -1464,11 +1464,25 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio)
1464 } 1464 }
1465 srs_info("Audio dts=%"PRId64", size=%d", msg.timestamp, msg.size); 1465 srs_info("Audio dts=%"PRId64", size=%d", msg.timestamp, msg.size);
1466 1466
  1467 + // directly process the audio message.
1467 if (!mix_correct) { 1468 if (!mix_correct) {
1468 return on_audio_imp(&msg); 1469 return on_audio_imp(&msg);
1469 } 1470 }
1470 1471
1471 - return do_mix_correct(&msg); 1472 + // insert msg to the queue.
  1473 + mix_queue->push(msg.copy());
  1474 +
  1475 + // fetch someone from mix queue.
  1476 + SrsSharedPtrMessage* m = mix_queue->pop();
  1477 + if (!m) {
  1478 + return ret;
  1479 + }
  1480 +
  1481 + // consume the monotonically increase message.
  1482 + ret = on_audio_imp(m);
  1483 + srs_freep(m);
  1484 +
  1485 + return ret;
1472 } 1486 }
1473 1487
1474 int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) 1488 int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg)
@@ -1619,6 +1633,18 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) @@ -1619,6 +1633,18 @@ int SrsSource::on_video(SrsCommonMessage* shared_video)
1619 { 1633 {
1620 int ret = ERROR_SUCCESS; 1634 int ret = ERROR_SUCCESS;
1621 1635
  1636 + // drop any unknown header video.
  1637 + // @see https://github.com/simple-rtmp-server/srs/issues/421
  1638 + if (!SrsFlvCodec::video_is_acceptable(shared_video->payload, shared_video->size)) {
  1639 + char b0 = 0x00;
  1640 + if (shared_video->size > 0) {
  1641 + b0 = shared_video->payload[0];
  1642 + }
  1643 +
  1644 + srs_warn("drop unknown header video, size=%d, bytes[0]=%#x", shared_video->size, b0);
  1645 + return ret;
  1646 + }
  1647 +
1622 // convert shared_video to msg, user should not use shared_video again. 1648 // convert shared_video to msg, user should not use shared_video again.
1623 // the payload is transfer to msg, and set to NULL in shared_video. 1649 // the payload is transfer to msg, and set to NULL in shared_video.
1624 SrsSharedPtrMessage msg; 1650 SrsSharedPtrMessage msg;
@@ -1628,11 +1654,26 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) @@ -1628,11 +1654,26 @@ int SrsSource::on_video(SrsCommonMessage* shared_video)
1628 } 1654 }
1629 srs_info("Video dts=%"PRId64", size=%d", msg.timestamp, msg.size); 1655 srs_info("Video dts=%"PRId64", size=%d", msg.timestamp, msg.size);
1630 1656
  1657 + // directly process the audio message.
1631 if (!mix_correct) { 1658 if (!mix_correct) {
1632 return on_video_imp(&msg); 1659 return on_video_imp(&msg);
1633 } 1660 }
1634 1661
1635 - return do_mix_correct(&msg); 1662 + // insert msg to the queue.
  1663 + mix_queue->push(msg.copy());
  1664 +
  1665 + // fetch someone from mix queue.
  1666 + SrsSharedPtrMessage* m = mix_queue->pop();
  1667 + if (!m) {
  1668 + return ret;
  1669 + }
  1670 + SrsAutoFree(SrsSharedPtrMessage, m);
  1671 +
  1672 + // consume the monotonically increase message.
  1673 + ret = on_video_imp(m);
  1674 + srs_freep(m);
  1675 +
  1676 + return ret;
1636 } 1677 }
1637 1678
1638 int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) 1679 int SrsSource::on_video_imp(SrsSharedPtrMessage* msg)
@@ -1766,29 +1807,6 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) @@ -1766,29 +1807,6 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg)
1766 return ret; 1807 return ret;
1767 } 1808 }
1768 1809
1769 -int SrsSource::do_mix_correct(SrsSharedPtrMessage* msg)  
1770 -{  
1771 - int ret = ERROR_SUCCESS;  
1772 -  
1773 - // insert msg to the queue.  
1774 - mix_queue->push(msg->copy());  
1775 -  
1776 - // fetch someone from mix queue.  
1777 - SrsSharedPtrMessage* m = mix_queue->pop();  
1778 - if (!m) {  
1779 - return ret;  
1780 - }  
1781 - SrsAutoFree(SrsSharedPtrMessage, m);  
1782 -  
1783 - // consume the monotonically increase message.  
1784 - if (m->is_audio()) {  
1785 - return on_audio_imp(m);  
1786 - }  
1787 -  
1788 - srs_assert(m->is_video());  
1789 - return on_video_imp(m);  
1790 -}  
1791 -  
1792 int SrsSource::on_aggregate(SrsCommonMessage* msg) 1810 int SrsSource::on_aggregate(SrsCommonMessage* msg)
1793 { 1811 {
1794 int ret = ERROR_SUCCESS; 1812 int ret = ERROR_SUCCESS;
@@ -536,8 +536,6 @@ public: @@ -536,8 +536,6 @@ public:
536 virtual int on_video(SrsCommonMessage* video); 536 virtual int on_video(SrsCommonMessage* video);
537 private: 537 private:
538 virtual int on_video_imp(SrsSharedPtrMessage* video); 538 virtual int on_video_imp(SrsSharedPtrMessage* video);
539 -private:  
540 - virtual int do_mix_correct(SrsSharedPtrMessage* msg);  
541 public: 539 public:
542 virtual int on_aggregate(SrsCommonMessage* msg); 540 virtual int on_aggregate(SrsCommonMessage* msg);
543 /** 541 /**
@@ -266,6 +266,28 @@ bool SrsFlvCodec::audio_is_aac(char* data, int size) @@ -266,6 +266,28 @@ bool SrsFlvCodec::audio_is_aac(char* data, int size)
266 return sound_format == SrsCodecAudioAAC; 266 return sound_format == SrsCodecAudioAAC;
267 } 267 }
268 268
  269 +bool SrsFlvCodec::video_is_acceptable(char* data, int size)
  270 +{
  271 + // 1bytes required.
  272 + if (size < 1) {
  273 + return false;
  274 + }
  275 +
  276 + char frame_type = data[0];
  277 + char codec_id = frame_type & 0x0f;
  278 + frame_type = (frame_type >> 4) & 0x0f;
  279 +
  280 + if (frame_type < 1 || frame_type > 5) {
  281 + return false;
  282 + }
  283 +
  284 + if (codec_id < 2 || codec_id > 7) {
  285 + return false;
  286 + }
  287 +
  288 + return true;
  289 +}
  290 +
269 string srs_codec_avc_nalu2str(SrsAvcNaluType nalu_type) 291 string srs_codec_avc_nalu2str(SrsAvcNaluType nalu_type)
270 { 292 {
271 switch (nalu_type) { 293 switch (nalu_type) {
@@ -222,6 +222,12 @@ public: @@ -222,6 +222,12 @@ public:
222 * check codec aac. 222 * check codec aac.
223 */ 223 */
224 static bool audio_is_aac(char* data, int size); 224 static bool audio_is_aac(char* data, int size);
  225 + /**
  226 + * check the video RTMP/flv header info,
  227 + * @return true if video RTMP/flv header is ok.
  228 + * @remark all type of audio is possible, no need to check audio.
  229 + */
  230 + static bool video_is_acceptable(char* data, int size);
225 }; 231 };
226 232
227 /** 233 /**
@@ -97,8 +97,8 @@ void SrsFastBuffer::set_buffer(int buffer_size) @@ -97,8 +97,8 @@ void SrsFastBuffer::set_buffer(int buffer_size)
97 } 97 }
98 98
99 // realloc for buffer change bigger. 99 // realloc for buffer change bigger.
100 - int start = p - buffer;  
101 - int nb_bytes = end - p; 100 + int start = (int)(p - buffer);
  101 + int nb_bytes = (int)(end - p);
102 102
103 buffer = (char*)realloc(buffer, nb_resize_buf); 103 buffer = (char*)realloc(buffer, nb_resize_buf);
104 nb_buffer = nb_resize_buf; 104 nb_buffer = nb_resize_buf;