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

流媒体/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. 2001.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  *              Bill May        wmay@cisco.com
  20.  */
  21. #include "systems.h"
  22. #include <rtp/rtp.h>
  23. #include <rtp/memory.h>
  24. #include <sdp/sdp.h> // for NTP_TO_UNIX_TIME
  25. #include "bitstream/bitstream.h"
  26. #include "isma_rtp_bytestream.h"
  27. #include "our_config_file.h"
  28. #include <mp4util/mpeg4_audio_config.h>
  29. //#define DEBUG_ISMA_AAC
  30. #ifdef _WIN32
  31. DEFINE_MESSAGE_MACRO(isma_message, "ismartp")
  32. #else
  33. #define isma_message(loglevel, fmt...) message(loglevel, "ismartp", fmt)
  34. #endif
  35. /*
  36.  * Isma rtp bytestream has a potential set of headers at the beginning
  37.  * of each rtp frame.  This can interleave frames in different packets
  38.  */
  39. CIsmaAudioRtpByteStream::CIsmaAudioRtpByteStream (format_list_t *media_fmt,
  40.   fmtp_parse_t *fmtp,
  41.   unsigned int rtp_pt,
  42.   int ondemand,
  43.   uint64_t tps,
  44.   rtp_packet **head, 
  45.   rtp_packet **tail,
  46.   int rtp_seq_set,
  47.   uint16_t rtp_base_seq,
  48.   int rtp_ts_set,
  49.   uint32_t rtp_base_ts,
  50.   int rtcp_received,
  51.   uint32_t ntp_frac,
  52.   uint32_t ntp_sec,
  53.   uint32_t rtp_ts) :
  54.   CRtpByteStreamBase("ismaaac", media_fmt, rtp_pt, ondemand, tps, head, tail, 
  55.      rtp_seq_set, rtp_base_seq, rtp_ts_set, rtp_base_ts,
  56.      rtcp_received, ntp_frac, ntp_sec, rtp_ts)
  57. {
  58. #ifdef ISMA_RTP_DUMP_OUTPUT_TO_FILE
  59.   m_outfile = fopen("isma.aac", "w");
  60. #endif
  61.   m_frame_data_head = NULL;
  62.   m_frame_data_on = NULL;
  63.   m_frame_data_free = NULL;
  64.   isma_frame_data_t *p;
  65.   for (m_frame_data_max = 0; m_frame_data_max < 25; m_frame_data_max++) {
  66.     p = (isma_frame_data_t *)malloc(sizeof(isma_frame_data_t));
  67.     p->frame_data_next = m_frame_data_free;
  68.     m_frame_data_free = p;
  69.   }
  70.   mpeg4_audio_config_t audio_config;
  71.   decode_mpeg4_audio_config(fmtp->config_binary,
  72.     fmtp->config_binary_len,
  73.     &audio_config);
  74.   if (audio_object_type_is_aac(&audio_config)) {
  75.     m_rtp_ts_add = audio_config.codec.aac.frame_len_1024 != 0 ? 1024 : 960;
  76.   } else {
  77.     m_rtp_ts_add = audio_config.codec.celp.samples_per_frame;
  78.     isma_message(LOG_DEBUG, "celp spf is %d", m_rtp_ts_add);
  79.   }
  80.   m_rtp_ts_add = (m_rtp_ts_add * media_fmt->rtpmap->clock_rate) /
  81.     audio_config.frequency;
  82.   isma_message(LOG_DEBUG, 
  83.        "Rtp ts add is %d (%d %d)", m_rtp_ts_add,
  84.        media_fmt->rtpmap->clock_rate, 
  85.        audio_config.frequency);
  86.   m_fmtp = *fmtp;
  87.   m_min_first_header_bits = m_fmtp.size_length + m_fmtp.index_length;
  88.   m_min_header_bits = m_fmtp.size_length + m_fmtp.index_delta_length;
  89.   if (m_fmtp.CTS_delta_length > 0) {
  90.     m_min_header_bits++;
  91.     m_min_first_header_bits++;
  92.   }
  93.   if (m_fmtp.DTS_delta_length > 0) {
  94.     m_min_header_bits++;
  95.     m_min_first_header_bits++;
  96.   }
  97.   isma_message(LOG_DEBUG, "min headers are %d %d", m_min_first_header_bits,
  98.        m_min_header_bits);
  99.   m_min_header_bits += m_fmtp.auxiliary_data_size_length;
  100.   m_min_first_header_bits += m_fmtp.auxiliary_data_size_length;
  101.   m_frag_reass_buffer = NULL;
  102.   m_frag_reass_size_max = 0;
  103. }
  104. CIsmaAudioRtpByteStream::~CIsmaAudioRtpByteStream (void)
  105. {
  106. #ifdef ISMA_RTP_DUMP_OUTPUT_TO_FILE
  107.   fclose(m_outfile);
  108. #endif
  109.   isma_frame_data_t *p;
  110.   
  111.   if (m_frag_reass_buffer != NULL) {
  112.     free(m_frag_reass_buffer);
  113.     m_frag_reass_buffer = NULL;
  114.   }
  115.   if (m_frame_data_on != NULL) {
  116.     m_frame_data_on->frame_data_next = m_frame_data_head;
  117.     m_frame_data_head = m_frame_data_on;
  118.     m_frame_data_on = NULL;
  119.   }
  120.   while (m_frame_data_free != NULL) {
  121.     p = m_frame_data_free;
  122.     m_frame_data_free = p->frame_data_next;
  123.     free(p);
  124.   }
  125.   while (m_frame_data_head != NULL) {
  126.     p = m_frame_data_head;
  127.     // if fragmented frame, free all frag_data
  128.     if (p->is_fragment == 1) {
  129.       isma_frag_data_t * q = p->frag_data;
  130.       while (q != NULL) {
  131. p->frag_data = q->frag_data_next;
  132. free(q);
  133. q = p->frag_data;
  134.       }
  135.     }
  136.     m_frame_data_head = p->frame_data_next;
  137.     free(p);
  138.   }
  139. }
  140. int CIsmaAudioRtpByteStream::insert_frame_data (isma_frame_data_t *frame_data)
  141. {
  142.   SDL_LockMutex(m_rtp_packet_mutex);
  143.   if (m_frame_data_head == NULL) {
  144.     m_frame_data_head = frame_data;
  145.   } else {
  146.     int32_t diff;
  147.     isma_frame_data_t *p, *q;
  148.     q = NULL;
  149.     p = m_frame_data_head;
  150.     do {
  151.       diff = frame_data->rtp_timestamp - p->rtp_timestamp;
  152.       if (diff == 0) {
  153. isma_message(LOG_ERR, "Duplicate timestamp of %x found in RTP packet",
  154.      frame_data->rtp_timestamp);
  155. isma_message(LOG_DEBUG, 
  156.      "Seq number orig %d new %d", 
  157.      p->pak->rtp_pak_seq, frame_data->pak->rtp_pak_seq); 
  158. // if fragmented frame, free all frag_data
  159. if (frame_data->is_fragment == 1) {
  160.   isma_frag_data_t * p = NULL;
  161.   while ((p = frame_data->frag_data) != NULL) {
  162.     frame_data->frag_data = p->frag_data_next;
  163.     free(p);
  164.   }
  165. }
  166. // put frame_data on free list
  167. frame_data->frame_data_next = m_frame_data_free;
  168. m_frame_data_free = frame_data;
  169. SDL_UnlockMutex(m_rtp_packet_mutex);
  170. return 1;
  171.       } else if (diff < 0) {
  172. if (q == NULL) {
  173.   frame_data->frame_data_next = m_frame_data_head;
  174.   m_frame_data_head = frame_data;
  175. } else {
  176.   q->frame_data_next = frame_data;
  177.   frame_data->frame_data_next = p;
  178. }
  179. SDL_UnlockMutex(m_rtp_packet_mutex);
  180. return 0;
  181.       }
  182.       q = p;
  183.       p = p->frame_data_next;
  184.     } while (p != NULL);
  185.     // insert at end;
  186.     q->frame_data_next = frame_data;
  187.   }
  188.   SDL_UnlockMutex(m_rtp_packet_mutex);
  189.   return 0;
  190. }
  191. void CIsmaAudioRtpByteStream::get_au_header_bits (void)
  192. {
  193.   uint32_t temp;
  194.   if (m_fmtp.CTS_delta_length > 0) {
  195.     m_header_bitstream.getbits(1, &temp);
  196.     if (temp > 0) {
  197.       m_header_bitstream.getbits(m_fmtp.CTS_delta_length, &temp);
  198.     }
  199.   }
  200.   if (m_fmtp.DTS_delta_length > 0) {
  201.     m_header_bitstream.getbits(1, &temp);
  202.     if (temp > 0) {
  203.       m_header_bitstream.getbits(m_fmtp.DTS_delta_length, &temp);
  204.     }
  205.   }
  206. }
  207. // check where need to lock 
  208. void CIsmaAudioRtpByteStream::cleanup_frag (isma_frame_data_t * frame_data)
  209. {
  210.   // free all frag_data for this frame
  211.   isma_frag_data_t * p = NULL;
  212.   while ((p = frame_data->frag_data) != NULL) {
  213.     frame_data->frag_data = p->frag_data_next;
  214.     free(p);
  215.   } 
  216.   // now put frame_data back on free list
  217.   SDL_LockMutex(m_rtp_packet_mutex);
  218.   frame_data->frame_data_next = m_frame_data_free;
  219.   m_frame_data_free = frame_data;
  220.   SDL_UnlockMutex(m_rtp_packet_mutex);
  221.   return;
  222. }
  223. // Frame is fragmented.
  224. // Process next RTP paks until have the entire frame.
  225. // Paks will be in order in the queue, but maybe some missing?
  226. // So if process pkt w/ Mbit set (last of fragm) and total < frameLength
  227. // ignore pkt.
  228. // Insert frame data only after got all fragments for the frame.
  229. int CIsmaAudioRtpByteStream::process_fragment (rtp_packet *pak, 
  230.        isma_frame_data_t *frame_data)
  231. {
  232.   uint16_t seq = pak->rtp_pak_seq; 
  233.   uint32_t ts = pak->rtp_pak_ts;
  234.   isma_frag_data_t *cur = NULL;
  235.   int read_mBit = 0;
  236.   uint32_t total_len = 0; 
  237.   frame_data->is_fragment = 1;
  238.   do {
  239.     if (read_mBit == 1) {
  240.       // get rid of frame_data - last frag seen but total length wrong
  241.       cleanup_frag(frame_data);
  242.       isma_message(LOG_ERR, "Error processing frag: early mBit");
  243.       return (1); 
  244.     }
  245.     if (pak == NULL) {
  246.       cleanup_frag(frame_data);
  247.       isma_message(LOG_ERR, "Error processing frag: not enough packets");
  248.       return (1);
  249.     }
  250.     // check if ts and rtp seq numbers are ok, and lengths match
  251.     if (ts != pak->rtp_pak_ts) {
  252.       cleanup_frag(frame_data);
  253.       isma_message(LOG_ERR, 
  254.    "Error processing frag: wrong ts: ts= %x, pak->ts = %x", 
  255.    ts, pak->rtp_pak_ts);
  256.       return (1);
  257.     }
  258.     if (seq != pak->rtp_pak_seq) {
  259.       cleanup_frag(frame_data);
  260.       isma_message(LOG_ERR, "Error processing frag: wrong seq num");
  261.       return (1);
  262.     }
  263.     // insert fragment info
  264.     isma_frag_data_t *p = (isma_frag_data_t *)
  265.       malloc(sizeof(isma_frag_data_t));
  266.     if (p == NULL) {
  267.       isma_message(LOG_ERR, "Error processing frag: can't malloc");
  268.       remove_packet_rtp_queue(pak, 0);
  269.       return (1);
  270.     }
  271.     if (cur == NULL) {
  272.       frame_data->frag_data = p;
  273.       cur = p;
  274.     } else {
  275.       cur->frag_data_next = p;
  276.       cur = p;
  277.     }
  278.     cur->frag_data_next = NULL;
  279.     cur->pak = pak; 
  280.     // length in bits
  281.     uint16_t header_len = ntohs(*(unsigned short *)pak->rtp_data);
  282.     m_header_bitstream.init(&pak->rtp_data[sizeof(uint16_t)], header_len);
  283.     // frag_ptr should just point to beginning of data in pkt
  284.     uint32_t header_len_bytes = ((header_len + 7) / 8) + sizeof(uint16_t);
  285.     cur->frag_ptr =  &pak->rtp_data[header_len_bytes];
  286.     cur->frag_len = pak->rtp_data_len - header_len_bytes;
  287.     // if aux data, move frag pointer
  288.     if (m_fmtp.auxiliary_data_size_length > 0) {
  289.       m_header_bitstream.byte_align();
  290.       uint32_t aux_len;
  291.       m_header_bitstream.getbits(m_fmtp.auxiliary_data_size_length, &aux_len);
  292.       aux_len = (aux_len + 7) / 8;
  293.       cur->frag_ptr += aux_len;
  294.       cur->frag_len -= aux_len;
  295.     }
  296.     total_len += cur->frag_len;
  297. #ifdef DEBUG_ISMA_RTP_FRAGS
  298.     isma_message(LOG_DEBUG, 
  299.  "rtp seq# %d, fraglen: %d, ts: %x", 
  300.  pak->seq, cur->frag_len, pak->ts);
  301. #endif
  302.     seq = pak->rtp_pak_seq + 1;
  303.     if (pak->rtp_pak_m) 
  304.       read_mBit = 1;
  305.     remove_packet_rtp_queue(pak, 0);
  306.     pak = m_head; // get next pkt in the queue
  307.   } while (total_len < frame_data->frame_len);
  308.   // insert frame and return
  309.   int error = insert_frame_data(frame_data);
  310.   frame_data->last_in_pak = 1; // only one frame in pak
  311.   // no need to remove pkt from queue, done at the end of do-while
  312.   return (error);
  313. }
  314. void CIsmaAudioRtpByteStream::process_packet_header (void)
  315. {
  316.   rtp_packet *pak;
  317.   uint32_t frame_len;
  318.   uint16_t header_len;
  319.   uint32_t retvalue;
  320.   pak = m_head;
  321.   if (pak == NULL) {
  322.     return;
  323.   }
  324. #ifdef DEBUG_ISMA_AAC
  325.   isma_message(LOG_DEBUG, 
  326.        "processing pak seq %d ts %x len %d", 
  327.        pak->rtp_pak_seq, pak->rtp_pak_ts, pak->rtp_data_len);
  328. #endif
  329.   // This pak has not had it's header processed
  330.   // length in bytes
  331.   if (pak->rtp_data_len == 0) {
  332.     remove_packet_rtp_queue(pak, 1);
  333.     isma_message(LOG_ERR, "RTP audio packet with data length of 0");
  334.     return;
  335.   }
  336.   header_len = ntohs(*(unsigned short *)pak->rtp_data);
  337.   if (header_len < m_min_first_header_bits) {
  338.     // bye bye, frame...
  339.     remove_packet_rtp_queue(pak, 1);
  340.     isma_message(LOG_ERR, "ISMA rtp - header len %d less than min %d", 
  341.  header_len, m_min_first_header_bits);
  342.     return;
  343.   }
  344.   m_header_bitstream.init(&pak->rtp_data[sizeof(uint16_t)],
  345.   header_len);
  346.   if (m_header_bitstream.getbits(m_fmtp.size_length, &frame_len) != 0) 
  347.     return;
  348.   m_header_bitstream.getbits(m_fmtp.index_length, &retvalue);
  349.   get_au_header_bits();
  350. #ifdef DEBUG_ISMA_AAC
  351.   uint64_t wrap_offset = m_wrap_offset;
  352.   uint64_t msec = rtp_ts_to_msec(pak->rtp_pak_ts, wrap_offset);
  353.   isma_message(LOG_DEBUG, 
  354.        "1st - header len %u frame len %u ts %x %llu", 
  355.        header_len, frame_len, pak->rtp_pak_ts, msec);
  356. #endif
  357.   if (frame_len == 0) {
  358.     remove_packet_rtp_queue(pak, 1);
  359.     return;
  360.   }
  361.   uint8_t *frame_ptr;
  362.   isma_frame_data_t *frame_data;
  363.   uint32_t ts;
  364.   ts = pak->rtp_pak_ts;
  365.   frame_data = get_frame_data();
  366.   frame_data->pak = pak;
  367.   // frame pointer is after header_len + header_len size.  Header_len
  368.   // is in bits - add 7, divide by 8 to get padding correctly.
  369.   frame_data->frame_ptr = &pak->rtp_data[((header_len + 7) / 8) 
  370.     + sizeof(uint16_t)];
  371.   frame_data->frame_len = frame_len;
  372.   frame_data->rtp_timestamp = ts;
  373.   // Check if frame is fragmented
  374.   // frame_len plus the length of the 2 headers
  375.   int frag_check = frame_len + sizeof(uint16_t);
  376.   frag_check += m_fmtp.size_length / 8;
  377.   if ((m_fmtp.size_length % 8) != 0) frag_check++;
  378.   if (frag_check > pak->rtp_data_len) {
  379. #ifdef DEBUG_ISMA_AAC
  380.     isma_message(LOG_DEBUG, "Frame is fragmented");
  381. #endif
  382.     frame_data->is_fragment = 1;
  383.     int err = process_fragment(pak, frame_data);
  384.     if (err == 1)
  385.       isma_message(LOG_ERR, "Error in processing the fragment");
  386.     return; 
  387.   }
  388.   else {
  389. #ifdef DEBUG_ISMA_AAC
  390.     isma_message(LOG_DEBUG, "Frame is not fragmented");
  391. #endif
  392.     frame_data->is_fragment = 0;
  393.     frame_data->frag_data = NULL;
  394.   }
  395.   int error = insert_frame_data(frame_data);
  396.   frame_ptr = frame_data->frame_ptr + frame_data->frame_len;
  397.   while (m_header_bitstream.bits_remain() >= m_min_header_bits) {
  398.     uint32_t stride;
  399.     m_header_bitstream.getbits(m_fmtp.size_length, &frame_len);
  400.     m_header_bitstream.getbits(m_fmtp.index_delta_length, &stride);
  401.     get_au_header_bits();
  402.     ts += (m_rtp_ts_add * (1 + stride));
  403. #ifdef DEBUG_ISMA_AAC
  404.     wrap_offset = m_wrap_offset;
  405.     msec = rtp_ts_to_msec(ts, wrap_offset);
  406.     isma_message(LOG_DEBUG, 
  407.  "Stride %d len %d ts %x %llu", 
  408.  stride, frame_len, ts, msec);
  409. #endif
  410.     frame_data = get_frame_data();
  411.     frame_data->pak = pak;
  412.     frame_data->is_fragment = 0;
  413.     frame_data->frag_data = NULL;
  414.     frame_data->frame_ptr = frame_ptr;
  415.     frame_data->frame_len = frame_len;
  416.     frame_ptr += frame_len;
  417.     frame_data->rtp_timestamp = ts;
  418.     error |= insert_frame_data(frame_data);
  419.   }
  420.   if (error == 0 && frame_data != NULL) { 
  421.     frame_data->last_in_pak = 1;
  422.   }
  423.   else {
  424.     isma_frame_data_t *p, *last = NULL;
  425.     p = m_frame_data_head;
  426.     while (p != NULL) {
  427.       if (p->pak == pak) last = p;
  428.       p = p->frame_data_next;
  429.     }
  430.     if (last != NULL) {
  431.       last->last_in_pak = 1;
  432.       isma_message(LOG_WARNING, "error at end - marked ts %x", last->rtp_timestamp);
  433.     } else {
  434.       // Didn't find pak in list.  Weird
  435.       isma_message(LOG_ERR, 
  436.    "Decoded packet with RTP timestamp %x and didn't"
  437.    "see any good frames", pak->rtp_pak_ts);
  438.       remove_packet_rtp_queue(pak, 1);
  439.       return;
  440.     }
  441.   }
  442.   if (m_fmtp.auxiliary_data_size_length > 0) {
  443.     m_header_bitstream.byte_align();
  444.     uint32_t aux_len;
  445.     m_header_bitstream.getbits(m_fmtp.auxiliary_data_size_length, &aux_len);
  446.     aux_len = (aux_len + 7) / 8;
  447. #ifdef DEBUG_ISMA_AAC
  448.     isma_message(LOG_DEBUG, "Adding %d bytes for aux data size", aux_len);
  449. #endif
  450.     isma_frame_data_t *p;
  451.     p = m_frame_data_head;
  452.     while (p != NULL) {
  453.       if (p->pak == pak) {
  454. p->frame_ptr += aux_len;
  455.       }
  456.       p = p->frame_data_next;
  457.     }
  458.   }
  459.     
  460.   remove_packet_rtp_queue(pak, 0);
  461. }
  462. uint64_t CIsmaAudioRtpByteStream::start_next_frame (uint8_t **buffer, 
  463.     uint32_t *buflen,
  464.     void **userdata)
  465. {
  466.   uint64_t timetick;
  467.   if (m_frame_data_on != NULL) {
  468.     uint32_t next_ts;
  469. #ifdef DEBUG_ISMA_AAC
  470.     isma_message(LOG_DEBUG, "Advancing to next pak data - old ts %x", 
  471.  m_frame_data_on->rtp_timestamp);
  472. #endif
  473.     if (m_frame_data_on->last_in_pak != 0) {
  474.       // We're done with all the data in this packet - get rid
  475.       // of the rtp packet.
  476.       if (m_frame_data_on->is_fragment == 1) {
  477. // if fragmented, need to get rid of all paks pointed to
  478. isma_frag_data_t *q =  m_frame_data_on->frag_data;
  479. while (q != NULL) {
  480.   rtp_packet *pak = q->pak;
  481.   q->pak = NULL;
  482.   if (pak != NULL)
  483.     xfree(pak);
  484.   q = q->frag_data_next;
  485. #ifdef DEBUG_ISMA_AAC
  486.   isma_message(LOG_DEBUG, "removing pak - frag %d", pak->rtp_pak_seq);
  487. #endif
  488. }
  489.       } else {
  490. rtp_packet *pak = m_frame_data_on->pak;
  491. m_frame_data_on->pak = NULL;
  492. xfree(pak);
  493. #ifdef DEBUG_ISMA_AAC
  494. isma_message(LOG_DEBUG, "removing pak %d", pak->rtp_pak_seq);
  495. #endif
  496.       }
  497.     }
  498.     /*
  499.      * Remove the frame data head pointer, and put it on the free list
  500.      */
  501.     isma_frame_data_t *p = NULL;
  502.     SDL_LockMutex(m_rtp_packet_mutex);
  503.     p = m_frame_data_on;
  504.     m_frame_data_on = NULL;
  505.     next_ts = p->rtp_timestamp;
  506.     p->frame_data_next = m_frame_data_free;
  507.     m_frame_data_free = p;
  508.     // free all frag_data for this frame
  509.     if (p->is_fragment == 1) {
  510.       isma_frag_data_t * q = p->frag_data;
  511.       while (q != NULL) {
  512. p->frag_data = q->frag_data_next;
  513. free(q);
  514. q = p->frag_data;
  515.       } 
  516.     }
  517.     SDL_UnlockMutex(m_rtp_packet_mutex);
  518.     /* 
  519.      * Now, look for the next timestamp - process a bunch of new
  520.      * rtp packets, if we have to...
  521.      */
  522.     next_ts += m_rtp_ts_add;
  523.     if (m_frame_data_head == NULL ||
  524. m_frame_data_head->rtp_timestamp != next_ts) {
  525.       // process next pak in list.  Process until next timestamp is found, 
  526.       // or 500 msec worth of data is found (in which case, go with first)
  527.       do {
  528. process_packet_header();
  529.       } while (m_head != NULL && 
  530.        ((m_frame_data_head == NULL) || 
  531. (m_frame_data_head->rtp_timestamp != next_ts)) &&  
  532.        (m_frame_data_free != NULL));
  533.     }
  534. #ifdef DEBUG_ISMA_AAC
  535.     else {
  536.       // m_frame_data_head is correct
  537.       isma_message(LOG_DEBUG, "frame_data_head is correct");
  538.     }
  539. #endif
  540.   } else {
  541.     // first time.  Process a bunch of packets, go with first one...
  542.     // asdf - will want to eventually add code to drop the first couple
  543.     // of packets if they're not consecutive.
  544.     do {
  545.       process_packet_header();
  546.     } while (m_frame_data_free != NULL);
  547.   }
  548.   /*
  549.    * Init up the offsets
  550.    */
  551.   if (m_frame_data_head != NULL) {
  552.     SDL_LockMutex(m_rtp_packet_mutex);
  553.     m_frame_data_on = m_frame_data_head;
  554.     m_frame_data_head = m_frame_data_head->frame_data_next;
  555.     SDL_UnlockMutex(m_rtp_packet_mutex);
  556.     if (m_frame_data_on->is_fragment == 1) {   
  557.       m_frag_reass_size = 0;
  558.       isma_frag_data_t *ptr;
  559.       ptr = m_frame_data_on->frag_data;
  560.       while (ptr != NULL) {
  561. if (m_frag_reass_size + ptr->frag_len > m_frag_reass_size_max) {
  562.   m_frag_reass_size_max += max(4096, ptr->frag_len);
  563.   m_frag_reass_buffer = (uint8_t *)realloc(m_frag_reass_buffer, 
  564.  m_frag_reass_size_max);
  565. }
  566. memmove(m_frag_reass_buffer + m_frag_reass_size, 
  567. ptr->frag_ptr,
  568. ptr->frag_len);
  569. m_frag_reass_size += ptr->frag_len;
  570. ptr = ptr->frag_data_next;
  571.       }
  572.       *buffer = m_frag_reass_buffer;
  573.       *buflen = m_frag_reass_size;
  574.     } else { 
  575.       *buffer = m_frame_data_on->frame_ptr;
  576.       *buflen = m_frame_data_on->frame_len;
  577.     }
  578.   } else {
  579.     *buffer = NULL;
  580.   }
  581. #ifdef ISMA_RTP_DUMP_OUTPUT_TO_FILE
  582.   if (*buffer != NULL) {
  583.     fwrite(*buffer, *buflen,  1, m_outfile);
  584.   }
  585. #endif
  586.   timetick = rtp_ts_to_msec(m_frame_data_on != NULL ? 
  587.     m_frame_data_on->rtp_timestamp : m_ts, 
  588.     m_wrap_offset);
  589.   if (m_frame_data_on != NULL)
  590.     m_ts =  m_frame_data_on->rtp_timestamp;
  591.   // We're going to have to handle wrap better...
  592. #ifdef DEBUG_ISMA_AAC
  593.   isma_message(LOG_DEBUG, "start next frame %p %d ts %x "LLU, 
  594.        *buffer, *buflen, m_ts, timetick);
  595. #endif
  596.   return (timetick);
  597. }
  598. void CIsmaAudioRtpByteStream::used_bytes_for_frame (uint32_t bytes)
  599. {
  600. }
  601. void CIsmaAudioRtpByteStream::flush_rtp_packets (void)
  602. {
  603.   isma_frame_data_t *p;
  604.   SDL_LockMutex(m_rtp_packet_mutex);
  605.   if (m_frame_data_on != NULL) {
  606.     m_frame_data_on->frame_data_next = m_frame_data_head;
  607.     m_frame_data_head = m_frame_data_on;
  608.     m_frame_data_on = NULL;
  609.   }
  610.   if (m_frame_data_head != NULL) {
  611.     p = m_frame_data_head;
  612.     while (p->frame_data_next != NULL) {
  613. #ifdef DEBUG_ISMA_AAC
  614.       isma_message(LOG_DEBUG, "reset removing pak %d", p->pak->rtp_pak_seq);
  615. #endif
  616.       if (p->last_in_pak != 0) {
  617. if (p->is_fragment == 1) {
  618.   // get rid of frag data 
  619.   isma_frag_data_t * q = NULL;
  620.   while ((q = p->frag_data) != NULL) {
  621.     p->frag_data = q->frag_data_next;
  622.     free(q);
  623.   } 
  624. }
  625. xfree(p->pak);
  626.       }
  627.       p = p->frame_data_next;
  628.     }
  629.     p->frame_data_next = m_frame_data_free;
  630.     m_frame_data_free = m_frame_data_head;
  631.     m_frame_data_head = NULL;
  632.   }
  633.   SDL_UnlockMutex(m_rtp_packet_mutex);
  634.   CRtpByteStreamBase::flush_rtp_packets();
  635. }
  636. void CIsmaAudioRtpByteStream::reset (void)
  637. {
  638.   isma_message(LOG_INFO, "Hit isma rtp reset");
  639.   CRtpByteStreamBase::reset();
  640. }
  641. int CIsmaAudioRtpByteStream::have_no_data (void)
  642. {
  643.   return (m_head == NULL && m_frame_data_head == NULL);
  644. }