winlin

support hls ingest, fix the bugs.

@@ -169,6 +169,23 @@ int SrsTsMessage::stream_number() @@ -169,6 +169,23 @@ int SrsTsMessage::stream_number()
169 return -1; 169 return -1;
170 } 170 }
171 171
  172 +SrsTsMessage* SrsTsMessage::detach()
  173 +{
  174 + // @remark the packet cannot be used, but channel is ok.
  175 + SrsTsMessage* cp = new SrsTsMessage(channel, NULL);
  176 + cp->start_pts = start_pts;
  177 + cp->write_pcr = write_pcr;
  178 + cp->is_discontinuity = is_discontinuity;
  179 + cp->dts = dts;
  180 + cp->pts = pts;
  181 + cp->sid = sid;
  182 + cp->PES_packet_length = PES_packet_length;
  183 + cp->continuity_counter = continuity_counter;
  184 + cp->payload = payload;
  185 + payload = NULL;
  186 + return cp;
  187 +}
  188 +
172 ISrsTsHandler::ISrsTsHandler() 189 ISrsTsHandler::ISrsTsHandler()
173 { 190 {
174 } 191 }
@@ -309,6 +309,13 @@ public: @@ -309,6 +309,13 @@ public:
309 * @return the stream number for audio/video; otherwise, -1. 309 * @return the stream number for audio/video; otherwise, -1.
310 */ 310 */
311 virtual int stream_number(); 311 virtual int stream_number();
  312 +public:
  313 + /**
  314 + * detach the ts message,
  315 + * for user maybe need to parse the message by queue.
  316 + * @remark we always use the payload of original message.
  317 + */
  318 + virtual SrsTsMessage* detach();
312 }; 319 };
313 320
314 /** 321 /**
@@ -23,8 +23,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -23,8 +23,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 23
24 #include <srs_core.hpp> 24 #include <srs_core.hpp>
25 25
  26 +#include <stdlib.h>
26 #include <string> 27 #include <string>
27 #include <vector> 28 #include <vector>
  29 +#include <map>
28 using namespace std; 30 using namespace std;
29 31
30 #include <srs_kernel_error.hpp> 32 #include <srs_kernel_error.hpp>
@@ -148,7 +150,7 @@ private: @@ -148,7 +150,7 @@ private:
148 dirty = false; 150 dirty = false;
149 } 151 }
150 152
151 - int fetch(std::string m3u8, SrsHttpClient* client); 153 + int fetch(std::string m3u8);
152 }; 154 };
153 private: 155 private:
154 SrsHttpUri* in_hls; 156 SrsHttpUri* in_hls;
@@ -196,7 +198,7 @@ private: @@ -196,7 +198,7 @@ private:
196 /** 198 /**
197 * fetch all ts body. 199 * fetch all ts body.
198 */ 200 */
199 - virtual void fetch_all_ts(bool fresh_m3u8, SrsHttpClient* client); 201 + virtual void fetch_all_ts(bool fresh_m3u8);
200 /** 202 /**
201 * remove all ts which is dirty. 203 * remove all ts which is dirty.
202 */ 204 */
@@ -209,6 +211,7 @@ int SrsIngestSrsInput::connect() @@ -209,6 +211,7 @@ int SrsIngestSrsInput::connect()
209 211
210 int64_t now = srs_update_system_time_ms(); 212 int64_t now = srs_update_system_time_ms();
211 if (now < next_connect_time) { 213 if (now < next_connect_time) {
  214 + srs_trace("input hls wait for %dms", next_connect_time - now);
212 st_usleep((next_connect_time - now) * 1000); 215 st_usleep((next_connect_time - now) * 1000);
213 } 216 }
214 217
@@ -328,7 +331,7 @@ int SrsIngestSrsInput::connect() @@ -328,7 +331,7 @@ int SrsIngestSrsInput::connect()
328 } 331 }
329 332
330 // fetch all ts. 333 // fetch all ts.
331 - fetch_all_ts(fresh_m3u8, &client); 334 + fetch_all_ts(fresh_m3u8);
332 335
333 // remove all dirty ts. 336 // remove all dirty ts.
334 remove_dirty(); 337 remove_dirty();
@@ -344,12 +347,19 @@ int SrsIngestSrsInput::parse(ISrsTsHandler* handler) @@ -344,12 +347,19 @@ int SrsIngestSrsInput::parse(ISrsTsHandler* handler)
344 347
345 for (int i = 0; i < (int)pieces.size(); i++) { 348 for (int i = 0; i < (int)pieces.size(); i++) {
346 SrsTsPiece* tp = pieces.at(i); 349 SrsTsPiece* tp = pieces.at(i);
  350 +
  351 + // sent only once.
  352 + if (tp->sent) {
  353 + continue;
  354 + }
347 tp->sent = true; 355 tp->sent = true;
348 356
349 if (tp->body.empty()) { 357 if (tp->body.empty()) {
350 continue; 358 continue;
351 } 359 }
352 360
  361 + srs_trace("proxy the ts to rtmp, ts=%s, duration=%.2f", tp->url.c_str(), tp->duration);
  362 +
353 // use stream to parse ts packet. 363 // use stream to parse ts packet.
354 int nb_packet = (int)tp->body.length() / SRS_TS_PACKET_SIZE; 364 int nb_packet = (int)tp->body.length() / SRS_TS_PACKET_SIZE;
355 for (int i = 0; i < nb_packet; i++) { 365 for (int i = 0; i < nb_packet; i++) {
@@ -360,6 +370,12 @@ int SrsIngestSrsInput::parse(ISrsTsHandler* handler) @@ -360,6 +370,12 @@ int SrsIngestSrsInput::parse(ISrsTsHandler* handler)
360 370
361 // process each ts packet 371 // process each ts packet
362 if ((ret = context->decode(stream, handler)) != ERROR_SUCCESS) { 372 if ((ret = context->decode(stream, handler)) != ERROR_SUCCESS) {
  373 + // when peer closed, must interrupt parse and reconnect.
  374 + if (srs_is_client_gracefully_close(ret)) {
  375 + srs_warn("interrupt parse for peer closed. ret=%d", ret);
  376 + return ret;
  377 + }
  378 +
363 srs_warn("mpegts: ignore parse ts packet failed. ret=%d", ret); 379 srs_warn("mpegts: ignore parse ts packet failed. ret=%d", ret);
364 continue; 380 continue;
365 } 381 }
@@ -392,7 +408,7 @@ void SrsIngestSrsInput::dirty_all_ts() @@ -392,7 +408,7 @@ void SrsIngestSrsInput::dirty_all_ts()
392 } 408 }
393 } 409 }
394 410
395 -void SrsIngestSrsInput::fetch_all_ts(bool fresh_m3u8, SrsHttpClient* client) 411 +void SrsIngestSrsInput::fetch_all_ts(bool fresh_m3u8)
396 { 412 {
397 int ret = ERROR_SUCCESS; 413 int ret = ERROR_SUCCESS;
398 414
@@ -410,17 +426,16 @@ void SrsIngestSrsInput::fetch_all_ts(bool fresh_m3u8, SrsHttpClient* client) @@ -410,17 +426,16 @@ void SrsIngestSrsInput::fetch_all_ts(bool fresh_m3u8, SrsHttpClient* client)
410 continue; 426 continue;
411 } 427 }
412 428
413 - if ((ret = tp->fetch(in_hls->get_url(), client)) != ERROR_SUCCESS) { 429 + if ((ret = tp->fetch(in_hls->get_url())) != ERROR_SUCCESS) {
414 srs_warn("ignore ts %s for error. ret=%d", tp->url.c_str(), ret); 430 srs_warn("ignore ts %s for error. ret=%d", tp->url.c_str(), ret);
415 tp->skip = true; 431 tp->skip = true;
416 continue; 432 continue;
417 } 433 }
418 434
419 - // set the next connect time.  
420 - if (next_connect_time <= 0) {  
421 - next_connect_time = srs_update_system_time_ms(); 435 + // only wait for a duration of last piece.
  436 + if (i == pieces.size() - 1) {
  437 + next_connect_time = srs_update_system_time_ms() + (int)tp->duration * 1000;
422 } 438 }
423 - next_connect_time += (int)tp->duration * 1000;  
424 } 439 }
425 } 440 }
426 441
@@ -432,6 +447,7 @@ void SrsIngestSrsInput::remove_dirty() @@ -432,6 +447,7 @@ void SrsIngestSrsInput::remove_dirty()
432 SrsTsPiece* tp = *it; 447 SrsTsPiece* tp = *it;
433 448
434 if (tp->dirty) { 449 if (tp->dirty) {
  450 + srs_trace("erase dirty ts, url=%s, duration=%.2f", tp->url.c_str(), tp->duration);
435 srs_freep(tp); 451 srs_freep(tp);
436 it = pieces.erase(it); 452 it = pieces.erase(it);
437 } else { 453 } else {
@@ -440,7 +456,7 @@ void SrsIngestSrsInput::remove_dirty() @@ -440,7 +456,7 @@ void SrsIngestSrsInput::remove_dirty()
440 } 456 }
441 } 457 }
442 458
443 -int SrsIngestSrsInput::SrsTsPiece::fetch(string m3u8, SrsHttpClient* client) 459 +int SrsIngestSrsInput::SrsTsPiece::fetch(string m3u8)
444 { 460 {
445 int ret = ERROR_SUCCESS; 461 int ret = ERROR_SUCCESS;
446 462
@@ -450,8 +466,7 @@ int SrsIngestSrsInput::SrsTsPiece::fetch(string m3u8, SrsHttpClient* client) @@ -450,8 +466,7 @@ int SrsIngestSrsInput::SrsTsPiece::fetch(string m3u8, SrsHttpClient* client)
450 466
451 size_t pos = string::npos; 467 size_t pos = string::npos;
452 468
453 - bool use_abs_client = false;  
454 - SrsHttpClient abs_client; 469 + SrsHttpClient client;
455 470
456 std::string ts_url = url; 471 std::string ts_url = url;
457 if (!srs_string_starts_with(ts_url, "http://")) { 472 if (!srs_string_starts_with(ts_url, "http://")) {
@@ -460,10 +475,6 @@ int SrsIngestSrsInput::SrsTsPiece::fetch(string m3u8, SrsHttpClient* client) @@ -460,10 +475,6 @@ int SrsIngestSrsInput::SrsTsPiece::fetch(string m3u8, SrsHttpClient* client)
460 baseurl = m3u8.substr(0, pos); 475 baseurl = m3u8.substr(0, pos);
461 } 476 }
462 ts_url = baseurl + "/" + url; 477 ts_url = baseurl + "/" + url;
463 -  
464 - // use fresh client for absolute url.  
465 - client = &abs_client;  
466 - use_abs_client = true;  
467 } 478 }
468 479
469 SrsHttpUri uri; 480 SrsHttpUri uri;
@@ -472,12 +483,12 @@ int SrsIngestSrsInput::SrsTsPiece::fetch(string m3u8, SrsHttpClient* client) @@ -472,12 +483,12 @@ int SrsIngestSrsInput::SrsTsPiece::fetch(string m3u8, SrsHttpClient* client)
472 } 483 }
473 484
474 // initialize the fresh http client. 485 // initialize the fresh http client.
475 - if (use_abs_client && (ret = client->initialize(uri.get_host(), uri.get_port()) != ERROR_SUCCESS)) { 486 + if ((ret = client.initialize(uri.get_host(), uri.get_port()) != ERROR_SUCCESS)) {
476 return ret; 487 return ret;
477 } 488 }
478 489
479 SrsHttpMessage* msg = NULL; 490 SrsHttpMessage* msg = NULL;
480 - if ((ret = client->get(uri.get_path(), "", &msg)) != ERROR_SUCCESS) { 491 + if ((ret = client.get(uri.get_path(), "", &msg)) != ERROR_SUCCESS) {
481 srs_error("HTTP GET %s failed. ret=%d", uri.get_url(), ret); 492 srs_error("HTTP GET %s failed. ret=%d", uri.get_url(), ret);
482 return ret; 493 return ret;
483 } 494 }
@@ -501,6 +512,9 @@ class SrsIngestSrsOutput : public ISrsTsHandler @@ -501,6 +512,9 @@ class SrsIngestSrsOutput : public ISrsTsHandler
501 private: 512 private:
502 SrsHttpUri* out_rtmp; 513 SrsHttpUri* out_rtmp;
503 private: 514 private:
  515 + bool disconnected;
  516 + std::multimap<int64_t, SrsTsMessage*> queue;
  517 +private:
