diff -r 000000000000 -r 951a5db380a0 videoeditorengine/mp3aacManipLib/MP3Gain/src/mpif.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videoeditorengine/mp3aacManipLib/MP3Gain/src/mpif.cpp Fri Jan 29 14:08:33 2010 +0200 @@ -0,0 +1,909 @@ +/* +* 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: +* +*/ + + +/************************************************************************** + mpif.cpp - MPEG-1, MPEG-2 LSF and MPEG-2.5 file format implementations. + + Author(s): Juha Ojanpera + Copyright (c) 1999-2004 by Nokia Research Center, Speech and Audio Systems. + *************************************************************************/ + +/*-- project headers --*/ +#include "mpif.h" +//#include "auddef.h" +#include "mpheader.h" +#include "nok_bits.h" +#include "mstream.h" + + +/************************************************************************** + Internal Objects + *************************************************************************/ + +/* + Purpose: Sync lost after 16384 bytes. + Explanation: - */ +#define SYNC_THRESHOLD (16384 << 3) + +/************************************************************************** + 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 file format parameters + + Output : y - # of payload bytes for this frame + + Author(s) : Juha Ojanpera + *************************************************************************/ + +INLINE int32 +main_data_slots(TMpTransportHandle *tHandle) +{ + int16 nSlots; + + if(bit_rate(&tHandle->header)) + { + nSlots = tHandle->SlotTable[bit_rate_idx(&tHandle->header)]; + + if(padding(&tHandle->header)) + nSlots++; + if(error_protection(&tHandle->header)) + nSlots -= 2; + } + else + { + nSlots = tHandle->FreeFormatSlots; + + if(padding(&tHandle->header)) + nSlots++; + } + + return(nSlots); +} + +/* + * Maximum # of bits needed for the header. Note that only + * 20 bits are read since 12 bits were read already when + * locating the start of frame. 16 bits are needed for + * the optional CRC codeword. + */ +#define MAX_MP_HEADER_SIZE (20 + 16) + +/************************************************************************** + Title : decode_header + + Purpose : Reads header information (excluding syncword) from the bitstream. + + Usage : decode_header(tHandle, bs) + + Input : tHandle - file format parser + bs - input bitstream + + 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 + *************************************************************************/ + +INLINE SEEK_STATUS +decode_header(TMpTransportHandle *tHandle, TBitStream *bs) +{ + uint32 header, bitsLeft; + + bitsLeft = (BsGetBufSize(bs) << 3) - BsGetBitsRead(bs); + if(bitsLeft < MAX_MP_HEADER_SIZE) + return (SYNC_BITS_OUT); + + /*-- Read rest of the header bits. --*/ + tHandle->headerOld.header = tHandle->header.header; + header = (!tHandle->mpeg25) << HEADER_BITS; + header |= BsGetBits(bs, HEADER_BITS); + tHandle->header.header = header; + + /*-- Read CRC codeword. --*/ + if(error_protection(&tHandle->header)) + tHandle->crc.crc = (int16) BsGetBits(bs, 16); + + return (SYNC_FOUND); +} + +/************************************************************************** + Title : GetSideInfoSlots + + Purpose : Retrieves the amount of side info for layer III stream. + + Usage : y = GetSideInfoSlots(tHandle) + + Input : tHandle - file format parser + + Output : y - # of side info bytes + + Author(s) : Juha Ojanpera + *************************************************************************/ + +int16 +GetSideInfoSlots(TMpTransportHandle *tHandle) +{ + int16 nSlots = 0; + + if(version(&tHandle->header) != MPEG_PHASE2_LSF) + nSlots = (channels(&tHandle->header) == 1) ? (int16) 17 : (int16) 32; + else + nSlots = (channels(&tHandle->header) == 1) ? (int16) 9 : (int16) 17; + + return (nSlots); +} + +int16 +GetSideInfoSlots(TMPEG_Header *header) +{ + int16 nSlots = 0; + + if(version(header) != MPEG_PHASE2_LSF) + nSlots = (channels(header) == 1) ? 17 : 32; + else + nSlots = (channels(header) == 1) ? 9 : 17; + + return (nSlots); +} + +/************************************************************************** + Title : GetSlotSize + + Purpose : Retrieves the amount of frame data for layer III stream. + + Usage : y = GetSlotSize(tHandle) + + Input : tHandle - file format parser + + Output : y - # of frame data bytes + + Author(s) : Juha Ojanpera + *************************************************************************/ + +static INLINE int16 +GetSlotSize(TMpTransportHandle *tHandle) +{ + int16 ave_slots; + + if(bit_rate(&tHandle->header)) + ave_slots = (int16) tHandle->aveFrameLen; + else + { + ave_slots = (int16) (tHandle->FreeFormatSlots + GetSideInfoSlots(tHandle)); + if(error_protection(&tHandle->header)) + ave_slots += 2; + ave_slots += 4; + } + + return (ave_slots); +} + +INLINE int32 * +GetSeekOffset(TMpTransportHandle *tHandle, int32 *seekValues) +{ + int16 main_data; + int32 frameOffset, byte_offset; + + /* + * Some reinitialization need to be performed after file pointer has been + * moved to the new postion. For this reason, the total number of frames + * to be skipped does not correspond exactly to the given time offset. + * However, after reinitialization the playback position should be the correct. + */ + byte_offset = GetSlotSize(tHandle); + main_data = (int16) ((version(&tHandle->header) == MPEG_PHASE2_LSF) ? 256 : 512); + frameOffset = (byte_offset) ? main_data / byte_offset : 0; + + if(byte_offset) + if(main_data % byte_offset) + frameOffset++; + + seekValues[0] = frameOffset; + seekValues[1] = byte_offset; + + return (seekValues); +} + +/* + * Estimates the bitrate of the mp3 stream from the size of the + * payload + side info + header. The accuracy of the computed + * bitrate depends very much on the accuracy of the average frame + * size. + */ +int16 +MP_EstimateBitrate(TMpTransportHandle *tHandle, uint8 isVbr) +{ + int16 bitRate; + + if(!bit_rate(&tHandle->header) || isVbr) + { + FLOAT div; + + div = (FLOAT) ((version(&tHandle->header) == MPEG_PHASE2_LSF) ? 72 : 144); + bitRate = (int16) (((frequency(&tHandle->header) / 1000.0f) * GetSlotSize(tHandle) / div) + 0.5f); + } + else + bitRate = bit_rate(&tHandle->header); + + return (bitRate); +} + +/* + * Returns the length of the track in milliseconds. + */ +uint32 +MP_FileLengthInMs(TMpTransportHandle *tHandle, int32 fileSize) +{ + FLOAT frames = fileSize / (FLOAT) GetSlotSize(tHandle); + + return (uint32) (frames * GetFrameTime(&tHandle->header) + 0.5f); +} + +/* + * Returns the byte offset corresponding to the specified seeking position. + */ +int32 +MP_GetSeekOffset(TMpTransportHandle *tHandle, int32 seekPos) +{ + FLOAT numFrames; + int32 seekValues[2], frameOffset, byte_offset; + + GetSeekOffset(tHandle, seekValues); + + frameOffset = seekValues[0]; + byte_offset = seekValues[1]; + + numFrames = seekPos / (FLOAT) GetFrameTime(&tHandle->header); + if(numFrames < frameOffset) + frameOffset = 0; + + /*-- Total offset. --*/ + byte_offset = (int32) ((byte_offset * (numFrames - frameOffset)) + 0.5f); + + return (byte_offset); +} + +/* + * Returns the duration of each frame in milliseconds. + */ +int32 +MP_GetFrameTime(TMpTransportHandle *tHandle) +{ + return (GetFrameTime(&tHandle->header)); +} + +/* + * Checks if the specified mp3 stream is using free format + * i.e., bitrate is not specified in the header part + * of the frame. + * + * Return TRUE if bitrate not specified, FALSE otherwise + */ +BOOL +IsMP3FreeFormat(TMpTransportHandle *tHandle) +{ + return (bit_rate(&tHandle->header) == 0); +} + +/************************************************************************** + Title : FillDataSlotTable + + Purpose : Pre-computes (to avoid division operation during decoding) + the payload size of layer III for all bitrates. This function + should be called once the start of 1st frame has been located. + + Usage : y = FillDataSlotTable(tHandle) + + Input : tHandle - file format parser + + Author(s) : Juha Ojanpera + *************************************************************************/ + +INLINE void +FillDataSlotTable(TMpTransportHandle *tHandle) +{ + int16 nSlots; + const int16 *brTbl; + + brTbl = GetBitRateTable(&tHandle->header); + + /* + * index 0 is free format and index 14 illegal bitrate. + */ + for(int16 i = 1; i < 15; i++) + { + nSlots = (int16)((144 * brTbl[i]) / (frequency(&tHandle->header) / 1000.0f)); + + if(version(&tHandle->header) == MPEG_PHASE2_LSF) + nSlots >>= 1; + + nSlots = (int16) (nSlots - GetSideInfoSlots(tHandle) - 4); + tHandle->SlotTable[i] = nSlots; + } +} + +/************************************************************************** + Title : SeekSync + + Purpose : Seeks for a byte aligned sync word in the bitstream and + places the bitstream pointer right after the sync word. + + Usage : y = SeekSync(mp, bs_mcu, bufMapper, execState) + + Input : mp - mp3 stream parameters + bs_mcu - bitstream parameters + execState - exec status of this function + + Output : y : + SYNC_BITS_OUT - bit buffer need to be updated + SYNC_LOST - start of next frame was not found + SYNC_FOUND - OK to decode next frame + + Author(s) : Juha Ojanpera + *************************************************************************/ + +INLINE SEEK_STATUS +SeekSync(TMpTransportHandle *tHandle, TBitStream *bs_mcu, ExecState *execState) +{ +#define PRESYNCBITS (MP_SYNC_WORD_LENGTH + 8) +#define POSTSYNCBITS (MAX_MP_HEADER_SIZE + 1) + + uint32 hdr, bits_left; + BOOL exitCheck = TRUE; + int32 sync_cand, bits_read; + + bits_left = (BsSlotsLeft(bs_mcu) - 1) << 3; + + if(execState->execMode == GLITCH_FREE && bits_left > PRESYNCBITS) + { + bits_left -= (BsByteAlign(bs_mcu) + (bits_read = tHandle->syncInfo.sync_length)); + sync_cand = BsGetBits(bs_mcu, tHandle->syncInfo.sync_length); + } + else if(execState->execMode == GLITCH_FREE) + { + execState->execMode = GLITCH_FREE; + + return (SYNC_BITS_OUT); + } + else + { + sync_cand = (int32)execState->a0_u32[0]; + bits_read = (int32)execState->a0_u32[1]; + } + + while(exitCheck) + { + while(sync_cand != tHandle->syncInfo.sync_word && + bits_read < SYNC_THRESHOLD && bits_left) + { + bits_read++; + bits_left--; + sync_cand = (sync_cand << 1) & tHandle->syncInfo.sync_mask; + sync_cand |= (int16) BsGetBits(bs_mcu, 1); + } + + if(bits_read > SYNC_THRESHOLD) + return (SYNC_LOST); + else if(bits_left < POSTSYNCBITS) + { + execState->execMode = GLITCH0; + execState->a0_u32[0] = sync_cand; + execState->a0_u32[1] = bits_read; + + return (SYNC_BITS_OUT); + } + else + { + bits_read++; + bits_left--; + sync_cand = (sync_cand << 1) & tHandle->syncInfo.sync_mask; + sync_cand |= (int16) BsGetBits(bs_mcu, 1); + + tHandle->mpeg25 = !(sync_cand & 0x1); + + /* Check the next frame header. */ + hdr = (!tHandle->mpeg25) << HEADER_BITS; + tHandle->header.header = hdr | BsLookAhead(bs_mcu, HEADER_BITS); + + /* Detect false frame boundaries. */ + switch(tHandle->syncInfo.sync_status) + { + case LAYER3_STREAM: + if(HEADER_MASK(tHandle->header.header) == HEADER_MASK(tHandle->headerOld.header) && + sfreq(&tHandle->header) != 3 && LAYER_MASK(tHandle->header.header) == 0x1) + { + if(tHandle->FreeFormatSlots == 0) + { + if(bit_rate(&tHandle->header)) + exitCheck = FALSE; + } + else exitCheck = FALSE; + } + break; + + case INIT_LAYER3_STREAM: + if(!(version(&tHandle->header) && mp25version(&tHandle->header))) + { + if(sfreq(&tHandle->header) != 3 && LAYER_MASK(tHandle->header.header) == 0x1 && bit_rate_idx(&tHandle->header) != 15) + { + tHandle->headerOld.header = tHandle->header.header; + tHandle->syncInfo.sync_status = LAYER3_STREAM; + exitCheck = FALSE; + } + } + break; + + default: + break; + } + } + } + + execState->execMode = GLITCH_FREE; + + return (SYNC_FOUND); +} + +/************************************************************************** + Title : FindFreeFormatSlotCount + + Purpose : Determines the size of the payload of a free format stream. + + Usage : y = FindFreeFormatSlotCount(mpDec, bs_mcu, execState) + + Input : mpDec - mp3 stream parameters + bs_mcu - bitstream parameters + execState - exec status of this function + + Output : y : + SYNC_BITS_OUT - bit buffer need to be updated + SYNC_LOST - stream is undecodable + SYNC_FOUND - OK to start playback + + Author(s) : Juha Ojanpera + *************************************************************************/ + +INLINE SEEK_STATUS +FreeFormat(TMpTransportHandle *tHandle, TBitStream *bs_mcu, ExecState *execState) +{ + int16 exitCheck; + TMPEG_Header oldHeader; + uint16 sync_cand; + uint32 bits_read, bits_left; + + tHandle->FreeFormatSlots = 0; + + if(execState->execMode == GLITCH_FREE) + { + int16 nSlots, minBytes; + + nSlots = GetSideInfoSlots(tHandle); + minBytes = (uint16) (nSlots + 7); + if((BsSlotsLeft(bs_mcu) - 1) < (uint16) minBytes) + { + execState->execMode = GLITCH_FREE; + return (SYNC_BITS_OUT); + } + + /*-- Read 1st header. --*/ + decode_header(tHandle, bs_mcu); + oldHeader.header = tHandle->header.header; + + /*-- Skip side info part. --*/ + BsSkipNBits(bs_mcu, nSlots << 3); + + sync_cand = (uint16) BsGetBits(bs_mcu, tHandle->syncInfo.sync_length); + bits_read = tHandle->syncInfo.sync_length; + } + else + { + sync_cand = (uint16) execState->a0_u32[0]; + bits_read = (uint32) execState->a0_u32[1]; + oldHeader.header = (uint32)execState->a0_u32[2]; + } + + exitCheck = 1; + bits_left = (BsSlotsLeft(bs_mcu) - 1) << 3; + //mask = (uint16) ((1 << (tHandle->syncInfo.sync_length - 1)) - 1); + + while(exitCheck) + { + while(sync_cand != tHandle->syncInfo.sync_word && bits_left) + { + bits_read++; + bits_left--; + sync_cand = (uint16) ((sync_cand << 1) & tHandle->syncInfo.sync_mask); + sync_cand |= (uint16) BsGetBits(bs_mcu, 1); + } + + if(bits_left < (HEADER_BITS + 1)) + { + execState->a0_u32[0] = sync_cand; + execState->a0_u32[1] = bits_read; + execState->a0_u32[2] = oldHeader.header; + execState->execMode = GLITCH0; + + return (SYNC_BITS_OUT); + } + else + { + uint32 hdr; + + bits_read++; + bits_left--; + sync_cand = (sync_cand << 1) & tHandle->syncInfo.sync_mask; + sync_cand |= (int16) BsGetBits(bs_mcu, 1); + + tHandle->mpeg25 = !(sync_cand & 0x1); + + /* Check the next frame header. */ + hdr = (!tHandle->mpeg25) << HEADER_BITS; + tHandle->header.header = hdr | BsLookAhead(bs_mcu, HEADER_BITS); + + /* + * Detect false frame boundraries. We could use header macros here + * to speed up the comparison but since this function is called only + * once (before playback/editing starts) the advantages of macros are + * negligible. + */ + if(channels(&tHandle->header) == channels(&oldHeader) && + sfreq(&tHandle->header) == sfreq(&oldHeader) && + bit_rate(&tHandle->header) == bit_rate(&oldHeader) && + layer_number(&tHandle->header) == layer_number(&oldHeader) && + version(&tHandle->header) == version(&oldHeader) && + mode(&tHandle->header) == mode(&oldHeader) && + error_protection(&tHandle->header) == error_protection(&oldHeader)) + exitCheck = 0; + + /* The payload size cannot be determined. */ + else if(bits_read > SYNC_THRESHOLD) + return (SYNC_LOST); + } + } + + /*-- Determine the size of the payload data. --*/ + if(bits_read != 0) + { + bits_read -= (tHandle->syncInfo.sync_length + 1); + tHandle->FreeFormatSlots = (int16) (bits_read >> 3); + + if(padding(&oldHeader)) + tHandle->FreeFormatSlots -= 1; + } + else + { + tHandle->FreeFormatSlots = -1; + + return (SYNC_LOST); + } + + execState->execMode = GLITCH_FREE; + tHandle->transportType = GET_MPSYNC_STREAM; + tHandle->syncInfo.sync_status = INIT_LAYER3_STREAM; + + return (SYNC_FOUND); +} + +/************************************************************************** + Title : mpSyncTransport + + Purpose : Sync layer interface for MPEG Layer I/II/III file formats. + + Usage : y = mpSyncTransport(tHandle, syncBuf, syncBufLen, readBits) + + Input : tHandle - handle to MPEG Layer I/II/III parser + syncBuf - handle to sync layer buffer + syncBufLen - # of bytes present in sync layer buffer + + Output : y - status of operation + SYNC_BITS_OUT - the sync layer buffer needs to be updated + SYNC_LOST - function failed + SYNC_FOUND - sync layer processing successfull + readBits - # of bits read from sync layer buffer + + Author(s) : Juha Ojanpera + *************************************************************************/ + + +SEEK_STATUS +mpSyncTransport(TMpTransportHandle *tHandle, uint8 *syncBuf, + uint32 syncBufLen, uint32 *readBits) +{ + BOOL hitExit; + ExecState *execState; + TBitStream m_Bitstream; + SEEK_STATUS frameStatus; + + *readBits = 0; + hitExit = FALSE; + frameStatus = SYNC_LOST; + execState = &tHandle->execState; + + BsInit(&m_Bitstream, syncBuf, syncBufLen); + + if(tHandle->offsetBits) + BsSkipNBits(&m_Bitstream, tHandle->offsetBits); + tHandle->offsetBits = 0; + + while(hitExit == FALSE) + { + uint32 tmp; + uint8 syncByte(0); + + switch(tHandle->transportType) + { + case INIT_MP_STREAM: + frameStatus = SYNC_LOST; + tHandle->transportType = GET_1ST_MPSYNC_STREAM; + break; + + case GET_1ST_MPSYNC_STREAM: + /* + * Locate sync and on succes, switch to read + * the headers values. + */ + frameStatus = SeekSync(tHandle, &m_Bitstream, execState); + if((frameStatus == SYNC_FOUND) && IsMP3FreeFormat(tHandle)) + { + hitExit = TRUE; + frameStatus = SYNC_MP3_FREE; + tHandle->offsetBits = (int16) (BsGetBitsRead(&m_Bitstream) & 0x7); + } + else if(frameStatus == SYNC_FOUND) + tHandle->transportType = GET_MPHEADER_STREAM; + else + { + hitExit = TRUE; + if(frameStatus != SYNC_LOST) + { + /* + * The sync search locates the syncword which is at the + * start of the header (1st 12 bits). Also in order to + * make the search reliable, the rest of the header bits + * are also checked via lookahead by the sync routine. + * Because of this it is possible that the input buffer + * may run out of bits in the lookahead part. In that case + * the input buffer needs to be updated. The number of bytes + * to be updated are calculated based on the number of read + * bits. Thus, in the worst case, the update process will + * throw away the 1st 8 bits from the syncword. This is + * something we don't want to experience since subsequent + * processing relies on the fact that the whole header can + * be read from the input buffer once the start of the frame + * has been found. That's why we reduce the update size of the + * input buffer (shown below). + */ + tmp = BsGetBitsRead(&m_Bitstream); + syncByte = syncBuf[MAX(0, ((int32) (tmp >> 3) - 1))]; + if((tmp & 0x7) && syncByte == 0xFF) + { + /*-- Keep the previous byte in the buffer as it may be part of header. --*/ + tHandle->offsetBits = (int16) (8 + (tmp & 0x7)); + + tmp -= 8; + BsClearBitsRead(&m_Bitstream); + BsSetBitsRead(&m_Bitstream, tmp); + } + else tHandle->offsetBits = (int16) (tmp & 0x7); + } + } + break; + + case GET_MPSYNC_STREAM: + /* + * Locate sync and on succes, switch to read + * the headers values. + */ + frameStatus = SeekSync(tHandle, &m_Bitstream, execState); + if(frameStatus == SYNC_FOUND) + tHandle->transportType = GET_MPHEADER_STREAM; + else + { + hitExit = TRUE; + if(frameStatus != SYNC_LOST) + { + /*-- See explanation above. --*/ + tmp = BsGetBitsRead(&m_Bitstream); + syncByte = syncBuf[MAX(0, ((int32) (tmp >> 3) - 1))]; + if((tmp & 0x7) && syncByte == 0xFF) + { + /*-- Keep the previous byte in the buffer as it may be part of header. --*/ + tHandle->offsetBits = (int16) (8 + (tmp & 0x7)); + + tmp -= 8; + BsClearBitsRead(&m_Bitstream); + BsSetBitsRead(&m_Bitstream, tmp); + } + else tHandle->offsetBits = (int16) (tmp & 0x7); + } + } + break; + + case GET_MPHEADER_STREAM: + /* + * Read headers values and on success, switch the state back + * to sync search for next frame. + */ + hitExit = TRUE; + frameStatus = decode_header(tHandle, &m_Bitstream); + if(frameStatus == SYNC_FOUND) + tHandle->transportType = GET_MPSYNC_STREAM; + else if(frameStatus != SYNC_LOST) + { + /*-- Don't loose the syncword... --*/ + tmp = BsGetBitsRead(&m_Bitstream); + syncByte = syncBuf[MAX(0, ((int32) (tmp >> 3) - 1))]; + if((tmp & 0x7) && syncByte == 0xFF) + { + /*-- Keep the previous byte in the buffer as it may be part of header. --*/ + tHandle->offsetBits = (int16) (8 + (tmp & 0x7)); + + tmp -= 8; + BsClearBitsRead(&m_Bitstream); + BsSetBitsRead(&m_Bitstream, tmp); + } + else tHandle->offsetBits = (int16) (tmp & 0x7); + } + break; + + default: + hitExit = TRUE; + frameStatus = SYNC_LOST; + break; + } + } + + *readBits = BsGetBitsRead(&m_Bitstream); + + return (frameStatus); +} + +/* + * Returns the # of bytes reserved for the Layer I/II/III payload part of current frame. + */ +INLINE int16 +mpGetTranportFrameLength(TMpTransportHandle *tHandle) +{ + int16 frameBytes; + + tHandle->mainDataSlots = 0; + + switch(tHandle->transportType) + { + case GET_MPSYNC_STREAM: + case GET_MPHEADER_STREAM: + tHandle->mainDataSlots = (int16) main_data_slots(tHandle); + frameBytes = (int16) (tHandle->mainDataSlots + GetSideInfoSlots(tHandle)); + break; + + default: + frameBytes = 0; + break; + } + + return (frameBytes); +} + +/* + * Initializes MPEG Layer I/II/III transport handle. + */ +void +mpInitTransport(TMpTransportHandle *tHandle) +{ + ZERO_MEMORY(tHandle, sizeof(TMpTransportHandle)); + + tHandle->syncInfo.sync_word = (int16) SYNC_WORD; + tHandle->syncInfo.sync_length = (int16) MP_SYNC_WORD_LENGTH; + tHandle->syncInfo.sync_mask = (uint16) ((1 << tHandle->syncInfo.sync_length) - 1); + tHandle->syncInfo.sync_status = INIT_LAYER3_STREAM; + tHandle->transportType = INIT_MP_STREAM; + tHandle->execState.execMode = GLITCH_FREE; + tHandle->offsetBits = 0; +} + +/************************************************************************** + Title : MP_SeekSync + + Purpose : Interface to layer I/II/III frame search implementation. + + Usage : y = MP_SeekSync(tHandle, syncBuf, syncBufLen, readBytes, + frameBytes, headerBytes, initMode) + + Input : tHandle - layer I/II/III transport handle + syncBuf - input buffer + syncBufLen - length of 'sync_buf' + initMode - '1' when searching the 1st frame, '0' otherwise + + Output : y - status of operation + frameBytes - # of bytes reserved for the payload part of the frame + readBytes - # of bytes read from the buffer + headerBytes - # of bytes reserved for the header part of the frame + + Author(s) : Juha Ojanpera + *************************************************************************/ + +int16 +MP_SeekSync(TMpTransportHandle *tHandle, uint8 *syncBuf, uint32 syncBufLen, + int16 *readBytes, int16 *frameBytes, int16 *headerBytes, + uint8 initMode) +{ + uint32 readBits; + SEEK_STATUS syncSeekStatus; + + syncSeekStatus = mpSyncTransport(tHandle, syncBuf, syncBufLen, &readBits); + if(initMode && syncSeekStatus == SYNC_FOUND) + FillDataSlotTable(tHandle); + + *readBytes = (int16) (readBits >> 3); + *frameBytes = (int16) mpGetTranportFrameLength(tHandle); + *headerBytes = (int16) ((error_protection(&tHandle->header) ? 2 : 0) + 4); + + return (int16) (syncSeekStatus); +} + +/************************************************************************** + Title : MP_FreeMode + + Purpose : Interface for determining the frame/payload size of free format + layer III bitstream. + + Usage : y = MP_FreeMode(tHandle, syncBuf, syncBufLen, readBytes, + frameBytes, headerBytes) + + Input : tHandle - layer I/II/III transport handle + syncBuf - input buffer + syncBufLen - length of 'sync_buf' + + Output : y - status of operation + frameBytes - # of bytes reserved for the payload part of the frames + readBytes - # of bytes read from the buffer + headerBytes - # of bytes reserved for the header part of the frame + + Author(s) : Juha Ojanpera + *************************************************************************/ + +int16 +MP_FreeMode(TMpTransportHandle *tHandle, uint8 *syncBuf, uint32 syncBufLen, + int16 *readBytes, int16 *frameBytes, int16 *headerBytes) +{ + TBitStream m_Bitstream; + SEEK_STATUS syncSeekStatus; + + BsInit(&m_Bitstream, syncBuf, syncBufLen); + + if(tHandle->offsetBits) + BsSkipNBits(&m_Bitstream, tHandle->offsetBits); + tHandle->offsetBits = 0; + + syncSeekStatus = FreeFormat(tHandle, &m_Bitstream, &tHandle->execState); + if(syncSeekStatus == SYNC_BITS_OUT) + tHandle->offsetBits = (int16) (BsGetBitsRead(&m_Bitstream) & 0x7); + + *readBytes = (int16) (BsGetBitsRead(&m_Bitstream) >> 3); + *frameBytes = (int16) mpGetTranportFrameLength(tHandle); + *headerBytes = (int16) ((error_protection(&tHandle->header) ? 2 : 0) + 4); + + return (int16) (syncSeekStatus); +}