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

📄 umc_index.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
字号:
/*
//
//                  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) 2003-2007 Intel Corporation. All Rights Reserved.
//
*/

#include "umc_index.h"
#include "umc_automatic_mutex.h"

using namespace UMC;

TrackIndex::TrackIndex()
{
    m_uiTotalEntries = 0;
    m_iFirstEntryPos = 0;
    m_iLastEntryPos = 0;
    m_iLastReturned = -1;
    vm_mutex_set_invalid(&m_Mutex);
    vm_mutex_init(&m_Mutex);
} // TrackIndex::TrackIndex()

TrackIndex::~TrackIndex()
{
    m_iLastReturned = -1;
    m_iFirstEntryPos = 0;
    m_iLastEntryPos = 0;
    m_uiTotalEntries = 0;

    // delete memory allocated for arrays of entries
    IndexFragment frag;
    Status umcRes = m_FragmentList.First(frag);
    while (UMC_OK == umcRes)
    {
        frag.iNOfEntries = 0;
        delete[] frag.pEntryArray;
        umcRes = m_FragmentList.Next(frag);
    }

    // destroy mutex
    if (1 == vm_mutex_is_valid(&m_Mutex))
        vm_mutex_destroy(&m_Mutex);
} // TrackIndex::~TrackIndex()

Ipp32u TrackIndex::NOfEntries(void)
{
    AutomaticMutex guard(m_Mutex);
    return m_uiTotalEntries;
} // Ipp32u TrackIndex::NOfEntries(void)

Status TrackIndex::First(IndexEntry &entry)
{
    AutomaticMutex guard(m_Mutex);

    Status umcRes = m_FragmentList.First(m_ActiveFrag);
    if (UMC_OK != umcRes)
        return umcRes;

    m_iLastReturned = 0;
    m_iFirstEntryPos = 0;
    m_iLastEntryPos = m_ActiveFrag.iNOfEntries - 1;
    entry = m_ActiveFrag.pEntryArray[m_iLastReturned];
    return UMC_OK;
} // Status TrackIndex::First(IndexEntry &entry)

Status TrackIndex::Last(IndexEntry &entry)
{
    AutomaticMutex guard(m_Mutex);

    Status umcRes = m_FragmentList.Last(m_ActiveFrag);
    if (UMC_OK != umcRes)
        return umcRes;

    m_iLastReturned = m_ActiveFrag.iNOfEntries - 1;
    m_iFirstEntryPos = m_uiTotalEntries - m_ActiveFrag.iNOfEntries;
    m_iLastEntryPos = m_uiTotalEntries - 1;
    entry = m_ActiveFrag.pEntryArray[m_iLastReturned];
    return UMC_OK;
} // Status TrackIndex::Last(IndexEntry &entry)

Status TrackIndex::Next(IndexEntry &entry)
{
    AutomaticMutex guard(m_Mutex);

    if (m_iLastReturned < 0)
        return UMC_ERR_FAILED;

    IndexEntry *pNextEntry = NextEntry();
    if (NULL == pNextEntry)
        return UMC_ERR_NOT_ENOUGH_DATA;

    entry = *pNextEntry;
    return UMC_OK;
} // Status TrackIndex::Next(IndexEntry &entry)

Status TrackIndex::Prev(IndexEntry &entry)
{
    AutomaticMutex guard(m_Mutex);

    if (m_iLastReturned < 0)
        return UMC_ERR_FAILED;

    IndexEntry *pPrevEntry = PrevEntry();
    if (NULL == pPrevEntry)
        return UMC_ERR_NOT_ENOUGH_DATA;

    entry = *pPrevEntry;
    return UMC_OK;
} // Status TrackIndex::Prev(IndexEntry &entry)

Status TrackIndex::NextKey(IndexEntry &entry)
{
    AutomaticMutex guard(m_Mutex);

    if (m_iLastReturned < 0)
        return UMC_ERR_FAILED;

    IndexEntry *pNextEntry;

    do {
        pNextEntry = NextEntry();
    } while (NULL != pNextEntry && I_PICTURE != pNextEntry->uiFlags);

    if (NULL == pNextEntry)
        return UMC_ERR_NOT_ENOUGH_DATA;

    entry = *pNextEntry;
    return UMC_OK;
} // Status TrackIndex::NextKey(IndexEntry &entry)

Status TrackIndex::PrevKey(IndexEntry &entry)
{
    AutomaticMutex guard(m_Mutex);

    if (m_iLastReturned < 0)
        return UMC_ERR_FAILED;

    IndexEntry *pPrevEntry;

    do {
        pPrevEntry = PrevEntry();
    } while (NULL != pPrevEntry && I_PICTURE != pPrevEntry->uiFlags);

    if (NULL == pPrevEntry)
        return UMC_ERR_NOT_ENOUGH_DATA;

    entry = *pPrevEntry;
    return UMC_OK;
} // Status TrackIndex::PrevKey(IndexEntry &entry)