504 SrsRequest* req; 518 SrsRequest* req;
505 st_netfd_t stfd; 519 st_netfd_t stfd;
506 SrsStSocket* io; 520 SrsStSocket* io;
@@ -519,6 +533,7 @@ private: @@ -519,6 +533,7 @@ private:
519 public: 533 public:
520 SrsIngestSrsOutput(SrsHttpUri* rtmp) { 534 SrsIngestSrsOutput(SrsHttpUri* rtmp) {
521 out_rtmp = rtmp; 535 out_rtmp = rtmp;
  536 + disconnected = false;
522 537
523 req = NULL; 538 req = NULL;
524 io = NULL; 539 io = NULL;
@@ -537,14 +552,22 @@ public: @@ -537,14 +552,22 @@ public:
537 552
538 srs_freep(avc); 553 srs_freep(avc);
539 srs_freep(aac); 554 srs_freep(aac);
  555 +
  556 + std::multimap<int64_t, SrsTsMessage*>::iterator it;
  557 + for (it = queue.begin(); it != queue.end(); ++it) {
  558 + SrsTsMessage* msg = it->second;
  559 + srs_freep(msg);
  560 + }
  561 + queue.clear();
540 } 562 }
541 // interface ISrsTsHandler 563 // interface ISrsTsHandler
542 public: 564 public:
543 virtual int on_ts_message(SrsTsMessage* msg); 565 virtual int on_ts_message(SrsTsMessage* msg);
544 private: 566 private:
  567 + virtual int parse_message_queue();
