rtp_transmitter.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:11k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is MPEG4IP.
  13.  * 
  14.  * The Initial Developer of the Original Code is Cisco Systems Inc.
  15.  * Portions created by Cisco Systems Inc. are
  16.  * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  * Dave Mackie dmackie@cisco.com
  20.  * Bill May  wmay@cisco.com
  21.  */
  22. #include "mp4live.h"
  23. #include "rtp_transmitter.h"
  24. // #define RTP_DEBUG 1
  25. int CRtpTransmitter::ThreadMain(void) 
  26. {
  27. while (SDL_SemWait(m_myMsgQueueSemaphore) == 0) {
  28. CMsg* pMsg = m_myMsgQueue.get_message();
  29. if (pMsg != NULL) {
  30. switch (pMsg->get_value()) {
  31. case MSG_NODE_STOP_THREAD:
  32. DoStopTransmit();
  33. delete pMsg;
  34. return 0;
  35. case MSG_NODE_START:
  36. DoStartTransmit();
  37. break;
  38. case MSG_NODE_STOP:
  39. DoStopTransmit();
  40. break;
  41. case MSG_SINK_FRAME:
  42. size_t dontcare;
  43. DoSendFrame((CMediaFrame*)pMsg->get_message(dontcare));
  44. break;
  45. }
  46. delete pMsg;
  47. }
  48. }
  49. return -1;
  50. }
  51. void CRtpTransmitter::DoStartTransmit()
  52. {
  53. if (m_sink) {
  54. return;
  55. }
  56. m_startTimestamp = GetTimestamp();
  57. if (m_pConfig->GetBoolValue(CONFIG_AUDIO_ENABLE)) {
  58. m_audioTimeScale = 
  59. m_pConfig->GetIntegerValue(CONFIG_AUDIO_SAMPLE_RATE); 
  60. m_audioDestAddress = 
  61. m_pConfig->GetStringValue(CONFIG_RTP_DEST_ADDRESS); 
  62. if (m_pConfig->GetBoolValue(CONFIG_RTP_DISABLE_TS_OFFSET)) {
  63. m_audioRtpTimestampOffset = 0;
  64. } else {
  65. m_audioRtpTimestampOffset = random();
  66. }
  67. m_audioSrcPort = GetRandomPortBlock();
  68. if (m_pConfig->GetIntegerValue(CONFIG_RTP_AUDIO_DEST_PORT) == 0) {
  69. m_pConfig->SetIntegerValue(CONFIG_RTP_AUDIO_DEST_PORT,
  70. m_audioSrcPort + 2);
  71. }
  72. m_audioRtpSession = rtp_init(m_audioDestAddress, 
  73. m_audioSrcPort, 
  74. m_pConfig->GetIntegerValue(CONFIG_RTP_AUDIO_DEST_PORT),
  75. m_pConfig->GetIntegerValue(CONFIG_RTP_MCAST_TTL), 
  76. m_rtcpBandwidth, 
  77. RtpCallback, (uint8_t *)this);
  78. m_audioQueueCount = 0;
  79. m_audioQueueSize = 0;
  80. if (!strcasecmp(m_pConfig->GetStringValue(CONFIG_AUDIO_ENCODING),
  81.   AUDIO_ENCODING_MP3)) {
  82. m_audioFrameType = CMediaFrame::Mp3AudioFrame;
  83. m_audioPayloadBytesPerPacket = 4;
  84. m_audioPayloadBytesPerFrame = 0;
  85. } else { // AAC
  86. m_audioFrameType = CMediaFrame::AacAudioFrame;
  87. m_audioPayloadBytesPerPacket = 2;
  88. m_audioPayloadBytesPerFrame = 2;
  89. }
  90. }
  91. if (m_pConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)) {
  92. m_videoDestAddress = 
  93. m_pConfig->GetStringValue(CONFIG_RTP_DEST_ADDRESS); 
  94. if (m_pConfig->GetBoolValue(CONFIG_RTP_DISABLE_TS_OFFSET)) {
  95. m_videoRtpTimestampOffset = 0;
  96. } else {
  97. m_videoRtpTimestampOffset = random();
  98. }
  99. m_videoSrcPort = GetRandomPortBlock();
  100. if (m_pConfig->GetIntegerValue(CONFIG_RTP_VIDEO_DEST_PORT) == 0) {
  101. m_pConfig->SetIntegerValue(CONFIG_RTP_VIDEO_DEST_PORT,
  102. m_videoSrcPort + 2);
  103. }
  104. m_videoRtpSession = rtp_init(m_videoDestAddress, 
  105. m_videoSrcPort, 
  106. m_pConfig->GetIntegerValue(CONFIG_RTP_VIDEO_DEST_PORT),
  107. m_pConfig->GetIntegerValue(CONFIG_RTP_MCAST_TTL), 
  108. m_rtcpBandwidth, 
  109. RtpCallback, (uint8_t *)this);
  110. }
  111. if (m_audioRtpSession || m_videoRtpSession) {
  112. // automatic sdp file generation
  113. GenerateSdpFile(m_pConfig);
  114. m_sink = true;
  115. }
  116. }
  117. void CRtpTransmitter::DoStopTransmit()
  118. {
  119. if (!m_sink) {
  120. return;
  121. }
  122. if (m_audioRtpSession) {
  123. // send any pending frames
  124. SendQueuedAudioFrames();
  125. rtp_done(m_audioRtpSession);
  126. m_audioRtpSession = NULL;
  127. }
  128. if (m_videoRtpSession) {
  129. rtp_done(m_videoRtpSession);
  130. m_videoRtpSession = NULL;
  131. }
  132. m_sink = false;
  133. }
  134. void CRtpTransmitter::DoSendFrame(CMediaFrame* pFrame)
  135. {
  136. if (pFrame == NULL) {
  137. return;
  138. }
  139. if (!m_sink) {
  140. delete pFrame;
  141. return;
  142. }
  143. if (pFrame->GetType() == m_audioFrameType && m_audioRtpSession) {
  144. SendAudioFrame(pFrame);
  145. } else if (pFrame->GetType() == CMediaFrame::Mpeg4VideoFrame 
  146.   && m_videoRtpSession) {
  147. SendMpeg4VideoWith3016(pFrame);
  148. } else {
  149. delete pFrame;
  150. }
  151. }
  152. void CRtpTransmitter::SendAudioFrame(CMediaFrame* pFrame)
  153. {
  154. u_int16_t newAudioQueueSize;
  155. if (m_audioQueueCount > 0) {
  156. newAudioQueueSize =
  157. m_audioQueueSize 
  158. + m_audioPayloadBytesPerFrame
  159. + pFrame->GetDataLength();
  160. if (newAudioQueueSize <= 
  161.   m_pConfig->GetIntegerValue(CONFIG_RTP_PAYLOAD_SIZE)) {
  162. m_audioQueue[m_audioQueueCount++] = pFrame;
  163. m_audioQueueSize = newAudioQueueSize;
  164. // if we fill the last slot in the queue
  165. // send the packet
  166. if (m_audioQueueCount == audioQueueMaxCount) {
  167. SendQueuedAudioFrames();
  168. }
  169. return;
  170. } else {
  171. // send queued frames
  172. SendQueuedAudioFrames();
  173. // fall thru
  174. }
  175. }
  176. // by here m_audioQueueCount == 0
  177. newAudioQueueSize =
  178. m_audioPayloadBytesPerPacket
  179. + m_audioPayloadBytesPerFrame
  180. + pFrame->GetDataLength();
  181. if (newAudioQueueSize 
  182.   <= m_pConfig->GetIntegerValue(CONFIG_RTP_PAYLOAD_SIZE)) {
  183. m_audioQueue[m_audioQueueCount++] = pFrame;
  184. m_audioQueueSize = newAudioQueueSize;
  185. } else {
  186. // highly unusual case 
  187. // we need to fragment audio frame
  188. // over multiple packets
  189. SendAudioJumboFrame(pFrame);
  190. }
  191. }
  192. void CRtpTransmitter::SendQueuedAudioFrames(void)
  193. {
  194. static u_int32_t zero32 = 0;
  195. u_int8_t aacHeader[2 + (audioQueueMaxCount * 2)];
  196. struct iovec iov[audioQueueMaxCount + 1];
  197. if (m_audioQueueCount == 0) {
  198. return;
  199. }
  200. u_int32_t rtpTimestamp =
  201. AudioTimestampToRtp(m_audioQueue[0]->GetTimestamp());
  202. u_int64_t ntpTimestamp =
  203. TimestampToNtp(m_audioQueue[0]->GetTimestamp());
  204. #if RTP_DEBUG
  205. debug_message("A ts %llu rtp %u ntp %u.%u",
  206. m_audioQueue[0]->GetTimestamp(),
  207. rtpTimestamp,
  208. (u_int32_t)(ntpTimestamp >> 32),
  209. (u_int32_t)ntpTimestamp);
  210. #endif
  211. // check if RTCP SR needs to be sent
  212. rtp_send_ctrl_2(m_audioRtpSession, rtpTimestamp, ntpTimestamp, NULL);
  213. rtp_update(m_audioRtpSession);
  214. // create the iovec list
  215. u_int8_t i;
  216. // audio payload headers
  217. if (m_audioQueue[0]->GetType() == CMediaFrame::Mp3AudioFrame) {
  218. iov[0].iov_base = &zero32;
  219. iov[0].iov_len = 4;
  220. } else { // AAC
  221. u_int16_t numHdrBits = 16 * m_audioQueueCount;
  222. aacHeader[0] = numHdrBits >> 8;
  223. aacHeader[1] = numHdrBits & 0xFF;
  224. for (i = 0; i < m_audioQueueCount; i++) {
  225. aacHeader[2 + (i * 2)] = 
  226. m_audioQueue[i]->GetDataLength() >> 5;
  227. aacHeader[2 + (i * 2) + 1] = 
  228. (m_audioQueue[i]->GetDataLength() & 0x1F) << 3;
  229. }
  230. iov[0].iov_base = aacHeader;
  231. iov[0].iov_len = 2 + (m_audioQueueCount * 2);
  232. }
  233. // audio payload data
  234. for (i = 0; i < m_audioQueueCount; i++) {
  235. iov[i+1].iov_base = m_audioQueue[i]->GetData();
  236. iov[i+1].iov_len = m_audioQueue[i]->GetDataLength();
  237. }
  238. // send packet
  239. rtp_send_data_iov(
  240. m_audioRtpSession,
  241. rtpTimestamp,
  242. m_audioPayloadNumber, 1, 0, NULL,
  243. iov, m_audioQueueCount + 1,
  244. NULL, 0, 0);
  245. // delete all the pending media frames
  246. for (int i = 0; i < m_audioQueueCount; i++) {
  247. delete m_audioQueue[i];
  248. m_audioQueue[i] = NULL;
  249. }
  250. m_audioQueueCount = 0;
  251. m_audioQueueSize = 0;
  252. }
  253. void CRtpTransmitter::SendAudioJumboFrame(CMediaFrame* pFrame)
  254. {
  255. u_int32_t rtpTimestamp = 
  256. AudioTimestampToRtp(pFrame->GetTimestamp());
  257. u_int64_t ntpTimestamp =
  258. TimestampToNtp(pFrame->GetTimestamp());
  259. #if RTP_DEBUG
  260. debug_message("A ts %llu rtp %u ntp %u.%u",
  261. pFrame->GetTimestamp(),
  262. rtpTimestamp,
  263. (u_int32_t)(ntpTimestamp >> 32),
  264. (u_int32_t)ntpTimestamp);
  265. #endif
  266. // check if RTCP SR needs to be sent
  267. rtp_send_ctrl_2(m_audioRtpSession, rtpTimestamp, ntpTimestamp, NULL);
  268. rtp_update(m_audioRtpSession);
  269. u_int32_t dataOffset = 0;
  270. u_int32_t spaceAvailable = 
  271. m_pConfig->GetIntegerValue(CONFIG_RTP_PAYLOAD_SIZE)
  272. - (m_audioPayloadBytesPerPacket + m_audioPayloadBytesPerFrame);
  273. bool firstPacket = true;
  274. u_int8_t payloadHeader[4];
  275. struct iovec iov[2];
  276. iov[0].iov_base = &payloadHeader;
  277. iov[0].iov_len = 4;
  278. if (pFrame->GetType() == CMediaFrame::Mp3AudioFrame) {
  279. payloadHeader[0] = 0;
  280. payloadHeader[1] = 0;
  281. do {
  282. // update MP3 payload header
  283. payloadHeader[2] = (dataOffset >> 8);
  284. payloadHeader[3] = (dataOffset & 0xFF);
  285. iov[1].iov_base = (u_int8_t*)pFrame->GetData() + dataOffset;
  286. // figure out how much data we're sending
  287. u_int32_t dataPending = pFrame->GetDataLength() - dataOffset;
  288. iov[1].iov_len = MIN(dataPending, spaceAvailable); 
  289. // send packet
  290. rtp_send_data_iov(
  291. m_audioRtpSession,
  292. rtpTimestamp,
  293. m_audioPayloadNumber, firstPacket, 0, NULL,
  294. iov, 2,
  295. NULL, 0, 0);
  296. dataOffset += iov[1].iov_len;
  297. firstPacket = false;
  298. } while (dataOffset < pFrame->GetDataLength());
  299. } else { // AAC
  300. bool lastPacket = false;
  301. payloadHeader[0] = 0;
  302. payloadHeader[1] = 16;
  303. payloadHeader[2] = pFrame->GetDataLength() >> 5;
  304. payloadHeader[3] = (pFrame->GetDataLength() & 0x1F) << 3;
  305. do {
  306. iov[1].iov_base = (u_int8_t*)pFrame->GetData() + dataOffset;
  307. // figure out how much data we're sending
  308. u_int32_t dataPending = pFrame->GetDataLength() - dataOffset;
  309. if (dataPending <= spaceAvailable) {
  310. iov[1].iov_len = dataPending;
  311. lastPacket = true;
  312. } else {
  313. iov[1].iov_len = spaceAvailable;
  314. }
  315. // send packet
  316. if (firstPacket) {
  317. rtp_send_data_iov(
  318. m_audioRtpSession,
  319. rtpTimestamp,
  320. m_audioPayloadNumber, false, 0, NULL,
  321. &iov[0], 2,
  322. NULL, 0, 0);
  323. firstPacket = false;
  324. spaceAvailable += 
  325. m_audioPayloadBytesPerPacket 
  326. + m_audioPayloadBytesPerFrame;
  327. } else {
  328. rtp_send_data_iov(
  329. m_audioRtpSession,
  330. rtpTimestamp,
  331. m_audioPayloadNumber, lastPacket, 0, NULL,
  332. &iov[1], 1,
  333. NULL, 0, 0);
  334. }
  335. dataOffset += iov[1].iov_len;
  336. } while (dataOffset < pFrame->GetDataLength());
  337. }
  338. delete pFrame;
  339. }
  340. void CRtpTransmitter::SendMpeg4VideoWith3016(CMediaFrame* pFrame)
  341. {
  342. u_int32_t rtpTimestamp =
  343. VideoTimestampToRtp(pFrame->GetTimestamp());
  344. u_int64_t ntpTimestamp =
  345. TimestampToNtp(pFrame->GetTimestamp());
  346. #if RTP_DEBUG
  347. debug_message("V ts %llu rtp %u ntp %u.%u",
  348. pFrame->GetTimestamp(),
  349. rtpTimestamp,
  350. (u_int32_t)(ntpTimestamp >> 32),
  351. (u_int32_t)ntpTimestamp);
  352. #endif
  353. // check if RTCP SR needs to be sent
  354. rtp_send_ctrl_2(m_videoRtpSession, rtpTimestamp, ntpTimestamp, NULL);
  355. rtp_update(m_videoRtpSession);
  356. u_int8_t* pData = (u_int8_t*)pFrame->GetData();
  357. u_int32_t bytesToSend = pFrame->GetDataLength();
  358. struct iovec iov;
  359. while (bytesToSend) {
  360. u_int32_t payloadLength;
  361. bool lastPacket;
  362. if (bytesToSend 
  363.   <= m_pConfig->GetIntegerValue(CONFIG_RTP_PAYLOAD_SIZE)) {
  364. payloadLength = bytesToSend;
  365. lastPacket = true;
  366. } else {
  367. payloadLength = 
  368. m_pConfig->GetIntegerValue(CONFIG_RTP_PAYLOAD_SIZE);
  369. lastPacket = false;
  370. }
  371. iov.iov_base = pData;
  372. iov.iov_len = payloadLength;
  373. rtp_send_data_iov(
  374. m_videoRtpSession,
  375. rtpTimestamp,
  376. m_videoPayloadNumber, lastPacket, 0, NULL,
  377. &iov, 1,
  378.   NULL, 0, 0);
  379. pData += payloadLength;
  380. bytesToSend -= payloadLength;
  381. }
  382. delete pFrame;
  383. }