⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 celp.cpp

📁 网络MPEG4IP流媒体开发源代码
💻 CPP
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is MPEG4IP. *  * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved. *  * Contributor(s):  *              Massimo Villari        mvillari@cisco.com */#include "celp.h"#include "bitstreamStruct.h"#include "dec_lpc.h"#include "celp_decoder.h"//#include "../include/audio.h"//#include "../include/austream.h"#include <mp4util/mpeg4_audio_config.h>#include <mp4util/mpeg4_sdp.h>#include <mp4v2/mp4.h>#define DEBUG_SYNC 2#define bit2byte(a) (((a)+8-1)/8)const char *celplib="celp";/* * Create CELP Codec class */static codec_data_t *celp_codec_create (const char *compressor, 					int type, 					int profile, 					format_list_t *media_fmt,					audio_info_t *audio,					const uint8_t *userdata,					uint32_t userdata_size,					audio_vft_t *vft,					void *ifptr){  int i;  celp_codec_t *celp;  celp = (celp_codec_t *)malloc(sizeof(celp_codec_t));  memset(celp, 0, sizeof(celp_codec_t));  #if 1 	   celp->m_vft = vft;  celp->m_ifptr = ifptr;  fmtp_parse_t *fmtp = NULL;  BsInit(0, 0, 0);    // Start setting up CELP stuff...    celp->m_resync_with_header = 1;  celp->m_record_sync_time = 1;    celp->m_celp_inited = 0;  celp->m_audio_inited = 0;  //celp->m_temp_buff = (float *)malloc(4096);    // Use media_fmt to indicate that we're streaming.  if (media_fmt != NULL) {    // haven't checked for null buffer    // This is not necessarilly right - it is, for the most part, but    // we should be reading the fmtp statement, and looking at the config.    // (like we do below in the userdata section...    celp->m_freq = media_fmt->rtpmap->clock_rate;    fmtp = parse_fmtp_for_mpeg4(media_fmt->fmt_param, vft->log_msg);    if (fmtp != NULL) {      userdata = fmtp->config_binary;      userdata_size = fmtp->config_binary_len;    }  } else {    if (audio != NULL) {      celp->m_freq = audio->freq;    } else {      celp->m_freq = 44100;    }  }  //celp->m_chans = 1; // this may be wrong - the isma spec, Appendix A.1.1 of  // Appendix H says the default is 1 channel...  //celp->m_output_frame_size = 2048;  // celp->m_object_type = 8;CELP  AACMAIN;  mpeg4_audio_config_t audio_config;  if (userdata != NULL || fmtp != NULL) {        celp_message(LOG_DEBUG, celplib, "config len %d %02x %02x %02x %02x", 		 userdata_size, userdata[0], userdata[1], userdata[2], 		 userdata[3]);    decode_mpeg4_audio_config(userdata, userdata_size, &audio_config);    celp->m_object_type = audio_config.audio_object_type;    celp->m_freq = audio_config.frequency;    celp->m_chans = audio_config.channels;  }	  // write   BsBitBuffer *bitHeader;  BsBitStream	*hdrStream;  bitHeader=BsAllocBuffer(userdata_size * 8);  //wmay removed  bitHeader->numBit=userdata_size*8;  bitHeader->size=userdata_size*8;  memcpy(bitHeader->data,userdata,userdata_size);  hdrStream = BsOpenBufferRead(bitHeader);  BsGetSkip (hdrStream,userdata_size*8-audio_config.codec.celp.NumOfBitsInBuffer);  BsBitBuffer *bBuffer=BsAllocBuffer(userdata_size*8);  BsGetBuffer (hdrStream, bBuffer,audio_config.codec.celp.NumOfBitsInBuffer);  int delayNumSample;  DecLpcInit(celp->m_chans,celp->m_freq,0,NULL,	     bBuffer ,&celp->m_output_frame_size,&delayNumSample);  celp->m_msec_per_frame *= M_LLU;  celp->m_msec_per_frame /= celp->m_freq;  celp->m_last=userdata_size;	  BsFreeBuffer (bitHeader);  BsFreeBuffer (bBuffer);	  celp->m_sampleBuf=(float**)malloc(celp->m_chans*sizeof(float*));  for(i=0;i<celp->m_chans;i++)    // wmay - added 2 times    celp->m_sampleBuf[i]=(float*)malloc(2*celp->m_output_frame_size*sizeof(float));  celp->m_bufs =     (uint16_t *)malloc(sizeof(uint16_t) * 2 * celp->m_chans * celp->m_output_frame_size);  //celp->audiFile = AudioOpenWrite("out1.au",".au",  //		  celp->m_chans,celp->m_freq);  celp_message(LOG_INFO, celplib,"CELP object type is %d", celp->m_object_type);  //celp_message(LOG_INFO, celplib,"CELP channel are %d", celp->m_chans );  celp_message(LOG_INFO, celplib, "Setting freq to %d", celp->m_freq);  celp_message(LOG_INFO, celplib, "output frame size is %d", celp->m_output_frame_size);   #if DUMP_OUTPUT_TO_FILE  celp->m_outfile = fopen("temp.raw", "w");#endif  if (fmtp != NULL) {    free_fmtp_parse(fmtp);  }#endif	   celp->m_vft->audio_configure(celp->m_ifptr,			       celp->m_freq, 			       celp->m_chans, 			       AUDIO_S16SYS,			       celp->m_output_frame_size);  return (codec_data_t *)celp;}void celp_close (codec_data_t *ptr){  		  int i;  if (ptr == NULL) {    printf("\nin celp close\n");        return;  }   celp_codec_t *celp = (celp_codec_t *)ptr; 		  if(celp->m_bufs) {    free(celp->m_bufs);    celp->m_bufs=NULL;  }  //AudioClose(celp->audiFile);  	  // if (celp->m_temp_buff) {  //    free(celp->m_temp_buff);  //    celp->m_temp_buff = NULL;  //  }  if(celp->m_sampleBuf){    for(i=0; i<celp->m_chans;i++) {      free(celp->m_sampleBuf[i]);      celp->m_sampleBuf[i] = NULL;    }    free(celp->m_sampleBuf);    celp->m_sampleBuf = NULL;  }  DecLpcFree();#if DUMP_OUTPUT_TO_FILE  fclose(celp->m_outfile);#endif  free(celp);  		} /* * Handle pause - basically re-init the codec */static void celp_do_pause (codec_data_t *ifptr){    celp_codec_t *celp = (celp_codec_t *)ifptr;  celp->m_resync_with_header = 1;  celp->m_record_sync_time = 1;  celp->m_audio_inited = 0;  celp->m_celp_inited = 0;	}/* * Decode task call for CELP */static int celp_decode (codec_data_t *ptr,			uint64_t ts,			int from_rtp,			int *sync_frame,			uint8_t *buffer,			uint32_t buflen,			void *userdata){  int usedNumBit;	  celp_codec_t *celp = (celp_codec_t *)ptr;    if (celp->m_record_sync_time) {    celp->m_current_frame = 0;    celp->m_record_sync_time = 0;    celp->m_current_time = ts;    celp->m_last_rtp_ts = ts;  } else {    if (celp->m_last_rtp_ts == ts) {      celp->m_current_time += celp->m_msec_per_frame;      celp->m_current_frame++;    } else {      celp->m_last_rtp_ts = ts;      celp->m_current_time = ts;      celp->m_current_frame = 0;    }    // Note - here m_current_time should pretty much always be >= rtpts.      // If we're not, we most likely want to stop and resync.  We don't    // need to keep decoding - just decode this frame and indicate we    // need a resync... That should handle fast forwards...  We need    // someway to handle reverses - perhaps if we're more than .5 seconds    // later...  }	  if (celp->m_celp_inited == 0) {    	    /*     * If not initialized, do so.       */        //    celp->m_celp_inited = 1;	  }  //printf("buflen:%d\n",buflen);  //if ( ((celp->m_last-buflen)/celp->m_last) < 0.2) return (0);  if ( buflen<5) return (-1);    BsBitBuffer local;  local.data= (unsigned char *)buffer;  local.numBit=buflen*8;  local.size=buflen*8;	  DecLpcFrame(&local,celp->m_sampleBuf,&usedNumBit);	  //AudioWriteData(celp->audiFile,celp->m_sampleBuf,celp->m_output_frame_size);	  int chan,sample;  uint8_t *now = celp->m_vft->audio_get_buffer(celp->m_ifptr);  if (now != NULL) {    uint16_t *buf = (uint16_t *)now;        for(chan=0;chan<celp->m_chans;chan++){      for(sample=0;sample < celp->m_output_frame_size; sample++){	buf[sample +(chan*celp->m_output_frame_size)]=	  (uint16_t)celp->m_sampleBuf[chan][sample];	      }    }  }	#if DUMP_OUTPUT_TO_FILE  fwrite(buff, celp->m_output_frame_size * 4, 1, celp->m_outfile);#endif  celp->m_vft->audio_filled_buffer(celp->m_ifptr,				   celp->m_current_time, 				   celp->m_resync_with_header);  if (celp->m_resync_with_header == 1) {    celp->m_resync_with_header = 0;#ifdef DEBUG_SYNC    celp_message(LOG_DEBUG, celplib, "Back to good at "LLU, celp->m_current_time);#endif  }        return bit2byte(usedNumBit);}static const char *celp_compressors[] = {  "celp ",  "mp4a",  NULL};static int celp_codec_check (lib_message_func_t message,			     const char *compressor,			     int type,			     int profile,			     format_list_t *fptr, 			     const uint8_t *userdata,			     uint32_t userdata_size){  fmtp_parse_t *fmtp = NULL;  if (compressor != NULL &&       strcasecmp(compressor, "MP4 FILE") == 0 &&      type != -1) {    switch (type) {    case MP4_MPEG4_AUDIO_TYPE:      break;    default:      return -1;    }  }  if (fptr != NULL &&       fptr->rtpmap != NULL &&      fptr->rtpmap->encode_name != NULL) {    if (strcasecmp(fptr->rtpmap->encode_name, "mpeg4-generic") != 0) {      return -1;    }    if (userdata == NULL) {      fmtp = parse_fmtp_for_mpeg4(fptr->fmt_param, message);      if (fmtp != NULL) {	userdata = fmtp->config_binary;	userdata_size = fmtp->config_binary_len;      }    }  }  if (userdata != NULL) {    mpeg4_audio_config_t audio_config;    decode_mpeg4_audio_config(userdata, userdata_size, &audio_config);    if (fmtp != NULL) free_fmtp_parse(fmtp);    if (audio_object_type_is_celp(&audio_config) == 0) {      return -1;    }    return 1;  }  if (compressor != NULL) {    const char **lptr = celp_compressors;    while (*lptr != NULL) {      if (strcasecmp(*lptr, compressor) == 0) {	return 1;      }      lptr++;    }  }  return -1;}AUDIO_CODEC_PLUGIN("celp",		   celp_codec_create,		   celp_do_pause,		   celp_decode,		   NULL,		   celp_close,		   celp_codec_check);/* end file aa.cpp */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -