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

📄 encoder.c

📁 jpeg and mpeg 编解码技术源代码
💻 C
字号:

/* MBSoft Encoder DLL interface module.*/

#include <windows.h>
#include <commctrl.h>

#include "aacenc.h"
#include "common.h"	/* common module */
#include "bitstream.h"	/* bit stream module */

#include "enc.h"	/* encoder cores */

#define BITHEADERBUFSIZE (65536)

/* ---------- functions ---------- */


#define HIGHQ 7
#define NORMALQ 10
#define LOWQ 13


int ByteAlign(BsBitStream* ptrBs)
{
	int len, i,j;
	len = BsBufferNumBit( ptrBs );
	   
	j = (8 - (len%8))%8;

	if ((len % 8) == 0) j = 0;
	for( i=0; i<j; i++ ) {
		BsPutBit( ptrBs, 0, 1 ); 
	}
	return j;
}

mbAACStream *mbEncodeInit(mbAACConfig *ac, int *samplesToRead, int *bitBufferSize, int *headerSize)
{
	int frameNumSample,delayNumSample;
	int ch;
	int VBR_setting;
	mbAACStream *as;

	int startupNumFrame;

	as = malloc( sizeof(mbAACStream));
	if ((as->inputBuffer = (float**)malloc( ac->channels*sizeof(float*)))==NULL)
		return NULL;
	for (ch=0; ch < ac->channels; ch++)
	{
		if ((as->inputBuffer[ch]=(float*)malloc( 1024*sizeof(float)))==NULL)
			return NULL;
	}

	if (ac->sampling_rate != 44100)
		return NULL;
	if (ac->use_VBR) {
		if ((ac->VBR_setting > 2)||(ac->VBR_setting < 0))
			return NULL;
	} else {
		switch (ac->bit_rate) {
		case 64000:
		case 80000:
		case 96000:
		case 112000:
		case 128000:
		case 160000:
		case 192000:
		case 224000:
		case 256000:
			break;
		default:
			return NULL;
		}
	}
	if (ac->channels != 2)
		return NULL;
	if ((ac->profile != MAIN_PROFILE)&&(ac->profile != LOW_PROFILE))
		return NULL;

	as->total_bits = 0;
	as->frames = 0;
	as->cur_frame = 0;
	as->channels = ac->channels;
	as->sampling_rate = ac->sampling_rate;
	as->write_header = ac->write_header;
	as->use_VBR = ac->use_VBR;
	as->profile = ac->profile;
	as->is_first_frame = 1;

	if (as->write_header) {
		*headerSize = 17;
	} else {
		*headerSize = 0;
	}

	if (ac->use_VBR) {
		ac->bit_rate = 128000;
	}

	if (ac->VBR_setting == VBR_HIGH)
		VBR_setting = HIGHQ;
	else if (ac->VBR_setting == VBR_LOW)
		VBR_setting = LOWQ;
	else if (ac->VBR_setting == VBR_NORMAL)
		VBR_setting = NORMALQ;

	EncTfInit(
		ac->channels,
		(float)ac->sampling_rate,
		(float)ac->bit_rate,
		ac->profile,
		VBR_setting,
		ac->write_header,
		1); // Should be removed

	frameNumSample = 1024;
	delayNumSample = 2*frameNumSample;

	*samplesToRead = frameNumSample * ac->channels;

	as->frame_bits = (int)(ac->bit_rate*frameNumSample/ac->sampling_rate+0.5);
	if (ac->use_VBR) {
		*bitBufferSize = (int)(as->frame_bits * 5 + 8)/8; // Should be enough
	} else {
		*bitBufferSize = (int)(as->frame_bits * 2 + 8)/8;
	}


	/* num frames to start up encoder due to delay compensation */
	startupNumFrame = (delayNumSample+frameNumSample-1)/frameNumSample;

	/* process audio file frame by frame */
	as->cur_frame = -startupNumFrame;
	as->available_bits = 8184;

	return as;
}

int mbEncodeFrame(mbAACStream *as, short *Buffer, int Samples, unsigned char *bitBuffer, int *bitBufSize)
{
	int i, error;
	int usedNumBit, usedBytes;
	BsBitStream *bitBuf;

	// Is this the last (incomplete) frame
	if ((Samples < 2048)&&(Samples > 0)) {
		// Padd with zeros
		memset(Buffer + Samples, 0, (2048-Samples)*sizeof(short));
	}

	// Process Buffer
	if (as->channels == 2)
	{
		if (Samples > 0)
			for (i = 0; i < 1024; i++)
			{
				as->inputBuffer[0][i] = *Buffer++;
				as->inputBuffer[1][i] = *Buffer++;
			}
		else // (Samples == 0) when called by mbEncodeFinish
			for (i = 0; i < 1024; i++)
			{
				as->inputBuffer[0][i] = 0;
				as->inputBuffer[1][i] = 0;
			}
	} else {
		// No mono supported yet (basically only a problem with decoder
		// the encoder in fact supports it).
		return MBERROR;
	}

	if (as->is_first_frame) {
		EncTfFrame(
			as->inputBuffer,
			(BsBitStream*)NULL,
			0,
			as->frame_bits,
			0,
			as->frame_bits + 8184,
			as->use_VBR);

		as->is_first_frame = 0;
		as->cur_frame++;

		*bitBufSize = 0;

		return MBNO_ERROR;
	}

	bitBuf = BsOpenWrite(as->frame_bits * 10);

	/* compute available number of bits */
	/* frameAvailNumBit contains number of bits in reservoir */
	/* variable bit rate: don't exceed bit reservoir size */
	if (as->available_bits > 8184)
		as->available_bits = 8184;
		
	/* Add to frameAvailNumBit the number of bits for this frame */
	as->available_bits += as->frame_bits;

	/* Encode frame */
	error = EncTfFrame(
		as->inputBuffer,
		bitBuf,
		as->available_bits,
		as->frame_bits,
		8,
		as->frame_bits + 8184,
		as->use_VBR);

	if (error == MBERROR)
		return MBERROR;

	usedNumBit = BsBufferNumBit(bitBuf);
	as->total_bits += usedNumBit;

	// Copy bitBuf into bitBuffer here
	usedBytes = (int)(usedNumBit/8)+0.5;
	*bitBufSize = usedBytes;
	for (i = 0; i < usedBytes; i++)
		bitBuffer[i] = bitBuf->data[i];
	BsClose(bitBuf);

	/* Adjust available bit counts */
	as->available_bits -= usedNumBit;    /* Subtract bits used */

	as->cur_frame++;

	return MBNO_ERROR;
}