Status TrackIndex::Get(IndexEntry &entry)
{
    AutomaticMutex guard(m_Mutex);

    if (m_iLastReturned < 0)
        return UMC_ERR_FAILED;

    entry = m_ActiveFrag.pEntryArray[m_iLastReturned];
    return UMC_OK;
} // Status TrackIndex::Get(IndexEntry &entry)

Status TrackIndex::Get(IndexEntry &entry, Ipp32s pos)
{
    AutomaticMutex guard(m_Mutex);

    if (pos < 0 || pos >= (Ipp32s)m_uiTotalEntries)
        return UMC_ERR_FAILED;

    // init search session if not inited
    if (m_iLastReturned < 0)
    {
        m_FragmentList.First(m_ActiveFrag);
        m_iFirstEntryPos = 0;
        m_iLastEntryPos = m_ActiveFrag.iNOfEntries - 1;
    }

    IndexEntry *pEntryToGet = GetEntry(pos);

    // something goes wrong
    if (NULL == pEntryToGet)
        return UMC_ERR_FAILED;

    entry = *pEntryToGet;
    return UMC_OK;
} // Status TrackIndex::Get(IndexEntry &entry, Ipp32s pos)

Status TrackIndex::Get(IndexEntry &entry, Ipp64f time)
{
    AutomaticMutex guard(m_Mutex);

    if (time < 0)
        return UMC_ERR_FAILED;

    // init search session if not inited
    if (m_iLastReturned < 0)
    {
        m_FragmentList.First(m_ActiveFrag);
        m_iFirstEntryPos = 0;
        m_iLastEntryPos = m_ActiveFrag.iNOfEntries - 1;
    }

    IndexEntry *pEntryToGet = GetEntry(time);

    // something goes wrong
    if (NULL == pEntryToGet)
        return UMC_ERR_FAILED;

    entry = *pEntryToGet;
    return UMC_OK;
} // Status TrackIndex::Get(IndexEntry &entry, Ipp64f time)

Status TrackIndex::Add(IndexFragment &newFrag)
{
    AutomaticMutex guard(m_Mutex);

    if (0 == newFrag.iNOfEntries || NULL == newFrag.pEntryArray)
        return UMC_ERR_FAILED;

    Status umcRes = m_FragmentList.Add(newFrag);
    if (UMC_OK != umcRes)
        return umcRes;

    m_uiTotalEntries += newFrag.iNOfEntries;

    return UMC_OK;
} // Status TrackIndex::Add(IndexFragment &newFrag)

Status TrackIndex::Remove(void)
{
    AutomaticMutex guard(m_Mutex);

    IndexFragment frag;
    Status umcRes = m_FragmentList.Last(frag);
    if (UMC_OK != umcRes)
        return umcRes;

    // reset state
    m_iLastReturned = -1;
    m_iFirstEntryPos = 0;
    m_iLastEntryPos = 0;

    // decrease entries counter
    m_uiTotalEntries -= frag.iNOfEntries;

    m_FragmentList.Remove();
    return UMC_OK;
} // Status TrackIndex::Remove(void)

IndexEntry *TrackIndex::NextEntry(void)
{
    if (m_iLastReturned + 1 >= m_ActiveFrag.iNOfEntries)
    { // go to next fragment
        Status umcRes = m_FragmentList.Next(m_ActiveFrag);
        if (UMC_OK != umcRes)
            return NULL;

        m_iLastReturned = 0;
        m_iFirstEntryPos = m_iLastEntryPos + 1;
        m_iLastEntryPos += m_ActiveFrag.iNOfEntries;
    }
    else
        m_iLastReturned++;

    return &m_ActiveFrag.pEntryArray[m_iLastReturned];
} // IndexEntry *TrackIndex::NextEntry(void)

IndexEntry *TrackIndex::PrevEntry(void)
{
    if (m_iLastReturned - 1 < 0)
    { // go to previous fragment
        Status umcRes = m_FragmentList.Prev(m_ActiveFrag);
        if (UMC_OK != umcRes)
            return NULL;

        m_iLastEntryPos = m_iFirstEntryPos - 1;
        m_iFirstEntryPos -= m_ActiveFrag.iNOfEntries;
        m_iLastReturned = m_ActiveFrag.iNOfEntries - 1;
    }
    else
        m_iLastReturned--;

    return &m_ActiveFrag.pEntryArray[m_iLastReturned];
} // IndexEntry *TrackIndex::PrevEntry(void)

