⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp4stream.c

📁 audio-video-codecs.rar语音编解码器
💻 C
字号:
/* ///////////////////////////////////////////////////////////////////////
//
//               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 "umc_defs.h"

#if defined (UMC_ENABLE_MPEG4_VIDEO_DECODER)

#include "mp4.h"

#ifndef USE_INLINE_BITS_FUNC

Ipp32u mp4_ShowBits(mp4_Info* pInfo, Ipp32s n)
{
    Ipp8u* ptr = pInfo->bufptr;
    Ipp32u tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] <<  8) | (ptr[3]);
    tmp <<= pInfo->bitoff;
    tmp >>= 32 - n;
    return tmp;
}

Ipp32u mp4_ShowBit(mp4_Info* pInfo)
{
    Ipp32u tmp = pInfo->bufptr[0];
    tmp >>= 7 - pInfo->bitoff;
    return (tmp & 1);
}

Ipp32u mp4_ShowBits9(mp4_Info* pInfo, Ipp32s n)
{
    Ipp8u* ptr = pInfo->bufptr;
    Ipp32u tmp = (ptr[0] <<  8) | ptr[1];
    tmp <<= (pInfo->bitoff + 16);
    tmp >>= 32 - n;
    return tmp;
}

void mp4_FlushBits(mp4_Info* pInfo, Ipp32s n)
{
    n = n + pInfo->bitoff;
    pInfo->bufptr += n >> 3;
    pInfo->bitoff = n & 7;
}

Ipp32u mp4_GetBits(mp4_Info* pInfo, Ipp32s n)
{
    Ipp8u* ptr = pInfo->bufptr;
    Ipp32u 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;
}

/*
Ipp32u mp4_GetBit(mp4_Info* pInfo)
{
    Ipp32u tmp = pInfo->bufptr[0];
    if (pInfo->bitoff == 7) {
        pInfo->bitoff = 0;
        pInfo->bufptr ++;
    } else {
        tmp >>= 7 - pInfo->bitoff;
        pInfo->bitoff ++;
    }
    return (tmp & 1);
}
*/

Ipp32u mp4_GetBits9(mp4_Info* pInfo, Ipp32s n)
{
    Ipp8u* ptr = pInfo->bufptr;
    Ipp32u 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;
}

/*
//  align bit stream to the byte boundary
*/
void mp4_AlignBits(mp4_Info* pInfo)
{
    if (pInfo->bitoff > 0) {
        pInfo->bitoff = 0;
        (pInfo->bufptr)++;
    }
}

/*
//  align bit stream to the byte boundary (skip 0x7F)
*/
void mp4_AlignBits7F(mp4_Info* pInfo)
{
    if (pInfo->bitoff > 0) {
        pInfo->bitoff = 0;
        (pInfo->bufptr)++;
    } else {
        if (*pInfo->bufptr == 0x7F)
            (pInfo->bufptr)++;
    }
}

Ipp32u mp4_ShowBitsAlign(mp4_Info* pInfo, Ipp32s n)
{
    Ipp8u* ptr = pInfo->bitoff ? (pInfo->bufptr + 1) : pInfo->bufptr;
    Ipp32u tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] <<  8) | (ptr[3]);
    tmp >>= 32 - n;
    return tmp;
}

Ipp32u mp4_ShowBitsAlign7F(mp4_Info* pInfo, Ipp32s n)
{
    Ipp8u* ptr = pInfo->bitoff ? (pInfo->bufptr + 1) : pInfo->bufptr;
    Ipp32u 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

/*
//  find MPEG-4 start code in buffer
*/
Ipp8u* mp4_FindStartCodePtr(mp4_Info* pInfo)
{
    Ipp32s  i, len = pInfo->buflen - (pInfo->bufptr - pInfo->buffer);
    Ipp8u*  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;
}

/*
//  find MPEG-4 start code or short_vedo_header code in buffer
*/
Ipp8u* mp4_FindStartCodeOrShortPtr(mp4_Info* pInfo)
{
    Ipp32s  i, len = pInfo->buflen - (pInfo->bufptr - pInfo->buffer);
    Ipp8u*  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;
        }
    }
    return NULL;
}

/*
//  find MPEG-4 start code in stream
*/
Ipp32s mp4_SeekStartCodePtr(mp4_Info* pInfo)
{
    Ipp8u* 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;
        return 0;
    }
}

/*
//  find MPEG-4 start code or short_vedo_header code  in stream
*/
Ipp32s mp4_SeekStartCodeOrShortPtr(mp4_Info* pInfo)
{
    Ipp8u* 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;
        return 0;
    }
}

/*
//  find MPEG-4 start code value in stream
*/
Ipp32s mp4_SeekStartCodeValue(mp4_Info* pInfo, Ipp8u code)
{
    while (mp4_SeekStartCodePtr(pInfo)) {
        if (*(pInfo->bufptr) == code) {
            (pInfo->bufptr) ++;
            return 1;
        }
    }
    return 0;
}

/*
//  find ptr to ShortVideoStartMarker in buffer
*/
Ipp8u* mp4_FindShortVideoStartMarkerPtr(mp4_Info* pInfo)
{
    Ipp32s  i, len = pInfo->buflen - (pInfo->bufptr - pInfo->buffer);
    Ipp8u*  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;
}

/*
//  find ShortVideoStartMarker value in stream
*/
Ipp32s mp4_SeekShortVideoStartMarker(mp4_Info* pInfo)
{
    Ipp8u* 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;
        return 0;
    }
}

/*
//  Seek next GOB marker
*///changed pInfo->len on pInfo->buflen!!!
Ipp32s 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;
}

/*
//  Seek next resync marker
*/
Ipp32s mp4_SeekResyncMarker(mp4_Info* pInfo)
{
    Ipp32s  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;
}

Ipp32s mp4_FindResyncMarker(mp4_Info* pInfo)
{
    Ipp32s  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;
}

#endif //defined (UMC_ENABLE_MPEG4_VIDEO_DECODER)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -