@@ -24,6 +24,9 @@ static ngx_int_t ngx_rtmp_mp4_send(ngx_rtmp_session_t *s, ngx_file_t *f,
24
24
static ngx_int_t ngx_rtmp_mp4_reset (ngx_rtmp_session_t * s );
25
25
26
26
27
+ #define NGX_RTMP_MP4_MAX_FRAMES 8
28
+
29
+
27
30
#pragma pack(push,4)
28
31
29
32
@@ -2092,15 +2095,16 @@ ngx_rtmp_mp4_send(ngx_rtmp_session_t *s, ngx_file_t *f, ngx_uint_t *ts)
2092
2095
ngx_rtmp_header_t h , lh ;
2093
2096
ngx_rtmp_core_srv_conf_t * cscf ;
2094
2097
ngx_chain_t * out , in ;
2095
- ngx_rtmp_mp4_track_t * t ;
2096
- ngx_rtmp_mp4_cursor_t * cr ;
2097
- uint32_t buflen , end_timestamp , sched ,
2098
- timestamp , last_timestamp , rdelay ;
2098
+ ngx_rtmp_mp4_track_t * t , * cur_t ;
2099
+ ngx_rtmp_mp4_cursor_t * cr , * cur_cr ;
2100
+ uint32_t buflen , end_timestamp ,
2101
+ timestamp , last_timestamp , rdelay ,
2102
+ cur_timestamp ;
2099
2103
ssize_t ret ;
2100
2104
u_char fhdr [5 ];
2101
2105
size_t fhdr_size ;
2102
2106
ngx_int_t rc ;
2103
- ngx_uint_t n , active ;
2107
+ ngx_uint_t n , counter ;
2104
2108
2105
2109
cscf = ngx_rtmp_get_module_srv_conf (s , ngx_rtmp_core_module );
2106
2110
@@ -2123,31 +2127,57 @@ ngx_rtmp_mp4_send(ngx_rtmp_session_t *s, ngx_file_t *f, ngx_uint_t *ts)
2123
2127
buflen = (s -> buflen ? s -> buflen + NGX_RTMP_MP4_BUFLEN_ADDON :
2124
2128
NGX_RTMP_MP4_DEFAULT_BUFLEN );
2125
2129
2126
- t = ctx -> tracks ;
2127
-
2128
- sched = 0 ;
2129
- active = 0 ;
2130
+ counter = 0 ;
2130
2131
last_timestamp = 0 ;
2131
-
2132
2132
end_timestamp = ctx -> start_timestamp +
2133
2133
(ngx_current_msec - ctx -> epoch ) + buflen ;
2134
2134
2135
- for (n = 0 ; n < ctx -> ntracks ; ++ n , ++ t ) {
2136
- cr = & t -> cursor ;
2135
+ for ( ;; ) {
2136
+ counter ++ ;
2137
+ if (counter > NGX_RTMP_MP4_MAX_FRAMES ) {
2138
+ return NGX_OK ;
2139
+ }
2137
2140
2138
- if (!cr -> valid ) {
2139
- continue ;
2141
+ timestamp = 0 ;
2142
+ t = NULL ;
2143
+
2144
+ for (n = 0 ; n < ctx -> ntracks ; n ++ ) {
2145
+ cur_t = & ctx -> tracks [n ];
2146
+ cur_cr = & cur_t -> cursor ;
2147
+
2148
+ if (!cur_cr -> valid ) {
2149
+ continue ;
2150
+ }
2151
+
2152
+ cur_timestamp = ngx_rtmp_mp4_to_rtmp_timestamp (cur_t ,
2153
+ cur_cr -> timestamp );
2154
+
2155
+ if (t == NULL || cur_timestamp < timestamp ) {
2156
+ timestamp = cur_timestamp ;
2157
+ t = cur_t ;
2158
+ }
2140
2159
}
2141
2160
2142
- timestamp = ngx_rtmp_mp4_to_rtmp_timestamp (t , cr -> timestamp );
2161
+ if (t == NULL ) {
2162
+ ngx_log_error (NGX_LOG_ERR , s -> connection -> log , 0 ,
2163
+ "mp4: no track" );
2164
+ return NGX_DONE ;
2165
+ }
2143
2166
2144
2167
if (timestamp > end_timestamp ) {
2145
2168
ngx_log_debug3 (NGX_LOG_DEBUG_RTMP , s -> connection -> log , 0 ,
2146
- "mp4: track#%ui ahead %uD > %uD" ,
2147
- t -> id , timestamp , end_timestamp );
2148
- goto next ;
2169
+ "mp4: track#%ui ahead %uD > %uD" ,
2170
+ t -> id , timestamp , end_timestamp );
2171
+
2172
+ if (ts ) {
2173
+ * ts = last_timestamp ;
2174
+ }
2175
+
2176
+ return (uint32_t ) (timestamp - end_timestamp );
2149
2177
}
2150
2178
2179
+ cr = & t -> cursor ;
2180
+
2151
2181
last_timestamp = ngx_rtmp_mp4_to_rtmp_timestamp (t , cr -> last_timestamp );
2152
2182
2153
2183
ngx_memzero (& h , sizeof (h ));
@@ -2245,7 +2275,7 @@ ngx_rtmp_mp4_send(ngx_rtmp_session_t *s, ngx_file_t *f, ngx_uint_t *ts)
2245
2275
ngx_log_error (NGX_LOG_ERR , s -> connection -> log , 0 ,
2246
2276
"mp4: track#%ui too big frame: %D>%uz" ,
2247
2277
t -> id , cr -> size , sizeof (ngx_rtmp_mp4_buffer ));
2248
- continue ;
2278
+ goto next ;
2249
2279
}
2250
2280
2251
2281
ret = ngx_read_file (f , ngx_rtmp_mp4_buffer + fhdr_size ,
@@ -2254,7 +2284,7 @@ ngx_rtmp_mp4_send(ngx_rtmp_session_t *s, ngx_file_t *f, ngx_uint_t *ts)
2254
2284
if (ret != (ssize_t ) cr -> size ) {
2255
2285
ngx_log_error (NGX_LOG_ERR , s -> connection -> log , 0 ,
2256
2286
"mp4: track#%ui could not read frame" , t -> id );
2257
- continue ;
2287
+ goto next ;
2258
2288
}
2259
2289
2260
2290
in .buf = & in_buf ;
@@ -2273,35 +2303,11 @@ ngx_rtmp_mp4_send(ngx_rtmp_session_t *s, ngx_file_t *f, ngx_uint_t *ts)
2273
2303
2274
2304
s -> current_time = timestamp ;
2275
2305
2276
- if (ngx_rtmp_mp4_next (s , t ) != NGX_OK ) {
2277
- continue ;
2278
- }
2279
-
2280
2306
next :
2281
- active = 1 ;
2282
-
2283
- if (timestamp > end_timestamp &&
2284
- (sched == 0 || timestamp < end_timestamp + sched ))
2285
- {
2286
- sched = (uint32_t ) (timestamp - end_timestamp );
2307
+ if (ngx_rtmp_mp4_next (s , t ) != NGX_OK ) {
2308
+ return NGX_DONE ;
2287
2309
}
2288
2310
}
2289
-
2290
- if (sched ) {
2291
- return sched ;
2292
- }
2293
-
2294
- if (active ) {
2295
- return NGX_OK ;
2296
- }
2297
-
2298
- if (ts ) {
2299
- * ts = last_timestamp ;
2300
- }
2301
-
2302
- /*ngx_rtmp_mp4_reset(s);*/
2303
-
2304
- return NGX_DONE ;
2305
2311
}
2306
2312
2307
2313
0 commit comments