IndexEntry *TrackIndex::GetEntry(Ipp32s pos)
{
    // if needed entry is located before active fragment
    while (pos < m_iFirstEntryPos)
    {
        Status umcRes = m_FragmentList.Prev(m_ActiveFrag);
        if (UMC_OK != umcRes)
            return NULL;

        m_iLastEntryPos = m_iFirstEntryPos - 1;
        m_iFirstEntryPos -= m_ActiveFrag.iNOfEntries;
    }

    // needed entry is located after active fragment
    while (pos > m_iLastEntryPos)
    {
        Status umcRes = m_FragmentList.Next(m_ActiveFrag);
        if (UMC_OK != umcRes)
            return NULL;

        m_iFirstEntryPos = m_iLastEntryPos + 1;
        m_iLastEntryPos += m_ActiveFrag.iNOfEntries;
    }

    // requested fragment have been found
    m_iLastReturned = pos - m_iFirstEntryPos;
    return &m_ActiveFrag.pEntryArray[m_iLastReturned];
} // IndexEntry *TrackIndex::GetEntry(Ipp32s pos)

IndexEntry *TrackIndex::GetEntry(Ipp64f time)
{
    // if needed entry is located before active fragment
    while (time < m_ActiveFrag.pEntryArray[0].GetTimeStamp())
    {
        Status umcRes = m_FragmentList.Prev(m_ActiveFrag);
        if (UMC_OK != umcRes)
            return NULL;

        m_iLastEntryPos = m_iFirstEntryPos - 1;
        m_iFirstEntryPos -= m_ActiveFrag.iNOfEntries;
    }

    // needed entry is located after active fragment
    while (time > m_ActiveFrag.pEntryArray[m_ActiveFrag.iNOfEntries - 1].GetTimeStamp())
    {
        Status umcRes = m_FragmentList.Next(m_ActiveFrag);
        if (UMC_OK != umcRes)
            return NULL;

        if (time > m_ActiveFrag.pEntryArray[0].GetTimeStamp())
        {
            m_FragmentList.Prev(m_ActiveFrag);
            break;
        }

        m_iFirstEntryPos = m_iLastEntryPos + 1;
        m_iLastEntryPos += m_ActiveFrag.iNOfEntries;
    }

    // requested fragment have been found
    Ipp32s nOfEntries = m_ActiveFrag.iNOfEntries;
    IndexEntry *pEntryArray = m_ActiveFrag.pEntryArray;
    Ipp64f dStartTime = pEntryArray[0].GetTimeStamp();
    Ipp64f dEndTime = pEntryArray[nOfEntries - 1].GetTimeStamp();

    // approximate position of requested entry
    m_iLastReturned = (Ipp32s)(nOfEntries * (time - dStartTime) / (dEndTime - dStartTime));

    if (pEntryArray[m_iLastReturned].GetTimeStamp() < time)
        while (m_iLastReturned + 1 < nOfEntries && pEntryArray[m_iLastReturned + 1].GetTimeStamp() < time)
            m_iLastReturned++;
    else
        while (m_iLastReturned - 1 >= 0 && pEntryArray[m_iLastReturned - 1].GetTimeStamp() > time)
            m_iLastReturned--;


    return &m_ActiveFrag.pEntryArray[m_iLastReturned];
} // IndexEntry *TrackIndex::GetEntry(Ipp64f time)

/*
 * These functions are not necessary for AVI and MPEG4 splitters,
 * so they are temporary commented

Status TrackIndex::Modify(IndexEntry &entry)
{
    AutomaticMutex guard(m_Mutex);

    if (m_iLastReturned < 0)
        return UMC_ERR_FAILED;

    m_ActiveFrag.pEntryArray[m_iLastReturned] = entry;
    return UMC_OK;
} // Status TrackIndex::Modify(IndexEntry &entry)

Status TrackIndex::Modify(IndexEntry &entry, Ipp32s pos)
{
    AutomaticMutex guard(m_Mutex);

    if (pos < 0 || pos >= m_uiTotalEntries)
        return UMC_ERR_FAILED;

    // init search session if not inited
    if (m_iLastReturned < 0)
    {
        m_FragmentList.First(m_ActiveFrag);
        m_iFirstEntryPos = 0;
        m_iLastEntryPos = m_ActiveFrag.iNOfEntries - 1;
    }

    IndexEntry *pEntryToModify = GetEntry(pos);

    // something goes wrong
    if (NULL == pEntryToModify)
        return UMC_ERR_FAILED;

    *pEntryToModify = entry;
    return UMC_OK;
} // Status TrackIndex::Modify(IndexEntry &entry, Ipp32s pos)
*/

⌨️ 快捷键说明

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