1616#include "ngx_hls_live_module.h"
1717#include "ngx_rbuf.h"
1818#include "ngx_rtmp_dynamic.h"
19- #include "ngx_hls_live_module.h"
2019
2120#ifndef NGX_HTTP_GONE
2221#define NGX_HTTP_GONE 410
@@ -50,7 +49,8 @@ typedef struct {
5049 ngx_msec_t timeout ;
5150
5251 ngx_chain_t * m3u8 ;
53- ngx_mpegts_frame_t * out_frame ;
52+ ngx_uint_t out_pos ;
53+ ngx_uint_t out_last ;
5454 ngx_chain_t * out_chain ;
5555 ngx_hls_live_frag_t * frag ;
5656} ngx_hls_http_ctx_t ;
@@ -244,7 +244,7 @@ ngx_hls_http_ctx_init(ngx_http_request_t *r, ngx_rtmp_addr_conf_t *addr_conf)
244244 stream -> data = buf -> pos ;
245245 stream -> len = buf -> last - buf -> pos ;
246246
247- ngx_log_error (NGX_LOG_INFO , r -> connection -> log , 0 ,
247+ ngx_log_error (NGX_LOG_DEBUG , r -> connection -> log , 0 ,
248248 "hls-http: ctx_init| hls stream (%V)." , stream );
249249
250250 return NGX_OK ;
@@ -397,18 +397,23 @@ ngx_hls_http_cleanup(void *data)
397397{
398398 ngx_http_request_t * r ;
399399 ngx_hls_http_ctx_t * ctx ;
400+ ngx_chain_t * cl ;
400401
401402 r = data ;
402403 ctx = ngx_http_get_module_ctx (r , ngx_hls_http_module );
403404
404- if (ctx && ctx -> m3u8 ) {
405- ngx_put_chainbuf (ctx -> m3u8 );
406- }
407- 408405 if (!ctx || !ctx -> session ) {
409406 return ;
410407 }
411408
409+ cl = ctx -> out_chain ;
410+ while (cl ) {
411+ ctx -> out_chain = cl -> next ;
412+ ngx_put_chainbuf (cl );
413+ cl = ctx -> out_chain ;
414+ }
415+ ctx -> out_chain = NULL ;
416+ 412417 ctx -> session -> request = NULL ;
413418 ctx -> session -> connection = NULL ;
414419
@@ -599,7 +604,7 @@ ngx_hls_http_m3u8_handler(ngx_http_request_t *r, ngx_rtmp_addr_conf_t *addr_conf
599604 ngx_hls_http_ctx_t * ctx ;
600605 ngx_int_t rc ;
601606 ngx_rtmp_session_t * s ;
602- ngx_chain_t * out ;
607+ ngx_chain_t out ;
603608 ngx_buf_t * buf ;
604609
605610 ctx = ngx_hls_http_create_ctx (r , addr_conf );
@@ -609,9 +614,7 @@ ngx_hls_http_m3u8_handler(ngx_http_request_t *r, ngx_rtmp_addr_conf_t *addr_conf
609614 return NGX_HTTP_INTERNAL_SERVER_ERROR ;
610615 }
611616
612- if (!ctx -> m3u8 ) {
613- ctx -> m3u8 = ngx_get_chainbuf (1024 * 512 , 1 );
614- }
617+ buf = ngx_create_temp_buf (r -> connection -> pool , 1024 * 512 );
615618
616619 s = ngx_hls_live_fetch_session (& ctx -> serverid , & ctx -> stream , & ctx -> sid );
617620 if (s == NULL ) {
@@ -635,17 +638,8 @@ ngx_hls_http_m3u8_handler(ngx_http_request_t *r, ngx_rtmp_addr_conf_t *addr_conf
635638
636639 ctx -> session = s ;
637640
638- out = ctx -> m3u8 ;
639- 640- if (out == NULL ) {
641- ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 ,
642- "hls-http: m3u8_handler| hls session %V, create temp buf failed" ,
643- & ctx -> sid );
644- return NGX_HTTP_INTERNAL_SERVER_ERROR ;
645- }
646- out -> next = NULL ;
647- 648- buf = out -> buf ;
641+ out .buf = buf ;
642+ out .next = NULL ;
649643
650644 buf -> last = buf -> pos = buf -> start ;
651645 buf -> memory = 1 ;
@@ -667,7 +661,7 @@ ngx_hls_http_m3u8_handler(ngx_http_request_t *r, ngx_rtmp_addr_conf_t *addr_conf
667661 return rc ;
668662 }
669663
670- rc = ngx_http_output_filter (r , out );
664+ rc = ngx_http_output_filter (r , & out );
671665 if (rc != NGX_OK ) {
672666 ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 ,
673667 "hls-http: m3u8_handler| send http content failed" );
@@ -731,6 +725,103 @@ ngx_hls_http_parse_frag(ngx_http_request_t *r, ngx_str_t *name)
731725}
732726
733727
728+ static void
729+ ngx_hls_http_write_handler (ngx_http_request_t * r )
730+ {
731+ ngx_hls_http_ctx_t * ctx ;
732+ ngx_rtmp_session_t * s ;
733+ ngx_event_t * wev ;
734+ size_t present , sent ;
735+ ngx_int_t rc ;
736+ ngx_chain_t * cl ;
737+ ngx_hls_live_frag_t * frag ;
738+ 739+ wev = r -> connection -> write ; //wev->handler = ngx_http_request_handler;
740+ 741+ if (r -> connection -> destroyed ) {
742+ return ;
743+ }
744+ 745+ ctx = ngx_http_get_module_ctx (r , ngx_hls_http_module );
746+ s = ctx -> session ;
747+ frag = ctx -> frag ;
748+ 749+ if (wev -> timedout ) {
750+ ngx_log_error (NGX_LOG_INFO , s -> log , NGX_ETIMEDOUT ,
751+ "hls_http: write_handler| client timed out" );
752+ r -> connection -> timedout = 1 ;
753+ if (r -> header_sent ) {
754+ ngx_http_finalize_request (r , NGX_HTTP_CLIENT_CLOSED_REQUEST );
755+ } else {
756+ r -> error_page = 1 ;
757+ ngx_http_finalize_request (r , NGX_HTTP_SERVICE_UNAVAILABLE );
758+ }
759+ 760+ return ;
761+ }
762+ 763+ if (wev -> timer_set ) {
764+ ngx_del_timer (wev );
765+ }
766+ 767+ if (ctx -> out_chain == NULL ) {
768+ ctx -> out_chain = ngx_hls_live_prepare_out_chain (s , ctx -> frag , 1 );
769+ }
770+ 771+ rc = NGX_OK ;
772+ 773+ while (ctx -> out_chain ) {
774+ present = r -> connection -> sent ;
775+ 776+ if (r -> connection -> buffered ) {
777+ rc = ngx_http_output_filter (r , NULL );
778+ } else {
779+ rc = ngx_http_output_filter (r , ctx -> out_chain );
780+ }
781+ 782+ sent = r -> connection -> sent - present ;
783+ 784+ ngx_rtmp_update_bandwidth (& ngx_rtmp_bw_out , sent );
785+ 786+ if (rc == NGX_AGAIN ) {
787+ ngx_add_timer (wev , s -> timeout );
788+ if (ngx_handle_write_event (wev , 0 ) != NGX_OK ) {
789+ ngx_log_error (NGX_LOG_ERR , s -> log , ngx_errno ,
790+ "hls_http: write_handler| handle write event failed" );
791+ ngx_http_finalize_request (r , NGX_ERROR );
792+ }
793+ return ;
794+ }
795+ 796+ if (rc == NGX_ERROR ) {
797+ ngx_log_error (NGX_LOG_ERR , s -> log , ngx_errno ,
798+ "hls_http: write_handler| send error" );
799+ ngx_http_finalize_request (r , NGX_ERROR );
800+ 801+ return ;
802+ }
803+ 804+ /* NGX_OK */
805+ cl = ctx -> out_chain ;
806+ while (cl ) {
807+ ctx -> out_chain = cl -> next ;
808+ ngx_put_chainbuf (cl );
809+ cl = ctx -> out_chain ;
810+ }
811+ 812+ if (ctx -> frag -> content_pos == ctx -> frag -> content_last ) {
813+ ctx -> out_chain = NULL ;
814+ break ;
815+ }
816+ 817+ ctx -> out_chain = ngx_hls_live_prepare_out_chain (s , ctx -> frag , 1 );
818+ }
819+ 820+ if (wev -> active ) {
821+ ngx_del_event (wev , NGX_WRITE_EVENT , 0 );
822+ }
823+ }
824+ 734825static ngx_int_t
735826ngx_hls_http_ts_handler (ngx_http_request_t * r , ngx_rtmp_addr_conf_t * addr_conf )
736827{
@@ -775,17 +866,30 @@ ngx_hls_http_ts_handler(ngx_http_request_t *r, ngx_rtmp_addr_conf_t *addr_conf)
775866
776867 ctx -> frag = frag ;
777868
778- r -> headers_out .content_length_n = frag -> length + 376 ;
869+ r -> headers_out .content_length_n = frag -> length ;
779870 rc = ngx_hls_http_send_header (r , NGX_HTTP_OK , ngx_ts_headers );
780871 if (rc != NGX_OK ) {
781872 ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 ,
782873 "hls-http: ts_handler| send http header failed, %V" , & r -> uri );
783874 return NGX_HTTP_INTERNAL_SERVER_ERROR ;
784875 }
785876
786- ctx -> out_chain = ngx_hls_live_prepare_frag (s , frag );
877+ ngx_rtmp_shared_acquire_frag (frag );
878+ 879+ if (0 ) {
880+ r -> count ++ ;
881+ r -> write_event_handler = ngx_hls_http_write_handler ;
882+ 883+ ngx_hls_http_write_handler (r );
787884
788- return ngx_http_output_filter (r , ctx -> out_chain );
885+ return NGX_DONE ;
886+ } else {
887+ ctx -> out_chain = ngx_hls_live_prepare_frag (s , frag );
888+ 889+ ngx_rtmp_update_bandwidth (& ngx_rtmp_bw_out , frag -> length );
890+ 891+ return ngx_http_output_filter (r , ctx -> out_chain );
892+ }
789893}
790894
791895
0 commit comments