AudioDecoderACM.cpp
资源名称:VC++视频传输.rar [点击查看]
上传用户:hxb_1234
上传日期:2010-03-30
资源大小:8328k
文件大小:12k
源码类别:
VC书籍
开发平台:
Visual C++
- /**************************************************************************************
- * *
- * *
- **************************************************************************************/
- #include "AudioDecoderACM.h"
- /*
- * ACM封装器类
- *
- */
- MediaAudioDecoderACM::MediaAudioDecoderACM()
- {
- this->out_buffer = NULL;
- this->in_buffer = NULL;
- this->oFormat = NULL;
- this->ring = new MediaRingBuffer();
- }
- MediaAudioDecoderACM::~MediaAudioDecoderACM()
- {
- delete this->ring;
- }
- /*
- * 媒体项函数
- */
- media_type_t MediaAudioDecoderACM::GetType()
- {
- return MEDIA_TYPE_AUDIO_DECODER;
- }
- char *MediaAudioDecoderACM::GetName()
- {
- if(this->hacm != NULL) {
- char *name;
- HACMDRIVERID dId;
- ACMDRIVERDETAILS details;
- name = (char *) new char[128];
- if(acmDriverID((HACMOBJ) this->hacm, &dId, 0) > 0) {
- return NULL;
- }
- memset(&details, 0, sizeof(ACMDRIVERDETAILS));
- details.cbStruct = sizeof(ACMDRIVERDETAILS);
- if(acmDriverDetails(dId, &details, 0) == MMSYSERR_INVALHANDLE) {
- return NULL;
- }
- strcpy(name, details.szLongName);
- return name;
- }
- return "ACM Wrapper";
- }
- MP_RESULT MediaAudioDecoderACM::Connect(MediaItem *item)
- {
- MMRESULT mmres;
- WAVEFORMATEX *inFormat;
- DWORD dwOutputFormatSize;
- if(item && item->GetType() == MEDIA_TYPE_DECAPS) {
- this->decaps = (MediaItemDecaps *) item;
- inFormat = this->decaps->GetAudioFormat(0);
- if(inFormat->wFormatTag == 85 && inFormat->cbSize != 12) {
- MPEGLAYER3WAVEFORMAT *format;
- format = (MPEGLAYER3WAVEFORMAT *) inFormat;
- format->wfx.cbSize = 12;
- format->wID = 1;
- format->fdwFlags = 2;
- format->nBlockSize = 313;
- format->nFramesPerBlock = 1;
- format->nCodecDelay = 1393;
- }
- if (acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, (LPVOID)&dwOutputFormatSize)) {
- return MP_RESULT_ERROR;
- }
- this->oFormat = (WAVEFORMATEX *) new WAVEFORMATEX;
- this->oFormat->wFormatTag = WAVE_FORMAT_PCM;
- if (acmFormatSuggest(NULL, inFormat, this->oFormat, dwOutputFormatSize, ACM_FORMATSUGGESTF_WFORMATTAG)) {
- }
- if (oFormat->wBitsPerSample!=8 && oFormat->wBitsPerSample!=16)
- oFormat->wBitsPerSample=16;
- if (oFormat->nChannels!=1 && oFormat->nChannels!=2)
- oFormat->nChannels = 2;
- oFormat->nBlockAlign = (oFormat->wBitsPerSample/8) * oFormat->nChannels;
- oFormat->nAvgBytesPerSec = oFormat->nBlockAlign * oFormat->nSamplesPerSec;
- oFormat->cbSize = 0;
- mmres = acmStreamOpen(&hacm, NULL, inFormat,
- this->oFormat, NULL, NULL, 0, ACM_STREAMOPENF_NONREALTIME);
- if(mmres != 0) {
- return MP_RESULT_ERROR;
- }
- this->inputSize = max(2048 - (2048 % inFormat->nBlockAlign), 8*inFormat->nBlockAlign);
- this->outputSize = 0;
- if (acmStreamSize(this->hacm, this->inputSize, &this->outputSize, ACM_STREAMSIZEF_SOURCE))
- return MP_RESULT_ERROR;
- this->ring->Init();
- this->in_buffer = (char *) new char[this->inputSize];
- this->out_buffer = (char *) new char[this->outputSize];
- this->acmInLeft = 0;
- this->acmLeft = 0;
- return MP_RESULT_OK;
- }
- return MP_RESULT_ERROR;
- }
- MP_RESULT MediaAudioDecoderACM::ReleaseConnections()
- {
- this->decaps = NULL;
- free(this->in_buffer);
- this->in_buffer = NULL;
- free(this->out_buffer);
- this->out_buffer = NULL;
- free(this->oFormat);
- this->oFormat = NULL;
- acmStreamClose(this->hacm, 0);
- return MP_RESULT_OK;
- }
- DWORD MediaAudioDecoderACM::GetCaps()
- {
- return 0;
- }
- MP_RESULT MediaAudioDecoderACM::Configure(HINSTANCE hInstance, HWND hwnd)
- {
- return MP_RESULT_ERROR;
- }
- WAVEFORMATEX *MediaAudioDecoderACM::GetAudioFormat()
- {
- return this->oFormat;
- }
- MP_RESULT MediaAudioDecoderACM::EmptyAudioBuffer()
- {
- if(this->ring)
- this->ring->Init();
- this->acmLeft = 0;
- this->acmInLeft = 0;
- return MP_RESULT_OK;
- }
- unsigned int MediaAudioDecoderACM::Decompress(void *buffer, unsigned int size)
- {
- DWORD i, done;
- MMRESULT res;
- done = 0;
- if(this->hacm) {
- if(size < 16384) {
- if(this->acmLeft > 0 && !this->ring->IsFullFor(this->acmLeft)) {
- this->ring->Write((char *) this->out_buffer, this->acmLeft);
- this->acmLeft = 0;
- }
- if(this->acmLeft > 0)
- goto done;
- if(!this->acmInLeft) {
- if(this->decaps->ReadAudioData(0, this->in_buffer, this->inputSize) != this->inputSize) {
- return done;
- }
- }
- memset(&this->acmHeader, 0, sizeof(ACMSTREAMHEADER));
- this->acmHeader.cbStruct = sizeof(ACMSTREAMHEADER);
- if(this->acmInLeft > 0) {
- memcpy(this->in_buffer, ((char *) this->in_buffer) + this->inputSize - this->acmInLeft, this->acmInLeft);
- if(this->decaps->ReadAudioData(0, ((char *) this->in_buffer) + this->acmInLeft, this->inputSize - this->acmInLeft) != (this->inputSize - this->acmInLeft) ) {
- return done;
- }
- this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
- this->acmHeader.cbSrcLength = this->inputSize;
- this->acmInLeft = 0;
- }
- else {
- this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
- this->acmHeader.cbSrcLength = this->inputSize;
- }
- this->acmHeader.pbDst = (unsigned char *) this->out_buffer;
- this->acmHeader.cbDstLength = this->outputSize;
- res = acmStreamPrepareHeader(this->hacm, &this->acmHeader, 0);
- if(res > 0) {
- return done;
- }
- res = acmStreamConvert(this->hacm, &this->acmHeader, 0);
- if(res > 0) {
- acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
- return done;
- }
- while(!this->ring->IsFullFor(this->acmHeader.cbDstLengthUsed)) {
- this->ring->Write((char *) this->acmHeader.pbDst, this->acmHeader.cbDstLengthUsed);
- acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
- if(!this->acmInLeft) {
- if(this->decaps->ReadAudioData(0, this->in_buffer, this->inputSize) != this->inputSize) {
- return done;
- }
- }
- memset(&this->acmHeader, 0, sizeof(ACMSTREAMHEADER));
- this->acmHeader.cbStruct = sizeof(ACMSTREAMHEADER);
- if(this->acmInLeft > 0) {
- memcpy(this->in_buffer, ((char *) this->in_buffer) + this->inputSize - this->acmInLeft, this->acmInLeft);
- if(this->decaps->ReadAudioData(0, ((char *) this->in_buffer) + this->acmInLeft, this->inputSize - this->acmInLeft) != (this->inputSize - this->acmInLeft) ) {
- return done;
- }
- this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
- this->acmHeader.cbSrcLength = this->inputSize;
- this->acmInLeft = 0;
- }
- else {
- this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
- this->acmHeader.cbSrcLength = this->inputSize;
- }
- this->acmHeader.pbDst = (unsigned char *) this->out_buffer;
- this->acmHeader.cbDstLength = this->outputSize;
- res = acmStreamPrepareHeader(this->hacm, &this->acmHeader, 0);
- if(res > 0) {
- return done;
- }
- res = acmStreamConvert(this->hacm, &this->acmHeader, 0);
- if(res > 0) {
- acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
- return done;
- }
- this->acmInLeft = this->inputSize - this->acmHeader.cbSrcLengthUsed;
- }
- this->acmLeft = this->acmHeader.cbDstLengthUsed;
- acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
- done:
- this->ring->Read((char *) buffer, size);
- done += size;
- return done;
- }
- else {
- unsigned int blocks = size / 16384;
- for(i = 0; i < blocks; i++) {
- if(this->acmLeft > 0 && !this->ring->IsFullFor(this->acmLeft)) {
- this->ring->Write((char *) this->out_buffer, this->acmLeft);
- this->acmLeft = 0;
- }
- if(this->acmLeft > 0)
- goto done2;
- if(!this->acmInLeft) {
- if(this->decaps->ReadAudioData(0, this->in_buffer, this->inputSize) != this->inputSize) {
- return done;
- }
- }
- memset(&this->acmHeader, 0, sizeof(ACMSTREAMHEADER));
- this->acmHeader.cbStruct = sizeof(ACMSTREAMHEADER);
- if(this->acmInLeft > 0) {
- memcpy(this->in_buffer, ((char *) this->in_buffer) + this->inputSize - this->acmInLeft, this->acmInLeft);
- if(this->decaps->ReadAudioData(0, ((char *) this->in_buffer) + this->acmInLeft, this->inputSize - this->acmInLeft) != (this->inputSize - this->acmInLeft) ) {
- return done;
- }
- this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
- this->acmHeader.cbSrcLength = this->inputSize;
- this->acmInLeft = 0;
- }
- else {
- this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
- this->acmHeader.cbSrcLength = this->inputSize;
- }
- this->acmHeader.pbDst = (unsigned char *) this->out_buffer;
- this->acmHeader.cbDstLength = this->outputSize;
- res = acmStreamPrepareHeader(this->hacm, &this->acmHeader, 0);
- if(res > 0) {
- return done;
- }
- res = acmStreamConvert(this->hacm, &this->acmHeader, 0);
- if(res > 0) {
- acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
- return done;
- }
- while(!this->ring->IsFullFor(this->acmHeader.cbDstLengthUsed)) {
- this->ring->Write((char *) this->acmHeader.pbDst, this->acmHeader.cbDstLengthUsed);
- acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
- if(!this->acmInLeft) {
- if(this->decaps->ReadAudioData(0, this->in_buffer, this->inputSize) != this->inputSize) {
- return done;
- }
- }
- memset(&this->acmHeader, 0, sizeof(ACMSTREAMHEADER));
- this->acmHeader.cbStruct = sizeof(ACMSTREAMHEADER);
- if(this->acmInLeft > 0) {
- memcpy(this->in_buffer, ((char *) this->in_buffer) + this->inputSize - this->acmInLeft, this->acmInLeft);
- if(this->decaps->ReadAudioData(0, ((char *) this->in_buffer) + this->acmInLeft, this->inputSize - this->acmInLeft) != (this->inputSize - this->acmInLeft) ) {
- return done;
- }
- this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
- this->acmHeader.cbSrcLength = this->inputSize;
- this->acmInLeft = 0;
- }
- else {
- this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
- this->acmHeader.cbSrcLength = this->inputSize;
- }
- this->acmHeader.pbDst = (unsigned char *) this->out_buffer;
- this->acmHeader.cbDstLength = this->outputSize;
- res = acmStreamPrepareHeader(this->hacm, &this->acmHeader, 0);
- if(res > 0) {
- return done;
- }
- res = acmStreamConvert(this->hacm, &this->acmHeader, 0);
- if(res > 0) {
- acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
- return done;
- }
- this->acmInLeft = this->inputSize - this->acmHeader.cbSrcLengthUsed;
- }
- this->acmLeft = this->acmHeader.cbDstLengthUsed;
- acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
- done2:
- this->ring->Read(((char *) buffer) + i*16384, 16384);
- done += 16384;
- }
- int left = size - (blocks * 16384);
- if(left > 0) {
- this->Decompress((void *) ((char *) buffer + size - left), left);
- done += left;
- }
- return done;
- }
- }
- return 0;
- }