📄 maiaacdec.c
字号:
last_frame = 1; #endif } else { if (mp4file) pPInfo->m_uiBufPadSize = 736; /* Try to play the end of the file. Some .mp4 containers seg fault with a value smaller than this. */ else pPInfo->m_uiBufPadSize = 512; last_frame = 1; } } if ((pPInfo->m_uiAACtype != AAC_TYPE_RAW_FROM_DEMUX) && (pPInfo->m_LeftOverInput > 0)) { DPRINTF((M_TEXT("AACDEC _processbuffer pPInfo->m_LeftOverInput %x\n"), pPInfo->m_LeftOverInput)); if (pPInfo->m_pucAudioInBuf == NULL) { unsigned int min_in_buf_size = pInBufferInfo->uiDataSize < DEFAULT_INBUFSIZE ? DEFAULT_INBUFSIZE : pInBufferInfo->uiDataSize; pPInfo->m_pucAudioInBuf = (unsigned char *)malloc(min_in_buf_size + MP4_BUF_PAD); if (pPInfo->m_pucAudioInBuf == NULL) { last_frame = 1; eStatus = MAI_STATUS_MEMORY; goto cleanup; } } memcpy(pPInfo->m_pucAudioInBuf, pPInfo->m_pucLeftOver, pPInfo->m_LeftOverInput); memcpy(pPInfo->m_pucAudioInBuf + pPInfo->m_LeftOverInput, inbuf, pInBufferInfo->uiDataSize); insize = pInBufferInfo->uiDataSize + pPInfo->m_LeftOverInput; inbuf_ptr = pPInfo->m_pucAudioInBuf; /* HWG20050819: If we already had data, and we see a new PTS or frame end flag, we will force a decode of the previous data since we should have a complete AAC frame. This is necessary for Read/WriteBuffer, to prevent too much buffering before starting playback. */ if ((pInBufferInfo->dwFlags&(MAICOMPBUF_FLAG_PTS|MAICOMPBUF_FLAG_FRAMEEND))!=0) { bForceDecode=M_TRUE; DPRINTF((M_TEXT("AACDEC _processbuffer found PTS on input\n"))); } } else inbuf_ptr = inbuf; if ((uiBufFlags&(MAICOMPBUF_FLAG_SOS|MAICOMPBUF_FLAG_DATADISCON))!=0) /* sent SOS/DATADISCON downstream */ { /* we were checking this in the decode loop, but not always hit if no data is decoded. */ BufferInfo.dwFlags = uiBufFlags&(MAICOMPBUF_FLAG_SOS|MAICOMPBUF_FLAG_DATADISCON); APIPRINTF((M_TEXT("AACDEC: _processbuffer() pass SOS/DATADISCON\n"))); BufferInfo.pBuffer = NULL; BufferInfo.uiDataSize = 0; MAICompBase_OutputPutBuf(hComp, 0, &BufferInfo); uiBufFlags&=~(MAICOMPBUF_FLAG_SOS|MAICOMPBUF_FLAG_DATADISCON); /* clear flags */ } DPRINTF((M_TEXT("AACDEC insize %x, pad %x, stat %x, bForceDecode %x\n"), insize, pPInfo->m_uiBufPadSize, eStatus, bForceDecode)); while ((bForceDecode || (insize >= pPInfo->m_uiBufPadSize)) && (eStatus == MAI_STATUS_OK)) { int out_size; int len; unsigned short m_usTestSyncword; unsigned char *pAudioOutBuf = NULL; if (pPInfo->m_uiAACtype == AAC_TYPE_ADTS) m_usTestSyncword = ((((unsigned short)(*(inbuf_ptr + 1))) << 8) + (unsigned short)(*inbuf_ptr)) & 0xf0ff; else if (pPInfo->m_uiAACtype == AAC_TYPE_ADIF) m_usTestSyncword = ((((unsigned short)(*(inbuf_ptr + 1))) << 8) + (unsigned short)(*inbuf_ptr)); else if (pPInfo->m_uiAACtype == AAC_TYPE_RAW_FROM_DEMUX) m_usTestSyncword = (unsigned short)(*inbuf_ptr); else m_usTestSyncword = ((((unsigned short)(*(inbuf_ptr + 1))) << 8) + (unsigned short)(*inbuf_ptr)) & 0xfe;#if 0 if (pPInfo->m_uiAACtype == AAC_TYPE_RAW_FROM_DEMUX) { if (m_usTestSyncword != 1) m_usTestSyncword &= 0xfe; SYNCPRINTF((M_TEXT("AAC_TYPE_RAW_FROM_DEMUX counter %d\n"), pPInfo->m_iDemuxSyncwordCounter)); if (pPInfo->m_iDemuxSyncwordCounter == 0) { pPInfo->m_usSyncword = m_usTestSyncword; pPInfo->m_iDemuxSyncwordCounter = 1; } else if (pPInfo->m_iDemuxSyncwordCounter < 0) { pPInfo->m_iDemuxSyncwordCounter++; pPInfo->m_usSyncword = 0; } SYNCPRINTF((M_TEXT("AAC_TYPE_RAW_FROM_DEMUX %x %x, stream_position %d, size %d, pad %d %x %x %x %x\n"), pPInfo->m_usSyncword, m_usTestSyncword, pPInfo->m_uiStreamPosition, insize, pPInfo->m_uiBufPadSize, inbuf_ptr[0], inbuf_ptr[1], inbuf_ptr[2], inbuf_ptr[3])); }#endif DPRINTF((M_TEXT("stream_position %d, size %d, pad %d, sync %x %x\n"), pPInfo->m_uiStreamPosition, insize, pPInfo->m_uiBufPadSize, pPInfo->m_usSyncword, m_usTestSyncword)); if (pPInfo->m_uiAACtype != AAC_TYPE_RAW_FROM_DEMUX) { if ((pPInfo->m_usSyncword != 0) && (pPInfo->m_usSyncword != m_usTestSyncword)) { int ii, top = insize; SYNCPRINTF((M_TEXT("syncword does not match %x %x, stream_position %d, size %d, pad %d %x %x %x %x\n"), pPInfo->m_usSyncword, m_usTestSyncword, pPInfo->m_uiStreamPosition, insize, pPInfo->m_uiBufPadSize, inbuf_ptr[0], inbuf_ptr[1], inbuf_ptr[2], inbuf_ptr[3])); /* Try to re-sync */ for (ii = 0; ii < top; ii++) { inbuf_ptr++; pPInfo->m_uiStreamPosition++; insize--; if (pPInfo->m_uiAACtype == AAC_TYPE_ADTS) m_usTestSyncword = ((((unsigned short)(*(inbuf_ptr + 1))) << 8) + (unsigned short)(*inbuf_ptr)) & 0xf0ff; else if (pPInfo->m_uiAACtype == AAC_TYPE_ADIF) m_usTestSyncword = ((((unsigned short)(*(inbuf_ptr + 1))) << 8) + (unsigned short)(*inbuf_ptr)); else if (pPInfo->m_uiAACtype == AAC_TYPE_RAW_FROM_DEMUX) { m_usTestSyncword = (unsigned short)(*inbuf_ptr); if (m_usTestSyncword != 1) m_usTestSyncword &= 0xfe; } else m_usTestSyncword = ((((unsigned short)(*(inbuf_ptr + 1))) << 8) + (unsigned short)(*inbuf_ptr)) & 0xfe; if (pPInfo->m_usSyncword == m_usTestSyncword) { SYNCPRINTF((M_TEXT("found new sync %x %x, stream_position %d, size %d, pad %d %x %x %x %x\n"), pPInfo->m_usSyncword, m_usTestSyncword, pPInfo->m_uiStreamPosition, insize, pPInfo->m_uiBufPadSize, inbuf_ptr[0], inbuf_ptr[1], inbuf_ptr[2], inbuf_ptr[3])); break; } } if (ii < 2) /* if we just skipped padding, then use the frame */ pPInfo->m_iDoNotOutputCounter = 0; else pPInfo->m_iDoNotOutputCounter = 3; SYNCPRINTF((M_TEXT("after search sync %x %x, stream_position %d, size %d, pad %d %x %x %x %x\n"), pPInfo->m_usSyncword, m_usTestSyncword, pPInfo->m_uiStreamPosition, insize, pPInfo->m_uiBufPadSize, inbuf_ptr[0], inbuf_ptr[1], inbuf_ptr[2], inbuf_ptr[3])); } } len = aacdecode(&pPInfo->ci, &pAudioOutBuf, &out_size, inbuf_ptr, insize, pPInfo->m_uiStreamPosition); if (pPInfo->m_uiPrevSRate != (unsigned int)pPInfo->ci.sampling_rate) { pPInfo->m_uiPrevSRate = pPInfo->ci.sampling_rate; pPInfo->m_bNewFormat = 1; } if (pPInfo->m_nPrevChannels != (unsigned int)pPInfo->ci.channels) { pPInfo->m_nPrevChannels = pPInfo->ci.channels; pPInfo->m_bNewFormat = 1; } if (pPInfo->m_bNewFormat) { MAIMediaTypeAudio_t AudioInfo; MAIMediaTypeAudio_t *pAudioInfo=&AudioInfo; DPRINTF((M_TEXT("AACDEC: _processbuffer() New Format\n"))); /* clear EOS flag, we're on a new stream */ MAICompBase_SetEOS(hComp, EOS_NONE); MAICompBase_SetFormatState(hComp, FORMAT_STATE_KNOWN); if (pPInfo->m_uiAACtype != AAC_TYPE_RAW_FROM_DEMUX) { SYNCPRINTF((M_TEXT("AAC header type %x %s\n"), frameInfo.header_type, (frameInfo.header_type == 0) ? M_TEXT("RAW") : ((frameInfo.header_type == 1) ? M_TEXT("ADIF") : ((frameInfo.header_type == 2) ? M_TEXT("ADTS") : M_TEXT("OTHER"))) )); switch (frameInfo.header_type) { case 0: pPInfo->m_uiAACtype = AAC_TYPE_RAW; break; case ADIF: pPInfo->m_uiAACtype = AAC_TYPE_ADIF; break; case ADTS: pPInfo->m_uiAACtype = AAC_TYPE_ADTS; break; } if (mp4file) pPInfo->m_uiAACtype = AAC_TYPE_MP4; pPInfo->m_usSyncword = syncwords[pPInfo->m_uiAACtype]; } SYNCPRINTF((M_TEXT("AAC type %x, syncword %x\n"), pPInfo->m_uiAACtype, pPInfo->m_usSyncword)); pPInfo->m_bNewFormat = 0; memset(pAudioInfo, 0, sizeof(MAIMediaTypeAudio_t)); pAudioInfo->MediaTypeInfo.uiSize=sizeof(MAIMediaTypeAudio_t); pAudioInfo->MediaTypeInfo.eMType=MAI_MTYPE_AUDIO; pAudioInfo->MediaTypeInfo.eMSubtype=MAI_MSUBTYPE_PCM; pAudioInfo->MediaTypeInfo.uiFlags=0; pAudioInfo->uiFlags = 0; pAudioInfo->uiModeFlags = 0; pAudioInfo->uiBitsPerSample = 16; pAudioInfo->uiMaxBufSize = pPInfo->ci.max_output_buffer_size; pAudioInfo->uiChannels = pPInfo->ci.channels; pAudioInfo->uiSamplesPerSec = pPInfo->ci.sampling_rate; APIPRINTF((M_TEXT("AACDEC: processbuffer() NEWFORMAT: %d ch, %d rate, %d bits, %d bufsize\n"), pAudioInfo->uiChannels, pAudioInfo->uiSamplesPerSec, pAudioInfo->uiBitsPerSample, pAudioInfo->uiMaxBufSize)); BufferInfo.dwFlags = MAICOMPBUF_FLAG_NEWFORMAT|MAICOMPBUF_FLAG_AUDIO; BufferInfo.tTimeStamp = 0; BufferInfo.pBuffer = (unsigned char *)pAudioInfo; BufferInfo.uiBufSize = 0; BufferInfo.uiDataSize = sizeof(MAIMediaTypeAudio_t); MAICompBase_OutputPutBuf(hComp, 0, &BufferInfo); } DPRINTF((M_TEXT("AACDEC: _processbuffer() len %x, out_size %x\n"), len, out_size)); if (len < 0) { ERRORPRINTF((M_TEXT("Error AAC while decoding, length %d."), len)); eStatus = MAI_STATUS_WRONGSTATE; goto cleanup; } if (out_size > 0) { /* if a frame has been decoded, output it */ BufferInfo.dwFlags = 0; /* default - no special flags */ BufferInfo.tTimeStamp = 0; if (pInBufferInfo && (uiBufFlags&MAICOMPBUF_FLAG_PTS)!=0) /* input buffer was timestamped */ { MAITIME_ASSIGN(BufferInfo.tTimeStamp, pInBufferInfo->tTimeStamp); MAICompBase_UpdateTime(hComp, 0, BufferInfo.tTimeStamp); PTSPRINTF((M_TEXT("AACDEC: _processbuffer() pass PTS=%u %d bytes\n"), (unsigned int)(BufferInfo.tTimeStamp), out_size)); BufferInfo.dwFlags |= MAICOMPBUF_FLAG_PTS; MAICompBase_ReportTime(hComp, 0); uiBufFlags&=~MAICOMPBUF_FLAG_PTS; /* clear PTS flag, report only once for this buffer */ } else { PTSPRINTF((M_TEXT("AACDEC: _processbuffer() NO PTS %d bytes\n"), out_size)); } if ((uiBufFlags&MAICOMPBUF_FLAG_DATADISCON)!=0) /* check for discontinuity */ { APIPRINTF((M_TEXT("AACDEC: _processbuffer() pass DATADISCON\n"))); BufferInfo.dwFlags |= MAICOMPBUF_FLAG_DATADISCON; uiBufFlags&=~MAICOMPBUF_FLAG_DATADISCON; /* clear DATADISCON flag, report only once for this buffer */ } BufferInfo.pBuffer = pAudioOutBuf; BufferInfo.uiDataSize = out_size; DPRINTF((M_TEXT("AACDEC: output %d bytes\n"), BufferInfo.uiDataSize)); if (pAudioOutBuf != NULL) { if (bForceDecode || (pPInfo->m_iDoNotOutputCounter == 0)) { DUMPAUDIO(&BufferInfo); if (MAICompBase_OutputPutBuf(hComp, 0, &BufferInfo) != MAI_STATUS_OK) { APIPRINTF((M_TEXT("AACDEC: _processbuffer() MAICompBase_OutputPutBuf failed\n"))); /* Do not break. We must continue to prcess the input, else we will crash due to input buffer overflow. */ } } else { APIPRINTF((M_TEXT("AACDEC: _processbuffer() DO NOT MAICompBase_OutputPutBuf pPInfo->m_iDoNotOutputCounter %d\n"), pPInfo->m_iDoNotOutputCounter)); } } else /* Error recovery: assume raw AAC and try to sync up */ { /* look for 21 0c 4? */ SYNCPRINTF((M_TEXT("NULL %p buffer, looking for sync, BufferInfo.uiDataSize %x, PTS %x\n"), BufferInfo.pBuffer, BufferInfo.uiDataSize, pInBufferInfo && (uiBufFlags&MAICOMPBUF_FLAG_PTS))); if (pPInfo->m_uiAACtype != AAC_TYPE_RAW_FROM_DEMUX) { int spot = 0, tsize = insize; unsigned char *buf = inbuf_ptr; while (tsize) { if (*buf == 0x21) { if (*(buf+1) == 0x0c) { if ((*(buf+2) & 0xf0) == 0x40) { SYNCPRINTF((M_TEXT("found sync at %x, len %x\n"), spot, len)); if (spot == 0) /* just go on to the next */ break; insize = tsize; inbuf = buf; inbuf_ptr = inbuf; len = 0; break; } } } spot++; buf++; tsize--; } } } output_sample_count += out_size; pPInfo->m_uiProcessLoops++; } bForceDecode=M_FALSE; /* done forcing a decode of only a single frame */ if (pPInfo->m_iDoNotOutputCounter > 0) pPInfo->m_iDoNotOutputCounter--; if ((len == 0) && (out_size <= 0)) len = 100; /* We are stuck, so gobble up some of the stream and try again. */ if (len > insize) len = insize; /* safety, should never happen */ insize -= len; inbuf_ptr += len; pPInfo->m_uiStreamPosition += len; DPRINTF((M_TEXT("AACDEC insize %x, pad %x, stat %x, bForceDecode %x\n"), insize, pPInfo->m_uiBufPadSize, eStatus, bForceDecode)); }cleanup: if ((uiBufFlags&MAICOMPBUF_FLAG_EOS)!=0) /* EOF not yet sent downstream */ { BufferInfo.dwFlags = MAICOMPBUF_FLAG_EOS; APIPRINTF((M_TEXT("AACDEC: _processbuffer() pass EOS\n"))); BufferInfo.pBuffer = NULL; BufferInfo.uiDataSize = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -