diff -r 000000000000 -r 951a5db380a0 videoeditorengine/mp3aacManipLib/src/mstream.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videoeditorengine/mp3aacManipLib/src/mstream.cpp Fri Jan 29 14:08:33 2010 +0200 @@ -0,0 +1,565 @@ +/* +* Copyright (c) 2010 Ixonos Plc. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - Initial contribution +* +* Contributors: +* Ixonos Plc +* +* Description: +* +*/ + + +/************************************************************************** + External Objects Needed + *************************************************************************/ + +/*-- Project Headers --*/ +#include "mstream.h" +#include "mpheader.h" +#include "mp3Tool.h" + + + +CIII_Channel_Info* CIII_Channel_Info::NewL() + { + + + CIII_Channel_Info* self = new (ELeave) CIII_Channel_Info(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void CIII_Channel_Info::ConstructL() + { + + } + +CIII_Channel_Info::CIII_Channel_Info() + { + + + } + +CIII_Channel_Info::~CIII_Channel_Info() + { + + + } + + +CIII_SfbData* CIII_SfbData::NewL() + { + + CIII_SfbData* self = new (ELeave) CIII_SfbData(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void CIII_SfbData::ConstructL() + { + sfbOffsetLong = new (ELeave) int16[MAX_LONG_SFB_BANDS + 1]; + sfbOffsetShort = new (ELeave) int16[MAX_SHORT_SFB_BANDS + 1]; + sfbWidthShort = new (ELeave) int16[MAX_SHORT_SFB_BANDS + 1]; + } + +CIII_SfbData::CIII_SfbData() + { + + + } + +CIII_SfbData::~CIII_SfbData() + { + if (sfbOffsetLong != 0) delete[] sfbOffsetLong; + if (sfbOffsetShort != 0) delete[] sfbOffsetShort; + if (sfbWidthShort != 0) delete[] sfbWidthShort; + + } + +CIII_Side_Info* CIII_Side_Info::NewL() + { + + CIII_Side_Info* self = new (ELeave) CIII_Side_Info(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void CIII_Side_Info::ConstructL() + { + sfbData = GET_SYMBIAN_CHUNK(CIII_SfbData); + + } + +CIII_Side_Info::CIII_Side_Info() + { + + } + +CIII_Side_Info::~CIII_Side_Info() + { + if (sfbData != 0) SAFE_SYMBIAN_DELETE(sfbData); + + } + +CMCUBuf* CMCUBuf::NewL(TInt aBufLen) + { + + CMCUBuf* self = new (ELeave) CMCUBuf(); + CleanupStack::PushL(self); + self->ConstructL(aBufLen); + CleanupStack::Pop(self); + return self; + } + +void CMCUBuf::ConstructL(TInt aBufLen) + { + + bs = new (ELeave) TBitStream(); + + mcuBufbits = new (ELeave) uint8[aBufLen]; + + + } + +CMCUBuf::CMCUBuf() + { + + } + +CMCUBuf::~CMCUBuf() + { + + if (bs != 0) delete bs; + if (mcuBufbits != 0) + { + delete[] mcuBufbits; + mcuBufbits = 0; + } + + } + +/************************************************************************** + Title : decode_header + + Purpose : Reads header information (excluding syncword) from the bitstream. + + Usage : decode_header(mp) + + Input : mp - mp3 bitstream parameters + + Explanation : Header information is commmon to all layers. Note also that + this function doesn't interprete the fields of the header. + + Author(s) : Juha Ojanpera + *************************************************************************/ + +void +decode_header(CMP_Stream *mp, TBitStream *bs) +{ + uint32 header; + + mp->headerOld.header = mp->header->header; + header = (!mp->side_info->mpeg25) << HEADER_BITS; + header |= BsGetBits(bs, HEADER_BITS); + mp->header->header = header; + + /*-- Store the header bits 16-31 for CRC error checking. --*/ + mp->mp3_crc.crc_payload[0] = (uint8)((header >> 8) & 255); + mp->mp3_crc.crc_payload[1] = (uint8) (header & 255); + + if(error_protection(mp->header)) + mp->mp3_crc.crc = (int16)(BsGetBits(bs, 16)); +} + +/************************************************************************** + Title : FillDataSlotTable + + Purpose : Pre-computes (to avoid division operation during decoding) + the payload size of layer III for all bitrates. + + Usage : y = FillDataSlotTable(mp) + + Input : mp - mp3 stream parameters + + Author(s) : Juha Ojanpera + *************************************************************************/ + +void +FillDataSlotTable(CMP_Stream *mp) +{ + const int16 *brTbl; + int16 nSlots; + + brTbl = GetBitRateTable(mp->header); + /* + * index 0 is free format and index 14 illegal bitrate. + */ + for(int16 i = 1; i < 15; i++) + { + nSlots = (int16)((144 * brTbl[i]) / (frequency(mp->header) / 1000.0f)); + + if(version(mp->header) == MPEG_PHASE2_LSF) + nSlots >>= 1; + + mp->FrameTable[i] = nSlots; + + nSlots = (int16)(nSlots - (GetSideInfoSlots(mp->header) + 4)); + mp->SlotTable[i] = nSlots; + } +} + +/************************************************************************** + Title : main_data_slots + + Purpose : Computes the number of bytes for the layer III payload. The + payload consists of the scalefactors and quantized data of + the channel(s). + + Usage : y = main_data_slots(mp) + + Input : mp - mp3 stream parameters + + Output : y - # of payload bytes for this frame + + Author(s) : Juha Ojanpera + *************************************************************************/ + +int32 +main_data_slots(CMP_Stream *mp) +{ + int16 nSlots; + + if(bit_rate(mp->header)) + { + nSlots = mp->SlotTable[bit_rate_idx(mp->header)]; + + if(padding(mp->header)) + nSlots++; + if(error_protection(mp->header)) + nSlots -= 2; + } + else + { + nSlots = mp->FreeFormatSlots; + + if(padding(mp->header)) + nSlots++; + } + + return(nSlots); +} + +/************************************************************************** + Title : ReleaseMP3Decoder + + Purpose : Releases resources allocated to the mp3 decoder core. + + Usage : ReleaseMP3Decoder(mp) + + Input : mp - mp3 decoder core + + Author(s) : Juha Ojanpera + *************************************************************************/ + +void +ReleaseMP3Decoder(CMP_Stream *mp) + { + int16 i, j; + + if(mp) + { + /* Scalefactors. */ + SAFE_DELETE(mp->frame->scale_factors); + + /* Quantized samples. */ + SAFE_DELETE(mp->frame->quant); + + /* Synthesis buffer. */ + for(i = 0; i < MAX_CHANNELS; i++) + { + SAFE_DELETE(mp->buffer->synthesis_buffer[i]); + } + + + /* Dequantized samples. */ + SAFE_DELETE(mp->buffer->reconstructed); + + /* Huffman codebooks. */ + SAFE_DELETE(mp->huffman); + + if(mp->side_info) + { + for(i = 0; i < MAX_CHANNELS; i++) + { + SAFE_DELETE(mp->side_info->ch_info[i]->scale_fac); + + for(j = 0; j < 2; j++) + { + SAFE_DELETE(mp->side_info->ch_info[i]->gr_info[j]); + } + + + SAFE_SYMBIAN_DELETE(mp->side_info->ch_info[i]); + } + + SAFE_DELETE(mp->side_info->s_mode_long); + + for(i = 0; i < 3; i++) + { + SAFE_DELETE(mp->side_info->s_mode_short[i]); + } + + + SAFE_SYMBIAN_DELETE(mp->side_info); + } + + SAFE_DELETE(mp->header); + SAFE_DELETE(mp->frame); + SAFE_DELETE(mp->buffer); + SAFE_DELETE(mp->br); +// SAFE_DELETE(mp->bs); + } + } + +/************************************************************************** + Title : GetMP3Handle + + Purpose : Returns mp3 decoder core handle to the callee. + + Usage : GetMP3Handle() + + Output : mp - handle of mp3 decoder core + + Author(s) : Juha Ojanpera + *************************************************************************/ + +CMP_Stream * +GetMP3HandleL(void) +{ + int16 i, j, groups, idx[] = {0, 23, 36, 49, 62, 85, 98, 111}; + CIII_Scale_Factors *scale_fac; + CMP_Stream *mp; + + //mp = (CMP_Stream *) GET_CHUNK(sizeof(CMP_Stream)); + + mp = new (ELeave) CMP_Stream(); + IS_ERROR(mp); + + + + //mp->bs = (TBitStream *) GET_CHUNK(sizeof(TBitStream)); + //IS_ERROR(mp->bs); + + mp->header = (TMPEG_Header *) GET_CHUNK(sizeof(TMPEG_Header)); + IS_ERROR(mp->header); + + mp->frame = (TMPEG_Frame *) GET_CHUNK(sizeof(TMPEG_Frame)); + IS_ERROR(mp->frame); + + mp->buffer = (TMPEG_Buffer *) GET_CHUNK(sizeof(TMPEG_Buffer)); + IS_ERROR(mp->buffer); + + mp->side_info = (CIII_Side_Info *) GET_SYMBIAN_CHUNK(CIII_Side_Info); + IS_ERROR(mp->side_info); + + mp->frame->scale_factors = (uint8 *) GET_CHUNK(MAX_CHANNELS * SBLIMIT * 3 * sizeof(uint8)); + Mem::FillZ (mp->frame->scale_factors, MAX_CHANNELS * SBLIMIT * 3 * sizeof(uint8)); + + IS_ERROR(mp->frame->scale_factors); + + mp->huffman = (CHuffman *) GET_CHUNK(33 * sizeof(CHuffman)); + IS_ERROR(mp->huffman); + + mp->br = (TBitStream *) GET_CHUNK(sizeof(TBitStream)); + IS_ERROR(mp->br); + + Mem::Fill(mp->PrevStreamInfo, sizeof(uint32) * 2, 0); + + for(i = 0; i < MAX_CHANNELS; i++) + { + //mp->side_info->ch_info[i] = (CIII_Channel_Info *) GET_CHUNK(sizeof(CIII_Channel_Info)); + mp->side_info->ch_info[i] = GET_SYMBIAN_CHUNK(CIII_Channel_Info); + IS_ERROR(mp->side_info->ch_info[i]); + for(j = 0; j < 2; j++) + { + mp->side_info->ch_info[i]->gr_info[j] = (TGranule_Info *) GET_CHUNK(sizeof(TGranule_Info)); + IS_ERROR(mp->side_info->ch_info[i]->gr_info[j]); + } + } + + mp->side_info->s_mode_long = (StereoMode *) GET_CHUNK(22 * sizeof(StereoMode)); + IS_ERROR(mp->side_info->s_mode_long); + for(i = 0; i < 3; i++) + { + mp->side_info->s_mode_short[i] = (StereoMode *) GET_CHUNK(13 * sizeof(StereoMode)); + IS_ERROR(mp->side_info->s_mode_short[i]); + } + + for(i = j = 0; i < MAX_CHANNELS; i++) + { + mp->side_info->ch_info[i]->scale_fac = (CIII_Scale_Factors *) GET_CHUNK(sizeof(CIII_Scale_Factors)); + IS_ERROR(mp->side_info->ch_info[i]->scale_fac); + scale_fac = mp->side_info->ch_info[i]->scale_fac; + + scale_fac->scalefac_long = mp->frame->scale_factors + idx[j++]; + scale_fac->scalefac_short[0] = mp->frame->scale_factors + idx[j++]; + scale_fac->scalefac_short[1] = mp->frame->scale_factors + idx[j++]; + scale_fac->scalefac_short[2] = mp->frame->scale_factors + idx[j++]; + } + + groups = MAX_MONO_SAMPLES * MAX_CHANNELS; + + TInt a = 0; + mp->frame->quant = (int16 *) GET_CHUNK((groups + 10) * sizeof(int16)); + for (a = 0 ; a < groups ; a++) mp->frame->quant[a] = 0; + + IS_ERROR(mp->frame->quant); + + mp->buffer->reconstructed = (FLOAT *) GET_CHUNK(groups * sizeof(FLOAT)); + IS_ERROR(mp->buffer->reconstructed); + for (a = 0 ; a < groups ; a++) mp->buffer->reconstructed[a] = 0; + + for(i = 0; i < MAX_CHANNELS; i++) + { + mp->frame->ch_quant[i] = mp->frame->quant + i * MAX_MONO_SAMPLES; + mp->buffer->ch_reconstructed[i] = mp->buffer->reconstructed + i * MAX_MONO_SAMPLES; + for(j = 0; j < SBLIMIT; j++) + mp->spectrum[i][j] = &mp->buffer->ch_reconstructed[i][j * SSLIMIT]; + } + + for(i = 0; i < MAX_CHANNELS; i++) + { + mp->buffer->buf_idx[i] = mp->buffer->dct_idx[i] = 0; + mp->buffer->synthesis_buffer[i] = (FLOAT *) GET_CHUNK((HAN_SIZE << 1) * sizeof(FLOAT)); + IS_ERROR(mp->buffer->synthesis_buffer[i]); + } + + //-- Get the Huffman codebooks. -- + //init_huffman(mp->huffman); + InitL3Huffman(mp->huffman); + return (mp); + +// error_exit: + + //ReleaseMP3Decoder(mp); + + //return (NULL); +} + +/************************************************************************** + Title : MP3DecPrepareInit + + Purpose : Prepares the core engine parameters for the search of + first mp3 frame. + + Usage : MP3DecPrepareInit(mp, out_param, complex, br_buffer, br_size) + + Input : mp - handle of mp3 decoder core + out_param - output parameters of current track + complex - decoding complexity parameters + br_buffer - address of bit reservoir buffer + br_size - size of bit reservoir buffer + + Author(s) : Juha Ojanpera + *************************************************************************/ + +void +MP3DecPrepareInit(CMP_Stream *mp, Out_Param *out_param, Out_Complexity *complex, + DSP_BYTE *br_buffer, uint32 br_size) +{ + mp->complex = complex; + mp->out_param = out_param; + + BsInit2(mp->br, br_buffer, br_size); + + mp->mp3_crc.crc = 0; + + mp->header->header = 0; + + mp->syncInfo.sync_word = (int16)SYNC_WORD; + mp->syncInfo.sync_length = (int16)SYNC_WORD_LENGTH; + mp->syncInfo.sync_mask = (int16)((1 << mp->syncInfo.sync_length) - 1); + mp->syncInfo.sync_status = FIRST_FRAME_WITH_LAYER3; + + mp->FreeFormatSlots = 0; + mp->idx_increment = 0; + mp->PrevSlots = 0; + mp->FrameStart = 0; + mp->SkipBr = FALSE; + mp->WasSeeking = FALSE; + mp->OverlapBufPtr[0] = mp->OverlapBufPtr[1] = 0; +} + +/************************************************************************** + Title : MP3DecCompleteInit + + Purpose : Completes the initialization of the core engine parameters. + + Usage : MP3DecPrepareInit(mp, frameBytes) + + Input : mp - handle of mp3 decoder core + + Output : frameBytes - # of bytes for the first frame + + Author(s) : Juha Ojanpera + *************************************************************************/ + +void +MP3DecCompleteInit(CMP_Stream *mp, int16 *frameBytes) +{ + //-- Fixed size (unit is bytes !!). -- + mp->mp3_crc.bufLen = (uint16)(2 + GetSideInfoSlots(mp->header)); + + //-- MPEG-1 --/ + if(version(mp->header) == MPEG_AUDIO_ID) + { + mp->side_info->lsf = FALSE; + mp->side_info->max_gr = 2; + } + //-- MPEG-2 LSF or MPEG-2.5 -- + else + { + mp->side_info->lsf = TRUE; + mp->side_info->max_gr = 1; + } + + //-- Determine the size of the payload only when necessary. --/ + if(bit_rate(mp->header)) + { + mp->FreeFormatSlots = 0; + + if((int32)(frequency(mp->header) != mp->PrevStreamInfo[0]) || + (int32)(channels(mp->header) != mp->PrevStreamInfo[1])) + FillDataSlotTable(mp); + } + else FillDataSlotTable(mp); + + mp->PrevStreamInfo[0] = frequency(mp->header); + mp->PrevStreamInfo[1] = channels(mp->header); + + //-- Get the scalefactor band related parameters. --/ + III_SfbDataInit(mp->side_info->sfbData, mp->header); + + //-- Init re-ordering table. --// + init_III_reorder(mp->reorder_idx, mp->side_info->sfbData->sfbShort, + mp->side_info->sfbData->sfbWidth); + + //-- Number of bytes for next frame. --/ + *frameBytes = (int16)(main_data_slots(mp) + GetSideInfoSlots(mp->header) + 3); + if(error_protection(mp->header)) + *frameBytes += 2; +}