📄 umc_avi_chunk.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-2005 Intel Corporation. All Rights Reserved.//*/#include <memory.h>#include "vm_debug.h"#include "umc_avi_chunk.h"#define MAP_SIZE (128) // Map section size in pages#define AVI_FOURCC_FILE uimcFOURCC( 'F', 'I', 'L', 'E' )inline vm_sizet AlignTo2(const vm_sizet ullChunkSize){ return (ullChunkSize + 1) & ~0x1; }UMC::AVIChunk::AVIChunk(): m_ulStackPos(0){ m_ChnkStack[0].m_chnkName = AVI_FOURCC_FILE; }UMC::StatusUMC::AVIChunk::Init(LockableDataReaderRef Reader){ Status umcRes = UMC_OK; m_ulStackPos = 0; // Zero indexed m_ChnkStack entry corresponds file itself m_ChnkStack[0].m_chnkName = AVI_FOURCC_FILE; m_ChnkStack[0].m_stSize = 0; m_ChnkStack[0].m_stFilePos = 0; if (UMC_OK == umcRes) { m_Reader = Reader; m_ChnkStack[0].m_stSize = m_Reader.GetRdr()->GetSize(); } if (UMC_OK != umcRes) { vm_debug_trace(4, VM_STRING("AVIChunk Init failed\n")); } return umcRes;}boolUMC::AVIChunk::CmpChunkNames(const tFOURCC chnkName1, const tFOURCC chnkName2){ if (chnkName1 == chnkName2) { return true; } if((AVI_FOURCC_DB == (chnkName1 & 0xFFFF0000) || AVI_FOURCC_DC == (chnkName1 & 0xFFFF0000)) && (AVI_FOURCC_DB == (chnkName2 & 0xFFFF0000) || AVI_FOURCC_DC == (chnkName2 & 0xFFFF0000)) && ((chnkName1 & 0x0000FFFF) == (chnkName2 & 0x0000FFFF))) { return true; } return false;}UMC::StatusUMC::AVIChunk::DescendChunk(tFOURCC chnkName){ Status umcRes = UMC_OK; assert(MAX_AVI_CHUNK_DEPTH - 1 > m_ulStackPos); CChnkInfo& rCurChunk = m_ChnkStack[m_ulStackPos]; // Check if we are not already at the end of the current chunk// assert(rCurChunk.m_stFilePos + AlignTo2(rCurChunk.m_stSize) >= m_stFilePos); if (rCurChunk.m_stFilePos + AlignTo2(rCurChunk.m_stSize) == m_Reader.GetPosition()) { umcRes = UMC_NOT_FIND_SYNCWORD; } // Look for the chunk we need while (UMC_OK == umcRes && !CmpChunkNames(m_ChnkStack[m_ulStackPos + 1].m_chnkName, chnkName) && m_Reader.GetPosition() < m_ChnkStack[m_ulStackPos].m_stFilePos + AlignTo2(m_ChnkStack[m_ulStackPos].m_stSize)) { CChnkInfo& rNextChunk = m_ChnkStack[m_ulStackPos + 1]; if (UMC_OK == umcRes) { umcRes = m_Reader.LockForExclusiveUse(); } if (UMC_OK == umcRes) { umcRes = m_Reader.GetRdr()->GetVar32NoSwap(&rNextChunk.m_chnkName); } if (UMC_OK == umcRes) { rNextChunk.m_stSize = 0; umcRes = m_Reader.GetRdr()->GetVar32NoSwap( reinterpret_cast<vm_var32*>(&rNextChunk.m_stSize)); } m_Reader.UnlockFromExclusiveUse(); if (UMC_OK == umcRes) { rNextChunk.m_stFilePos = m_Reader.GetPosition(); } if (UMC_OK == umcRes) { if (AVI_FOURCC_ANY_ == chnkName) { break; } else if (!CmpChunkNames(rNextChunk.m_chnkName, chnkName)) // If we've found another chunk - skip it { umcRes = m_Reader.MovPos(AlignTo2(rNextChunk.m_stSize)); } } } if (UMC_OK == umcRes) { if (m_Reader.GetPosition() >= m_ChnkStack[m_ulStackPos].m_stFilePos + AlignTo2(m_ChnkStack[m_ulStackPos].m_stSize)) // Chunk wasn't found in current chunk { umcRes = UMC_NOT_FIND_SYNCWORD; } else if (CmpChunkNames(m_ChnkStack[m_ulStackPos + 1].m_chnkName, chnkName) || AVI_FOURCC_ANY_== chnkName) // We've found it! { m_ulStackPos++; } } if (UMC_OK != umcRes) { vm_debug_trace(4, VM_STRING("AVIChunk DescendChunk failed\n")); } return umcRes;}UMC::StatusUMC::AVIChunk::DescendChunkList(tFOURCC chnkName, tFOURCC listName){ Status umcRes = UMC_OK; assert(MAX_AVI_CHUNK_DEPTH - 1 > m_ulStackPos); while (UMC_OK == umcRes) { umcRes = DescendChunk(chnkName); if (UMC_OK == umcRes) { umcRes = m_Reader.LockForExclusiveUse(); } tFOURCC fcData = 0; if (UMC_OK == umcRes) { umcRes = m_Reader.GetRdr()->GetVar32NoSwap(&fcData); } m_Reader.UnlockFromExclusiveUse(); if (UMC_OK == umcRes) { if (UMC_OK == umcRes && CmpChunkNames(fcData, listName)) { // we've found the list chunk we was looking for m_ChnkStack[m_ulStackPos].m_stFilePos += sizeof(tFOURCC); m_ChnkStack[m_ulStackPos].m_stSize -= sizeof(tFOURCC); break; } else { umcRes = Ascend(); } } } if (UMC_OK != umcRes) { vm_debug_trace(4, VM_STRING("AVIChunk DescendChunkList failed\n")); } return umcRes;}UMC::StatusUMC::AVIChunk::Ascend(){ Status umcRes = UMC_OK; assert(0 < m_ulStackPos); if (0 == m_ulStackPos) { umcRes = UMC_OPERATION_FAILED; } if (UMC_OK == umcRes) { CChnkInfo& rCurChunk = m_ChnkStack[m_ulStackPos]; m_Reader.SetPosition(rCurChunk.m_stFilePos + AlignTo2(rCurChunk.m_stSize)); rCurChunk.m_chnkName = AVI_FOURCC_WRONG; m_ulStackPos--; } if (UMC_OK != umcRes) { vm_debug_trace(4, VM_STRING("AVIChunk Ascend failed\n")); } return umcRes;}UMC::StatusUMC::AVIChunk::GetData(vm_byte* pbBuffer, vm_var32 uiBufSize){ Status umcRes = UMC_OK; CChnkInfo& rCurChunk = m_ChnkStack[m_ulStackPos]; assert(rCurChunk.m_stFilePos + AlignTo2(rCurChunk.m_stSize) >= m_Reader.GetPosition()); // Check if we have enough data if (rCurChunk.m_stSize - (m_Reader.GetPosition() - rCurChunk.m_stFilePos) < uiBufSize) { umcRes = UMC_NOT_ENOUGH_DATA; } if (UMC_OK == umcRes) { umcRes = m_Reader.LockForExclusiveUse(); } if (UMC_OK == umcRes) { m_Reader.GetRdr()->GetData(pbBuffer, &uiBufSize); } m_Reader.UnlockFromExclusiveUse(); if (UMC_OK != umcRes) { vm_debug_trace(4, VM_STRING("AVIChunk GetData failed\n")); } return umcRes;}UMC::StatusUMC::AVIChunk::JumpToFilePos(const vm_sizet uiFilePos){ Status umcRes = UMC_OK; while ((uiFilePos < m_ChnkStack[m_ulStackPos].m_stFilePos || uiFilePos > m_ChnkStack[m_ulStackPos].m_stFilePos + m_ChnkStack[m_ulStackPos].m_stSize) && 0 < m_ulStackPos) { m_ulStackPos--; } if (0 == m_ulStackPos && uiFilePos > m_ChnkStack[m_ulStackPos].m_stFilePos + m_ChnkStack[m_ulStackPos].m_stSize) { umcRes = UMC_END_OF_STREAM; } if (UMC_OK == umcRes) { umcRes = m_Reader.SetPosition(uiFilePos); } return umcRes;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -