@@ -32,6 +32,7 @@ static inline int __retrieve_sprop(rtsp_handle h, unsigned char *buf, size_t len
3232struct __transfer_set_t {
3333 struct list_head_t list_head ;
3434 rtsp_handle h ;
35+ int track_id ;
3536};
3637
3738/******************************************************************************
@@ -158,12 +159,11 @@ static inline int __rtp_send_eachconnection(struct list_t *e, void *v)
158159 struct transfer_item_t * trans ;
159160 struct nal_rtp_t * rtp = v ;
160161 int track_id = rtp -> packet .header .pt == 96 ? 0 : 1 ;
161- char attempts = 0 ;
162162
163163 list_upcast (trans ,e );
164164
165165 MUST (con = trans -> con , return FAILURE );
166- if (!con -> trans [track_id ].server_port_rtp ) return SUCCESS ;
166+ if (!con -> trans [track_id ].server_port_rtp && ! con -> trans [ track_id ]. is_tcp ) return SUCCESS ;
167167
168168 rtp -> packet .header .seq = htons (con -> trans [track_id ].rtp_seq );
169169 if (rtp -> packet .header .m )
@@ -172,21 +172,58 @@ static inline int __rtp_send_eachconnection(struct list_t *e, void *v)
172172 rtp -> packet .header .ssrc = htonl (con -> ssrc );
173173 con -> trans [track_id ].rtp_seq += 1 ;
174174
175- do {
176- send_bytes = send (con -> trans [track_id ].server_rtp_fd ,
177- & (rtp -> packet ),rtp -> rtpsize ,0 );
175+ if (con -> trans [track_id ].is_tcp ) {
176+ unsigned char head [4 ];
177+ head [0 ] = '$' ;
178+ head [1 ] = con -> trans [track_id ].channel_rtp ;
179+ head [2 ] = (rtp -> rtpsize >> 8 ) & 0xFF ;
180+ head [3 ] = rtp -> rtpsize & 0xFF ;
181+
182+ pthread_mutex_lock (& con -> write_mutex );
183+ int sent_h = 0 ;
184+ while (sent_h < 4 ) {
185+ int r = send (con -> client_fd , head + sent_h , 4 - sent_h , 0 );
186+ if (r > 0 ) sent_h += r ;
187+ else if (r < 0 && (errno == EAGAIN || errno == EWOULDBLOCK )) usleep (1000 );
188+ else { sent_h = -1 ; break ; }
189+ }
190+ if (sent_h == 4 ) {
191+ int sent_b = 0 ;
192+ while (sent_b < rtp -> rtpsize ) {
193+ int r = send (con -> client_fd , (char * )& (rtp -> packet ) + sent_b , rtp -> rtpsize - sent_b , 0 );
194+ if (r > 0 ) sent_b += r ;
195+ else if (r < 0 && (errno == EAGAIN || errno == EWOULDBLOCK )) usleep (1000 );
196+ else { sent_b = -1 ; break ; }
197+ }
198+ send_bytes = sent_b ;
199+ } else {
200+ send_bytes = -1 ;
201+ }
202+ pthread_mutex_unlock (& con -> write_mutex );
178203
179204 if (send_bytes == rtp -> rtpsize ) {
180205 con -> trans [track_id ].rtcp_packet_cnt += 1 ;
181206 con -> trans [track_id ].rtcp_octet += rtp -> rtpsize ;
182207 return SUCCESS ;
183- } else if (con -> con_state != __CON_S_PLAYING ) {
184- DBG ("connection state changed before send\n" );
185- return SUCCESS ;
186- } else
187- usleep (5000 );
188- } while (++ attempts < 10 &&
189- send_bytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK ));
208+ }
209+ } else {
210+ char attempts = 0 ;
211+ do {
212+ send_bytes = send (con -> trans [track_id ].server_rtp_fd ,
213+ & (rtp -> packet ),rtp -> rtpsize ,0 );
214+
215+ if (send_bytes == rtp -> rtpsize ) {
216+ con -> trans [track_id ].rtcp_packet_cnt += 1 ;
217+ con -> trans [track_id ].rtcp_octet += rtp -> rtpsize ;
218+ return SUCCESS ;
219+ } else if (con -> con_state != __CON_S_PLAYING ) {
220+ DBG ("connection state changed before send\n" );
221+ return SUCCESS ;
222+ } else
223+ usleep (5000 );
224+ } while (++ attempts < 10 &&
225+ send_bytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK ));
226+ }
190227
191228 ERR ("send:%d:%s\n" , send_bytes , strerror (errno ));
192229 return FAILURE ;
@@ -214,7 +251,7 @@ static inline int __rtp_setup_transfer(struct list_t *e, void *v)
214251 if (con -> con_state == __CON_S_PLAYING ) {
215252
216253 ASSERT (bufpool_get_free (trans_set -> h -> transfer_pool , & trans ) == SUCCESS , ({
217- ERR ("transfer object resouce starvation detected. possibly connection limits are wrongfully setup\n" );
254+ ERR ("transfer object resource starvation detected. possibly connection limits are wrongfully setup\n" );
218255 goto error ;}));
219256
220257 MUST (bufpool_attach (con -> pool , con ) == SUCCESS ,
@@ -227,8 +264,8 @@ static inline int __rtp_setup_transfer(struct list_t *e, void *v)
227264
228265 timestamp_offset = trans_set -> h -> stat .ts_offset ;
229266
230- con -> trans [con -> track_id ].rtp_timestamp =
231- ((unsigned int )con -> trans [con -> track_id ].rtp_timestamp + timestamp_offset );
267+ con -> trans [trans_set -> track_id ].rtp_timestamp =
268+ ((unsigned int )con -> trans [trans_set -> track_id ].rtp_timestamp + timestamp_offset );
232269 }
233270
234271 ret = SUCCESS ;
@@ -278,8 +315,8 @@ static inline int __retrieve_sprop(rtsp_handle h, unsigned char *buf, size_t len
278315 single_len = 0 ;
279316
280317 while (__split_nal (buf , & nalptr , & single_len , len ) == SUCCESS ) {
281- if ((!(h -> isH265 ) && nalptr [0 ] & 0x1F == H264_NAL_TYPE_SPS ) ||
282- (h -> isH265 && nalptr [0 ] >> 1 & 0x3F == H265_NAL_TYPE_SPS )) {
318+ if ((!(h -> isH265 ) && ( nalptr [0 ] & 0x1F ) == H264_NAL_TYPE_SPS ) ||
319+ (h -> isH265 && ( nalptr [0 ] >> 1 & 0x3F ) == H265_NAL_TYPE_SPS )) {
283320 ASSERT (base64 = mime_base64_create ((char * )& (nalptr [0 ]), single_len ), return FAILURE );
284321 ASSERT (base16 = mime_base16_create ((char * )& (nalptr [1 ]), 3 ), return FAILURE );
285322
@@ -314,8 +351,8 @@ static inline int __retrieve_sprop(rtsp_handle h, unsigned char *buf, size_t len
314351 nalptr = buf ;
315352 single_len = 0 ;
316353 while (__split_nal (buf , & nalptr , & single_len , len ) == SUCCESS ) {
317- if ((!(h -> isH265 ) && nalptr [0 ] & 0x1F == H264_NAL_TYPE_PPS ) ||
318- (h -> isH265 && nalptr [0 ] >> 1 & 0x3F == H265_NAL_TYPE_PPS )) {
354+ if ((!(h -> isH265 ) && ( nalptr [0 ] & 0x1F ) == H264_NAL_TYPE_PPS ) ||
355+ (h -> isH265 && ( nalptr [0 ] >> 1 & 0x3F ) == H265_NAL_TYPE_PPS )) {
319356 ASSERT (single_len >= 4 , return FAILURE );
320357 ASSERT (base64 = mime_base64_create ((char * )& (nalptr [0 ]), single_len ), return FAILURE );
321358
@@ -369,10 +406,8 @@ void rtp_disable_audio(rtsp_handle h)
369406 h -> audioPt = 255 ;
370407}
371408
372- int rtp_send_h26x (rtsp_handle h , unsigned char * buf , size_t len , char isH265 )
409+ int rtp_send_h26x (rtsp_handle h , hal_vidstream * stream , char isH265 )
373410{
374- unsigned char * nalptr = buf ;
375- size_t single_len = 0 ;
376411 int ret = FAILURE ;
377412 int track_id = 0 ;
378413 struct __transfer_set_t trans = {};
@@ -389,16 +424,24 @@ int rtp_send_h26x(rtsp_handle h, unsigned char *buf, size_t len, char isH265)
389424
390425 h -> isH265 = isH265 ;
391426
392- ASSERT (__retrieve_sprop (h , buf , len ) == SUCCESS , goto error );
427+ for (int i = 0 ; i < stream -> count ; i ++ ) {
428+ ASSERT (__retrieve_sprop (h , stream -> pack [i ].data + stream -> pack [i ].offset ,
429+ stream -> pack [i ].length - stream -> pack [i ].offset ) == SUCCESS , goto error );
430+ }
393431
394432 trans .h = h ;
433+ trans .track_id = track_id ;
395434
396- /* setup transmission objecl t*/
397- ASSERT (list_map_inline (& h -> con_list , (__rtp_setup_transfer ), & trans ) == SUCCESS , goto error );
435+ /* setup transmission object */
436+ rtsp_lock (h );
437+ ASSERT (list_map_inline (& h -> con_list , (__rtp_setup_transfer ), & trans ) == SUCCESS , ({rtsp_unlock (h ); goto error ;}));
438+ rtsp_unlock (h );
398439
399440 if (trans .list_head .list ) {
400- while (__split_nal (buf , & nalptr , & single_len , len ) == SUCCESS ) {
401- ASSERT (__transfer_nal_h26x (& (trans .list_head ), nalptr , single_len , h -> isH265 ) == SUCCESS , goto error );
441+ for (int i = 0 ; i < stream -> count ; i ++ ) {
442+ ASSERT (__transfer_nal_h26x (& (trans .list_head ),
443+ stream -> pack [i ].data + stream -> pack [i ].offset ,
444+ stream -> pack [i ].length - stream -> pack [i ].offset , h -> isH265 ) == SUCCESS , goto error );
402445 }
403446 ASSERT (list_map_inline (& (trans .list_head ), (__rtcp_poll ), & track_id ) == SUCCESS , goto error );
404447 }
@@ -430,9 +473,12 @@ int rtp_send_mp3(rtsp_handle h, unsigned char *buf, size_t len)
430473 h -> audioPt = 14 ;
431474
432475 trans .h = h ;
476+ trans .track_id = track_id ;
433477
434- /* setup transmission objecl t*/
435- ASSERT (list_map_inline (& h -> con_list , (__rtp_setup_transfer ), & trans ) == SUCCESS , goto error );
478+ /* setup transmission object */
479+ rtsp_lock (h );
480+ ASSERT (list_map_inline (& h -> con_list , (__rtp_setup_transfer ), & trans ) == SUCCESS , ({rtsp_unlock (h ); goto error ;}));
481+ rtsp_unlock (h );
436482
437483 if (trans .list_head .list ) {
438484 ASSERT (__transfer_nal_mpga (& (trans .list_head ), buf , len ) == SUCCESS , goto error );
@@ -445,4 +491,4 @@ int rtp_send_mp3(rtsp_handle h, unsigned char *buf, size_t len)
445491 list_destroy (& (trans .list_head ));
446492
447493 return ret ;
448- }
494+ }
0 commit comments