545 virtual int on_ts_video(SrsTsMessage* msg, SrsStream* avs); 568 virtual int on_ts_video(SrsTsMessage* msg, SrsStream* avs);
546 virtual int write_h264_sps_pps(u_int32_t dts, u_int32_t pts); 569 virtual int write_h264_sps_pps(u_int32_t dts, u_int32_t pts);
547 - virtual int write_h264_ipb_frame(char* frame, int frame_size, u_int32_t dts, u_int32_t pts); 570 + virtual int write_h264_ipb_frame(std::string ibps, SrsCodecVideoAVCFrame frame_type, u_int32_t dts, u_int32_t pts);
548 virtual int on_ts_audio(SrsTsMessage* msg, SrsStream* avs); 571 virtual int on_ts_audio(SrsTsMessage* msg, SrsStream* avs);
549 virtual int write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, u_int32_t dts); 572 virtual int write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, u_int32_t dts);
550 private: 573 private:
@@ -554,6 +577,10 @@ public: @@ -554,6 +577,10 @@ public:
554 * connect to output rtmp server. 577 * connect to output rtmp server.
555 */ 578 */
556 virtual int connect(); 579 virtual int connect();
  580 + /**
  581 + * flush the message queue when all ts parsed.
  582 + */
  583 + virtual int flush_message_queue();
