/* ------------------------------------------------------------------ * Copyright (C) 1998-2009 PacketVideo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. * See the License for the specific language governing permissions * and limitations under the License. * ------------------------------------------------------------------- */ /* Pathname: ./src/find_adts_syncword.c ------------------------------------------------------------------------------ REVISION HISTORY Description: Fixed error in logic that determines whether there are enough bits available to conduct a search for the syncword. The plus sign in the following condition should be a minus. if (pInputStream->usedBits < (pInputStream->availableBits + syncword_length) The length of the syncword should subtract from the number of available bits, not add. Description: Fixed condition when the end of file was found, unsigned comparison produced a undesired search. Fixed by casting comparison if ((Int)pInputStream->usedBits < ((Int)pInputStream->availableBits - syncword_length) ) Description: ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: pSyncword = Pointer to variable containing the syncword that the function should be scanning for in the buffer. [ UInt32 * ] pInputStream = Pointer to a BITS structure, used by the function getbits to retrieve data from the bitstream. [ BITS * ] syncword_length = The length of the syncword. [ Int ] syncword_mask = A mask to be applied to the bitstream before comparison with the value pointed to by pSyncword. [ UInt32 ] Local Stores/Buffers/Pointers Needed: None Global Stores/Buffers/Pointers Needed: None Outputs: None Pointers and Buffers Modified: None Local Stores Modified: None Global Stores Modified: None ------------------------------------------------------------------------------ FUNCTION DESCRIPTION This module scans the bitstream for a syncword of any length between 1 and 32. If certain bits in the syncword are to be ignored, that bit position should be set to 0 in both parameters *(pSyncword) and syncword_mask. This allows for a syncword to be constructed out of non-contiguous bits. Upon finding the syncword's position in the bitstream, a value denoting the syncword's degree of deviance from being byte-aligned (byte_align_offset) is set in the structure pointed to by pInputStream. This is a value between 0 and 7. If no syncword is found, the function returns status == ERROR. ------------------------------------------------------------------------------ REQUIREMENTS "Don't care" bits must be set to '0' in both *(pSyncword) and syncword_mask. This function should not be called if there are less than (8 + syncword_length) bits in the buffer. ------------------------------------------------------------------------------ REFERENCES (1) ISO/IEC 13818-7:1997(E) Part 7 Subpart 6.2 (Audio_Data_Transport_Stream frame, ADTS) (2) ISO/IEC 11172-3:1993(E) Part 3 Subpart 2.4.3 The audio decoding process ------------------------------------------------------------------------------ PSEUDO-CODE IF (pInputStream->usedBits < (pInputStream->availableBits + syncword_length) ) max_search_length = (pInputStream->availableBits - pInputStream->usedBits); max_search_length = max_search_length - syncword_length; search_length = 0; adts_header = CALL getbits(syncword_length, pInputStream); MODIFYING pInputStream->usedBits RETURNING bits from bitstream of length (syncword_length) test_for_syncword = adts_header AND syncword_mask; test_for_syncword = test_for_syncword XOR syncword; WHILE ( (test_for_syncword != 0) && (search_length > 0) ) search_length = search_length - 1; adts_header = adts_header << 1; adts_header = adts_header OR ... CALL getbits(syncword_length, pInputStream); MODIFYING pInputStream->usedBits RETURNING 1 bit from the bitstream test_for_syncword = adts_header AND syncword_mask; test_for_syncword = test_for_syncword XOR syncword; ENDWHILE IF (search_length == 0) status = ERROR; ENDIF *(pSyncword) = adts_header; pInputStream->byteAlignOffset = (pInputStream->usedBits - syncwordlength) AND 0x7; ELSE status = ERROR; ENDIF return (status); ------------------------------------------------------------------------------ RESOURCES USED When the code is written for a specific target processor the the resources used should be documented below. STACK USAGE: [stack count for this module] + [variable to represent stack usage for each subroutine called] where: [stack usage variable] = stack usage for [subroutine name] (see [filename].ext) DATA MEMORY USED: x words PROGRAM MEMORY USED: x words CLOCK CYCLES: [cycle count equation for this module] + [variable used to represent cycle count for each subroutine called] where: [cycle count variable] = cycle count for [subroutine name] (see [filename].ext) ------------------------------------------------------------------------------ */ /*---------------------------------------------------------------------------- ; INCLUDES ----------------------------------------------------------------------------*/ #include "pv_audio_type_defs.h" #include "s_bits.h" #include "ibstream.h" #include "find_adts_syncword.h" /*---------------------------------------------------------------------------- ; MACROS ; Define module specific macros here ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; DEFINES ; Include all pre-processor statements here. Include conditional ; compile variables also. ----------------------------------------------------------------------------*/ #define FIND_ADTS_ERROR -1 /*---------------------------------------------------------------------------- ; LOCAL FUNCTION DEFINITIONS ; Function Prototype declaration ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; LOCAL STORE/BUFFER/POINTER DEFINITIONS ; Variable declaration - defined here and used outside this module ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; EXTERNAL FUNCTION REFERENCES ; Declare functions defined elsewhere and referenced in this module ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES ; Declare variables used in this module but defined elsewhere ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; FUNCTION CODE ----------------------------------------------------------------------------*/ Int find_adts_syncword( UInt32 *pSyncword, BITS *pInputStream, Int syncword_length, UInt32 syncword_mask) { Int status = SUCCESS; UInt search_length; UInt32 adts_header = 0; UInt32 test_for_syncword; UInt32 syncword = *(pSyncword); /* * Determine the maximum number of bits available to this function for * the syncword search. */ if ((Int)pInputStream->usedBits < ((Int)pInputStream->availableBits - syncword_length)) { search_length = (pInputStream->availableBits - pInputStream->usedBits); search_length -= syncword_length; adts_header = getbits(syncword_length, pInputStream); /* * Mask the result in adts_header with the syncword_mask, so only the * bits relevant to syncword detection are compared to *(pSyncword). */ test_for_syncword = adts_header & syncword_mask; test_for_syncword ^= syncword; /* * Scan bit-by-bit through the bitstream, until the function either * runs out of bits, or finds the syncword. */ while ((test_for_syncword != 0) && (search_length > 0)) { search_length--; adts_header <<= 1; adts_header |= getbits(1, pInputStream); test_for_syncword = adts_header & syncword_mask; test_for_syncword ^= syncword; } if (search_length == 0) { status = FIND_ADTS_ERROR; } /* * Return the syncword's position in the bitstream. Correct placement * of the syncword will result in byte_align_offset == 0. * If the syncword is found not to be byte-aligned, then return * the degree of disalignment, so further decoding can * be shifted as necessary. * */ pInputStream->byteAlignOffset = (pInputStream->usedBits - syncword_length) & 0x7; } /* END if (pInputStream->usedBits < ...) */ else { status = FIND_ADTS_ERROR; } *(pSyncword) = adts_header; return (status); } /* find_adts_syncword() */