@@ -76,10 +76,20 @@ int SrsMpegtsQueue::push(SrsSharedPtrMessage* msg)
76
76
{
77
77
int ret = ERROR_SUCCESS;
78
78
79
- if (msgs.find (msg->timestamp ) != msgs.end ()) {
80
- srs_warn (" mpegts: free the msg for dts exists, dts=%" PRId64, msg->timestamp );
81
- srs_freep (msg);
82
- return ret;
79
+ // TODO: FIXME: use right way.
80
+ for (int i = 0 ; i < 10 ; i++) {
81
+ if (msgs.find (msg->timestamp ) == msgs.end ()) {
82
+ break ;
83
+ }
84
+
85
+ // adjust the ts, add 1ms.
86
+ msg->timestamp += 1 ;
87
+
88
+ if (i >= 5 ) {
89
+ srs_warn (" mpegts: free the msg for dts exists, dts=%" PRId64, msg->timestamp );
90
+ srs_freep (msg);
91
+ return ret;
92
+ }
83
93
}
84
94
85
95
if (msg->is_audio ()) {
@@ -114,6 +124,8 @@ SrsSharedPtrMessage* SrsMpegtsQueue::dequeue()
114
124
if (msg->is_video ()) {
115
125
nb_videos--;
116
126
}
127
+
128
+ return msg;
117
129
}
118
130
119
131
return NULL ;
@@ -131,6 +143,7 @@ SrsMpegtsOverUdp::SrsMpegtsOverUdp(SrsConfDirective* c)
131
143
stfd = NULL ;
132
144
stream_id = 0 ;
133
145
avc = new SrsRawH264Stream ();
146
+ aac = new SrsRawAacStream ();
134
147
h264_sps_changed = false ;
135
148
h264_pps_changed = false ;
136
149
h264_sps_pps_sent = false ;
@@ -145,6 +158,7 @@ SrsMpegtsOverUdp::~SrsMpegtsOverUdp()
145
158
srs_freep (stream);
146
159
srs_freep (context);
147
160
srs_freep (avc);
161
+ srs_freep (aac);
148
162
srs_freep (queue);
149
163
}
150
164
@@ -309,6 +323,9 @@ int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg)
309
323
if (msg->channel ->stream == SrsTsStreamVideoH264) {
310
324
return on_ts_video (msg, &avs);
311
325
}
326
+ if (msg->channel ->stream == SrsTsStreamAudioAAC) {
327
+ return on_ts_audio (msg, &avs);
328
+ }
312
329
313
330
// TODO: FIXME: implements it.
314
331
return ret;
@@ -326,6 +343,10 @@ int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsStream* avs)
326
343
// ts tbn to flv tbn.
327
344
u_int32_t dts = msg->dts / 90 ;
328
345
u_int32_t pts = msg->dts / 90 ;
346
+
347
+ // the whole ts pes video packet must be a flv frame packet.
348
+ char * ibpframe = avs->data () + avs->pos ();
349
+ int ibpframe_size = avs->size () - avs->pos ();
329
350
330
351
// send each frame.
331
352
while (!avs->empty ()) {
@@ -342,59 +363,50 @@ int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsStream* avs)
342
363
continue ;
343
364
}
344
365
345
- // it may be return error, but we must process all packets.
346
- if ((ret = write_h264_raw_frame (frame, frame_size, dts, pts)) != ERROR_SUCCESS) {
347
- if (ret == ERROR_H264_DROP_BEFORE_SPS_PPS) {
366
+ // for sps
367
+ if (avc->is_sps (frame, frame_size)) {
368
+ std::string sps;
369
+ if ((ret = avc->sps_demux (frame, frame_size, sps)) != ERROR_SUCCESS) {
370
+ return ret;
371
+ }
372
+
373
+ if (h264_sps == sps) {
348
374
continue ;
349
375
}
350
- return ret;
351
- }
352
-
353
- // for video, drop others with same pts/dts.
354
- break ;
355
- }
356
-
357
- return ret;
358
- }
359
-
360
- int SrsMpegtsOverUdp::write_h264_raw_frame (char * frame, int frame_size, u_int32_t dts, u_int32_t pts)
361
- {
362
- int ret = ERROR_SUCCESS;
363
-
364
- // for sps
365
- if (avc->is_sps (frame, frame_size)) {
366
- std::string sps;
367
- if ((ret = avc->sps_demux (frame, frame_size, sps)) != ERROR_SUCCESS) {
368
- return ret;
369
- }
376
+ h264_sps_changed = true ;
377
+ h264_sps = sps;
370
378
371
- if (h264_sps == sps) {
372
- return ret;
379
+ if ((ret = write_h264_sps_pps (dts, pts)) != ERROR_SUCCESS) {
380
+ return ret;
381
+ }
382
+ continue ;
373
383
}
374
- h264_sps_changed = true ;
375
- h264_sps = sps;
376
-
377
- return write_h264_sps_pps (dts, pts);
378
- }
379
384
380
- // for pps
381
- if (avc->is_pps (frame, frame_size)) {
382
- std::string pps;
383
- if ((ret = avc->pps_demux (frame, frame_size, pps)) != ERROR_SUCCESS) {
384
- return ret;
385
- }
385
+ // for pps
386
+ if (avc->is_pps (frame, frame_size)) {
387
+ std::string pps;
388
+ if ((ret = avc->pps_demux (frame, frame_size, pps)) != ERROR_SUCCESS) {
389
+ return ret;
390
+ }
386
391
387
- if (h264_pps == pps) {
388
- return ret ;
389
- }
390
- h264_pps_changed = true ;
391
- h264_pps = pps;
392
+ if (h264_pps == pps) {
393
+ continue ;
394
+ }
395
+ h264_pps_changed = true ;
396
+ h264_pps = pps;
392
397
393
- return write_h264_sps_pps (dts, pts);
398
+ if ((ret = write_h264_sps_pps (dts, pts)) != ERROR_SUCCESS) {
399
+ return ret;
400
+ }
401
+ continue ;
402
+ }
403
+
404
+ break ;
394
405
}
395
406
396
407
// ibp frame.
397
- return write_h264_ipb_frame (frame, frame_size, dts, pts);
408
+ srs_info (" mpegts: demux avc ibp frame size=%d, dts=%d" , ibpframe_size, dts);
409
+ return write_h264_ipb_frame (ibpframe, ibpframe_size, dts, pts);
398
410
}
399
411
400
412
int SrsMpegtsOverUdp::write_h264_sps_pps (u_int32_t dts, u_int32_t pts)
@@ -421,14 +433,18 @@ int SrsMpegtsOverUdp::write_h264_sps_pps(u_int32_t dts, u_int32_t pts)
421
433
return ret;
422
434
}
423
435
436
+ // the timestamp in rtmp message header is dts.
437
+ u_int32_t timestamp = dts;
438
+ if ((ret = rtmp_write_packet (SrsCodecFlvTagVideo, timestamp, flv, nb_flv)) != ERROR_SUCCESS) {
439
+ return ret;
440
+ }
441
+
424
442
// reset sps and pps.
425
443
h264_sps_changed = false ;
426
444
h264_pps_changed = false ;
427
445
h264_sps_pps_sent = true ;
428
-
429
- // the timestamp in rtmp message header is dts.
430
- u_int32_t timestamp = dts;
431
- return rtmp_write_packet (SrsCodecFlvTagVideo, timestamp, flv, nb_flv);
446
+
447
+ return ret;
432
448
}
433
449
434
450
int SrsMpegtsOverUdp::write_h264_ipb_frame (char * frame, int frame_size, u_int32_t dts, u_int32_t pts)
@@ -459,6 +475,72 @@ int SrsMpegtsOverUdp::write_h264_ipb_frame(char* frame, int frame_size, u_int32_
459
475
return rtmp_write_packet (SrsCodecFlvTagVideo, timestamp, flv, nb_flv);
460
476
}
461
477
478
+ int SrsMpegtsOverUdp::on_ts_audio (SrsTsMessage* msg, SrsStream* avs)
479
+ {
480
+ int ret = ERROR_SUCCESS;
481
+
482
+ // ensure rtmp connected.
483
+ if ((ret = connect ()) != ERROR_SUCCESS) {
484
+ return ret;
485
+ }
486
+
487
+ // ts tbn to flv tbn.
488
+ u_int32_t dts = msg->dts / 90 ;
489
+
490
+ // send each frame.
491
+ while (!avs->empty ()) {
492
+ char * frame = NULL ;
493
+ int frame_size = 0 ;
494
+ SrsRawAacStreamCodec codec;
495
+ if ((ret = aac->adts_demux (avs, &frame, &frame_size, codec)) != ERROR_SUCCESS) {
496
+ return ret;
497
+ }
498
+
499
+ // ignore invalid frame,
500
+ // * atleast 1bytes for aac to decode the data.
501
+ if (frame_size <= 0 ) {
502
+ continue ;
503
+ }
504
+ srs_info (" mpegts: demux aac frame size=%d, dts=%d" , frame_size, dts);
505
+
506
+ // generate sh.
507
+ if (aac_specific_config.empty ()) {
508
+ std::string sh;
509
+ if ((ret = aac->mux_sequence_header (&codec, sh)) != ERROR_SUCCESS) {
510
+ return ret;
511
+ }
512
+ aac_specific_config = sh;
513
+
514
+ codec.aac_packet_type = 0 ;
515
+
516
+ if ((ret = write_audio_raw_frame ((char *)sh.data (), (int )sh.length (), &codec, dts)) != ERROR_SUCCESS) {
517
+ return ret;
518
+ }
519
+ }
520
+
521
+ // audio raw data.
522
+ codec.aac_packet_type = 1 ;
523
+ if ((ret = write_audio_raw_frame (frame, frame_size, &codec, dts)) != ERROR_SUCCESS) {
524
+ return ret;
525
+ }
526
+ }
527
+
528
+ return ret;
529
+ }
530
+
531
+ int SrsMpegtsOverUdp::write_audio_raw_frame (char * frame, int frame_size, SrsRawAacStreamCodec* codec, u_int32_t dts)
532
+ {
533
+ int ret = ERROR_SUCCESS;
534
+
535
+ char * data = NULL ;
536
+ int size = 0 ;
537
+ if ((ret = aac->mux_aac2flv (frame, frame_size, codec, dts, &data, &size)) != ERROR_SUCCESS) {
538
+ return ret;
539
+ }
540
+
541
+ return rtmp_write_packet (SrsCodecFlvTagAudio, dts, data, size);
542
+ }
543
+
462
544
int SrsMpegtsOverUdp::rtmp_write_packet (char type, u_int32_t timestamp, char * data, int size)
463
545
{
464
546
int ret = ERROR_SUCCESS;
@@ -482,6 +564,10 @@ int SrsMpegtsOverUdp::rtmp_write_packet(char type, u_int32_t timestamp, char* da
482
564
if ((msg = queue->dequeue ()) == NULL ) {
483
565
break ;
484
566
}
567
+
568
+ // TODO: FIXME: use pithy print.
569
+ srs_info (" mpegts: send msg %s dts=%" PRId64" , size=%d" ,
570
+ msg->is_audio ()? " A" :msg->is_video ()? " V" :" N" , msg->timestamp , msg->size );
485
571
486
572
// send out encoded msg.
487
573
if ((ret = client->send_and_free_message (msg, stream_id)) != ERROR_SUCCESS) {
0 commit comments