557 private: 584 private:
558 virtual int connect_app(std::string ep_server, std::string ep_port); 585 virtual int connect_app(std::string ep_server, std::string ep_port);
559 // close the connected io and rtmp to ready to be re-connect. 586 // close the connected io and rtmp to ready to be re-connect.
@@ -601,7 +628,7 @@ int SrsIngestSrsOutput::on_ts_message(SrsTsMessage* msg) @@ -601,7 +628,7 @@ int SrsIngestSrsOutput::on_ts_message(SrsTsMessage* msg)
601 // 14496-2 video stream number xxxx 628 // 14496-2 video stream number xxxx
602 // ((stream_id >> 4) & 0x0f) == SrsTsPESStreamIdVideo 629 // ((stream_id >> 4) & 0x0f) == SrsTsPESStreamIdVideo
603 630
604 - srs_trace("<- "SRS_CONSTS_LOG_STREAM_CASTER" mpegts: got %s stream=%s, dts=%"PRId64", pts=%"PRId64", size=%d, us=%d, cc=%d, sid=%#x(%s-%d)", 631 + srs_info("<- "SRS_CONSTS_LOG_STREAM_CASTER" mpegts: got %s stream=%s, dts=%"PRId64", pts=%"PRId64", size=%d, us=%d, cc=%d, sid=%#x(%s-%d)",
605 (msg->channel->apply == SrsTsPidApplyVideo)? "Video":"Audio", srs_ts_stream2string(msg->channel->stream).c_str(), 632 (msg->channel->apply == SrsTsPidApplyVideo)? "Video":"Audio", srs_ts_stream2string(msg->channel->stream).c_str(),
606 msg->dts, msg->pts, msg->payload->length(), msg->packet->payload_unit_start_indicator, msg->continuity_counter, msg->sid, 633 msg->dts, msg->pts, msg->payload->length(), msg->packet->payload_unit_start_indicator, msg->continuity_counter, msg->sid,
607 msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number()); 634 msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number());
@@ -621,41 +648,120 @@ int SrsIngestSrsOutput::on_ts_message(SrsTsMessage* msg) @@ -621,41 +648,120 @@ int SrsIngestSrsOutput::on_ts_message(SrsTsMessage* msg)
621 return ret; 648 return ret;
622 } 649 }
623 650
624 - // parse the stream.  
625 - SrsStream avs;  
626 - if ((ret = avs.initialize(msg->payload->bytes(), msg->payload->length())) != ERROR_SUCCESS) {  
627 - srs_error("mpegts: initialize av stream failed. ret=%d", ret); 651 + // we must use queue to cache the msg, then parse it if possible.
  652 + queue.insert(std::make_pair(msg->dts, msg->detach()));
  653 + if ((ret = parse_message_queue()) != ERROR_SUCCESS) {
  654 + // when peer closed, close the output and reconnect.
  655 + if (srs_is_client_gracefully_close(ret)) {
  656 + close();
  657 + }
628 return ret; 658 return ret;
629 } 659 }
630 660
631 - // publish audio or video.  
632 - if (msg->channel->stream == SrsTsStreamVideoH264) {  
633 - return on_ts_video(msg, &avs); 661 + return ret;
  662 +}
  663 +
  664 +int SrsIngestSrsOutput::parse_message_queue()
  665 +{
  666 + int ret = ERROR_SUCCESS;
  667 +
  668 + int nb_videos = 0;
  669 + int nb_audios = 0;
  670 + std::multimap<int64_t, SrsTsMessage*>::iterator it;
  671 + for (it = queue.begin(); it != queue.end(); ++it) {
  672 + SrsTsMessage* msg = it->second;
  673 +
  674 + // publish audio or video.
  675 + if (msg->channel->stream == SrsTsStreamVideoH264) {
  676 + nb_videos++;
  677 + } else {
  678 + nb_audios++;
  679 + }
  680 + }
  681 +
  682 + // always wait 2+ videos, to left one video in the queue.
  683 + // TODO: FIXME: support pure audio hls.
  684 + if (nb_videos <= 1) {
  685 + return ret;
634 } 686 }
635 - if (msg->channel->stream == SrsTsStreamAudioAAC) {  
636 - return on_ts_audio(msg, &avs); 687 +
  688 + // parse messages util the last video.
  689 + while (nb_videos > 1 && queue.size() > 0) {
  690 + std::multimap<int64_t, SrsTsMessage*>::iterator it = queue.begin();
  691 +
  692 + SrsTsMessage* msg = it->second;
  693 + if (msg->channel->stream == SrsTsStreamVideoH264) {
  694 + nb_videos--;
  695 + }
  696 + queue.erase(it);
  697 +
  698 + // parse the stream.
  699 + SrsStream avs;
  700 + if ((ret = avs.initialize(msg->payload->bytes(), msg->payload->length())) != ERROR_SUCCESS) {
  701 + srs_error("mpegts: initialize av stream failed. ret=%d", ret);
  702 + return ret;
  703 + }
  704 +
  705 + // publish audio or video.
  706 + if (msg->channel->stream == SrsTsStreamVideoH264) {
  707 + if ((ret = on_ts_video(msg, &avs)) != ERROR_SUCCESS) {
  708 + return ret;
  709 + }
  710 + }
  711 + if (msg->channel->stream == SrsTsStreamAudioAAC) {
  712 + if ((ret = on_ts_audio(msg, &avs)) != ERROR_SUCCESS) {
  713 + return ret;
  714 + }
  715 + }
637 } 716 }
638 717
639 - // TODO: FIXME: implements it.  
640 return ret; 718 return ret;
641 } 719 }
642 720
643 -int SrsIngestSrsOutput::on_ts_video(SrsTsMessage* msg, SrsStream* avs) 721 +int SrsIngestSrsOutput::flush_message_queue()
644 { 722 {
645 int ret = ERROR_SUCCESS; 723 int ret = ERROR_SUCCESS;
646 724
647 - // ensure rtmp connected.  
648 - if ((ret = connect()) != ERROR_SUCCESS) {  
649 - return ret; 725 + // parse messages util the last video.
  726 + while (!queue.empty()) {
  727 + std::multimap<int64_t, SrsTsMessage*>::iterator it = queue.begin();
  728 +
  729 + SrsTsMessage* msg = it->second;
  730 + queue.erase(it);
  731 +
  732 + // parse the stream.
  733 + SrsStream avs;
  734 + if ((ret = avs.initialize(msg->payload->bytes(), msg->payload->length())) != ERROR_SUCCESS) {
  735 + srs_error("mpegts: initialize av stream failed. ret=%d", ret);
  736 + return ret;
  737 + }
  738 +
  739 + // publish audio or video.
  740 + if (msg->channel->stream == SrsTsStreamVideoH264) {
  741 + if ((ret = on_ts_video(msg, &avs)) != ERROR_SUCCESS) {
  742 + return ret;
  743 + }
  744 + }
  745 + if (msg->channel->stream == SrsTsStreamAudioAAC) {
  746 + if ((ret = on_ts_audio(msg, &avs)) != ERROR_SUCCESS) {
  747 + return ret;
  748 + }
  749 + }
650 } 750 }
651 751
  752 + return ret;
  753 +}
  754 +
  755 +int SrsIngestSrsOutput::on_ts_video(SrsTsMessage* msg, SrsStream* avs)
  756 +{
  757 + int ret = ERROR_SUCCESS;
  758 +
652 // ts tbn to flv tbn. 759 // ts tbn to flv tbn.
653 u_int32_t dts = (u_int32_t)(msg->dts / 90); 760 u_int32_t dts = (u_int32_t)(msg->dts / 90);
654 u_int32_t pts = (u_int32_t)(msg->dts / 90); 761 u_int32_t pts = (u_int32_t)(msg->dts / 90);
655 762
656 - // the whole ts pes video packet must be a flv frame packet.  
657 - char* ibpframe = avs->data() + avs->pos();  
658 - int ibpframe_size = avs->size() - avs->pos(); 763 + std::string ibps;
  764 + SrsCodecVideoAVCFrame frame_type = SrsCodecVideoAVCFrameInterFrame;
659 765
660 // send each frame. 766 // send each frame.
661 while (!avs->empty()) { 767 while (!avs->empty()) {
@@ -665,10 +771,18 @@ int SrsIngestSrsOutput::on_ts_video(SrsTsMessage* msg, SrsStream* avs) @@ -665,10 +771,18 @@ int SrsIngestSrsOutput::on_ts_video(SrsTsMessage* msg, SrsStream* avs)
665 return ret; 771 return ret;
666 } 772 }
667 773
668 - // ignore invalid frame,  
669 - // * atleast 1bytes for SPS to decode the type  
670 - // * ignore the auth bytes '09f0'  
671 - if (frame_size <= 2) { 774 + // 5bits, 7.3.1 NAL unit syntax,
  775 + // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
  776 + // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
  777 + SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(frame[0] & 0x1f);
  778 +
  779 + // for IDR frame, the frame is keyframe.
  780 + if (nal_unit_type == SrsAvcNaluTypeIDR) {
  781 + frame_type = SrsCodecVideoAVCFrameKeyFrame;
  782 + }
  783 +
  784 + // ignore the nalu type aud(9)
  785 + if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) {
672 continue; 786 continue;
673 } 787 }
674 788
@@ -684,10 +798,6 @@ int SrsIngestSrsOutput::on_ts_video(SrsTsMessage* msg, SrsStream* avs) @@ -684,10 +798,6 @@ int SrsIngestSrsOutput::on_ts_video(SrsTsMessage* msg, SrsStream* avs)
684 } 798 }
685 h264_sps_changed = true; 799 h264_sps_changed = true;
686 h264_sps = sps; 800 h264_sps = sps;
687 -  
688 - if ((ret = write_h264_sps_pps(dts, pts)) != ERROR_SUCCESS) {  
689 - return ret;  
690 - }  
691 continue; 801 continue;
692 } 802 }
693 803
@@ -703,27 +813,45 @@ int SrsIngestSrsOutput::on_ts_video(SrsTsMessage* msg, SrsStream* avs) @@ -703,27 +813,45 @@ int SrsIngestSrsOutput::on_ts_video(SrsTsMessage* msg, SrsStream* avs)
703 } 813 }
704 h264_pps_changed = true; 814 h264_pps_changed = true;
705 h264_pps = pps; 815 h264_pps = pps;
706 -  
707 - if ((ret = write_h264_sps_pps(dts, pts)) != ERROR_SUCCESS) {  
708 - return ret;  
709 - }  
710 continue; 816 continue;
711 } 817 }
712 818
713 - break; 819 + // ibp frame.
  820 + std::string ibp;
  821 + if ((ret = avc->mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) {
  822 + return ret;
  823 + }
  824 + ibps.append(ibp);
  825 + }
  826 +
  827 + if ((ret = write_h264_sps_pps(dts, pts)) != ERROR_SUCCESS) {
  828 + return ret;
714 } 829 }
715 830
716 - // ibp frame.  
717 - srs_info("mpegts: demux avc ibp frame size=%d, dts=%d", ibpframe_size, dts);  
718 - return write_h264_ipb_frame(ibpframe, ibpframe_size, dts, pts); 831 + if ((ret = write_h264_ipb_frame(ibps, frame_type, dts, pts)) != ERROR_SUCCESS) {
  832 + // drop the ts message.
  833 + if (ret == ERROR_H264_DROP_BEFORE_SPS_PPS) {
  834 + return ERROR_SUCCESS;
  835 + }
  836 + return ret;
  837 + }
  838 +
  839 + return ret;
