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

📄 audio_lame.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):  *		Dave Mackie		dmackie@cisco.com */#include "mp4live.h"#include "audio_lame.h"#include <mp4av.h>MediaType lame_mp4_fileinfo (CLiveConfig *pConfig,			     bool *mpeg4,			     bool *isma_compliant,			     uint8_t *audioProfile,			     uint8_t **audioConfig,			     uint32_t *audioConfigLen,			     uint8_t *mp4AudioType){  *mpeg4 = true; // legal in an mp4 - create an iod  *isma_compliant = false;  *audioProfile = 0xfe;  *audioConfig = NULL;  *audioConfigLen = 0;  if (mp4AudioType != NULL) {    *mp4AudioType = MP4_MP3_AUDIO_TYPE;  }  return MP3AUDIOFRAME;}media_desc_t *lame_create_audio_sdp (CLiveConfig *pConfig,				     bool *mpeg4,				     bool *isma_compliant,				     uint8_t *audioProfile,				     uint8_t **audioConfig,				     uint32_t *audioConfigLen){  media_desc_t *sdpMediaAudio;  format_list_t *sdpMediaAudioFormat;  rtpmap_desc_t *sdpAudioRtpMap;  lame_mp4_fileinfo(pConfig, mpeg4, isma_compliant, audioProfile,		    audioConfig, audioConfigLen, NULL);  sdpMediaAudio = MALLOC_STRUCTURE(media_desc_t);  memset(sdpMediaAudio, 0, sizeof(*sdpMediaAudio));  sdp_add_string_to_list(&sdpMediaAudio->unparsed_a_lines,			 strdup("a=mpeg4-esid:10"));  sdpMediaAudioFormat = MALLOC_STRUCTURE(format_list_t);  memset(sdpMediaAudioFormat, 0, sizeof(*sdpMediaAudioFormat));  sdpMediaAudio->fmt = sdpMediaAudioFormat;  sdpMediaAudioFormat->media = sdpMediaAudio;  sdpAudioRtpMap = MALLOC_STRUCTURE(rtpmap_desc_t);  memset(sdpAudioRtpMap, 0, sizeof(*sdpAudioRtpMap));  sdpAudioRtpMap->clock_rate =     pConfig->GetIntegerValue(CONFIG_AUDIO_SAMPLE_RATE);		  if (pConfig->GetBoolValue(CONFIG_RTP_USE_MP3_PAYLOAD_14)) {    sdpMediaAudioFormat->fmt = strdup("14");    sdpAudioRtpMap->clock_rate = 90000;  } else {    sdpMediaAudioFormat->fmt = strdup("97");  }	      sdpAudioRtpMap->encode_name = strdup("MPA");    sdpMediaAudioFormat->rtpmap = sdpAudioRtpMap;	  return sdpMediaAudio;}static bool lame_set_rtp_header (struct iovec *iov,				 int queue_cnt,				 void *ud){  *(uint32_t *)ud = 0;  iov[0].iov_base = ud;  iov[0].iov_len = 4;  return true;}static bool lame_set_rtp_jumbo (struct iovec *iov,				uint32_t dataOffset,				uint32_t bufferLen,				uint32_t rtpPacketMax,				bool &mbit,				void *ud){  uint8_t *payloadHeader = (uint8_t *)ud;  uint32_t send;  payloadHeader[0] = 0;  payloadHeader[1] = 0;  payloadHeader[2] = (dataOffset >> 8);  payloadHeader[3] = (dataOffset & 0xff);  send = MIN(bufferLen - dataOffset, rtpPacketMax - 4);  iov[0].iov_base = payloadHeader;  iov[0].iov_len = 4;  iov[1].iov_len = send;  mbit = (dataOffset == 0);  return true;}bool lame_get_audio_rtp_info (CLiveConfig *pConfig,			      MediaType *audioFrameType,			      uint32_t *audioTimeScale,			      uint8_t *audioPayloadNumber,			      uint8_t *audioPayloadBytesPerPacket,			      uint8_t *audioPayloadBytesPerFrame,			      uint8_t *audioQueueMaxCount,			      audio_set_rtp_header_f *audio_set_header,			      audio_set_rtp_jumbo_frame_f *audio_set_jumbo,			      void **ud){  *audioFrameType = MP3AUDIOFRAME;  if (pConfig->GetBoolValue(CONFIG_RTP_USE_MP3_PAYLOAD_14)) {    *audioPayloadNumber = 14;    *audioTimeScale = 90000;  } else {    *audioPayloadNumber = 97;    *audioTimeScale = pConfig->GetIntegerValue(CONFIG_AUDIO_SAMPLE_RATE);  }  *audioPayloadBytesPerPacket = 4;  *audioPayloadBytesPerFrame = 0;  *audioQueueMaxCount = 8;  *audio_set_header = lame_set_rtp_header;  *audio_set_jumbo = lame_set_rtp_jumbo;  *ud = malloc(4);  memset(*ud, 0, 4);  return true;}CLameAudioEncoder::CLameAudioEncoder(){	m_mp3FrameBuffer = NULL;}bool CLameAudioEncoder::Init(CLiveConfig* pConfig, bool realTime){	m_pConfig = pConfig;	if ((m_lameParams = lame_init()) == NULL) {		error_message("error: failed to get lame_global_flags");		return false;	} 	lame_set_num_channels(m_lameParams,			      m_pConfig->GetIntegerValue(CONFIG_AUDIO_CHANNELS));	lame_set_in_samplerate(m_lameParams,			       m_pConfig->GetIntegerValue(CONFIG_AUDIO_SAMPLE_RATE));	lame_set_brate(m_lameParams,		       m_pConfig->GetIntegerValue(CONFIG_AUDIO_BIT_RATE) / 1000);	lame_set_mode(m_lameParams,		      (m_pConfig->GetIntegerValue(CONFIG_AUDIO_CHANNELS) == 1 ? MONO : STEREO));			lame_set_quality(m_lameParams,2);	// no match for silent flag	// no match for gtkflag	// THIS IS VERY IMPORTANT. MP4PLAYER DOES NOT SEEM TO LIKE VBR	lame_set_bWriteVbrTag(m_lameParams,0);	if (lame_init_params(m_lameParams) == -1) {		error_message("error: failed init lame params");		return false;	}	if (lame_get_in_samplerate(m_lameParams) != lame_get_out_samplerate(m_lameParams)) {		error_message("warning: lame audio sample rate mismatch - wanted %d got %d",			      lame_get_in_samplerate(m_lameParams), 			      lame_get_out_samplerate(m_lameParams));		m_pConfig->SetIntegerValue(CONFIG_AUDIO_SAMPLE_RATE,			lame_get_out_samplerate(m_lameParams));	}	m_samplesPerFrame = MP4AV_Mp3GetSamplingWindow(		m_pConfig->GetIntegerValue(CONFIG_AUDIO_SAMPLE_RATE));	m_mp3FrameMaxSize = (u_int)(1.25 * m_samplesPerFrame) + 7200;	m_mp3FrameBufferSize = 2 * m_mp3FrameMaxSize;	m_mp3FrameBufferLength = 0;	m_mp3FrameBuffer = (u_int8_t*)malloc(m_mp3FrameBufferSize);	if (!m_mp3FrameBuffer) {		return false;	}	return true;}u_int32_t CLameAudioEncoder::GetSamplesPerFrame(){	return m_samplesPerFrame;}bool CLameAudioEncoder::EncodeSamples(	int16_t* pSamples, 	u_int32_t numSamplesPerChannel,	u_int8_t numChannels){	if (numChannels != 1 && numChannels != 2) {		return false;	// invalid numChannels	}	u_int32_t mp3DataLength = 0;	if (pSamples != NULL) { 		int16_t* pLeftBuffer = NULL;		bool mallocedLeft = false;		int16_t* pRightBuffer = NULL;		bool mallocedRight = false;		if (numChannels == 1) {		  pLeftBuffer = pSamples;		  // both right and left need to be the same - can't 		  // pass NULL as pRightBuffer		  pRightBuffer = pSamples;		} else { // numChannels == 2		  // let lame handle stereo to mono conversion			DeinterleaveStereoSamples(				pSamples, 				numSamplesPerChannel,				&pLeftBuffer, 				&pRightBuffer);			mallocedLeft = true;			mallocedRight = true;		} 		// call lame encoder		mp3DataLength = lame_encode_buffer(			m_lameParams,			pLeftBuffer, 			pRightBuffer, 			m_samplesPerFrame,			(unsigned char*)&m_mp3FrameBuffer[m_mp3FrameBufferLength], 			m_mp3FrameBufferSize - m_mp3FrameBufferLength);		if (mallocedLeft) {			free(pLeftBuffer);			pLeftBuffer = NULL;		}		if (mallocedRight) {			free(pRightBuffer);			pRightBuffer = NULL;		}	} else { // pSamples == NULL		// signal to stop encoding	  mp3DataLength = 	    lame_encode_flush( m_lameParams,			       (unsigned char*)&m_mp3FrameBuffer[m_mp3FrameBufferLength], 			       m_mp3FrameBufferSize - m_mp3FrameBufferLength);	}	m_mp3FrameBufferLength += mp3DataLength;	//debug_message("audio -return from lame_encode_buffer is %d %d", mp3DataLength, m_mp3FrameBufferLength);	return (mp3DataLength >= 0);}bool CLameAudioEncoder::GetEncodedFrame(	u_int8_t** ppBuffer, 	u_int32_t* pBufferLength,	u_int32_t* pNumSamplesPerChannel){	const u_int8_t* mp3Frame;	u_int32_t mp3FrameLength;	if (!MP4AV_Mp3GetNextFrame(m_mp3FrameBuffer, m_mp3FrameBufferLength, 	  &mp3Frame, &mp3FrameLength)) {	  //debug_message("Can't find frame header - len %d", m_mp3FrameBufferLength);		return false;	}	// check if we have all the bytes for the MP3 frame	if (mp3FrameLength > m_mp3FrameBufferLength) {	  //debug_message("Not enough in buffer - %d %d", m_mp3FrameBufferLength, mp3FrameLength);		return false;	}	// need a buffer for this MP3 frame	*ppBuffer = (u_int8_t*)malloc(mp3FrameLength);	if (*ppBuffer == NULL) {	  error_message("Cannot alloc memory");		return false;	}	// copy the MP3 frame	memcpy(*ppBuffer, mp3Frame, mp3FrameLength);	*pBufferLength = mp3FrameLength;	// shift what remains in the buffer down	memcpy(m_mp3FrameBuffer, 		mp3Frame + mp3FrameLength, 		m_mp3FrameBufferLength - mp3FrameLength);	m_mp3FrameBufferLength -= mp3FrameLength;	*pNumSamplesPerChannel = m_samplesPerFrame;	return true;}void CLameAudioEncoder::Stop(){	free(m_mp3FrameBuffer);	m_mp3FrameBuffer = NULL;	lame_close(m_lameParams);	m_lameParams = NULL;}

⌨️ 快捷键说明

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