/* * Input : Filename * Output : 1 if succesful 0 if not */ int openFile(const char * name) { readOff = readBuf; if((fp = fopen(name, "rb"))) { if(strstr(name, ".aac") || strstr(name, ".AAC")) { dec_state = DEC_AAC; if((decoder = AACInitDecoder())) { if(fill_readBuffer(readBuf, &readOff, READ_BUF_SIZE, &dataLeft) == READ_BUF_SIZE) { int ret = 0; int bitOffset = 0, bitsAvail = dataLeft << 3; if(IS_ADIF(readBuf)) ret = UnpackADIFHeader((AACDecInfo*)decoder, &readOff, &bitOffset, &bitsAvail); else ret = UnpackADTSHeader((AACDecInfo*)decoder, &readOff, &bitOffset, &bitsAvail); if(!ret) { AACGetLastFrameInfo(decoder, &inf); readOff = readBuf; dataLeft = READ_BUF_SIZE; return 1; } } } } else { dec_state = DEC_MP4; mp4cb.user_data = fp; if((infile = mp4ff_open_read(&mp4cb))) { if ((track = findAudioTrack(infile)) >= 0) { /* Decoder failed to initialize */ if((decoder = AACInitDecoder())) { /* Decoder should be updated to decode raw blocks in the mp4 * IMPORTANT: * mp4ff_get_channel_count will return the wrong value for mono in this state */ inf.sampRateCore = mp4ff_get_sample_rate(infile, track); samples = mp4ff_num_samples(infile, track); /* DECODER CONFIG: [AAAA ABBB] [BCCC CDEF] A)object type B)frequency index C)channel configuration D)bit: frame length flag E)bit: dependsOnCoreCoder F)bit: extensionFlag */ unsigned char * config_buf; unsigned int config_bufSize; mp4ff_get_decoder_config(infile, track, &config_buf, &config_bufSize); inf.profile = AAC_PROFILE_LC; inf.nChans = (config_buf[1] >> 3) & 0xF; free(config_buf); if(!AACSetRawBlockParams(decoder, 0, &inf)) return 1; } } } } }
void AudioPlaySdAac::setupDecoder(int channels, int samplerate, int profile) { memset(&aacFrameInfo, 0, sizeof(AACFrameInfo)); aacFrameInfo.nChans = channels; //aacFrameInfo.bitsPerSample = bits; not used aacFrameInfo.sampRateCore = samplerate; aacFrameInfo.profile = AAC_PROFILE_LC; AACSetRawBlockParams(hAACDecoder, 0, &aacFrameInfo); }
/* * Input : Filename * Output : 1 if succesful -1 if not */ int mp4_openFile(char * name) { if((sndFile = fopen(name, "rb"))) { mp4cb.user_data = sndFile; if((infile = mp4ff_open_read(&mp4cb))) { if ((track = findAudioTrack(infile)) >= 0) { /* Decoder failed to initialize */ if((decoder = AACInitDecoder())) { /* Decoder should be updated to decode raw blocks in the mp4 */ inf.sampRateCore = mp4ff_get_sample_rate(infile, track); inf.nChans = mp4ff_get_channel_count(infile,track); /* AACSetRawBlockParams will fail if not set */ inf.profile = AAC_PROFILE_LC; samples = mp4ff_num_samples(infile, track); if(!AACSetRawBlockParams(decoder, 0, &inf)) return 0; } } } } return -1; /* sndFile == NULL */ }
static int init(sh_audio_t *sh){ int pos = 0; int32_t result = HXR_OK; uint16_t *temp; uint8_t *inBuf; int in_len; int32_t NumChannels, SampleRate; hAACDecoder = (HAACDecoder *)AACInitDecoder(); ga_config_data configData; int i; if (!hAACDecoder) { printf(" *** Error initializing decoder ***\n"); return 0; } if(!sh->codecdata_len && sh->wf) { sh->codecdata_len = sh->wf->cbSize; sh->codecdata = (char*)(sh->wf+1); mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"realaac: codecdata extracted from WAVEFORMATEX\n"); } if(!sh->codecdata_len){ //return 0; sh->a_in_buffer_len = demux_read_data(sh->ds, sh->a_in_buffer, sh->a_in_buffer_size); inBuf = sh->a_in_buffer; in_len = sh->a_in_buffer_len; temp = (uint16_t *)malloc(sizeof(uint16_t) * sh->audio_out_minsize); /* decode ADTS frame from opaque data to get config data */ result = AACDecode(hAACDecoder, &inBuf, &in_len, temp); free(temp); if (result != HXR_OK) { return 0; } /* get the config data struct from the decoder */ AACGetLastFrameInfo(hAACDecoder, frameInfo); NumChannels = frameInfo->nChans; SampleRate = frameInfo->sampRateCore; }else{ struct BITSTREAM *pBitstream ; pBitstream = (struct BITSTREAM *)malloc(sizeof(struct BITSTREAM)) ; if (!pBitstream) return 0 ; pBitstream->cacheBitsLeft = 0 ; pBitstream->buffer = sh->codecdata ; pBitstream->nBits = sh->codecdata_len*8 ; pBitstream->pkptr = pBitstream->buffer + (0>>3) ; pBitstream->cacheBitsLeft = 0 ; pBitstream->cache = 0 ; pBitstream->inc = 1 ; result = ga_config_get_data(pBitstream, &configData); if(pBitstream){ free(pBitstream); } if (result != HXR_OK) /* config data error */ { return 0; } NumChannels = frameInfo->nChans=configData.numChannels; SampleRate = frameInfo->sampRateCore=configData.samplingFrequency; /* see MPEG4 spec for index of each object type */ if (configData.audioObjectType == 2) frameInfo->profile = AAC_PROFILE_LC; else if (configData.audioObjectType == 1) frameInfo->profile = AAC_PROFILE_MP; else if (configData.audioObjectType == 3) frameInfo->profile = AAC_PROFILE_SSR; else return 0; /* don't know - assume LC */ /* set decoder to handle raw data blocks */ AACSetRawBlockParams(hAACDecoder, 0, frameInfo); } mp_msg(MSGT_DECAUDIO,MSGL_V,"realaac: Decoder init done (%dBytes)!\n", sh->a_in_buffer_len); // XXX: remove or move to debug! mp_msg(MSGT_DECAUDIO,MSGL_V,"realaac: Negotiated samplerate: %ldHz channels: %d\n", SampleRate, NumChannels); sh->channels = NumChannels; if (audio_output_channels <= 2) sh->channels = NumChannels > 1 ? 2 : 1; sh->samplerate = SampleRate; sh->samplesize=2; if(!sh->i_bps) { mp_msg(MSGT_DECAUDIO,MSGL_WARN,"realaac: compressed input bitrate missing, assuming 128kbit/s!\n"); sh->i_bps = 128*1000/8; // XXX: HACK!!! ::atmos } else mp_msg(MSGT_DECAUDIO,MSGL_V,"realaac: got %dkbit/s bitrate from MP4 header!\n",sh->i_bps*8/1000); return 1; // return values: 1=OK 0=ERROR }
/* * aac_decode_init */ HX_RESULT aac_decode_init(void* pInitParams, UINT32 ulInitParamsSize, ra_format_info* pStreamInfo, void** pDecode, void* pUserMem, rm_malloc_func_ptr fpMalloc, rm_free_func_ptr fpFree) { HX_RESULT result = HXR_OK; aac_decode* pDec; AACFrameInfo *frameInfo; ga_config_data configData; UCHAR *pData; UCHAR *inBuf; INT16 *temp; UINT32 numBytes, numBits; UINT32 cfgType; /* for MP4 bitstream parsing */ struct BITSTREAM *pBs = 0; /* allocate the aac_decode struct */ pDec = (aac_decode*) fpMalloc(pUserMem, sizeof(aac_decode)); if (pDec == HXNULL) { return HXR_OUTOFMEMORY; } memset(pDec, 0, sizeof(aac_decode)); *pDecode = (void *)pDec; /* allocate the frame info struct */ pDec->pFrameInfo = fpMalloc(pUserMem, sizeof(AACFrameInfo)); frameInfo = (AACFrameInfo *) pDec->pFrameInfo; /* allocate the decoder backend instance */ pDec->pDecoder = AACInitDecoder(1); if (pDec->pFrameInfo == HXNULL || pDec->pDecoder == HXNULL) { return HXR_OUTOFMEMORY; } /* save the stream info and init data we'll need later */ pDec->ulNumChannels = (UINT32)pStreamInfo->usNumChannels; pDec->ulBlockSize = pStreamInfo->ulGranularity; pDec->ulFrameSize = pStreamInfo->ulBitsPerFrame; pDec->ulFramesPerBlock = pDec->ulBlockSize / pDec->ulFrameSize; /* output frame size is doubled for safety in case of implicit SBR */ pDec->ulSamplesPerFrame = 1024*pStreamInfo->usNumChannels*2; pDec->ulSampleRateCore = pStreamInfo->ulSampleRate; pDec->ulSampleRateOut = pStreamInfo->ulActualRate; if (pStreamInfo->ulOpaqueDataSize < 1) { return HXR_FAIL; /* insufficient config data */ } /* get the config data */ pData = (UCHAR *)pStreamInfo->pOpaqueData; cfgType = pData[0]; inBuf = pData + 1; numBytes = pStreamInfo->ulOpaqueDataSize - 1; if (cfgType == 1) /* ADTS Frame */ { /* allocate temp buffer for decoding first ADTS frame */ temp = (INT16 *)fpMalloc(pUserMem, sizeof(INT16) * pDec->ulSamplesPerFrame); if (temp == HXNULL) { return HXR_OUTOFMEMORY; } else { /* decode ADTS frame from opaque data to get config data */ result = AACDecode(pDec->pDecoder, &inBuf, (INT32*)&numBytes, temp); /* free the temp buffer */ fpFree(pUserMem, temp); } if (result == HXR_OK) { /* get the config data struct from the decoder */ AACGetLastFrameInfo(pDec->pDecoder, frameInfo); pDec->ulNumChannels = frameInfo->nChans; pDec->ulSamplesPerFrame = frameInfo->outputSamps; pDec->ulSampleRateCore = frameInfo->sampRateCore; pDec->ulSampleRateOut = frameInfo->sampRateOut; pDec->bSBR = (pDec->ulSampleRateCore != pDec->ulSampleRateOut); } } else if (cfgType == 2) /* MP4 Audio Specific Config Data */ { numBits = numBytes*8; if (newBitstream(&pBs, numBits, pUserMem, fpMalloc)) { return HXR_FAIL; } feedBitstream(pBs, (const UCHAR *)inBuf, numBits); setAtBitstream(pBs, 0, 1); result = ga_config_get_data(pBs, &configData); deleteBitstream(pBs, pUserMem, fpFree); if (result != HXR_OK) /* config data error */ { return HXR_FAIL; } pDec->ulNumChannels = configData.numChannels; pDec->ulSampleRateCore = configData.samplingFrequency; pDec->ulSampleRateOut = configData.extensionSamplingFrequency; pDec->bSBR = configData.bSBR; /* ulSamplesPerFrame is set to the maximum possible output length. * The config data has the initial output length, which might * be doubled once the first frame is handed in (if AAC+ is * signalled implicitly). */ pDec->ulSamplesPerFrame = 2*configData.frameLength*configData.numChannels; /* setup decoder to handle raw data blocks */ frameInfo->nChans = pDec->ulNumChannels; frameInfo->sampRateCore = pDec->ulSampleRateCore; /* see MPEG4 spec for index of each object type */ if (configData.audioObjectType == 2) frameInfo->profile = AAC_PROFILE_LC; else if (configData.audioObjectType == 1) frameInfo->profile = AAC_PROFILE_MP; else if (configData.audioObjectType == 3) frameInfo->profile = AAC_PROFILE_SSR; else frameInfo->profile = AAC_PROFILE_LC; /* don't know - assume LC */ frameInfo->audio_send_by_frame=0; } else /* unsupported config type */ { return HXR_FAIL; } /* make certain that all the channels can be handled */ if (pDec->ulNumChannels > AAC_MAX_NCHANS) { return HXR_UNSUPPORTED_AUDIO; } /* set the channel mask - custom maps not supported */ switch (pDec->ulNumChannels) { case 1: pDec->ulChannelMask = 0x00004; /* FC */ case 2: pDec->ulChannelMask = 0x00003; /* FL,FR */ case 3: pDec->ulChannelMask = 0x00007; /* FL,FR,FC */ case 4: pDec->ulChannelMask = 0x00107; /* FL,FR,FC,BC */ case 5: pDec->ulChannelMask = 0x00037; /* FL,FR,FC,BL,BR */ case 6: pDec->ulChannelMask = 0x0003F; /* FL,FR,FC,LF,BL,BR */ default: pDec->ulChannelMask = 0xFFFFF; /* Unknown */ } /* set the delay samples */ pDec->ulDelayRemaining = pDec->ulSamplesPerFrame; /* set decoder to handle raw data blocks */ AACSetRawBlockParams(pDec->pDecoder, 0, frameInfo); return HXR_OK; }
/*---------------------------------------------------------------------- | AacDecoderInput_PutPacket +---------------------------------------------------------------------*/ BLT_METHOD AacDecoderInput_PutPacket(BLT_PacketConsumer* _self, BLT_MediaPacket* packet) { AacDecoder* self = ATX_SELF_M(input, AacDecoder, BLT_PacketConsumer); ATX_Result result; /* check to see if this is the end of a stream */ if (BLT_MediaPacket_GetFlags(packet) & BLT_MEDIA_PACKET_FLAG_END_OF_STREAM) { self->input.eos = BLT_TRUE; } /* check to see if we need to create a decoder for this */ if (self->helix_decoder == NULL) { AacDecoderConfig decoder_config; AACFrameInfo aac_frame_info; const BLT_MediaType* media_type; const BLT_Mp4AudioMediaType* mp4_media_type; BLT_MediaPacket_GetMediaType(packet, &media_type); if (media_type == NULL || media_type->id != self->mp4es_type_id) { return BLT_ERROR_INVALID_MEDIA_TYPE; } mp4_media_type = (const BLT_Mp4AudioMediaType*)media_type; if (mp4_media_type->base.stream_type != BLT_MP4_STREAM_TYPE_AUDIO) { return BLT_ERROR_INVALID_MEDIA_TYPE; } if (BLT_FAILED(AacDecoderConfig_Parse(mp4_media_type->decoder_info, mp4_media_type->decoder_info_length, &decoder_config))) { return BLT_ERROR_INVALID_MEDIA_FORMAT; } if (decoder_config.object_type != BLT_AAC_OBJECT_TYPE_AAC_LC && decoder_config.object_type != BLT_AAC_OBJECT_TYPE_SBR) { return BLT_ERROR_UNSUPPORTED_CODEC; } /* create the decoder */ self->helix_decoder = AACInitDecoder(); if (self->helix_decoder == NULL) return BLT_ERROR_OUT_OF_MEMORY; /* configure the decoder */ ATX_SetMemory(&aac_frame_info, 0, sizeof(aac_frame_info)); aac_frame_info.nChans = AacDecoderConfig_GetChannelCount(&decoder_config); aac_frame_info.sampRateCore = AacDecoderConfig_GetSampleRate(&decoder_config); if (decoder_config.object_type == BLT_AAC_OBJECT_TYPE_AAC_LC) { aac_frame_info.profile = AAC_PROFILE_LC; } self->sample_buffer_size = BLT_AAC_FRAME_SIZE*2*aac_frame_info.nChans*2; /* the last *2 is for SBR support */ AACSetRawBlockParams(self->helix_decoder, 0, &aac_frame_info); } { unsigned char* in_buffer; int in_size; short* out_buffer; BLT_MediaPacket* out_packet; AACFrameInfo aac_frame_info; /* create a PCM packet for the output */ result = BLT_Core_CreateMediaPacket(ATX_BASE(self, BLT_BaseMediaNode).core, self->sample_buffer_size, (BLT_MediaType*)&self->output.media_type, &out_packet); if (BLT_FAILED(result)) return result; /* copy the timestamp */ BLT_MediaPacket_SetTimeStamp(out_packet, BLT_MediaPacket_GetTimeStamp(packet)); /* decode the packet as a frame */ in_buffer = BLT_MediaPacket_GetPayloadBuffer(packet); in_size = BLT_MediaPacket_GetPayloadSize(packet); out_buffer = (short*)BLT_MediaPacket_GetPayloadBuffer(out_packet); result = AACDecode(self->helix_decoder, &in_buffer, &in_size, out_buffer); if (result != 0) { BLT_MediaPacket_Release(out_packet); return BLT_ERROR_INVALID_MEDIA_FORMAT; } /* check that the sample buffer matches our current media type */ AACGetLastFrameInfo(self->helix_decoder, &aac_frame_info); if (self->output.media_type.channel_count == 0) { /* first time, setup our media type */ self->output.media_type.channel_count = aac_frame_info.nChans; self->output.media_type.sample_rate = aac_frame_info.sampRateOut; self->output.media_type.bits_per_sample = 16; self->output.media_type.sample_format = BLT_PCM_SAMPLE_FORMAT_SIGNED_INT_NE; self->output.media_type.channel_mask = 0; /* update the stream info */ if (ATX_BASE(self, BLT_BaseMediaNode).context) { BLT_StreamInfo stream_info; stream_info.data_type = "MPEG-4 AAC"; stream_info.sample_rate = aac_frame_info.sampRateOut; stream_info.channel_count = aac_frame_info.nChans; stream_info.mask = BLT_STREAM_INFO_MASK_DATA_TYPE | BLT_STREAM_INFO_MASK_SAMPLE_RATE | BLT_STREAM_INFO_MASK_CHANNEL_COUNT; BLT_Stream_SetInfo(ATX_BASE(self, BLT_BaseMediaNode).context, &stream_info); } /* update the packet media type */ BLT_MediaPacket_SetMediaType(out_packet, (BLT_MediaType*)&self->output.media_type); } else { /* we've already setup a media type, check that this is the same */ if (self->output.media_type.sample_rate != (unsigned int)aac_frame_info.sampRateOut || self->output.media_type.channel_count != aac_frame_info.nChans) { BLT_MediaPacket_Release(out_packet); return BLT_ERROR_INVALID_MEDIA_FORMAT; } } /* add to the output packet list */ BLT_MediaPacket_SetPayloadSize(out_packet, aac_frame_info.outputSamps*2); ATX_List_AddData(self->output.packets, out_packet); } return BLT_SUCCESS; }