int mbEncodeFinish(mbAACStream *as, unsigned char *bitBuffer, int *bitBufSize)
{
	unsigned char tmpBitBuffer[2048];
	int tmpBitBufSize, i;
	mbEncodeFrame(as, NULL, 0, tmpBitBuffer, &tmpBitBufSize);
	for (i = 0; i < tmpBitBufSize; i++)
		bitBuffer[i] = tmpBitBuffer[i];
	mbEncodeFrame(as, NULL, 0, tmpBitBuffer, bitBufSize);
	for (i = 0; i < *bitBufSize; i++)
		bitBuffer[i+tmpBitBufSize] = tmpBitBuffer[i];
	*bitBufSize += tmpBitBufSize;

	return MBNO_ERROR;
}

int mbEncodeFree(mbAACStream *as, unsigned char *headerBuf)
{
	BsBitStream *bitHeader;
	float seconds;
	int bits, bytes, ch;

	seconds = as->sampling_rate/1024;
	seconds = as->cur_frame/seconds;

	/* free encoder memory */
	EncTfFree();

	if (as->write_header)
	{
		int i;
		static int SampleRates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,0};

		as->total_bits += 17 * 8;

		bitHeader = BsOpenWrite(BITHEADERBUFSIZE);

		for (i = 0; ; i++)
		{
			if (SampleRates[i] == as->sampling_rate)
				break;
			else if (SampleRates[i] == 0)
			{
				return MBERROR;
			}
		}

		// ADIF_Header
		BsPutBit(bitHeader,'A',8);
		BsPutBit(bitHeader,'D',8);
		BsPutBit(bitHeader,'I',8);
		BsPutBit(bitHeader,'F',8);
		BsPutBit(bitHeader,0,1);   // Copyright present
		BsPutBit(bitHeader,0,1);   // Original
		BsPutBit(bitHeader,0,1);   // Home
		BsPutBit(bitHeader,0,1);   // Bitstream type
		BsPutBit(bitHeader,(int)(as->total_bits/seconds),23);  // Bitrate
		BsPutBit(bitHeader, 0, 4);   // num program config elements

		// ADIF_buffer_fulness
		BsPutBit(bitHeader, 0, 20);

		// program_config_element
		BsPutBit(bitHeader,0,4);
		BsPutBit(bitHeader,as->profile,2);
		BsPutBit(bitHeader,i,4);
		BsPutBit(bitHeader,1,4);
		BsPutBit(bitHeader,0,4);
		BsPutBit(bitHeader,0,4);
		BsPutBit(bitHeader,0,2);
		BsPutBit(bitHeader,0,3);
		BsPutBit(bitHeader,0,4);
		BsPutBit(bitHeader,0,1);
		BsPutBit(bitHeader,0,1);
		BsPutBit(bitHeader,0,1);
		// element_list
		BsPutBit(bitHeader,(as->channels == 2),1);
		BsPutBit(bitHeader,0,4);

		ByteAlign(bitHeader);
		// Comment
		BsPutBit(bitHeader,0,8);

		bits = BsBufferNumBit(bitHeader);

		// Copy bitBuf into bitBuffer here
		bytes = (int)((bits+8)/8);
		for (i = 0; i < bytes; i++)
			headerBuf[i] = bitHeader->data[i];
		BsClose(bitHeader);
	}

	for (ch=0; ch < as->channels; ch++)
		if(as->inputBuffer[ch]) free(as->inputBuffer[ch]);
	if(as->inputBuffer) free(as->inputBuffer);
	free(as);

	return MBNO_ERROR;
}

mbVersion *mbEncodeVersion()
{
	mbVersion *mbv = malloc(sizeof(mbVersion));

	mbv->DLLMajorVersion = 1;
	mbv->DLLMinorVersion = 0;
	mbv->MajorVersion = 0;
	mbv->MinorVersion = 4;
	strcpy(mbv->HomePage, "http://fly.to/mbsoft/");

	return mbv;
}

BOOL APIENTRY DllMain(HANDLE hModule, 
                      DWORD  ul_reason_for_call, 
                      LPVOID lpReserved)
{
    return TRUE;
}


⌨️ 快捷键说明

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