winlin

fix #250, support push MPEGTS over UDP to SRS. 2.0.111

@@ -486,7 +486,7 @@ Supported operating systems and hardware: @@ -486,7 +486,7 @@ Supported operating systems and hardware:
486 ). 486 ).
487 1. Support HLS(h.264+mp3) streaming, read 487 1. Support HLS(h.264+mp3) streaming, read
488 [#301](https://github.com/winlinvip/simple-rtmp-server/issues/301). 488 [#301](https://github.com/winlinvip/simple-rtmp-server/issues/301).
489 -1. [dev] Support push MPEG-TS over UDP to SRS, read 489 +1. Support push MPEG-TS over UDP to SRS, read
490 [#250](https://github.com/winlinvip/simple-rtmp-server/issues/250). 490 [#250](https://github.com/winlinvip/simple-rtmp-server/issues/250).
491 1. [no-plan] Support <500ms latency, FRSC(Fast RTMP-compatible Stream Channel tech). 491 1. [no-plan] Support <500ms latency, FRSC(Fast RTMP-compatible Stream Channel tech).
492 1. [no-plan] Support RTMP 302 redirect [#92](https://github.com/winlinvip/simple-rtmp-server/issues/92). 492 1. [no-plan] Support RTMP 302 redirect [#92](https://github.com/winlinvip/simple-rtmp-server/issues/92).
@@ -525,6 +525,7 @@ Supported operating systems and hardware: @@ -525,6 +525,7 @@ Supported operating systems and hardware:
525 525
526 ### SRS 2.0 history 526 ### SRS 2.0 history
527 527
  528 +* v2.0, 2015-01-31, for [#250](https://github.com/winlinvip/simple-rtmp-server/issues/250), support push MPEGTS over UDP to SRS. 2.0.111
528 * v2.0, 2015-01-29, build libfdk-aac in ffmpeg. 2.0.108 529 * v2.0, 2015-01-29, build libfdk-aac in ffmpeg. 2.0.108
529 * v2.0, 2015-01-25, for [#301](https://github.com/winlinvip/simple-rtmp-server/issues/301), hls support h.264+mp3, ok for vlc. 2.0.107 530 * v2.0, 2015-01-25, for [#301](https://github.com/winlinvip/simple-rtmp-server/issues/301), hls support h.264+mp3, ok for vlc. 2.0.107
530 * v2.0, 2015-01-25, for [#301](https://github.com/winlinvip/simple-rtmp-server/issues/301), http ts stream support h.264+mp3. 2.0.106 531 * v2.0, 2015-01-25, for [#301](https://github.com/winlinvip/simple-rtmp-server/issues/301), http ts stream support h.264+mp3. 2.0.106
@@ -76,10 +76,20 @@ int SrsMpegtsQueue::push(SrsSharedPtrMessage* msg) @@ -76,10 +76,20 @@ int SrsMpegtsQueue::push(SrsSharedPtrMessage* msg)
76 { 76 {
77 int ret = ERROR_SUCCESS; 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 if (msg->is_audio()) { 95 if (msg->is_audio()) {
@@ -114,6 +124,8 @@ SrsSharedPtrMessage* SrsMpegtsQueue::dequeue() @@ -114,6 +124,8 @@ SrsSharedPtrMessage* SrsMpegtsQueue::dequeue()
114 if (msg->is_video()) { 124 if (msg->is_video()) {
115 nb_videos--; 125 nb_videos--;
116 } 126 }
  127 +
  128 + return msg;
117 } 129 }
118 130
119 return NULL; 131 return NULL;
@@ -131,6 +143,7 @@ SrsMpegtsOverUdp::SrsMpegtsOverUdp(SrsConfDirective* c) @@ -131,6 +143,7 @@ SrsMpegtsOverUdp::SrsMpegtsOverUdp(SrsConfDirective* c)
131 stfd = NULL; 143 stfd = NULL;
132 stream_id = 0; 144 stream_id = 0;
133 avc = new SrsRawH264Stream(); 145 avc = new SrsRawH264Stream();
  146 + aac = new SrsRawAacStream();
134 h264_sps_changed = false; 147 h264_sps_changed = false;
135 h264_pps_changed = false; 148 h264_pps_changed = false;
136 h264_sps_pps_sent = false; 149 h264_sps_pps_sent = false;
@@ -145,6 +158,7 @@ SrsMpegtsOverUdp::~SrsMpegtsOverUdp() @@ -145,6 +158,7 @@ SrsMpegtsOverUdp::~SrsMpegtsOverUdp()
145 srs_freep(stream); 158 srs_freep(stream);
146 srs_freep(context); 159 srs_freep(context);
147 srs_freep(avc); 160 srs_freep(avc);
  161 + srs_freep(aac);
148 srs_freep(queue); 162 srs_freep(queue);
149 } 163 }
150 164
@@ -309,6 +323,9 @@ int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg) @@ -309,6 +323,9 @@ int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg)
309 if (msg->channel->stream == SrsTsStreamVideoH264) { 323 if (msg->channel->stream == SrsTsStreamVideoH264) {
310 return on_ts_video(msg, &avs); 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 // TODO: FIXME: implements it. 330 // TODO: FIXME: implements it.
314 return ret; 331 return ret;
@@ -326,6 +343,10 @@ int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsStream* avs) @@ -326,6 +343,10 @@ int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsStream* avs)
326 // ts tbn to flv tbn. 343 // ts tbn to flv tbn.
327 u_int32_t dts = msg->dts / 90; 344 u_int32_t dts = msg->dts / 90;
328 u_int32_t pts = msg->dts / 90; 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 // send each frame. 351 // send each frame.
331 while (!avs->empty()) { 352 while (!avs->empty()) {
@@ -342,59 +363,50 @@ int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsStream* avs) @@ -342,59 +363,50 @@ int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsStream* avs)
342 continue; 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 continue; 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 // ibp frame. 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 int SrsMpegtsOverUdp::write_h264_sps_pps(u_int32_t dts, u_int32_t pts) 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,14 +433,18 @@ int SrsMpegtsOverUdp::write_h264_sps_pps(u_int32_t dts, u_int32_t pts)
421 return ret; 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 // reset sps and pps. 442 // reset sps and pps.
425 h264_sps_changed = false; 443 h264_sps_changed = false;
426 h264_pps_changed = false; 444 h264_pps_changed = false;
427 h264_sps_pps_sent = true; 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 int SrsMpegtsOverUdp::write_h264_ipb_frame(char* frame, int frame_size, u_int32_t dts, u_int32_t pts) 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,6 +475,72 @@ int SrsMpegtsOverUdp::write_h264_ipb_frame(char* frame, int frame_size, u_int32_
459 return rtmp_write_packet(SrsCodecFlvTagVideo, timestamp, flv, nb_flv); 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 int SrsMpegtsOverUdp::rtmp_write_packet(char type, u_int32_t timestamp, char* data, int size) 544 int SrsMpegtsOverUdp::rtmp_write_packet(char type, u_int32_t timestamp, char* data, int size)
463 { 545 {
464 int ret = ERROR_SUCCESS; 546 int ret = ERROR_SUCCESS;
@@ -482,6 +564,10 @@ int SrsMpegtsOverUdp::rtmp_write_packet(char type, u_int32_t timestamp, char* da @@ -482,6 +564,10 @@ int SrsMpegtsOverUdp::rtmp_write_packet(char type, u_int32_t timestamp, char* da
482 if ((msg = queue->dequeue()) == NULL) { 564 if ((msg = queue->dequeue()) == NULL) {
483 break; 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 // send out encoded msg. 572 // send out encoded msg.
487 if ((ret = client->send_and_free_message(msg, stream_id)) != ERROR_SUCCESS) { 573 if ((ret = client->send_and_free_message(msg, stream_id)) != ERROR_SUCCESS) {
@@ -45,6 +45,8 @@ class SrsStSocket; @@ -45,6 +45,8 @@ class SrsStSocket;
45 class SrsRequest; 45 class SrsRequest;
46 class SrsRawH264Stream; 46 class SrsRawH264Stream;
47 class SrsSharedPtrMessage; 47 class SrsSharedPtrMessage;
  48 +class SrsRawAacStream;
  49 +class SrsRawAacStreamCodec;
48 50
49 #include <srs_app_st.hpp> 51 #include <srs_app_st.hpp>
50 #include <srs_kernel_ts.hpp> 52 #include <srs_kernel_ts.hpp>
@@ -114,6 +116,10 @@ private: @@ -114,6 +116,10 @@ private:
114 std::string h264_pps; 116 std::string h264_pps;
115 bool h264_pps_changed; 117 bool h264_pps_changed;
116 bool h264_sps_pps_sent; 118 bool h264_sps_pps_sent;
  119 +private:
  120 + SrsRawAacStream* aac;
  121 + std::string aac_specific_config;
  122 +private:
117 SrsMpegtsQueue* queue; 123 SrsMpegtsQueue* queue;
118 public: 124 public:
119 SrsMpegtsOverUdp(SrsConfDirective* c); 125 SrsMpegtsOverUdp(SrsConfDirective* c);
@@ -126,9 +132,11 @@ public: @@ -126,9 +132,11 @@ public:
126 virtual int on_ts_message(SrsTsMessage* msg); 132 virtual int on_ts_message(SrsTsMessage* msg);
127 private: 133 private:
128 virtual int on_ts_video(SrsTsMessage* msg, SrsStream* avs); 134 virtual int on_ts_video(SrsTsMessage* msg, SrsStream* avs);
129 - virtual int write_h264_raw_frame(char* frame, int frame_size, u_int32_t dts, u_int32_t pts);  
130 virtual int write_h264_sps_pps(u_int32_t dts, u_int32_t pts); 135 virtual int write_h264_sps_pps(u_int32_t dts, u_int32_t pts);
131 virtual int write_h264_ipb_frame(char* frame, int frame_size, u_int32_t dts, u_int32_t pts); 136 virtual int write_h264_ipb_frame(char* frame, int frame_size, u_int32_t dts, u_int32_t pts);
  137 + virtual int on_ts_audio(SrsTsMessage* msg, SrsStream* avs);
  138 + virtual int write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, u_int32_t dts);
  139 +private:
132 virtual int rtmp_write_packet(char type, u_int32_t timestamp, char* data, int size); 140 virtual int rtmp_write_packet(char type, u_int32_t timestamp, char* data, int size);
133 private: 141 private:
134 // connect to rtmp output url. 142 // connect to rtmp output url.
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 110 34 +#define VERSION_REVISION 111
35 35
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "SRS" 37 #define RTMP_SIG_SRS_KEY "SRS"
@@ -81,9 +81,10 @@ struct Context @@ -81,9 +81,10 @@ struct Context
81 SimpleSocketStream* skt; 81 SimpleSocketStream* skt;
82 int stream_id; 82 int stream_id;
83 83
84 - // for h264 raw stream,  
85 - // @see: https://github.com/winlinvip/simple-rtmp-server/issues/66#issuecomment-62240521 84 + // the remux raw codec.
86 SrsRawH264Stream avc_raw; 85 SrsRawH264Stream avc_raw;
  86 + SrsRawAacStream aac_raw;
  87 +
87 // for h264 raw stream, 88 // for h264 raw stream,
88 // @see: https://github.com/winlinvip/simple-rtmp-server/issues/66#issuecomment-62240521 89 // @see: https://github.com/winlinvip/simple-rtmp-server/issues/66#issuecomment-62240521
89 SrsStream h264_raw_stream; 90 SrsStream h264_raw_stream;
@@ -1073,106 +1074,44 @@ srs_bool srs_rtmp_is_onMetaData(char type, char* data, int size) @@ -1073,106 +1074,44 @@ srs_bool srs_rtmp_is_onMetaData(char type, char* data, int size)
1073 * directly write a audio frame. 1074 * directly write a audio frame.
1074 */ 1075 */
1075 int __srs_write_audio_raw_frame(Context* context, 1076 int __srs_write_audio_raw_frame(Context* context,
1076 - char sound_format, char sound_rate, char sound_size, char sound_type,  
1077 - char aac_packet_type, char* frame, int frame_size, u_int32_t timestamp 1077 + char* frame, int frame_size, SrsRawAacStreamCodec* codec, u_int32_t timestamp
1078 ) { 1078 ) {
1079 -  
1080 - // for audio frame, there is 1 or 2 bytes header:  
1081 - // 1bytes, SoundFormat|SoundRate|SoundSize|SoundType  
1082 - // 1bytes, AACPacketType for SoundFormat == 10, 0 is sequence header.  
1083 - int size = frame_size + 1;  
1084 - if (sound_format == SrsCodecAudioAAC) {  
1085 - size += 1;  
1086 - }  
1087 - char* data = new char[size];  
1088 - char* p = data;  
1089 -  
1090 - u_int8_t audio_header = sound_type & 0x01;  
1091 - audio_header |= (sound_size << 1) & 0x02;  
1092 - audio_header |= (sound_rate << 2) & 0x0c;  
1093 - audio_header |= (sound_format << 4) & 0xf0;  
1094 -  
1095 - *p++ = audio_header;  
1096 -  
1097 - if (sound_format == SrsCodecAudioAAC) {  
1098 - *p++ = aac_packet_type; 1079 + int ret = ERROR_SUCCESS;
  1080 +
  1081 + char* data = NULL;
  1082 + int size = 0;
  1083 + if ((ret = context->aac_raw.mux_aac2flv(frame, frame_size, codec, timestamp, &data, &size)) != ERROR_SUCCESS) {
  1084 + return ret;
1099 } 1085 }
1100 1086
1101 - memcpy(p, frame, frame_size);  
1102 -  
1103 return srs_rtmp_write_packet(context, SRS_RTMP_TYPE_AUDIO, timestamp, data, size); 1087 return srs_rtmp_write_packet(context, SRS_RTMP_TYPE_AUDIO, timestamp, data, size);
1104 } 1088 }
1105 1089
1106 /** 1090 /**
1107 * write aac frame in adts. 1091 * write aac frame in adts.
1108 */ 1092 */
1109 -int __srs_write_aac_adts_frame(Context* context,  
1110 - char sound_format, char sound_rate, char sound_size, char sound_type,  
1111 - char aac_profile, char aac_samplerate, char aac_channel,  
1112 - char* frame, int frame_size, u_int32_t timestamp 1093 +int __srs_write_aac_adts_frame(Context* context,
  1094 + SrsRawAacStreamCodec* codec, char* frame, int frame_size, u_int32_t timestamp
1113 ) { 1095 ) {
1114 int ret = ERROR_SUCCESS; 1096 int ret = ERROR_SUCCESS;
1115 1097
1116 - // override the aac samplerate by user specified.  
1117 - // @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64146899  
1118 - switch (sound_rate) {  
1119 - case SrsCodecAudioSampleRate11025:  
1120 - aac_samplerate = 0x0a; break;  
1121 - case SrsCodecAudioSampleRate22050:  
1122 - aac_samplerate = 0x07; break;  
1123 - case SrsCodecAudioSampleRate44100:  
1124 - aac_samplerate = 0x04; break;  
1125 - default:  
1126 - break;  
1127 - }  
1128 -  
1129 // send out aac sequence header if not sent. 1098 // send out aac sequence header if not sent.
1130 if (context->aac_specific_config.empty()) { 1099 if (context->aac_specific_config.empty()) {
1131 - char ch = 0;  
1132 - // @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf  
1133 - // AudioSpecificConfig (), page 33  
1134 - // 1.6.2.1 AudioSpecificConfig  
1135 - // audioObjectType; 5 bslbf  
1136 - ch = (aac_profile << 3) & 0xf8;  
1137 - // 3bits left.  
1138 -  
1139 - // samplingFrequencyIndex; 4 bslbf  
1140 - ch |= (aac_samplerate >> 1) & 0x07;  
1141 - context->aac_specific_config += ch;  
1142 - ch = (aac_samplerate << 7) & 0x80;  
1143 - if (aac_samplerate == 0x0f) {  
1144 - return ERROR_AAC_DATA_INVALID;  
1145 - }  
1146 - // 7bits left.  
1147 -  
1148 - // channelConfiguration; 4 bslbf  
1149 - ch |= (aac_channel << 3) & 0x78;  
1150 - // 3bits left.  
1151 -  
1152 - // only support aac profile 1-4.  
1153 - if (aac_profile < 1 || aac_profile > 4) {  
1154 - return ERROR_AAC_DATA_INVALID; 1100 + std::string sh;
  1101 + if ((ret = context->aac_raw.mux_sequence_header(codec, sh)) != ERROR_SUCCESS) {
  1102 + return ret;
1155 } 1103 }
1156 - // GASpecificConfig(), page 451  
1157 - // 4.4.1 Decoder configuration (GASpecificConfig)  
1158 - // frameLengthFlag; 1 bslbf  
1159 - // dependsOnCoreCoder; 1 bslbf  
1160 - // extensionFlag; 1 bslbf  
1161 - context->aac_specific_config += ch;  
1162 -  
1163 - char* sh = (char*)context->aac_specific_config.data();  
1164 - int nb_sh = (int)context->aac_specific_config.length();  
1165 - if ((ret = __srs_write_audio_raw_frame(context,  
1166 - sound_format, sound_rate, sound_size, sound_type,  
1167 - 0, sh, nb_sh, timestamp)) != ERROR_SUCCESS  
1168 - ) { 1104 + context->aac_specific_config = sh;
  1105 +
  1106 + codec->aac_packet_type = 0;
  1107 +
  1108 + if ((ret = __srs_write_audio_raw_frame(context, (char*)sh.data(), (int)sh.length(), codec, timestamp)) != ERROR_SUCCESS) {
1169 return ret; 1109 return ret;
1170 } 1110 }
1171 } 1111 }
1172 1112
1173 - return __srs_write_audio_raw_frame(context,  
1174 - sound_format, sound_rate, sound_size, sound_type,  
1175 - 1, frame, frame_size, timestamp); 1113 + codec->aac_packet_type = 1;
  1114 + return __srs_write_audio_raw_frame(context, frame, frame_size, codec, timestamp);
1176 } 1115 }
1177 1116
1178 /** 1117 /**
@@ -1180,126 +1119,32 @@ int __srs_write_aac_adts_frame(Context* context, @@ -1180,126 +1119,32 @@ int __srs_write_aac_adts_frame(Context* context,
1180 */ 1119 */
1181 int __srs_write_aac_adts_frames(Context* context, 1120 int __srs_write_aac_adts_frames(Context* context,
1182 char sound_format, char sound_rate, char sound_size, char sound_type, 1121 char sound_format, char sound_rate, char sound_size, char sound_type,
1183 - char* frame, int frame_size, u_int32_t timestamp 1122 + char* frames, int frames_size, u_int32_t timestamp
1184 ) { 1123 ) {
1185 int ret = ERROR_SUCCESS; 1124 int ret = ERROR_SUCCESS;
1186 1125
1187 SrsStream* stream = &context->aac_raw_stream; 1126 SrsStream* stream = &context->aac_raw_stream;
1188 - if ((ret = stream->initialize(frame, frame_size)) != ERROR_SUCCESS) { 1127 + if ((ret = stream->initialize(frames, frames_size)) != ERROR_SUCCESS) {
1189 return ret; 1128 return ret;
1190 } 1129 }
1191 1130
1192 while (!stream->empty()) { 1131 while (!stream->empty()) {
1193 - int adts_header_start = stream->pos();  
1194 -  
1195 - // decode the ADTS.  
1196 - // @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 75,  
1197 - // 1.A.2.2 Audio_Data_Transport_Stream frame, ADTS  
1198 - // @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64145885  
1199 - // byte_alignment()  
1200 -  
1201 - // adts_fixed_header:  
1202 - // 12bits syncword,  
1203 - // 16bits left.  
1204 - // adts_variable_header:  
1205 - // 28bits  
1206 - // 12+16+28=56bits  
1207 - // adts_error_check:  
1208 - // 16bits if protection_absent  
1209 - // 56+16=72bits  
1210 - // if protection_absent:  
1211 - // require(7bytes)=56bits  
1212 - // else  
1213 - // require(9bytes)=72bits  
1214 - if (!stream->require(7)) {  
1215 - return ERROR_AAC_ADTS_HEADER;  
1216 - }  
1217 -  
1218 - // for aac, the frame must be ADTS format.  
1219 - if (!srs_aac_startswith_adts(stream)) {  
1220 - return ERROR_AAC_REQUIRED_ADTS;  
1221 - }  
1222 -  
1223 - // Syncword 12 bslbf  
1224 - stream->read_1bytes();  
1225 - // 4bits left.  
1226 - // adts_fixed_header(), 1.A.2.2.1 Fixed Header of ADTS  
1227 - // ID 1 bslbf  
1228 - // Layer 2 uimsbf  
1229 - // protection_absent 1 bslbf  
1230 - int8_t fh0 = (stream->read_1bytes() & 0x0f);  
1231 - /*int8_t fh_id = (fh0 >> 3) & 0x01;*/  
1232 - /*int8_t fh_layer = (fh0 >> 1) & 0x03;*/  
1233 - int8_t fh_protection_absent = fh0 & 0x01;  
1234 -  
1235 - int16_t fh1 = stream->read_2bytes();  
1236 - // Profile_ObjectType 2 uimsbf  
1237 - // sampling_frequency_index 4 uimsbf  
1238 - // private_bit 1 bslbf  
1239 - // channel_configuration 3 uimsbf  
1240 - // original/copy 1 bslbf  
1241 - // home 1 bslbf  
1242 - int8_t fh_Profile_ObjectType = (fh1 >> 14) & 0x03;  
1243 - int8_t fh_sampling_frequency_index = (fh1 >> 10) & 0x0f;  
1244 - /*int8_t fh_private_bit = (fh1 >> 9) & 0x01;*/  
1245 - int8_t fh_channel_configuration = (fh1 >> 6) & 0x07;  
1246 - /*int8_t fh_original = (fh1 >> 5) & 0x01;*/  
1247 - /*int8_t fh_home = (fh1 >> 4) & 0x01;*/  
1248 - // @remark, Emphasis is removed,  
1249 - // @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64154736  
1250 - //int8_t fh_Emphasis = (fh1 >> 2) & 0x03;  
1251 - // 4bits left.  
1252 - // adts_variable_header(), 1.A.2.2.2 Variable Header of ADTS  
1253 - // copyright_identification_bit 1 bslbf  
1254 - // copyright_identification_start 1 bslbf  
1255 - /*int8_t fh_copyright_identification_bit = (fh1 >> 3) & 0x01;*/  
1256 - /*int8_t fh_copyright_identification_start = (fh1 >> 2) & 0x01;*/  
1257 - // aac_frame_length 13 bslbf: Length of the frame including headers and error_check in bytes.  
1258 - // use the left 2bits as the 13 and 12 bit,  
1259 - // the aac_frame_length is 13bits, so we move 13-2=11.  
1260 - int16_t fh_aac_frame_length = (fh1 << 11) & 0x0800;  
1261 -  
1262 - int32_t fh2 = stream->read_3bytes();  
1263 - // aac_frame_length 13 bslbf: consume the first 13-2=11bits  
1264 - // the fh2 is 24bits, so we move right 24-11=13.  
1265 - fh_aac_frame_length |= (fh2 >> 13) & 0x07ff;  
1266 - // adts_buffer_fullness 11 bslbf  
1267 - /*int16_t fh_adts_buffer_fullness = (fh2 >> 2) & 0x7ff;*/  
1268 - // no_raw_data_blocks_in_frame 2 uimsbf  
1269 - /*int16_t fh_no_raw_data_blocks_in_frame = fh2 & 0x03;*/  
1270 - // adts_error_check(), 1.A.2.2.3 Error detection  
1271 - if (!fh_protection_absent) {  
1272 - if (!stream->require(2)) {  
1273 - return ERROR_AAC_ADTS_HEADER;  
1274 - }  
1275 - // crc_check 16 Rpchof  
1276 - /*int16_t crc_check = */stream->read_2bytes();  
1277 - }  
1278 -  
1279 - // TODO: check the fh_sampling_frequency_index  
1280 - // TODO: check the fh_channel_configuration  
1281 -  
1282 - // raw_data_blocks  
1283 - int adts_header_size = stream->pos() - adts_header_start;  
1284 - int raw_data_size = fh_aac_frame_length - adts_header_size;  
1285 - if (!stream->require(raw_data_size)) {  
1286 - return ERROR_AAC_ADTS_HEADER; 1132 + char* frame = NULL;
  1133 + int frame_size = 0;
  1134 + SrsRawAacStreamCodec codec;
  1135 + if ((ret = context->aac_raw.adts_demux(stream, &frame, &frame_size, codec)) != ERROR_SUCCESS) {
  1136 + return ret;
1287 } 1137 }
1288 -  
1289 - // the profile = object_id + 1  
1290 - // @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,  
1291 - // Table 1. A.9 – MPEG-2 Audio profiles and MPEG-4 Audio object types  
1292 - char aac_profile = fh_Profile_ObjectType + 1;  
1293 -  
1294 - char* raw_data = stream->data() + stream->pos();  
1295 - if ((ret = __srs_write_aac_adts_frame(context,  
1296 - sound_format, sound_rate, sound_size, sound_type,  
1297 - aac_profile, fh_sampling_frequency_index, fh_channel_configuration,  
1298 - raw_data, raw_data_size, timestamp)) != ERROR_SUCCESS  
1299 - ) { 1138 +
  1139 + // override by user specified.
  1140 + codec.sound_format = sound_format;
  1141 + codec.sound_rate = sound_rate;
  1142 + codec.sound_size = sound_size;
  1143 + codec.sound_type = sound_type;
  1144 +
  1145 + if ((ret = __srs_write_aac_adts_frame(context, &codec, frame, frame_size, timestamp)) != ERROR_SUCCESS) {
1300 return ret; 1146 return ret;
1301 } 1147 }
1302 - stream->skip(raw_data_size);  
1303 } 1148 }
1304 1149
1305 return ret; 1150 return ret;
@@ -1328,10 +1173,16 @@ int srs_audio_write_raw_frame(srs_rtmp_t rtmp, @@ -1328,10 +1173,16 @@ int srs_audio_write_raw_frame(srs_rtmp_t rtmp,
1328 sound_format, sound_rate, sound_size, sound_type, 1173 sound_format, sound_rate, sound_size, sound_type,
1329 frame, frame_size, timestamp); 1174 frame, frame_size, timestamp);
1330 } else { 1175 } else {
  1176 + // use codec info for aac.
  1177 + SrsRawAacStreamCodec codec;
  1178 + codec.sound_format = sound_format;
  1179 + codec.sound_rate = sound_rate;
  1180 + codec.sound_size = sound_size;
  1181 + codec.sound_type = sound_type;
  1182 + codec.aac_packet_type = 0;
  1183 +
1331 // for other data, directly write frame. 1184 // for other data, directly write frame.
1332 - return __srs_write_audio_raw_frame(context,  
1333 - sound_format, sound_rate, sound_size, sound_type,  
1334 - 0, frame, frame_size, timestamp); 1185 + return __srs_write_audio_raw_frame(context, frame, frame_size, &codec, timestamp);
1335 } 1186 }
1336 1187
1337 1188
@@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 using namespace std; 27 using namespace std;
28 28
29 #include <srs_kernel_error.hpp> 29 #include <srs_kernel_error.hpp>
  30 +#include <srs_kernel_log.hpp>
30 #include <srs_kernel_stream.hpp> 31 #include <srs_kernel_stream.hpp>
31 #include <srs_kernel_utility.hpp> 32 #include <srs_kernel_utility.hpp>
32 #include <srs_core_autofree.hpp> 33 #include <srs_core_autofree.hpp>
@@ -312,3 +313,254 @@ int SrsRawH264Stream::mux_avc2flv(string video, int8_t frame_type, int8_t avc_pa @@ -312,3 +313,254 @@ int SrsRawH264Stream::mux_avc2flv(string video, int8_t frame_type, int8_t avc_pa
312 return ret; 313 return ret;
313 } 314 }
314 315
  316 +SrsRawAacStream::SrsRawAacStream()
  317 +{
  318 +}
  319 +
  320 +SrsRawAacStream::~SrsRawAacStream()
  321 +{
  322 +}
  323 +
  324 +int SrsRawAacStream::adts_demux(SrsStream* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec)
  325 +{
  326 + int ret = ERROR_SUCCESS;
  327 +
  328 + while (!stream->empty()) {
  329 + int adts_header_start = stream->pos();
  330 +
  331 + // decode the ADTS.
  332 + // @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 75,
  333 + // 1.A.2.2 Audio_Data_Transport_Stream frame, ADTS
  334 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64145885
  335 + // byte_alignment()
  336 +
  337 + // adts_fixed_header:
  338 + // 12bits syncword,
  339 + // 16bits left.
  340 + // adts_variable_header:
  341 + // 28bits
  342 + // 12+16+28=56bits
  343 + // adts_error_check:
  344 + // 16bits if protection_absent
  345 + // 56+16=72bits
  346 + // if protection_absent:
  347 + // require(7bytes)=56bits
  348 + // else
  349 + // require(9bytes)=72bits
  350 + if (!stream->require(7)) {
  351 + return ERROR_AAC_ADTS_HEADER;
  352 + }
  353 +
  354 + // for aac, the frame must be ADTS format.
  355 + if (!srs_aac_startswith_adts(stream)) {
  356 + return ERROR_AAC_REQUIRED_ADTS;
  357 + }
  358 +
  359 + // Syncword 12 bslbf
  360 + stream->read_1bytes();
  361 + // 4bits left.
  362 + // adts_fixed_header(), 1.A.2.2.1 Fixed Header of ADTS
  363 + // ID 1 bslbf
  364 + // Layer 2 uimsbf
  365 + // protection_absent 1 bslbf
  366 + int8_t fh0 = (stream->read_1bytes() & 0x0f);
  367 + /*int8_t fh_id = (fh0 >> 3) & 0x01;*/
  368 + /*int8_t fh_layer = (fh0 >> 1) & 0x03;*/
  369 + int8_t fh_protection_absent = fh0 & 0x01;
  370 +
  371 + int16_t fh1 = stream->read_2bytes();
  372 + // Profile_ObjectType 2 uimsbf
  373 + // sampling_frequency_index 4 uimsbf
  374 + // private_bit 1 bslbf
  375 + // channel_configuration 3 uimsbf
  376 + // original/copy 1 bslbf
  377 + // home 1 bslbf
  378 + int8_t fh_Profile_ObjectType = (fh1 >> 14) & 0x03;
  379 + int8_t fh_sampling_frequency_index = (fh1 >> 10) & 0x0f;
  380 + /*int8_t fh_private_bit = (fh1 >> 9) & 0x01;*/
  381 + int8_t fh_channel_configuration = (fh1 >> 6) & 0x07;
  382 + /*int8_t fh_original = (fh1 >> 5) & 0x01;*/
  383 + /*int8_t fh_home = (fh1 >> 4) & 0x01;*/
  384 + // @remark, Emphasis is removed,
  385 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64154736
  386 + //int8_t fh_Emphasis = (fh1 >> 2) & 0x03;
  387 + // 4bits left.
  388 + // adts_variable_header(), 1.A.2.2.2 Variable Header of ADTS
  389 + // copyright_identification_bit 1 bslbf
  390 + // copyright_identification_start 1 bslbf
  391 + /*int8_t fh_copyright_identification_bit = (fh1 >> 3) & 0x01;*/
  392 + /*int8_t fh_copyright_identification_start = (fh1 >> 2) & 0x01;*/
  393 + // aac_frame_length 13 bslbf: Length of the frame including headers and error_check in bytes.
  394 + // use the left 2bits as the 13 and 12 bit,
  395 + // the aac_frame_length is 13bits, so we move 13-2=11.
  396 + int16_t fh_aac_frame_length = (fh1 << 11) & 0x0800;
  397 +
  398 + int32_t fh2 = stream->read_3bytes();
  399 + // aac_frame_length 13 bslbf: consume the first 13-2=11bits
  400 + // the fh2 is 24bits, so we move right 24-11=13.
  401 + fh_aac_frame_length |= (fh2 >> 13) & 0x07ff;
  402 + // adts_buffer_fullness 11 bslbf
  403 + /*int16_t fh_adts_buffer_fullness = (fh2 >> 2) & 0x7ff;*/
  404 + // no_raw_data_blocks_in_frame 2 uimsbf
  405 + /*int16_t fh_no_raw_data_blocks_in_frame = fh2 & 0x03;*/
  406 + // adts_error_check(), 1.A.2.2.3 Error detection
  407 + if (!fh_protection_absent) {
  408 + if (!stream->require(2)) {
  409 + return ERROR_AAC_ADTS_HEADER;
  410 + }
  411 + // crc_check 16 Rpchof
  412 + /*int16_t crc_check = */stream->read_2bytes();
  413 + }
  414 +
  415 + // TODO: check the fh_sampling_frequency_index
  416 + // TODO: check the fh_channel_configuration
  417 +
  418 + // raw_data_blocks
  419 + int adts_header_size = stream->pos() - adts_header_start;
  420 + int raw_data_size = fh_aac_frame_length - adts_header_size;
  421 + if (!stream->require(raw_data_size)) {
  422 + return ERROR_AAC_ADTS_HEADER;
  423 + }
  424 +
  425 + // the profile = object_id + 1
  426 + // @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,
  427 + // Table 1. A.9 ¨C MPEG-2 Audio profiles and MPEG-4 Audio object types
  428 + char aac_profile = fh_Profile_ObjectType + 1;
  429 +
  430 + // the codec info.
  431 + codec.protection_absent = fh_protection_absent;
  432 + codec.Profile_ObjectType = fh_Profile_ObjectType;
  433 + codec.sampling_frequency_index = fh_sampling_frequency_index;
  434 + codec.channel_configuration = fh_channel_configuration;
  435 + codec.aac_frame_length = fh_aac_frame_length;
  436 +
  437 + codec.aac_profile = aac_profile;
  438 + codec.aac_samplerate = fh_sampling_frequency_index;
  439 + codec.aac_channel = fh_channel_configuration;
  440 +
  441 + // @see srs_audio_write_raw_frame().
  442 + codec.sound_format = 10; // AAC
  443 + if (fh_sampling_frequency_index <= 0x0c && fh_sampling_frequency_index > 0x0a) {
  444 + codec.sound_rate = SrsCodecAudioSampleRate5512;
  445 + } else if (fh_sampling_frequency_index <= 0x0a && fh_sampling_frequency_index > 0x07) {
  446 + codec.sound_rate = SrsCodecAudioSampleRate11025;
  447 + } else if (fh_sampling_frequency_index <= 0x07 && fh_sampling_frequency_index > 0x04) {
  448 + codec.sound_rate = SrsCodecAudioSampleRate22050;
  449 + } else if (fh_sampling_frequency_index <= 0x04) {
  450 + codec.sound_rate = SrsCodecAudioSampleRate44100;
  451 + } else {
  452 + codec.sound_rate = SrsCodecAudioSampleRate44100;
  453 + srs_warn("adts invalid sample rate for flv, rate=%#x", fh_sampling_frequency_index);
  454 + }
  455 + codec.sound_size = srs_max(0, srs_min(1, fh_channel_configuration - 1));
  456 + // TODO: FIXME: finger it out the sound size by adts.
  457 + codec.sound_size = 1; // 0(8bits) or 1(16bits).
  458 +
  459 + // frame data.
  460 + *pframe = stream->data() + stream->pos();
  461 + *pnb_frame = raw_data_size;
  462 + stream->skip(raw_data_size);
  463 +
  464 + break;
  465 + }
  466 +
  467 + return ret;
  468 +}
  469 +
  470 +int SrsRawAacStream::mux_sequence_header(SrsRawAacStreamCodec* codec, string& sh)
  471 +{
  472 + int ret = ERROR_SUCCESS;
  473 +
  474 + char aac_channel = codec->aac_channel;
  475 + char aac_profile = codec->aac_profile;
  476 + char aac_samplerate = codec->aac_samplerate;
  477 +
  478 + // override the aac samplerate by user specified.
  479 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64146899
  480 + switch (codec->sound_rate) {
  481 + case SrsCodecAudioSampleRate11025:
  482 + aac_samplerate = 0x0a; break;
  483 + case SrsCodecAudioSampleRate22050:
  484 + aac_samplerate = 0x07; break;
  485 + case SrsCodecAudioSampleRate44100:
  486 + aac_samplerate = 0x04; break;
  487 + default:
  488 + break;
  489 + }
  490 +
  491 + sh = "";
  492 +
  493 + char ch = 0;
  494 + // @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf
  495 + // AudioSpecificConfig (), page 33
  496 + // 1.6.2.1 AudioSpecificConfig
  497 + // audioObjectType; 5 bslbf
  498 + ch = (aac_profile << 3) & 0xf8;
  499 + // 3bits left.
  500 +
  501 + // samplingFrequencyIndex; 4 bslbf
  502 + ch |= (aac_samplerate >> 1) & 0x07;
  503 + sh += ch;
  504 + ch = (aac_samplerate << 7) & 0x80;
  505 + if (aac_samplerate == 0x0f) {
  506 + return ERROR_AAC_DATA_INVALID;
  507 + }
  508 + // 7bits left.
  509 +
  510 + // channelConfiguration; 4 bslbf
  511 + ch |= (aac_channel << 3) & 0x78;
  512 + // 3bits left.
  513 +
  514 + // only support aac profile 1-4.
  515 + if (aac_profile < 1 || aac_profile > 4) {
  516 + return ERROR_AAC_DATA_INVALID;
  517 + }
  518 + // GASpecificConfig(), page 451
  519 + // 4.4.1 Decoder configuration (GASpecificConfig)
  520 + // frameLengthFlag; 1 bslbf
  521 + // dependsOnCoreCoder; 1 bslbf
  522 + // extensionFlag; 1 bslbf
  523 + sh += ch;
  524 +
  525 + return ret;
  526 +}
  527 +
  528 +int SrsRawAacStream::mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec* codec, u_int32_t dts, char** flv, int* nb_flv)
  529 +{
  530 + int ret = ERROR_SUCCESS;
  531 +
  532 + char sound_format = codec->sound_format;
  533 + char sound_type = codec->sound_type;
  534 + char sound_size = codec->sound_size;
  535 + char sound_rate = codec->sound_rate;
  536 + char aac_packet_type = codec->aac_packet_type;
  537 +
  538 + // for audio frame, there is 1 or 2 bytes header:
  539 + // 1bytes, SoundFormat|SoundRate|SoundSize|SoundType
  540 + // 1bytes, AACPacketType for SoundFormat == 10, 0 is sequence header.
  541 + int size = nb_frame + 1;
  542 + if (sound_format == SrsCodecAudioAAC) {
  543 + size += 1;
  544 + }
  545 + char* data = new char[size];
  546 + char* p = data;
  547 +
  548 + u_int8_t audio_header = sound_type & 0x01;
  549 + audio_header |= (sound_size << 1) & 0x02;
  550 + audio_header |= (sound_rate << 2) & 0x0c;
  551 + audio_header |= (sound_format << 4) & 0xf0;
  552 +
  553 + *p++ = audio_header;
  554 +
  555 + if (sound_format == SrsCodecAudioAAC) {
  556 + *p++ = aac_packet_type;
  557 + }
  558 +
  559 + memcpy(p, frame, nb_frame);
  560 +
  561 + *flv = data;
  562 + *nb_flv = size;
  563 +
  564 + return ret;
  565 +}
  566 +
@@ -86,4 +86,62 @@ public: @@ -86,4 +86,62 @@ public:
86 virtual int mux_avc2flv(std::string video, int8_t frame_type, int8_t avc_packet_type, u_int32_t dts, u_int32_t pts, char** flv, int* nb_flv); 86 virtual int mux_avc2flv(std::string video, int8_t frame_type, int8_t avc_packet_type, u_int32_t dts, u_int32_t pts, char** flv, int* nb_flv);
87 }; 87 };
88 88
  89 +/**
  90 +* the header of adts sample.
  91 +*/
  92 +struct SrsRawAacStreamCodec
  93 +{
  94 + int8_t protection_absent;
  95 + int8_t Profile_ObjectType;
  96 + int8_t sampling_frequency_index;
  97 + int8_t channel_configuration;
  98 + int16_t aac_frame_length;
  99 +
  100 + // calc by Profile_ObjectType+1
  101 + char aac_profile;
  102 + char aac_samplerate;
  103 + char aac_channel;
  104 +
  105 + char sound_format;
  106 + char sound_rate;
  107 + char sound_size;
  108 + char sound_type;
  109 + // 0 for sh; 1 for raw data.
  110 + int8_t aac_packet_type;
  111 +};
  112 +
  113 +/**
  114 +* the raw aac stream, in adts.
  115 +*/
  116 +class SrsRawAacStream
  117 +{
  118 +public:
  119 + SrsRawAacStream();
  120 + virtual ~SrsRawAacStream();
  121 +public:
  122 + /**
  123 + * demux the stream in adts format.
  124 + * @param stream the input stream bytes.
  125 + * @param pframe the output aac frame in stream. user should never free it.
  126 + * @param pnb_frame the output aac frame size.
  127 + * @param codec the output codec info.
  128 + */
  129 + virtual int adts_demux(SrsStream* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec);
  130 + /**
  131 + * aac raw data to aac packet, without flv payload header.
  132 + * mux the aac specific config to flv sequence header packet.
  133 + * @param sh output the sequence header.
  134 + */
  135 + virtual int mux_sequence_header(SrsRawAacStreamCodec* codec, std::string& sh);
  136 + /**
  137 + * mux the aac audio packet to flv audio packet.
  138 + * @param frame the aac raw data.
  139 + * @param nb_frame the count of aac frame.
  140 + * @param codec the codec info of aac.
  141 + * @param flv output the muxed flv packet.
  142 + * @param nb_flv output the muxed flv size.
  143 + */
  144 + virtual int mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec* codec, u_int32_t dts, char** flv, int* nb_flv);
  145 +};
  146 +
89 #endif 147 #endif