📄 maiaacdec.c
字号:
/* <LIC_AMD_STD> * Copyright (c) 2005 Advanced Micro Devices, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * The full GNU General Public License is included in this distribution in the * file called COPYING * </LIC_AMD_STD> *//* <CTL_AMD_STD> * </CTL_AMD_STD> *//* <DOC_AMD_STD> * Filename: maiaacdec.c - AAC Audio decoder interfaces for MAIengine * </DOC_AMD_STD> */#if defined(WIN32) || defined(UNDER_CE) #include <windows.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "mai_osal.h" /* needed for threads */#include "mai_component.h" /* was mai_def.h, mai_readandparse.h */#include "mai_compbase.h"#include "audio_change_info.h"#include "faad.h"#include "aacdecode.h"#ifdef TRACE_BUILD #define DPRINTF(_args_) MAIOSDebugPrint _args_ #define PTSPRINTF(_args_) MAIOSDebugPrint _args_ #define SYNCPRINTF(_args_) MAIOSDebugPrint _args_ #define APIPRINTF(_args_) MAIOSDebugPrint _args_ #define ERRORPRINTF(_args_) MAIOSDebugPrint _args_#else #define DPRINTF(_args_) /* MAIOSDebugPrint _args_ */ #define PTSPRINTF(_args_) /* MAIOSDebugPrint _args_ */ #define SYNCPRINTF(_args_) /* MAIOSDebugPrint _args_ */ #define APIPRINTF(_args_) /* MAIOSDebugPrint _args_ */ #define ERRORPRINTF(_args_) /* MAIOSDebugPrint _args_ */#endif#define DEFAULT_INBUFSIZE 8*1024#define DEFAULT_INBUFCOUNT 8//#define DUMP_TO_FILE //#define DUMP_AUDIO_TO_FILE /* Decoder State Definitions: MAI_RUNSTATE_NONE - decoder not initialized MAI_RUNSTATE_INIT - decoder initialized, decodes not started yet MAI_RUNSTATE_PLAYING - decoder initialized, decodes active MAI_RUNSTATE_PAUSED - decoder initialized, decodes paused MAI_RUNSTATE_DESTROYING - MAICompEnd() in progress - destroying decoder*/#define MP4_BUF_PAD 0x4000#define AAC_BUF_PAD 0x1000 #define AAC_FROM_DEMUX_BUF_PAD 0xaenum{ AAC_TYPE_RAW, // 21 xc syncword AAC_TYPE_ADIF, // 02 9f syncword AAC_TYPE_ADTS, // ff f9 syncword AAC_TYPE_MP4, // not used: we only handle mp4 containers with demux AAC_TYPE_RAW_FROM_DEMUX, // 21 xc syncword usually but not always};static unsigned short syncwords[] = { 0x0c21 & 0x00fe, 0x029f & 0xffff, 0xf9ff & 0xf0ff, 0x0000 & 0xcff, 0x0c21 & 0xcff,};/* Our component's private processor variables are stored here */typedef struct ProcessorInfo_s { unsigned int m_uiAACtype; unsigned int m_uiProcessLoops; unsigned int m_uiNeedsInit; unsigned int m_uiStreamPosition; unsigned int m_bNewFormat; unsigned int m_uiPrevSRate; unsigned int m_nPrevChannels; unsigned int m_LeftOverInput; unsigned short m_usSyncword; int m_iDemuxSyncwordCounter; int m_iDoNotOutputCounter; int m_uiBufPadSize; audiodecChangeInfo ci; unsigned char *m_pucAudioInBuf; unsigned char *m_pucLeftOver;} ProcessorInfo_t;#ifdef DUMP_AUDIO_TO_FILE #define DUMPAUDIO(bb) dump_audio(bb) void dump_audio(MAICompBuffer_t *pBufferInfo) { static FILE *ofp = NULL; #if defined(UNDER_CE) if (ofp == NULL) ofp = fopen("\\Hard Disk\\cedumpdecout.pcm", "wb"); #elif defined(WIN32) if (ofp == NULL) ofp = fopen("c:\\temp\\windumpdecout.pcm", "wb"); #else if (ofp == NULL) ofp = fopen("dumpaac.pcm", "wb"); #endif if (ofp != NULL) fwrite(pBufferInfo->pBuffer, 1, pBufferInfo->uiDataSize, ofp); }#else #define DUMPAUDIO(bb) #endifstatic void open_aac(ProcessorInfo_t *pPInfo){ pPInfo->m_uiProcessLoops = 0; pPInfo->m_LeftOverInput = 0; pPInfo->m_uiStreamPosition = 0; pPInfo->m_uiPrevSRate=0; pPInfo->m_nPrevChannels=0; pPInfo->m_bNewFormat = 1; pPInfo->m_uiNeedsInit = 0; pPInfo->m_iDemuxSyncwordCounter = 0; pPInfo->m_uiBufPadSize = MP4_BUF_PAD; /* open the AAC audio decoder */ init_aac(); APIPRINTF((M_TEXT("AACDEC: open_aac() done\n")));}MAIStatus_e _startprocessing(MAICompHandle_t hComp){ ProcessorInfo_t *pPInfo=(ProcessorInfo_t *)HCOMP_TO_USERINFO(hComp); MAIStatus_e eStatus = MAI_STATUS_OK; APIPRINTF((M_TEXT("AACDEC: _startprocessing() enter\n"))); if (!MAICompBase_IsState(hComp, MAI_RUNSTATE_NONE)) eStatus=MAI_STATUS_WRONGSTATE; else { APIPRINTF((M_TEXT("AACDEC: _startprocessing() Init codec\n"))); pPInfo->m_uiNeedsInit = 1; // do not open_aac(pPInfo) here. // Needs to be opened when first buffer comes so that we can check type of stream. /* Register output setup (needed for Read/WriteBuffer) */ MAICompBase_RegisterOutput(hComp, 0, M_NULL /* pfOutputGetBuffer */, M_NULL /* pfOutputPutBuffer */, hComp, 8*1024, 64); } if (eStatus==MAI_STATUS_OK) { if (pPInfo->m_pucLeftOver == NULL) { pPInfo->m_pucLeftOver = (unsigned char *)malloc(MP4_BUF_PAD); if (pPInfo->m_pucLeftOver == NULL) { ERRORPRINTF((M_TEXT("Cannot malloc pPInfo->m_pucLeftOver."))); eStatus = MAI_STATUS_MEMORY; } } /* call default StartProcessing */ if (eStatus==MAI_STATUS_OK) MAICompBase_StartProcessing(hComp); } APIPRINTF((M_TEXT("AACDEC: _startprocessing() exit: status=0x%X\n"), eStatus)); return eStatus;}MAIStatus_e _endprocessing(MAICompHandle_t hComp){ ProcessorInfo_t *pPInfo=(ProcessorInfo_t *)HCOMP_TO_USERINFO(hComp); MAIStatus_e eStatus = MAI_STATUS_OK; APIPRINTF((M_TEXT("AACDEC: _endprocessing() enter\n"))); if (MAICompBase_IsState(hComp, MAI_RUNSTATE_NONE)) eStatus=MAI_STATUS_WRONGSTATE; else { pPInfo->m_uiProcessLoops = 0; pPInfo->m_uiNeedsInit = 1; close_aac(); if (pPInfo->m_pucLeftOver != NULL) { free(pPInfo->m_pucLeftOver); pPInfo->m_pucLeftOver = NULL; pPInfo->m_LeftOverInput = 0; } if (pPInfo->m_pucAudioInBuf != NULL) { free(pPInfo->m_pucAudioInBuf); pPInfo->m_pucAudioInBuf = NULL; } } MAICompBase_EndProcessing(hComp); APIPRINTF((M_TEXT("AACDEC: _endprocessing() exit: status=0x%X\n"), eStatus)); return eStatus;}MAIStatus_e _processbuffer(MAICompHandle_t hComp, MAICompBuffer_t *pInBufferInfo){ ProcessorInfo_t *pPInfo=(ProcessorInfo_t *)HCOMP_TO_USERINFO(hComp); MAIStatus_e eStatus = MAI_STATUS_OK; int insize = pInBufferInfo->uiDataSize; unsigned char *inbuf = pInBufferInfo->pBuffer; unsigned char *inbuf_ptr; unsigned int uiBufFlags=pInBufferInfo->dwFlags; unsigned int output_sample_count = 0; MAICompBuffer_t BufferInfo; int last_frame = 0; int uiPrevBufPadSize = 0; m_bool bForceDecode=M_FALSE; #if 0 { //unsigned int ii; //DPRINTF((M_TEXT("INPUTINPUTINPUTINPUTINPUTINPUT size %x, "), pInBufferInfo->uiDataSize)); //for (ii = 0; ii < pInBufferInfo->uiDataSize; ii++) //for (ii = 0; ii < ((pInBufferInfo->uiDataSize > 16) ? 16 : pInBufferInfo->uiDataSize); ii++) // DPRINTF((M_TEXT(" %02x"), inbuf[ii])); DPRINTF((M_TEXT("INPUTINPUTINPUTINPUTINPUTINPUT size %x, %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n"), pInBufferInfo->uiDataSize, inbuf[0], inbuf[1], inbuf[2], inbuf[3], inbuf[4], inbuf[5], inbuf[6], inbuf[7], inbuf[8], inbuf[9], inbuf[10], inbuf[11], inbuf[12], inbuf[13], inbuf[14], inbuf[15])); //DPRINTF((M_TEXT("\n"))); //for (ii = 0; ii < 10; ii++) // printf("%c", isprint(inbuf[ii]) ? inbuf[ii] : '.'); //printf("\n"); } #endif APIPRINTF((M_TEXT("AACDEC _processbuffer() datasize=%d flags=0x%X\n"), pInBufferInfo->uiDataSize, pInBufferInfo->dwFlags)); #ifdef DUMP_TO_FILE if (!pPInfo->m_uiNeedsInit) { static FILE *ofp = NULL; if (ofp == NULL) ofp = fopen("c:\\temp\\dump.aac", "wb"); if (ofp != NULL) fwrite(pInBufferInfo->pBuffer, 1, pInBufferInfo->uiDataSize, ofp); return eStatus; } #endif if (pPInfo->m_uiNeedsInit) { open_aac(pPInfo); if (inbuf[0] == 'f' && inbuf[1] == 'a' && inbuf[2] == 'a' && inbuf[3] == 'c') { /* special case for audio streams coming from demux */ APIPRINTF((M_TEXT("special case for audio streams coming from demux\n"))); SYNCPRINTF((M_TEXT("special case for audio streams coming from demux\n"))); pPInfo->m_uiBufPadSize = AAC_FROM_DEMUX_BUF_PAD; pPInfo->m_uiAACtype = AAC_TYPE_RAW_FROM_DEMUX; pPInfo->m_iDemuxSyncwordCounter = -2; APIPRINTF((M_TEXT("AACDEC _processbuffer pPInfo->m_uiBufPadSize %x \n"), pPInfo->m_uiBufPadSize)); } } else if (pPInfo->m_uiBufPadSize != AAC_FROM_DEMUX_BUF_PAD) { switch (frameInfo.header_type) { default: case 0: if (mp4file) pPInfo->m_uiBufPadSize = MP4_BUF_PAD; else pPInfo->m_uiBufPadSize = AAC_BUF_PAD; break; case 1: case 2: pPInfo->m_uiBufPadSize = AAC_BUF_PAD; break; } } if (uiBufFlags & MAICOMPBUF_FLAG_EOS) { APIPRINTF((M_TEXT("AACDEC _processbuffer EOF flag found. Shortening pPInfo->m_uiBufPadSize %x\n"), pPInfo->m_uiBufPadSize)); uiPrevBufPadSize = pPInfo->m_uiBufPadSize; if (pPInfo->m_uiBufPadSize == AAC_FROM_DEMUX_BUF_PAD) { #ifndef UNDER_CE /* Ignore the EOS in CE when coming from the MP4 demux. It is reported incorrectly. */ pPInfo->m_uiBufPadSize = 256; /* We can play the end of the file with a small pad since there is no container. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -