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

流媒体/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. #include "rawa.h"
  22. #include <mp4v2/mp4.h>
  23. #include <SDL.h>
  24. #define LOGIT rawa->m_vft->log_msg
  25. /*
  26.  * Create raw audio structure
  27.  */
  28. static codec_data_t *rawa_codec_create (format_list_t *media_fmt,
  29. audio_info_t *audio,
  30. const uint8_t *userdata,
  31. uint32_t userdata_size,
  32. audio_vft_t *vft,
  33. void *ifptr)
  34. {
  35.   rawa_codec_t *rawa;
  36.   rawa = (rawa_codec_t *)malloc(sizeof(rawa_codec_t));
  37.   memset(rawa, 0, sizeof(rawa_codec_t));
  38.   rawa->m_vft = vft;
  39.   rawa->m_ifptr = ifptr;
  40.   rawa->m_initialized = 0;
  41.   rawa->m_temp_buff = NULL;
  42.   if (media_fmt != NULL) {
  43.     /*
  44.      * Raw pcm - L8 or L16
  45.      */
  46.     rawa->m_freq = media_fmt->rtpmap->clock_rate;
  47.     rawa->m_chans = media_fmt->rtpmap->encode_param != 0 ?
  48.       media_fmt->rtpmap->encode_param : 1;
  49.     if (strcasecmp(media_fmt->rtpmap->encode_name, "L16") == 0) {
  50.       rawa->m_bitsperchan = 16;
  51.       rawa->m_convert_bytes = 1;
  52.     } else if ((*media_fmt->rtpmap->encode_name == '1') &&
  53.        (media_fmt->rtpmap->encode_name[1] == '0') ||
  54.        (media_fmt->rtpmap->encode_name[1] == '1')) {
  55.       rawa->m_bitsperchan = 16;
  56.       rawa->m_convert_bytes = 1;
  57.       rawa->m_freq = 44100;
  58.       rawa->m_chans = media_fmt->rtpmap->encode_name[1] == '0' ? 2 : 1;
  59.     } else
  60.       rawa->m_bitsperchan = 8;
  61.   } else {
  62.     rawa->m_freq = audio->freq;
  63.     rawa->m_chans = audio->chans;
  64.     rawa->m_bitsperchan = audio->bitspersample;
  65.   }
  66.   LOGIT(LOG_DEBUG, "rawa", 
  67. "setting freq %d chans %d bitsper %d", 
  68. rawa->m_freq,
  69. rawa->m_chans, 
  70. rawa->m_bitsperchan);
  71.   return (codec_data_t *)rawa;
  72. }
  73. static void rawa_close (codec_data_t *ptr)
  74. {
  75.   rawa_codec_t *rawa = (rawa_codec_t *)ptr;
  76.   if (rawa->m_temp_buff != NULL) free(rawa->m_temp_buff);
  77.   free(rawa);
  78. }
  79. /*
  80.  * Handle pause - basically re-init the codec
  81.  */
  82. static void rawa_do_pause (codec_data_t *ifptr)
  83. {
  84.   rawa_codec_t *rawa = (rawa_codec_t *)ifptr;
  85.   rawa->m_resync = 1;
  86. }
  87. /*
  88.  * Decode task call for FAAC
  89.  */
  90. static int rawa_decode (codec_data_t *ptr,
  91.        uint64_t ts,
  92.        int from_rtp,
  93.        int *sync_frame,
  94.        uint8_t *buffer,
  95.        uint32_t buflen,
  96. void *ud)
  97. {
  98.   rawa_codec_t *rawa = (rawa_codec_t *)ptr;
  99.   uint32_t ix;
  100.   unsigned short *b;
  101.   //LOGIT(LOG_DEBUG, "rawa", "ts %llu buffer len %d", ts, buflen);
  102.   if (rawa->m_initialized == 0) {
  103.     if (rawa->m_chans == 0) {
  104.       // Special mp4 case - we don't know how many channels, but we
  105.       // do know that we've got 1 seconds worth of data...
  106.       if (rawa->m_temp_buff == NULL) {
  107. rawa->m_temp_buff = (uint8_t *)malloc(buflen);
  108. memcpy(rawa->m_temp_buff, buffer, buflen);
  109. rawa->m_temp_buffsize = buflen;
  110. LOGIT(LOG_DEBUG, "rawaudio", "setting %d bufsize", 
  111.       rawa->m_temp_buffsize);
  112. return (buflen);
  113.       } else {
  114. //
  115. if (buflen != rawa->m_temp_buffsize) {
  116.   LOGIT(LOG_ERR, "rawaudio", "Inconsistent raw audio buffer size %d should be %d", buflen, rawa->m_temp_buffsize);
  117.   return buflen;
  118. }
  119. uint64_t calc;
  120. LOGIT(LOG_DEBUG, "rawaudio",
  121.       "freq %d ts "LLU" buffsize %d",
  122.       rawa->m_freq, ts, rawa->m_temp_buffsize);
  123. calc = 1000 *  rawa->m_temp_buffsize;
  124. calc /= rawa->m_freq;
  125. calc /= ts;
  126. calc /= 2;
  127. LOGIT(LOG_DEBUG, "rawaudio", "Channels is %d", calc);
  128. rawa->m_chans = calc;
  129. rawa->m_bitsperchan = 16;
  130.       } 
  131.     }
  132.     rawa->m_vft->audio_configure(rawa->m_ifptr,
  133.  rawa->m_freq, 
  134.  rawa->m_chans, 
  135.  rawa->m_bitsperchan == 16 ? AUDIO_S16SYS :
  136.  AUDIO_U8, 
  137.  0);
  138.     if (rawa->m_temp_buff != NULL) {
  139.       rawa->m_vft->audio_load_buffer(rawa->m_ifptr,
  140.      rawa->m_temp_buff, 
  141.      rawa->m_temp_buffsize,
  142.      0, 
  143.      1);
  144.       if (ts == 0) rawa->m_bytes = rawa->m_temp_buffsize;
  145.       free(rawa->m_temp_buff);
  146.       rawa->m_temp_buff = NULL;
  147.     }
  148.     rawa->m_initialized = 1;
  149.   } 
  150.   if (ts == rawa->m_ts) {
  151.     uint64_t calc;
  152.     calc = rawa->m_bytes * M_LLU;
  153.     calc /= rawa->m_chans;
  154.     if (rawa->m_bitsperchan == 16) calc /= 2;
  155.     calc /= rawa->m_freq;
  156.     ts += calc;
  157.     rawa->m_bytes += buflen;
  158.   } else {
  159.     rawa->m_bytes = 0;
  160.     rawa->m_ts = ts;
  161.   }
  162.   /*
  163.    * if we're over RTP, we've got the buffer reversed...
  164.    */
  165.   if (rawa->m_convert_bytes) {
  166.     for (ix = 0, b = (unsigned short *)buffer; 
  167.  ix < buflen; 
  168.  ix += 2, b++) {
  169.       *b = ntohs(*b);
  170.     }
  171.   }
  172.   rawa->m_vft->audio_load_buffer(rawa->m_ifptr, 
  173.  buffer, 
  174.  buflen,
  175.  ts, 
  176.  rawa->m_resync);
  177.   rawa->m_resync = 0;
  178.   return (buflen);
  179. }
  180. static int rawa_codec_check (lib_message_func_t message,
  181.     const char *compressor,
  182.     int type,
  183.     int profile,
  184.     format_list_t *fptr, 
  185.     const uint8_t *userdata,
  186.     uint32_t userdata_size)
  187. {
  188.   if (compressor != NULL && 
  189.       strcasecmp(compressor, "MP4 FILE") == 0 &&
  190.       type != -1) {
  191.     if (type == MP4_PCM16_AUDIO_TYPE)
  192.       return 1;
  193.   }
  194.   if (compressor != NULL &&
  195.       strcasecmp(compressor, "AVI FILE") == 0 &&
  196.       type == 1) {
  197.     return 1;
  198.   }
  199.   if (fptr != NULL) {
  200.     if (fptr->rtpmap != NULL && fptr->rtpmap->encode_name != NULL) {
  201.       if (strcasecmp(fptr->rtpmap->encode_name, "L16") == 0) {
  202. return 1;
  203.       }
  204.       if (strcasecmp(fptr->rtpmap->encode_name, "L8") == 0) {
  205. return 1;
  206.       }
  207.     }
  208.   }
  209.   return -1;
  210. }
  211. AUDIO_CODEC_PLUGIN("rawa",
  212.    rawa_codec_create,
  213.    rawa_do_pause,
  214.    rawa_decode,
  215.    NULL,
  216.    rawa_close,
  217.    rawa_codec_check);
  218. /* end file rawa.cpp */