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

流媒体/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. 2002.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  *              Bill May        wmay@cisco.com
  20.  */
  21. /*
  22.  * rfc3119_bytestream.cpp - an implemention of rfc 3119
  23.  */
  24. #include "systems.h"
  25. #include <rtp/rtp.h>
  26. #include <rtp/memory.h>
  27. #include <sdp/sdp.h> // for NTP_TO_UNIX_TIME
  28. #include "rfc3119_bytestream.h"
  29. #include <mp3util/MP3Internals.hh>
  30. //#define DEBUG_3119 1
  31. //#define DEBUG_3119_INTERLEAVE 1
  32. #ifdef _WIN32
  33. DEFINE_MESSAGE_MACRO(mpa_message, "mparobust")
  34. #else
  35. #define mpa_message(loglevel, fmt...) message(loglevel, "mparobust", fmt)
  36. #endif
  37. CRfc3119RtpByteStream::CRfc3119RtpByteStream (unsigned int rtp_pt,
  38.       format_list_t *fmt,
  39.       int ondemand,
  40.       uint64_t tps,
  41.       rtp_packet **head, 
  42.       rtp_packet **tail,
  43.       int rtp_seq_set,
  44.       uint16_t rtp_base_seq,
  45.       int rtp_ts_set,
  46.       uint32_t rtp_base_ts,
  47.       int rtcp_received,
  48.       uint32_t ntp_frac,
  49.       uint32_t ntp_sec,
  50.       uint32_t rtp_ts) :
  51.   CRtpByteStreamBase("mparobust", fmt, rtp_pt, ondemand, tps, head, tail, 
  52.      rtp_seq_set, rtp_base_seq, rtp_ts_set, rtp_base_ts,
  53.      rtcp_received, ntp_frac, ntp_sec, rtp_ts)
  54. {
  55. #ifdef ISMA_RTP_DUMP_OUTPUT_TO_FILE
  56.   m_outfile = fopen("isma.aac", "w");
  57. #endif
  58.   m_adu_data_free = NULL;
  59.   m_deinterleave_list = NULL;
  60.   m_ordered_adu_list = NULL;
  61.   m_pending_adu_list = NULL;
  62.   adu_data_t *p;
  63.   for (int ix = 0; ix < 25; ix++) {
  64.     p = MALLOC_STRUCTURE(adu_data_t);
  65.     p->next_adu = m_adu_data_free;
  66.     m_adu_data_free = p;
  67.   }
  68.   m_rtp_ts_add = 0;
  69.   m_recvd_first_pak = 0;
  70.   m_got_next_idx = 0;
  71.   m_mp3_frame = NULL;
  72.   m_mp3_frame_size = 0;
  73. }
  74. CRfc3119RtpByteStream::~CRfc3119RtpByteStream (void)
  75. {
  76. #ifdef ISMA_RTP_DUMP_OUTPUT_TO_FILE
  77.   fclose(m_outfile);
  78. #endif
  79.   adu_data_t *p;
  80. #if 0
  81.   if (m_frag_reass_buffer != NULL) {
  82.     free(m_frag_reass_buffer);
  83.     m_frag_reass_buffer = NULL;
  84.   }
  85. #endif
  86.   dump_adu_list(m_deinterleave_list);
  87.   m_deinterleave_list = NULL;
  88.   dump_adu_list(m_ordered_adu_list);
  89.   m_ordered_adu_list = NULL;
  90.   dump_adu_list(m_pending_adu_list);
  91.   m_pending_adu_list = NULL;
  92.   while (m_adu_data_free != NULL) {
  93.     p = m_adu_data_free;
  94.     m_adu_data_free = p->next_adu;
  95.     free(p);
  96.   }
  97. }
  98. void CRfc3119RtpByteStream::insert_interleave_adu (adu_data_t *adu)
  99. {
  100.   adu_data_t *p, *q;
  101. #ifdef DEBUG_3119_INTERLEAVE
  102.   mpa_message(LOG_DEBUG, "inserting interleave %d %d %d", adu->aduDataSize,
  103.       adu->cyc_ct, adu->interleave_idx);
  104. #endif
  105.   SDL_LockMutex(m_rtp_packet_mutex);
  106.   
  107.   if (m_deinterleave_list == NULL) {
  108.     m_got_next_idx = 0;
  109.     m_deinterleave_list = adu;
  110.   } else {
  111.     q = NULL;
  112.     p = m_deinterleave_list;
  113.     if (adu->cyc_ct != p->cyc_ct) {
  114.       m_got_next_idx = 1;
  115.       do {
  116. q = p;
  117. p = p->next_adu;
  118.       } while (p != NULL && p->cyc_ct != adu->cyc_ct);
  119.       if (p == NULL) {
  120. q->next_adu = adu;
  121. SDL_UnlockMutex(m_rtp_packet_mutex);
  122. return;
  123.       } 
  124.     }
  125.     while (p != NULL && p->interleave_idx < adu->interleave_idx) {
  126.       q = p;
  127.       p = p->next_adu;
  128.     }
  129.     q->next_adu = adu;
  130.     adu->next_adu = p;
  131.   }
  132.   SDL_UnlockMutex(m_rtp_packet_mutex);
  133. }
  134. int CRfc3119RtpByteStream::insert_processed_adu (adu_data_t *adu)
  135. {
  136. #ifdef DEBUG_3119
  137.   mpa_message(LOG_DEBUG, "inserting processed %d", adu->aduDataSize);
  138. #endif
  139.   SDL_LockMutex(m_rtp_packet_mutex);
  140.   if (m_ordered_adu_list == NULL) {
  141.     m_ordered_adu_list = adu;
  142.   } else {
  143.     int32_t diff;
  144.     adu_data_t *p, *q;
  145.     q = NULL;
  146.     p = m_ordered_adu_list;
  147.     do {
  148.       diff = adu->timestamp - p->timestamp;
  149.       if (diff == 0) {
  150. mpa_message(LOG_ERR, "Duplicate timestamp of "LLU" found in RTP packet",
  151.     adu->timestamp);
  152. mpa_message(LOG_DEBUG, 
  153.      "Seq number orig %d new %d", 
  154.      p->pak->rtp_pak_seq, adu->pak->rtp_pak_seq); 
  155. mpa_message(LOG_ERR, "Dumping all processed packets");
  156. // put frame_data on free list
  157. if (adu->last_in_pak == 0) {
  158.   free_adu(adu);
  159. } else {
  160.   mpa_message(LOG_ERR, "Im lazy - duplicate ADU leads to memory leak");
  161. }
  162. SDL_UnlockMutex(m_rtp_packet_mutex);
  163. return -1;
  164.       } else if (diff < 0) {
  165. #ifdef DEBUG_3119
  166. mpa_message(LOG_DEBUG, "Inserting in front of ts %llu", p->timestamp);
  167. #endif
  168. if (q == NULL) {
  169.   adu->next_adu = m_ordered_adu_list;
  170.   m_ordered_adu_list = adu;
  171. } else {
  172.   q->next_adu = adu;
  173.   adu->next_adu = p;
  174. }
  175. SDL_UnlockMutex(m_rtp_packet_mutex);
  176. return 0;
  177.       }
  178.       q = p;
  179.       p = p->next_adu;
  180.     } while (p != NULL);
  181.     // insert at end;
  182.     q->next_adu = adu;
  183.   }
  184.   SDL_UnlockMutex(m_rtp_packet_mutex);
  185.   return 0;
  186. }
  187. void CRfc3119RtpByteStream::process_packet (void)
  188. {
  189.   rtp_packet *pak;
  190.   uint64_t pak_ts;
  191.   int adu_offset;
  192.   adu_data_t *prev_adu;
  193.   int thisAduSize;
  194.   do {
  195.     /*
  196.      * Take packet off list.  Loop through, looking for ADU headersize
  197.      * packets
  198.      */
  199.     pak = m_head;
  200.     if (pak != NULL) {
  201.       remove_packet_rtp_queue(m_head, 0);
  202.       pak_ts = rtp_ts_to_msec(pak->rtp_pak_ts, m_wrap_offset);
  203.       adu_offset = 0;
  204.       prev_adu = NULL;
  205. #ifdef DEBUG_3119
  206.       mpa_message(LOG_DEBUG, "Process pak seq %d", pak->rtp_pak_seq);
  207. #endif
  208.       while (pak != NULL && adu_offset < pak->rtp_data_len) {
  209. uint8_t *ptr;
  210. ptr = (uint8_t *)(pak->rtp_data + adu_offset);
  211. if ((*ptr & 0x80) == 0x80) {
  212.   // first one has a c field of 1 - that's bad
  213.   xfree(pak);
  214.   pak = NULL;
  215.   adu_offset = 0;
  216. } else {
  217.   /*
  218.    * Get a new adu - start loading the data
  219.    */
  220.   adu_data_t *adu = get_adu_data();
  221.   adu->pak = pak;
  222.   adu->next_adu = NULL;
  223.   adu->last_in_pak = 0;
  224.   adu->freeframe = 0;
  225.   if (adu_offset == 0) {
  226.     adu->first_in_pak = 1;
  227.     adu->timestamp = pak_ts;
  228.   } else {
  229.     adu->first_in_pak = 0;
  230.   }
  231.   /*
  232.    * Read the ADU header.  It will be 1 byte or 2
  233.    */
  234.   if ((*ptr & 0x40) == 0) {
  235.     // 1 byte header
  236.     adu->frame_ptr = ptr + 1;
  237.     adu->aduDataSize = *ptr & 0x3f;
  238.     adu_offset++;
  239.   } else {
  240.     // 2 byte header
  241.     adu->aduDataSize = ((*ptr & 0x3f) << 8) + ptr[1];
  242.     adu->frame_ptr = ptr + 2;
  243.     adu_offset += 2;
  244.   }
  245.   /*
  246.    * See if we're past the end of the packet
  247.    */
  248.   thisAduSize = adu->aduDataSize;
  249.   if (adu_offset + adu->aduDataSize > pak->rtp_data_len) {
  250.     // have a fragment here...
  251.     // malloc a frame pointer, and copy the rest... 
  252.     uint16_t seq = pak->rtp_pak_seq;
  253.     uint8_t *to, *from;
  254.     to = (uint8_t *)malloc(adu->aduDataSize);
  255.     int copied = pak->rtp_data_len - adu_offset;
  256.     memcpy(to, adu->frame_ptr, copied);
  257.     if (prev_adu != NULL) {
  258.       prev_adu->last_in_pak = 1;
  259.     } else {
  260.       xfree(pak);
  261.     }
  262.     adu->frame_ptr = to;
  263.     adu->freeframe = 1;
  264.     to += copied;
  265.     while (m_head != NULL && 
  266.    m_head->rtp_pak_seq == seq + 1 && 
  267.    (*m_head->rtp_data & 0x80) == 0x80 && 
  268.    copied < adu->aduDataSize) {
  269.       uint32_t bytes;
  270.       pak = m_head;
  271.       remove_packet_rtp_queue(m_head, 0);
  272.       ptr = (uint8_t *)pak->rtp_data;
  273.       if ((*ptr & 0x40) == 0) {
  274. // 1 byte header
  275. bytes = *ptr & 0x3f;
  276. from = ptr++;
  277.       } else {
  278. // 2 byte header
  279. bytes = ((*ptr & 0x3f) << 8) + ptr[1];
  280. from = ptr + 2;
  281.       }
  282.       memcpy(to, from, bytes);
  283.       copied += bytes;
  284.       to += bytes;
  285.       seq++;
  286.       adu_offset = 0;
  287.       pak = NULL;
  288.     }
  289.     if (copied < adu->aduDataSize) {
  290.       free_adu(adu);
  291.       continue;
  292.     }
  293.   } else {
  294.     /*
  295.      * adu_offset now points past the end of this adu
  296.      */
  297.     adu_offset += adu->aduDataSize;
  298.     if (adu_offset >= pak->rtp_data_len) {
  299.       adu->last_in_pak = 1;
  300.     }
  301.   }
  302.   /*
  303.    * Calculate the interleave index and the cyc_ct count
  304.    * Fill in those values with all 1's
  305.    */
  306.   adu->interleave_idx = *adu->frame_ptr;
  307.   adu->cyc_ct = *(adu->frame_ptr + 1) >> 5;
  308.   adu->frame_ptr[0] = 0xff;
  309.   adu->frame_ptr[1] |= 0xe0;
  310.   /*
  311.    * Decode the mp3 header
  312.    */
  313.   adu->mp3hdr = MP4AV_Mp3HeaderFromBytes(adu->frame_ptr);
  314.   adu->framesize = MP4AV_Mp3GetFrameSize(adu->mp3hdr);
  315.   /*
  316.    * Headersize, sideInfoSize and aduDataSize 
  317.    */
  318.   adu->headerSize = 4;
  319.   adu->sideInfoSize = MP4AV_Mp3GetSideInfoSize(adu->mp3hdr);
  320.   adu->aduDataSize -= (adu->headerSize + adu->sideInfoSize);
  321.   /*
  322.    * Calculate the timestamp add
  323.    */
  324.   if (m_rtp_ts_add == 0) {
  325.     m_rtp_ts_add = 
  326.       ( 1000 * MP4AV_Mp3GetHdrSamplingWindow(adu->mp3hdr));
  327.     m_rtp_ts_add /= MP4AV_Mp3GetHdrSamplingRate(adu->mp3hdr);
  328.   }
  329.   // here we make a few decisions as to where the packet should
  330.   // go.
  331.   // Look at first packet.  If it's got interleave, we're interleaved
  332.   // if not, set up the timestamp, put it in the ordered_adu_list.
  333.   // (Don't set recvd_first pak).  If it's the 2nd, and not interleaved,
  334.   // leave the first, go on non-interleaved
  335.   // If the first isn't, and the 2nd is, move the first to the
  336.   // m_deinterleave_list, put the 2nd on the deinterleave list, 
  337.   // continue.
  338.   // If not the first, put on the interleaved or deinterleaved list.
  339.   int insert_interleaved = 0;
  340.   if (m_recvd_first_pak == 0) {
  341.     if (adu->interleave_idx == 0xff &&
  342. adu->cyc_ct == 0x7) {
  343.       /*
  344.        * Have an packet all 1's.  It's either the last of the
  345.        * sequence for interleave, or indicates no interleave.
  346.        * Put it on the ordered list if there's nothing there.
  347.        * If there is something on the ordered list, we're not doing
  348.        * interleaved.
  349.        */
  350.       if (m_ordered_adu_list == NULL) {
  351. insert_interleaved = 0;
  352.       } else {
  353. // this is the 2nd packet with the regular
  354. // header - we're not doing interleaved
  355. insert_interleaved = 0;
  356. m_recvd_first_pak = 1;
  357. m_have_interleave = 0;
  358.       }
  359.     } else {
  360.       /*
  361.        * Have an interleaved packet
  362.        * If there was something on the ordered list, move it to 
  363.        * the deinterleaved list
  364.        */
  365.       m_recvd_first_pak = 1;
  366.       if (m_ordered_adu_list != NULL) {
  367. m_deinterleave_list = m_ordered_adu_list;
  368. m_ordered_adu_list = NULL;
  369.       } 
  370.       m_have_interleave = 1;
  371.       insert_interleaved = 1;
  372.       mpa_message(LOG_INFO, "mpa robust format is interleaved");
  373.     }
  374.   } else {
  375.     insert_interleaved = m_have_interleave;
  376.   }
  377.   adu->backpointer =  MP4AV_Mp3GetAduOffset(adu->frame_ptr, 
  378.     thisAduSize);
  379.   if (insert_interleaved) {
  380.     insert_interleave_adu(adu);
  381.   } else {
  382.     // calculate timestamp
  383.     if (adu->first_in_pak == 0) {
  384.       adu->timestamp = prev_adu->timestamp + m_rtp_ts_add;
  385.     }
  386.     insert_processed_adu(adu);
  387.   }
  388.   prev_adu = adu;
  389. }
  390.       } 
  391.     } else if (m_have_interleave && m_deinterleave_list != NULL) {
  392.       m_got_next_idx = 1;
  393.     }
  394.     // done with packet.  If we're interleaved, move things down
  395.     // to ordered ADU list.
  396.     // continue until we've got the cycct index number. 
  397.     // For non-interleaved, skip this step
  398.     if (m_have_interleave != 0) {
  399.       if (m_got_next_idx == 1) {
  400. // okay - we received the next index - we can move everything 
  401. // from the interleaved list to the processed list.
  402. adu_data_t *p, *q;
  403. int cur_cyc_ct;
  404. int ts_index;
  405. uint64_t ts = 0;
  406. m_got_next_idx = 0;
  407. q = NULL;
  408. p = m_deinterleave_list;
  409. ts_index = -1;
  410. cur_cyc_ct = p->cyc_ct;
  411. do {
  412.   if (ts_index == -1 && p->first_in_pak) {
  413.     ts = p->timestamp;
  414.     ts_index = p->interleave_idx;
  415.   }
  416.   q = p;
  417.   p = p->next_adu;
  418. } while (p != NULL && p->cyc_ct == cur_cyc_ct);
  419. q->next_adu = NULL;
  420. m_ordered_adu_list = m_deinterleave_list;
  421. m_deinterleave_list = p;
  422. // We've figured out that at least 1 packet has a valid timestamp.
  423. // Figure out the starting timestamp, then go ahead and set the
  424. // timestamps for the rest.
  425. // make sure ts_index is not -1 here
  426.      
  427. p = m_ordered_adu_list;
  428. ts -= ((ts_index - p->interleave_idx) * m_rtp_ts_add);
  429. ts_index = p->interleave_idx;
  430. while (p != NULL) {
  431.   if (p->first_in_pak == 0) {
  432.     // calculate ts
  433.     p->timestamp = ts + (p->interleave_idx - ts_index) * m_rtp_ts_add;
  434.   } else {
  435.     ts = p->timestamp;
  436.     ts_index = p->interleave_idx;
  437.   }
  438. #ifdef DEBUG_3119_INTERLEAVE
  439.   mpa_message(LOG_DEBUG, "cyc %d index %d fip %d ts %llu %d", 
  440.       p->cyc_ct,
  441.       p->interleave_idx,
  442.       p->first_in_pak,
  443.       p->timestamp,
  444.       m_rtp_ts_add);
  445. #endif
  446.   p = p->next_adu;
  447. }
  448.       } // end moving from deinterleave to processed list
  449.     }
  450.   } while (m_head != NULL && m_ordered_adu_list == NULL);
  451. }
  452. int CRfc3119RtpByteStream::needToGetAnADU (void)
  453. {
  454.   
  455.   if (m_pending_adu_list == NULL) 
  456.     return 1;
  457.   int endOfHeadFrame;
  458.   int frameOffset = 0;
  459.   adu_data_t *p;
  460.  
  461.   p = m_pending_adu_list;
  462.   endOfHeadFrame = p->framesize - p->headerSize - p->sideInfoSize;
  463.   while (p != NULL) {
  464.     int framesize = p->framesize;
  465.     int endOfData = frameOffset - p->backpointer + p->aduDataSize;
  466.     
  467. #ifdef DEBUG_3119
  468.     mpa_message(LOG_DEBUG, "add fr %d hd %d si %d bp %d adu %d", 
  469. framesize,
  470. p->headerSize,
  471. p->sideInfoSize,
  472. p->backpointer, p->aduDataSize);
  473.     mpa_message(LOG_DEBUG, "foffset %d endOfData %d eohf %d", 
  474. frameOffset, endOfData, endOfHeadFrame);
  475. #endif
  476.     if (endOfData >= endOfHeadFrame) {
  477.       return 0;
  478.     }
  479.     frameOffset += framesize - p->headerSize - p->sideInfoSize;
  480.     p = p->next_adu;
  481.   }
  482.   return 1;
  483. }
  484. void CRfc3119RtpByteStream::add_and_insertDummyADUsIfNecessary (void)
  485. {
  486.   adu_data_t *tailADU, *prevADU;
  487.   int prevADUend;
  488.   tailADU = m_ordered_adu_list;
  489.   m_ordered_adu_list = m_ordered_adu_list->next_adu;
  490.   tailADU->next_adu = NULL;
  491.   
  492. #ifdef DEBUG_3119
  493.   mpa_message(LOG_DEBUG, "tail fr %d bp %d si %d", 
  494.       tailADU->framesize,
  495.       tailADU->backpointer, 
  496.       tailADU->sideInfoSize);
  497. #endif
  498.   SDL_LockMutex(m_rtp_packet_mutex);
  499.   prevADU = m_pending_adu_list;
  500.   while (prevADU != NULL && prevADU->next_adu != NULL) 
  501.     prevADU = prevADU->next_adu;
  502.   if (prevADU != NULL) {
  503.     prevADU->next_adu = tailADU;
  504.   } else {
  505.     m_pending_adu_list = tailADU;
  506.   }
  507.   SDL_UnlockMutex(m_rtp_packet_mutex);
  508.   while (1) {
  509.     if (m_pending_adu_list != tailADU) {
  510.       prevADUend = prevADU->framesize + 
  511. prevADU->backpointer -
  512. prevADU->headerSize -
  513. prevADU->sideInfoSize;
  514.       if (prevADU->aduDataSize > prevADUend) {
  515. prevADUend = 0;
  516.       } else {
  517. prevADUend -= prevADU->aduDataSize;
  518.       }
  519. #ifdef DEBUG_3119
  520.       mpa_message(LOG_DEBUG, "fr %d bp %d si %d", 
  521.   prevADU->framesize,
  522.   prevADU->backpointer, 
  523.   prevADU->sideInfoSize);
  524.       mpa_message(LOG_DEBUG, "prevADUend is %d, prev size %d tail bpointer %d", 
  525.   prevADUend, prevADU->aduDataSize,
  526.   tailADU->backpointer);
  527. #endif
  528.     } else {
  529.       prevADUend = 0;
  530.     }
  531.     if (tailADU->backpointer > prevADUend) {
  532.       uint64_t ts;
  533. #ifdef DEBUG_3119
  534.       mpa_message(LOG_DEBUG, "Adding tail ts is %lld", tailADU->timestamp);
  535. #endif
  536.       SDL_LockMutex(m_rtp_packet_mutex);
  537.       if (prevADU == NULL) {
  538. prevADU = get_adu_data();
  539. ts = m_pending_adu_list->timestamp - m_rtp_ts_add;
  540. prevADU->next_adu = m_pending_adu_list;
  541. m_pending_adu_list = prevADU;
  542. #ifdef DEBUG_3119
  543. mpa_message(LOG_DEBUG, "Adding zero frame front, ts %lld", ts);
  544. #endif
  545.       } else {
  546. for (adu_data_t *p = m_pending_adu_list; 
  547.      p != tailADU;
  548.      p = p->next_adu) {
  549. #ifdef DEBUG_3119
  550.   mpa_message(LOG_DEBUG, "Adjusting %lld to %lld", p->timestamp,
  551.       p->timestamp - m_rtp_ts_add);
  552. #endif
  553.   p->timestamp -= m_rtp_ts_add;
  554. }
  555. ts = tailADU->timestamp - m_rtp_ts_add;
  556. prevADU->next_adu = get_adu_data();
  557. prevADU = prevADU->next_adu;
  558. #ifdef DEBUG_3119
  559. mpa_message(LOG_DEBUG, "Adding zero frame middle %lld", ts);
  560. #endif
  561.       }
  562.       prevADU->next_adu = tailADU;
  563.       SDL_UnlockMutex(m_rtp_packet_mutex);
  564.       prevADU->pak = NULL;
  565.       prevADU->frame_ptr = 
  566. (uint8_t *)malloc(tailADU->framesize);
  567.       prevADU->aduDataSize = 0;
  568.       prevADU->timestamp = ts;
  569.       prevADU->first_in_pak = 0;
  570.       prevADU->last_in_pak = 0;
  571.       prevADU->freeframe = 1;
  572.       prevADU->headerSize = tailADU->headerSize;
  573.       prevADU->sideInfoSize = tailADU->sideInfoSize;
  574.       memcpy(prevADU->frame_ptr, 
  575.      tailADU->frame_ptr, 
  576.      prevADU->headerSize + prevADU->sideInfoSize);
  577.       ZeroOutMP3SideInfo((unsigned char *)prevADU->frame_ptr, 
  578.  tailADU->framesize,
  579.  prevADUend);
  580.       prevADU->mp3hdr = MP4AV_Mp3HeaderFromBytes(prevADU->frame_ptr);
  581.       prevADU->framesize = MP4AV_Mp3GetFrameSize(prevADU->mp3hdr);
  582.       prevADU->backpointer = MP4AV_Mp3GetAduOffset(prevADU->frame_ptr,
  583.    prevADU->framesize);
  584.     } else {
  585.       return;
  586.     }
  587.   }
  588. }
  589. uint64_t CRfc3119RtpByteStream::start_next_frame (uint8_t **buffer, 
  590.   uint32_t *buflen,
  591.   void **ud)
  592. {
  593.   adu_data_t *p;
  594.   // Free up last used...
  595.   if (m_pending_adu_list != NULL) {
  596.     SDL_LockMutex(m_rtp_packet_mutex);
  597.     p = m_pending_adu_list->next_adu;
  598.     free_adu(m_pending_adu_list);
  599.     m_pending_adu_list = p;
  600.     SDL_UnlockMutex(m_rtp_packet_mutex);
  601.   }
  602.   /*
  603.    * load up ordered_adu_list here...
  604.    */
  605.   while (m_head != NULL && m_ordered_adu_list == NULL) {
  606.     process_packet();
  607.   }
  608.   /*
  609.    * Start moving things down to the pending list.  If it's NULL, 
  610.    * and the ordered list has data that's not layer 3, just move the
  611.    * first element of the ordered list to the pending list, and use that.
  612.    */
  613.   if (m_pending_adu_list == NULL) {
  614.     if (MP4AV_Mp3GetHdrLayer(m_ordered_adu_list->mp3hdr) != 1) {
  615.       //if (m_ordered_adu_list->mp3hdr.layer != 3)
  616.       SDL_LockMutex(m_rtp_packet_mutex);
  617.       m_pending_adu_list = m_ordered_adu_list;
  618.       m_ordered_adu_list = m_ordered_adu_list->next_adu;
  619.       m_pending_adu_list->next_adu = NULL;
  620.       SDL_UnlockMutex(m_rtp_packet_mutex);
  621.       /*
  622.        * mpeg1 layer 1 or 2
  623.        * No mpa robust - adu contains complete frame
  624.        */
  625. #ifdef DEBUG_3119
  626.       mpa_message(LOG_DEBUG, "Not layer 3");
  627. #endif
  628.       *buffer = m_pending_adu_list->frame_ptr;
  629.       *buflen = m_pending_adu_list->framesize;
  630.       return m_pending_adu_list->timestamp;
  631.     }
  632.   }
  633.   /*
  634.    * Now we need to handle the mpeg1 layer 3 ADU frame to MP3
  635.    * frame conversion
  636.    */
  637.   while (needToGetAnADU()) {
  638.     if (m_ordered_adu_list == NULL) {
  639.       // failure - we need to add, and can't
  640. #ifdef DEBUG_3119
  641.       mpa_message(LOG_DEBUG, "need to get an adu and ordered list is NULL");
  642. #endif
  643.       process_packet();
  644.       if (m_ordered_adu_list == NULL) {
  645. dump_adu_list(m_pending_adu_list);
  646. m_pending_adu_list = NULL;
  647. *buffer = NULL;
  648. *buflen = 0;
  649. return 0;
  650.       }
  651.     }
  652.     add_and_insertDummyADUsIfNecessary();
  653.   }
  654.   uint32_t endOfHeadFrame;
  655.   uint32_t frameOffset = 0;
  656.   uint32_t toOffset = 0;
  657.   /*
  658.    * We should have enough on the pending list to fill up a frame
  659.    */
  660.   endOfHeadFrame = m_pending_adu_list->framesize;
  661.   if (m_mp3_frame == NULL ||
  662.       m_mp3_frame_size < endOfHeadFrame) {
  663.     m_mp3_frame_size = endOfHeadFrame * 2;
  664.     m_mp3_frame = (uint8_t *)realloc(m_mp3_frame, m_mp3_frame_size);
  665.   }
  666.   int copy;
  667.   copy = m_pending_adu_list->headerSize + m_pending_adu_list->sideInfoSize;
  668.   memcpy(m_mp3_frame, m_pending_adu_list->frame_ptr, copy);
  669.   uint8_t *start_of_data;
  670.   endOfHeadFrame -= copy;
  671.   memset(m_mp3_frame + copy, 0, endOfHeadFrame);
  672.   start_of_data = m_mp3_frame + copy;
  673.   p = m_pending_adu_list;
  674.   while (toOffset < endOfHeadFrame) {
  675.     int startOfData = frameOffset - p->backpointer;
  676.     if (startOfData > (int)endOfHeadFrame) {
  677.       break;
  678.     }
  679.     int endOfData = startOfData + p->aduDataSize;
  680.     if (endOfData > (int)endOfHeadFrame) {
  681.       endOfData = endOfHeadFrame;
  682.     }
  683.     int fromOffset;
  684.     if (startOfData <= (int)toOffset) {
  685.       fromOffset = toOffset - startOfData;
  686.       startOfData = toOffset;
  687.       if (endOfData < startOfData) {
  688. endOfData = startOfData;
  689.       }
  690.     } else {
  691.       fromOffset = 0;
  692.       toOffset = startOfData;
  693.     }
  694.     int bytesUsedHere = endOfData - startOfData;
  695.     memcpy(start_of_data + toOffset,
  696.    p->frame_ptr + p->headerSize + p->sideInfoSize + fromOffset,
  697.    bytesUsedHere);
  698.     toOffset += bytesUsedHere;
  699.     frameOffset += p->framesize - p->headerSize - p->sideInfoSize;
  700.     p = p->next_adu;
  701.   }
  702. #ifdef DEBUG_3119
  703.   mpa_message(LOG_DEBUG, "ts %llu, framesize %d", 
  704.       m_pending_adu_list->timestamp, m_pending_adu_list->framesize);
  705. #endif
  706.   *buffer = m_mp3_frame;
  707.   *buflen = m_pending_adu_list->framesize;
  708.   return (m_pending_adu_list->timestamp);
  709. }
  710. void CRfc3119RtpByteStream::used_bytes_for_frame (uint32_t bytes)
  711. {
  712.   // we don't care - we'll move to the next frame ourselves.
  713. }
  714. void CRfc3119RtpByteStream::flush_rtp_packets (void)
  715. {
  716.   SDL_LockMutex(m_rtp_packet_mutex);
  717.  
  718.   dump_adu_list(m_deinterleave_list);
  719.   m_deinterleave_list = NULL;
  720.   dump_adu_list(m_ordered_adu_list);
  721.   m_ordered_adu_list = NULL;
  722.   dump_adu_list(m_pending_adu_list);
  723.   m_pending_adu_list = NULL;
  724.   SDL_UnlockMutex(m_rtp_packet_mutex);
  725.   CRtpByteStreamBase::flush_rtp_packets();
  726. }
  727. void CRfc3119RtpByteStream::reset (void)
  728. {
  729.   CRtpByteStreamBase::reset();
  730. }
  731. int CRfc3119RtpByteStream::have_no_data (void)
  732. {
  733.   return (m_head == NULL); // || m_pending_adu_list == NULL);
  734. }
  735. void CRfc3119RtpByteStream::free_adu (adu_data_t *adu)
  736. {
  737.   if (adu->freeframe != 0) {
  738.     free(adu->frame_ptr);
  739.     adu->frame_ptr = NULL;
  740.     adu->freeframe = 0;
  741.   }
  742.   if (adu->last_in_pak != 0 &&
  743.       adu->pak != NULL) {
  744.     xfree(adu->pak);
  745.     adu->pak = NULL;
  746.   }
  747.   adu->next_adu = m_adu_data_free;
  748.   m_adu_data_free = adu;
  749. }