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

流媒体/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.  *              Bill May        wmay@cisco.com
  20.  */
  21. /*
  22.  * media_utils.cpp - various utilities, globals (ick).
  23.  */
  24. #include <stdlib.h>
  25. #include <sdp/sdp.h>
  26. #include <libhttp/http.h>
  27. #include "media_utils.h"
  28. #include "player_session.h"
  29. #include "player_media.h"
  30. #include "codec/mp3/mp3_rtp_bytestream.h"
  31. #include "avi_file.h"
  32. #include "mp4_file.h"
  33. #include "qtime_file.h"
  34. #include "our_config_file.h"
  35. #include "rtp_bytestream.h"
  36. #include "codec/aa/isma_rtp_bytestream.h"
  37. #include "codec_plugin_private.h"
  38. #include <gnu/strcasestr.h>
  39. #include "rfc3119_bytestream.h"
  40. #include "mpeg3_rtp_bytestream.h"
  41. #include "mpeg3_file.h"
  42. #include "audio.h"
  43. #include "mpeg2t.h"
  44. /*
  45.  * This needs to be global so we can store any ports that we don't
  46.  * care about but need to reserve
  47.  */
  48. enum {
  49.   VIDEO_MPEG4_ISO,
  50.   VIDEO_DIVX,
  51.   VIDEO_MPEG4_ISO_OR_DIVX,
  52.   VIDEO_MPEG12,
  53. };
  54. enum {
  55.   MPEG4IP_AUDIO_AAC,
  56.   MPEG4IP_AUDIO_MP3,
  57.   MPEG4IP_AUDIO_WAV,
  58.   MPEG4IP_AUDIO_MPEG4_GENERIC,
  59.   MPEG4IP_AUDIO_MP3_ROBUST,
  60.   MPEG4IP_AUDIO_GENERIC,
  61. };
  62. /*
  63.  * these are lists of supported audio and video codecs
  64.  */
  65. static struct codec_list_t {
  66.   const char *name;
  67.   int val;
  68. } video_codecs[] = {
  69.   {"mp4 ", VIDEO_MPEG4_ISO},
  70.   {"mp4v", VIDEO_MPEG4_ISO},
  71.   {"MPG4", VIDEO_MPEG4_ISO},
  72.   {"MP4V-ES", VIDEO_MPEG4_ISO_OR_DIVX},
  73.   {"MPEG4-GENERIC", VIDEO_DIVX},
  74.   {"divx", VIDEO_DIVX},
  75.   {"dvx1", VIDEO_DIVX},
  76.   {"div4", VIDEO_DIVX},
  77.   {NULL, -1},
  78. },
  79.   audio_codecs[] = {
  80.     {"MPEG4-GENERIC", MPEG4IP_AUDIO_MPEG4_GENERIC},
  81.     {"MPA", MPEG4IP_AUDIO_MP3 },
  82.     {"mpa-robust", MPEG4IP_AUDIO_MP3_ROBUST}, 
  83.     {"L16", MPEG4IP_AUDIO_GENERIC },
  84.     {"L8", MPEG4IP_AUDIO_GENERIC },
  85.     {NULL, -1},
  86.   };
  87. static int lookup_codec_by_name (const char *name,
  88.  struct codec_list_t *codec_list)
  89. {
  90.   for (struct codec_list_t *cptr = codec_list; cptr->name != NULL; cptr++) {
  91.     if (strcasecmp(name, cptr->name) == 0) {
  92.       return (cptr->val);
  93.     }
  94.   }
  95.   return (-1);
  96. }
  97.   
  98. int lookup_audio_codec_by_name (const char *name)
  99. {
  100.   return (lookup_codec_by_name(name, audio_codecs));
  101. }
  102. int lookup_video_codec_by_name (const char *name)
  103. {
  104.   return (lookup_codec_by_name(name, video_codecs));
  105. }
  106. static int create_media_from_sdp (CPlayerSession *psptr,
  107.   const char *name,
  108.   session_desc_t *sdp,
  109.   char *errmsg,
  110.   uint32_t errlen,
  111.   int have_audio_driver,
  112.   int broadcast,
  113.   control_callback_vft_t *cc_vft)
  114. {
  115.   int err;
  116.   int media_count = 0;
  117.   int invalid_count = 0;
  118.   int have_audio_but_no_driver = 0;
  119.   char buffer[80];
  120.   codec_plugin_t *codec;
  121.   format_list_t *fmt;
  122.   int audio_count, video_count;
  123.   int audio_offset, video_offset;
  124.   int ix;
  125.   if (sdp->session_name != NULL) {
  126.     snprintf(buffer, sizeof(buffer), "Name: %s", sdp->session_name);
  127.     psptr->set_session_desc(0, buffer);
  128.   }
  129.   if (sdp->session_desc != NULL) {
  130.     snprintf(buffer, sizeof(buffer), "Description: %s", sdp->session_desc);
  131.     psptr->set_session_desc(1, buffer);
  132.   }
  133.   if (sdp->media != NULL &&
  134.       sdp->media->next == NULL &&
  135.       strcasecmp(sdp->media->media, "video") == 0 &&
  136.       sdp->media->fmt != NULL &&
  137.       strcmp(sdp->media->fmt->fmt, "33") == 0) {
  138.     // we have a mpeg2 transport stream
  139.   }
  140.   media_desc_t *sdp_media;
  141.   audio_count = video_count = 0;
  142.   for (sdp_media = psptr->get_sdp_info()->media;
  143.        sdp_media != NULL;
  144.        sdp_media = sdp_media->next) {
  145.     if (strcasecmp(sdp_media->media, "audio") == 0) {
  146.       if (have_audio_driver == 0) {
  147. have_audio_but_no_driver = 1;
  148.       } else {
  149. audio_count++;
  150.       }
  151.     } else if (strcasecmp(sdp_media->media, "video") == 0) {
  152.       video_count++;
  153.     }
  154.   }
  155.   video_query_t *vq;
  156.   audio_query_t *aq;
  157.   if (video_count > 0) {
  158.     vq = (video_query_t *)malloc(sizeof(video_query_t) * video_count);
  159.   } else {
  160.     vq = NULL;
  161.   }
  162.   if (audio_count > 0) {
  163.     aq = (audio_query_t *)malloc(sizeof(audio_query_t) * audio_count);
  164.   } else {
  165.     aq = NULL;
  166.   }
  167.       
  168.   video_offset = audio_offset = 0;
  169.   for (sdp_media = psptr->get_sdp_info()->media;
  170.        sdp_media != NULL;
  171.        sdp_media = sdp_media->next) {
  172.     if (have_audio_driver != 0 &&
  173. strcasecmp(sdp_media->media, "audio") == 0) {
  174.       fmt = sdp_media->fmt;
  175.       codec = NULL;
  176.       while (codec == NULL && fmt != NULL) {
  177. codec = check_for_audio_codec(NULL, 
  178.       fmt,
  179.       -1,
  180.       -1,
  181.       NULL,
  182.       0);
  183. if (codec == NULL) fmt = fmt->next;
  184.       }
  185.       if (codec == NULL) {
  186. invalid_count++;
  187. continue;
  188.       } else {
  189. // set up audio qualifier
  190. aq[audio_offset].track_id = audio_offset;
  191. aq[audio_offset].compressor = NULL;
  192. aq[audio_offset].type = -1;
  193. aq[audio_offset].profile = -1;
  194. aq[audio_offset].fptr = fmt;
  195. aq[audio_offset].sampling_freq = -1;
  196. aq[audio_offset].chans = -1;
  197. aq[audio_offset].enabled = 0;
  198. aq[audio_offset].reference = NULL;
  199. audio_offset++;
  200.       }
  201.     } else if (strcasecmp(sdp_media->media, "video") == 0) {
  202. fmt = sdp_media->fmt;
  203. codec = NULL;
  204. while (codec == NULL && fmt != NULL) {
  205.   codec = check_for_video_codec(NULL, 
  206. fmt,
  207. -1,
  208. -1,
  209. NULL,
  210. 0);
  211.   if (codec == NULL) fmt = fmt->next;
  212. }
  213. if (codec == NULL) {
  214.   invalid_count++;
  215.   continue;
  216. } else {
  217.   vq[video_offset].track_id = video_offset;
  218.   vq[video_offset].compressor = NULL;
  219.   vq[video_offset].type = -1;
  220.   vq[video_offset].profile = -1;
  221.   vq[video_offset].fptr = fmt;
  222.   vq[video_offset].h = -1;
  223.   vq[video_offset].w = -1;
  224.   vq[video_offset].frame_rate = -1;
  225.   vq[video_offset].enabled = 0;
  226.   vq[video_offset].reference = NULL;
  227.   video_offset++;
  228. }
  229.       } else {
  230. player_error_message("Skipping media type `%s'", sdp_media->media);
  231. continue;
  232.       }
  233.     }
  234.   // okay - from here, write the callback call, and go ahead...
  235.   if (cc_vft != NULL &&
  236.       cc_vft->media_list_query != NULL) {
  237.     (cc_vft->media_list_query)(psptr, video_offset, vq, audio_offset, aq);
  238.   } else {
  239.     if (video_offset > 0) {
  240.       vq[0].enabled = 1;
  241.     }
  242.     if (audio_offset > 0) {
  243.       aq[0].enabled = 1;
  244.     }
  245.   }
  246.   for (ix = 0; ix < video_offset; ix++) {
  247.     if (vq[ix].enabled != 0) {
  248.       CPlayerMedia *mptr = new CPlayerMedia(psptr);
  249.       err = mptr->create_streaming(vq[ix].fptr->media, 
  250.    errmsg, 
  251.    errlen,
  252.    broadcast, 
  253.    config.get_config_value(CONFIG_USE_RTP_OVER_RTSP),
  254.    media_count);
  255.       if (err < 0) {
  256. return (-1);
  257.       }
  258.       if (err > 0) {
  259. delete mptr;
  260.       } else 
  261. media_count++;
  262.     }
  263.   }
  264.   for (ix = 0; ix < audio_offset; ix++) {
  265.     if (aq[ix].enabled != 0) {
  266.       CPlayerMedia *mptr = new CPlayerMedia(psptr);
  267.       err = mptr->create_streaming(aq[ix].fptr->media, 
  268.    errmsg, 
  269.    errlen,
  270.    broadcast, 
  271.    config.get_config_value(CONFIG_USE_RTP_OVER_RTSP),
  272.    media_count);
  273.       if (err < 0) {
  274. return (-1);
  275.       }
  276.       if (err > 0) {
  277. delete mptr;
  278.       } else 
  279. media_count++;
  280.     }
  281.   }
  282.   if (aq != NULL) free(aq);
  283.   if (vq != NULL) free(vq);
  284.   if (media_count == 0) {
  285.     snprintf(errmsg, errlen, "No known codecs found in SDP");
  286.     return (-1);
  287.   }
  288.   psptr->streaming_media_set_up();
  289.   if (have_audio_but_no_driver > 0) {
  290.     snprintf(errmsg, errlen, "Not playing audio codecs - no driver");
  291.     return (1);
  292.   }
  293.   if (invalid_count > 0) {
  294.     snprintf(errmsg, errlen, 
  295.      "There were unknowns codecs during decode - playing valid ones");
  296.     return (1);
  297.   }
  298.   return (0);
  299. }
  300. static int create_media_for_streaming_broadcast (CPlayerSession *psptr,
  301.  const char *name,
  302.  session_desc_t *sdp,
  303.  char *errmsg,
  304.  uint32_t errlen,
  305.  int have_audio_driver,
  306.  control_callback_vft_t *cc_vft)
  307. {
  308.   int err;
  309.   // need to set range in player session...
  310.   err = psptr->create_streaming_broadcast(sdp, errmsg, errlen);
  311.   if (err != 0) {
  312.     return (-1);
  313.   }
  314.   return (create_media_from_sdp(psptr, 
  315. name, 
  316. sdp, 
  317. errmsg, 
  318. errlen,
  319. have_audio_driver, 
  320. 0,
  321. cc_vft));
  322. }
  323. /*
  324.  * create_media_for_streaming_ondemand - create streaming media session
  325.  * for an on demand program.
  326.  */
  327. static int create_media_for_streaming_ondemand (CPlayerSession *psptr, 
  328. const char *name,
  329. char *errmsg,
  330. uint32_t errlen,
  331. control_callback_vft_t *cc_vft)
  332. {
  333.   int err;
  334.   session_desc_t *sdp;
  335.   /*
  336.    * This will open the rtsp session
  337.    */
  338.   err = psptr->create_streaming_ondemand(name, 
  339.  errmsg,
  340.  errlen,
  341.  config.get_config_value(CONFIG_USE_RTP_OVER_RTSP));
  342.   if (err != 0) {
  343.     return (-1);
  344.   }
  345.   sdp = psptr->get_sdp_info();
  346.   int have_audio_driver = do_we_have_audio();
  347.   return (create_media_from_sdp(psptr,
  348. name, 
  349. sdp, 
  350. errmsg,
  351. errlen,
  352. have_audio_driver, 
  353. 1,
  354. cc_vft));
  355. }
  356. /*
  357.  * create_media_from_sdp_file - create a streaming session based on an
  358.  * sdp file.  It could be either an on-demand program (we look for the 
  359.  * url in the control string), or a broadcast.
  360.  */
  361. static int create_from_sdp (CPlayerSession *psptr,
  362.     const char *name,
  363.     char *errmsg,
  364.     uint32_t errlen,
  365.     sdp_decode_info_t *sdp_info,
  366.     int have_audio_driver,
  367.     control_callback_vft_t *cc_vft) 
  368. {
  369.   session_desc_t *sdp;
  370.   int translated;
  371.   if (sdp_info == NULL) {
  372.     strcpy(errmsg, "SDP error");
  373.     return (-1);
  374.   }
  375.   if (sdp_decode(sdp_info, &sdp, &translated) != 0) {
  376.     snprintf(errmsg, errlen, "Invalid SDP file");
  377.     sdp_decode_info_free(sdp_info);
  378.     return (-1);
  379.   }
  380.   if (translated != 1) {
  381.     snprintf(errmsg, errlen, "More than 1 program described in SDP");
  382.     sdp_decode_info_free(sdp_info);
  383.     return (-1);
  384.   }
  385.   int err;
  386.   if (sdp->control_string != NULL) {
  387.     // An on demand file... Just use the URL...
  388.     err = create_media_for_streaming_ondemand(psptr,
  389.       sdp->control_string,
  390.       errmsg,
  391.       errlen,
  392.       cc_vft);
  393.     sdp_free_session_desc(sdp);
  394.     sdp_decode_info_free(sdp_info);
  395.     return (err);
  396.   }
  397.   sdp_decode_info_free(sdp_info);
  398.   return (create_media_for_streaming_broadcast(psptr,
  399.        name, 
  400.        sdp,
  401.        errmsg,
  402.        errlen,
  403.        have_audio_driver,
  404.        cc_vft));
  405. }
  406. static int create_media_from_sdp_file(CPlayerSession *psptr, 
  407.       const char *name, 
  408.       char *errmsg,
  409.       uint32_t errlen,
  410.       int have_audio_driver,
  411.       control_callback_vft_t *cc_vft)
  412. {
  413.   sdp_decode_info_t *sdp_info;
  414.   sdp_info = set_sdp_decode_from_filename(name);
  415.   return (create_from_sdp(psptr, 
  416.   name, 
  417.   errmsg, 
  418.   errlen, 
  419.   sdp_info, 
  420.   have_audio_driver, 
  421.   cc_vft));
  422. }
  423. static int create_media_for_http (CPlayerSession *psptr,
  424.   const char *name,
  425.   char *errmsg,
  426.   uint32_t errlen,
  427.   control_callback_vft_t *cc_vft)
  428. {
  429.   http_client_t *http_client;
  430.   int ret;
  431.   http_resp_t *http_resp;
  432.   http_resp = NULL;
  433.   http_client = http_init_connection(name);
  434.   if (http_client == NULL) {
  435.     snprintf(errmsg, errlen, "Can't create http client");
  436.     return -1;
  437.   } 
  438.   ret = http_get(http_client, NULL, &http_resp);
  439.   if (ret > 0) {
  440.     sdp_decode_info_t *sdp_info;
  441.     int have_audio_driver = do_we_have_audio();
  442.     sdp_info = set_sdp_decode_from_memory(http_resp->body);
  443.     ret = create_from_sdp(psptr, 
  444.   name, 
  445.   errmsg, 
  446.   errlen, 
  447.   sdp_info, 
  448.   have_audio_driver,
  449.   cc_vft);
  450.   } else {
  451.     ret = -1;
  452.   }
  453.   http_resp_free(http_resp);
  454.   http_free_connection(http_client);
  455.   return (ret);
  456. }
  457. /*
  458.  * parse_name_for_session - look at the name, determine what routine to 
  459.  * call to set up the session.  This should be redone with plugins at
  460.  * some point.
  461.  */
  462. #define ADV_SPACE(a) {while (isspace(*(a)) && (*(a) != ''))(a)++;}
  463. int parse_name_for_session (CPlayerSession *psptr,
  464.     const char *name,
  465.     char *errmsg,
  466.     uint32_t errlen,
  467.     control_callback_vft_t *cc_vft)
  468. {
  469.   int err;
  470.   ADV_SPACE(name);
  471.   if (strncmp(name, "rtsp://", strlen("rtsp://")) == 0) {    
  472.     err = create_media_for_streaming_ondemand(psptr, 
  473.       name, 
  474.       errmsg, 
  475.       errlen,
  476.       cc_vft);
  477.     return (err);
  478.   }
  479.   if (strncmp(name, "http://", strlen("http://")) == 0) {
  480.     err = create_media_for_http(psptr, name, errmsg, errlen, cc_vft);
  481.     return (err);
  482.   }    
  483. #if 0
  484.   if (strncmp(name, "mpeg2t://", strlen("mpeg2t://")) == 0) {
  485.     err = create_mpeg2t_session(psptr, name, errmsg, errlen, cc_vft);
  486.     return (err);
  487.   }
  488. #endif
  489. #ifndef _WINDOWS
  490.   struct stat statbuf;
  491.   if (stat(name, &statbuf) != 0) {
  492.     snprintf(errmsg, errlen, "File '%s' not found", name);
  493.     return (-1);
  494.   }
  495.   if (!S_ISREG(statbuf.st_mode)) {
  496.     snprintf(errmsg, errlen, "File '%s' is not a file", name);
  497.     return (-1);
  498.   }
  499. #else
  500.   OFSTRUCT ReOpenBuff;
  501.   if (OpenFile(name, &ReOpenBuff,OF_READ) == HFILE_ERROR) {
  502.     snprintf(errmsg, errlen, "File %s not found", name);
  503.     return (-1);
  504.   }
  505. #endif
  506.   err = -1;
  507.   const char *suffix = strrchr(name, '.');
  508.   if (suffix == NULL) {
  509.     snprintf(errmsg, errlen, "No useable suffix on file %s", name);
  510.     return err;
  511.   }
  512.   int have_audio_driver;
  513.   have_audio_driver = do_we_have_audio();
  514.   if (strcasecmp(suffix, ".sdp") == 0) {
  515.     err = create_media_from_sdp_file(psptr, 
  516.      name, 
  517.      errmsg, 
  518.      errlen, 
  519.      have_audio_driver,
  520.      cc_vft);
  521.   } else if ((strcasecmp(suffix, ".mov") == 0) ||
  522.      ((config.get_config_value(CONFIG_USE_OLD_MP4_LIB) != 0) &&
  523.       (strcasecmp(suffix, ".mp4") == 0))){
  524.     err = create_media_for_qtime_file(psptr, 
  525.       name, 
  526.       errmsg, 
  527.       errlen,
  528.       have_audio_driver);
  529.   } else if (strcasecmp(suffix, ".mp4") == 0) {
  530.     err = create_media_for_mp4_file(psptr, 
  531.     name, 
  532.     errmsg, 
  533.     errlen,
  534.     have_audio_driver,
  535.     cc_vft);
  536.   } else if (strcasecmp(suffix, ".avi") == 0) {
  537.     err = create_media_for_avi_file(psptr, 
  538.     name, 
  539.     errmsg, 
  540.     errlen, 
  541.     have_audio_driver,
  542.     cc_vft);
  543.   } else if (strcasecmp(suffix, ".mpeg") == 0 ||
  544.      strcasecmp(suffix, ".mpg") == 0) {
  545.     err = create_media_for_mpeg_file(psptr, name, errmsg, 
  546.      errlen, have_audio_driver);
  547.   } else {
  548.     // raw files
  549.     if (have_audio_driver) {
  550.       err = audio_codec_check_for_raw_file(psptr, name);
  551.     }
  552.     if (err < 0) {
  553.       err = video_codec_check_for_raw_file(psptr, name);
  554.     }
  555.   }
  556.   
  557.   if (err >= 0) {
  558.     const char *temp;
  559.     temp = psptr->get_session_desc(0);
  560.     if (temp == NULL) {
  561.       psptr->set_session_desc(0, name);
  562.     }
  563.   }
  564.   return (err);
  565. }
  566.   
  567. CRtpByteStreamBase *create_rtp_byte_stream_for_format (format_list_t *fmt,
  568.        unsigned int rtp_pt,
  569.        int ondemand,
  570.        uint64_t tps,
  571.        rtp_packet **head, 
  572.        rtp_packet **tail,
  573.        int rtp_seq_set, 
  574.        uint16_t rtp_seq,
  575.        int rtp_ts_set,
  576.        uint32_t rtp_base_ts,
  577.        int rtcp_received,
  578.        uint32_t ntp_frac,
  579.        uint32_t ntp_sec,
  580.        uint32_t rtp_ts)
  581. {
  582.   CRtpByteStreamBase *rtp_byte_stream;
  583.   int codec;
  584.   if (strcmp("video", fmt->media->media) == 0) {
  585.     if (rtp_pt == 32) {
  586.       codec = VIDEO_MPEG12;
  587.       rtp_byte_stream = new CMpeg3RtpByteStream(rtp_pt,
  588. fmt, 
  589. ondemand,
  590. tps,
  591. head,
  592. tail,
  593. rtp_seq_set,
  594. rtp_seq,
  595. rtp_ts_set,
  596. rtp_base_ts,
  597. rtcp_received,
  598. ntp_frac,
  599. ntp_sec,
  600. rtp_ts);
  601.       if (rtp_byte_stream != NULL) {
  602. return (rtp_byte_stream);
  603.       }
  604.     } else {
  605.       codec = lookup_codec_by_name(fmt->rtpmap->encode_name, 
  606.    video_codecs);
  607.       if (codec < 0) {
  608. return (NULL);
  609.       }
  610.     }
  611.   } else {
  612.     if (rtp_pt == 14) {
  613.       codec = MPEG4IP_AUDIO_MP3;
  614.     } else {
  615.       codec = lookup_codec_by_name(fmt->rtpmap->encode_name, 
  616.    audio_codecs);
  617.       if (codec < 0) {
  618. return (NULL);
  619.       }
  620.     }
  621.     switch (codec) {
  622.     case MPEG4IP_AUDIO_AAC:
  623.     case MPEG4IP_AUDIO_MPEG4_GENERIC:
  624.       fmtp_parse_t *fmtp;
  625.       fmtp = parse_fmtp_for_mpeg4(fmt->fmt_param, message);
  626.       if (fmtp->size_length == 0) {
  627. // No headers in RTP packet -create normal bytestream
  628. player_debug_message("Size of AAC RTP header is 0 - normal bytestream");
  629. break;
  630.       }
  631.       rtp_byte_stream = new CIsmaAudioRtpByteStream(fmt,
  632.     fmtp,
  633.     rtp_pt,
  634.     ondemand,
  635.     tps,
  636.     head,
  637.     tail,
  638.     rtp_seq_set,
  639.     rtp_seq,
  640.     rtp_ts_set,
  641.     rtp_base_ts,
  642.     rtcp_received,
  643.     ntp_frac,
  644.     ntp_sec,
  645.     rtp_ts);
  646.       if (rtp_byte_stream != NULL) {
  647. return (rtp_byte_stream);
  648.       }
  649.       // Otherwise, create default...
  650.       break;
  651.     case MPEG4IP_AUDIO_MP3:
  652.       rtp_byte_stream = 
  653. new CMP3RtpByteStream(rtp_pt, fmt, ondemand, tps, head, tail, 
  654.       rtp_seq_set, rtp_seq,
  655.       rtp_ts_set, rtp_base_ts, 
  656.       rtcp_received, ntp_frac, ntp_sec, rtp_ts);
  657.       if (rtp_byte_stream != NULL) {
  658. player_debug_message("Starting mp3 2250 byte stream");
  659. return (rtp_byte_stream);
  660.       }
  661.       break;
  662.     case MPEG4IP_AUDIO_MP3_ROBUST:
  663.       rtp_byte_stream = 
  664. new CRfc3119RtpByteStream(rtp_pt, fmt, ondemand, tps, head, tail, 
  665.   rtp_seq_set, rtp_seq,
  666.   rtp_ts_set, rtp_base_ts, 
  667.   rtcp_received, ntp_frac, ntp_sec, rtp_ts);
  668.       if (rtp_byte_stream != NULL) {
  669. player_debug_message("Starting mpa robust byte stream");
  670. return (rtp_byte_stream);
  671.       }
  672.       break;
  673.     case MPEG4IP_AUDIO_GENERIC:
  674.       rtp_byte_stream = 
  675. new CAudioRtpByteStream(rtp_pt, fmt, ondemand, tps, head, tail, 
  676. rtp_seq_set, rtp_seq,
  677. rtp_ts_set, rtp_base_ts, 
  678. rtcp_received, ntp_frac, ntp_sec, rtp_ts);
  679.       if (rtp_byte_stream != NULL) {
  680. player_debug_message("Starting generic audio byte stream");
  681. return (rtp_byte_stream);
  682.       }
  683.     default:
  684.       break;
  685.     }
  686.   }
  687.   rtp_byte_stream = new CRtpByteStream(fmt->media->media,
  688.        fmt, 
  689.        rtp_pt,
  690.        ondemand,
  691.        tps,
  692.        head,
  693.        tail,
  694.        rtp_seq_set, 
  695.        rtp_seq,
  696.        rtp_ts_set,
  697.        rtp_base_ts,
  698.        rtcp_received,
  699.        ntp_frac,
  700.        ntp_sec,
  701.        rtp_ts);
  702.   return (rtp_byte_stream);
  703. }