719 } 840 }
720 841
721 int SrsIngestSrsOutput::write_h264_sps_pps(u_int32_t dts, u_int32_t pts) 842 int SrsIngestSrsOutput::write_h264_sps_pps(u_int32_t dts, u_int32_t pts)
722 { 843 {
723 int ret = ERROR_SUCCESS; 844 int ret = ERROR_SUCCESS;
724 845
725 - // only send when both sps and pps changed.  
726 - if (!h264_sps_changed || !h264_pps_changed) { 846 + // when sps or pps changed, update the sequence header,
  847 + // for the pps maybe not changed while sps changed.
  848 + // so, we must check when each video ts message frame parsed.
  849 + if (h264_sps_pps_sent && !h264_sps_changed && !h264_pps_changed) {
  850 + return ret;
  851 + }
  852 +
  853 + // when not got sps/pps, wait.
  854 + if (h264_pps.empty() || h264_sps.empty()) {
727 return ret; 855 return ret;
728 } 856 }
729 857
@@ -752,11 +880,12 @@ int SrsIngestSrsOutput::write_h264_sps_pps(u_int32_t dts, u_int32_t pts) @@ -752,11 +880,12 @@ int SrsIngestSrsOutput::write_h264_sps_pps(u_int32_t dts, u_int32_t pts)
752 h264_sps_changed = false; 880 h264_sps_changed = false;
753 h264_pps_changed = false; 881 h264_pps_changed = false;
754 h264_sps_pps_sent = true; 882 h264_sps_pps_sent = true;
  883 + srs_trace("hls: h264 sps/pps sent, sps=%dB, pps=%dB", h264_sps.length(), h264_pps.length());
755 884
756 return ret; 885 return ret;
757 } 886 }
758 887
759 -int SrsIngestSrsOutput::write_h264_ipb_frame(char* frame, int frame_size, u_int32_t dts, u_int32_t pts) 888 +int SrsIngestSrsOutput::write_h264_ipb_frame(string ibps, SrsCodecVideoAVCFrame frame_type, u_int32_t dts, u_int32_t pts)
760 { 889 {
761 int ret = ERROR_SUCCESS; 890 int ret = ERROR_SUCCESS;
762 891
@@ -766,26 +895,10 @@ int SrsIngestSrsOutput::write_h264_ipb_frame(char* frame, int frame_size, u_int3 @@ -766,26 +895,10 @@ int SrsIngestSrsOutput::write_h264_ipb_frame(char* frame, int frame_size, u_int3
766 return ERROR_H264_DROP_BEFORE_SPS_PPS; 895 return ERROR_H264_DROP_BEFORE_SPS_PPS;
767 } 896 }
768 897
769 - // 5bits, 7.3.1 NAL unit syntax,  
770 - // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.  
771 - // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame  
772 - SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(frame[0] & 0x1f);  
773 -  
774 - // for IDR frame, the frame is keyframe.  
775 - SrsCodecVideoAVCFrame frame_type = SrsCodecVideoAVCFrameInterFrame;  
776 - if (nal_unit_type == SrsAvcNaluTypeIDR) {  
777 - frame_type = SrsCodecVideoAVCFrameKeyFrame;  
778 - }  
779 -  
780 - std::string ibp;  
781 - if ((ret = avc->mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) {  
782 - return ret;  
783 - }  
784 -  
785 int8_t avc_packet_type = SrsCodecVideoAVCTypeNALU; 898 int8_t avc_packet_type = SrsCodecVideoAVCTypeNALU;
786 char* flv = NULL; 899 char* flv = NULL;
787 int nb_flv = 0; 900 int nb_flv = 0;
788 - if ((ret = avc->mux_avc2flv(ibp, frame_type, avc_packet_type, dts, pts, &flv, &nb_flv)) != ERROR_SUCCESS) { 901 + if ((ret = avc->mux_avc2flv(ibps, frame_type, avc_packet_type, dts, pts, &flv, &nb_flv)) != ERROR_SUCCESS) {
789 return ret; 902 return ret;
790 } 903 }
791 904
@@ -798,14 +911,17 @@ int SrsIngestSrsOutput::on_ts_audio(SrsTsMessage* msg, SrsStream* avs) @@ -798,14 +911,17 @@ int SrsIngestSrsOutput::on_ts_audio(SrsTsMessage* msg, SrsStream* avs)
798 { 911 {
799 int ret = ERROR_SUCCESS; 912 int ret = ERROR_SUCCESS;
800 913
801 - // ensure rtmp connected.  
802 - if ((ret = connect()) != ERROR_SUCCESS) {  
803 - return ret;  
804 - }  
805 -  
806 // ts tbn to flv tbn. 914 // ts tbn to flv tbn.
807 u_int32_t dts = (u_int32_t)(msg->dts / 90); 915 u_int32_t dts = (u_int32_t)(msg->dts / 90);
808 916
  917 + // got the next video to calc the delta duration for each audio.
  918 + u_int32_t duration = 0;
  919 + if (!queue.empty()) {
  920 + SrsTsMessage* nm = queue.begin()->second;
  921 + duration = (u_int32_t)(srs_max(0, nm->dts - msg->dts) / 90);
  922 + }
  923 + u_int32_t max_dts = dts + duration;
  924 +
809 // send each frame. 925 // send each frame.
810 while (!avs->empty()) { 926 while (!avs->empty()) {
811 char* frame = NULL; 927 char* frame = NULL;
@@ -842,6 +958,10 @@ int SrsIngestSrsOutput::on_ts_audio(SrsTsMessage* msg, SrsStream* avs) @@ -842,6 +958,10 @@ int SrsIngestSrsOutput::on_ts_audio(SrsTsMessage* msg, SrsStream* avs)
842 if ((ret = write_audio_raw_frame(frame, frame_size, &codec, dts)) != ERROR_SUCCESS) { 958 if ((ret = write_audio_raw_frame(frame, frame_size, &codec, dts)) != ERROR_SUCCESS) {
843 return ret; 959 return ret;
844 } 960 }
  961 +
  962 + // calc the delta of dts, when previous frame output.
  963 + u_int32_t delta = duration / (msg->payload->length() / frame_size);
  964 + dts = (u_int32_t)(srs_min(max_dts, dts + delta));
845 } 965 }
846 966
847 return ret; 967 return ret;
@@ -890,6 +1010,8 @@ int SrsIngestSrsOutput::connect() @@ -890,6 +1010,8 @@ int SrsIngestSrsOutput::connect()
890 return ret; 1010 return ret;
891 } 1011 }
892 1012
  1013 + srs_trace("connect output=%s", out_rtmp->get_url());
  1014 +
893 // parse uri 1015 // parse uri
894 if (!req) { 1016 if (!req) {
895 req = new SrsRequest(); 1017 req = new SrsRequest();
@@ -996,6 +1118,9 @@ int SrsIngestSrsOutput::connect_app(string ep_server, string ep_port) @@ -996,6 +1118,9 @@ int SrsIngestSrsOutput::connect_app(string ep_server, string ep_port)
996 1118
997 void SrsIngestSrsOutput::close() 1119 void SrsIngestSrsOutput::close()
998 { 1120 {
  1121 + srs_trace("close output=%s", out_rtmp->get_url());
  1122 + h264_sps_pps_sent = false;
  1123 +
999 srs_freep(client); 1124 srs_freep(client);
1000 srs_freep(io); 1125 srs_freep(io);
1001 srs_freep(req); 1126 srs_freep(req);
@@ -1035,6 +1160,11 @@ public: @@ -1035,6 +1160,11 @@ public:
1035 return ret; 1160 return ret;
1036 } 1161 }
1037 1162
  1163 + if ((ret = oc->flush_message_queue()) != ERROR_SUCCESS) {
  1164 + srs_warn("flush oc message failed. ret=%d", ret);
  1165 + return ret;
  1166 + }
  1167 +
1038 return ret; 1168 return ret;
1039 } 1169 }
1040 }; 1170 };