blob: 535f1774a6c51142c0d1ca03506c5cb1b378c722 [file] [log] [blame]
/* ------------------------------------------------------------------
* 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() */