diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/mpeg4dec/mp4stream.c | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/mpeg4dec/mp4stream.c')
-rw-r--r-- | Src/mpeg4dec/mp4stream.c | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/Src/mpeg4dec/mp4stream.c b/Src/mpeg4dec/mp4stream.c new file mode 100644 index 00000000..9c11d169 --- /dev/null +++ b/Src/mpeg4dec/mp4stream.c @@ -0,0 +1,326 @@ +/* /////////////////////////////////////////////////////////////////////// +// +// INTEL CORPORATION PROPRIETARY INFORMATION +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Intel Corporation and may not be copied +// or disclosed except in accordance with the terms of that agreement. +// Copyright (c) 2001-2008 Intel Corporation. All Rights Reserved. +// +// Description: Decodes MPEG-4 bitstream. +// +*/ + + +#include "mp4def.h" + +#ifndef USE_INLINE_BITS_FUNC + +uint32_t mp4_ShowBits(mp4_Info* pInfo, int32_t n) +{ + uint8_t* ptr = pInfo->bufptr; + uint32_t tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]); + tmp <<= pInfo->bitoff; + tmp >>= 32 - n; + return tmp; +} + +uint32_t mp4_ShowBit(mp4_Info* pInfo) +{ + uint32_t tmp = pInfo->bufptr[0]; + tmp >>= 7 - pInfo->bitoff; + return (tmp & 1); +} + +uint32_t mp4_ShowBits9(mp4_Info* pInfo, int32_t n) +{ + uint8_t* ptr = pInfo->bufptr; + uint32_t tmp = (ptr[0] << 8) | ptr[1]; + tmp <<= (pInfo->bitoff + 16); + tmp >>= 32 - n; + return tmp; +} + +void mp4_FlushBits(mp4_Info* pInfo, int32_t n) +{ + n = n + pInfo->bitoff; + pInfo->bufptr += n >> 3; + pInfo->bitoff = n & 7; +} + +uint32_t mp4_GetBits(mp4_Info* pInfo, int32_t n) +{ + uint8_t* ptr = pInfo->bufptr; + uint32_t tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]); + tmp <<= pInfo->bitoff; + tmp >>= 32 - n; + n = n + pInfo->bitoff; + pInfo->bufptr += n >> 3; + pInfo->bitoff = n & 7; + return tmp; +} + +uint32_t mp4_GetBits9(mp4_Info* pInfo, int32_t n) +{ + uint8_t* ptr = pInfo->bufptr; + uint32_t tmp = (ptr[0] << 8) | ptr[1]; + tmp <<= (pInfo->bitoff + 16); + tmp >>= 32 - n; + n = n + pInfo->bitoff; + pInfo->bufptr += n >> 3; + pInfo->bitoff = n & 7; + return tmp; +} + +void mp4_AlignBits(mp4_Info* pInfo) +{ + if (pInfo->bitoff > 0) { + pInfo->bitoff = 0; + (pInfo->bufptr)++; + } +} + +void mp4_AlignBits7F(mp4_Info* pInfo) +{ + if (pInfo->bitoff > 0) { + pInfo->bitoff = 0; + (pInfo->bufptr)++; + } else { + if (*pInfo->bufptr == 0x7F) + (pInfo->bufptr)++; + } +} + +uint32_t mp4_ShowBitsAlign(mp4_Info* pInfo, int32_t n) +{ + uint8_t* ptr = pInfo->bitoff ? (pInfo->bufptr + 1) : pInfo->bufptr; + uint32_t tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]); + tmp >>= 32 - n; + return tmp; +} + +uint32_t mp4_ShowBitsAlign7F(mp4_Info* pInfo, int32_t n) +{ + uint8_t* ptr = pInfo->bitoff ? (pInfo->bufptr + 1) : pInfo->bufptr; + uint32_t tmp; + if (!pInfo->bitoff) { + if (*ptr == 0x7F) + ptr ++; + } + tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]); + tmp >>= 32 - n; + return tmp; +} + +#endif + +uint8_t* mp4_FindStartCodePtr(mp4_Info* pInfo) +{ + int32_t i, len = pInfo->buflen - (pInfo->bufptr - pInfo->buffer); + uint8_t* ptr = pInfo->bufptr; + for (i = 0; i < len - 3; i++) { + if (ptr[i] == 0 && ptr[i + 1] == 0 && ptr[i + 2] == 1) { + return ptr + i + 3; + } + } + return NULL; +} + +uint8_t* mp4_FindStartCodeOrShortPtr(mp4_Info* pInfo) +{ + int32_t i, len = pInfo->buflen - (pInfo->bufptr - pInfo->buffer); + uint8_t* ptr = pInfo->bufptr; + for (i = 0; i < len - 3; i++) { + if (ptr[i] == 0 && ptr[i + 1] == 0 && ptr[i + 2] == 1) { + return ptr + i + 3; + } + // short_video_header + if (ptr[i] == 0 && ptr[i + 1] == 0 && (ptr[i + 2] & 0xFC) == 0x80) { + return ptr + i; + } + } + return NULL; +} + +int32_t mp4_SeekStartCodePtr(mp4_Info* pInfo) +{ + uint8_t* ptr; + + if (pInfo->bitoff) { + pInfo->bufptr ++; + pInfo->bitoff = 0; + } + ptr = mp4_FindStartCodePtr(pInfo); + if (ptr) { + pInfo->bufptr = ptr; + return 1; + } else { + pInfo->bufptr = pInfo->buffer + (pInfo->buflen > 3 ? pInfo->buflen - 3 : 0); + return 0; + } +} + +int32_t mp4_SeekStartCodeOrShortPtr(mp4_Info* pInfo) +{ + uint8_t* ptr; + + if (pInfo->bitoff) { + pInfo->bufptr ++; + pInfo->bitoff = 0; + } + ptr = mp4_FindStartCodeOrShortPtr(pInfo); + if (ptr) { + pInfo->bufptr = ptr; + return 1; + } else { + pInfo->bufptr = pInfo->buffer + (pInfo->buflen > 3 ? pInfo->buflen - 3 : 0); + return 0; + } +} + +int32_t mp4_SeekStartCodeValue(mp4_Info* pInfo, uint8_t code) +{ + while (mp4_SeekStartCodePtr(pInfo)) { + if (*(pInfo->bufptr) == code) { + (pInfo->bufptr) ++; + return 1; + } + } + return 0; +} + +uint8_t* mp4_FindShortVideoStartMarkerPtr(mp4_Info* pInfo) +{ + int32_t i, len = pInfo->buflen - (pInfo->bufptr - pInfo->buffer); + uint8_t* ptr = pInfo->bufptr; + for (i = 0; i < len - 3; i++) { + if (ptr[i] == 0 && ptr[i + 1] == 0 && (ptr[i + 2] & (~3)) == 0x80) { + return ptr + i + 2; + } + } + return NULL; +} + +int32_t mp4_SeekShortVideoStartMarker(mp4_Info* pInfo) +{ + uint8_t* ptr; + + if (pInfo->bitoff) { + pInfo->bufptr ++; + pInfo->bitoff = 0; + } + ptr = mp4_FindShortVideoStartMarkerPtr(pInfo); + if (ptr) { + pInfo->bufptr = ptr; + return 1; + } else { + pInfo->bufptr = pInfo->buffer + (pInfo->buflen > 3 ? pInfo->buflen - 3 : 0); + return 0; + } +} + +//changed pInfo->len on pInfo->buflen!!! +int32_t mp4_SeekGOBMarker(mp4_Info* pInfo) +{ + for (; pInfo->bufptr < pInfo->buffer + pInfo->buflen - 2; pInfo->bufptr ++) { + if (pInfo->bufptr[0] == 0) { + pInfo->bitoff = 0; + if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && (pInfo->bufptr[2] & (~3)) == 0x80) + return 0; + pInfo->bufptr --; + for (pInfo->bitoff = 1; pInfo->bitoff <= 7; pInfo->bitoff ++) { + if (mp4_ShowBits(pInfo, 17) == 1) + return 1; + } + pInfo->bufptr ++; + for (pInfo->bitoff = 0; pInfo->bitoff <= 7; pInfo->bitoff ++) { + if (mp4_ShowBits(pInfo, 17) == 1) + return 1; + } + pInfo->bufptr ++; + } + } + return 0; +} + +int32_t mp4_SeekResyncMarker(mp4_Info* pInfo) +{ + int32_t rml; + + if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_I) + rml = 17; + else if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_B) + rml = 16 + IPP_MAX(pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward, pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_backward); + else + rml = 16 + pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward; + pInfo->bitoff = 0; + for (; pInfo->bufptr < pInfo->buffer + pInfo->buflen - 2; pInfo->bufptr ++) { + if (pInfo->bufptr[0] == 0) { + if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && pInfo->bufptr[2] == 1) + return 0; + if (mp4_ShowBits(pInfo, rml) == 1) { + // check stuffing bits + pInfo->bufptr --; + pInfo->bitoff = 7; + while (pInfo->bitoff > 0 && mp4_ShowBit(pInfo)) + pInfo->bitoff --; + if (pInfo->bitoff == 0 && mp4_ShowBit(pInfo)) { + // stuffing bits are invalid + pInfo->bufptr[0] = 0x7f; + } + return 1; + } + pInfo->bufptr += 2; + } + } + return 0; +} + +int32_t mp4_FindResyncMarker(mp4_Info* pInfo) +{ + int32_t rml; + + if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_I) + rml = 17; + else if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_B) + rml = 16 + IPP_MAX(pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward, pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_backward); + else + rml = 16 + pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward; + pInfo->bitoff = 0; + for (; pInfo->bufptr < pInfo->buffer + pInfo->buflen - 2; pInfo->bufptr ++) { + if (pInfo->bufptr[0] == 0) + { + if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && pInfo->bufptr[2] == 1) + return 0; + if (mp4_ShowBits(pInfo, rml) == 1) + { + return rml; + } + } + } + return 0; +} + +int mp4_IsStartCodeOrShort(mp4_Info* pInfo) +{ + if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && (pInfo->bufptr[2] == 1 || ((pInfo->bufptr[2] & 0xFC) == 0x80))) + return 1; + return 0; +} + + +int mp4_IsStartCodeValue(mp4_Info* pInfo, int min, int max) +{ + if (pInfo->bufptr[0-3] == 0 && pInfo->bufptr[1-3] == 0 && pInfo->bufptr[2-3] == 1) + if (pInfo->bufptr[3-3] >= min && pInfo->bufptr[3-3] <= max) + return 1; + return 0; +} + + +int mp4_IsShortCode(mp4_Info* pInfo) +{ + if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && ((pInfo->bufptr[2] & 0xFC) == 0x80)) + return 1; + return 0; +} + |