www.pudn.com > mediator15src.zip > StateManager.cpp
/* * StateManager.cpp * Copyright (C) 2002 Arno Hornberger* Original Version Copyright (C) Alberto Vigata - January 2000 - ultraflask@yahoo.com * * This file is part of MPEG Mediator, a free MPEG stream converter. * * MPEG Mediator is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * MPEG Mediator is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "StateManager.h" bool CStateManager::GetFromMemoryBlock(PBYTE block) { TStateHeader *hdr; PBYTE tmp; if (!block) return false; hdr = (TStateHeader *)block; if (hdr->Mark != AVI_BLOCK_MARK) return false; tmp = new BYTE[hdr->blockSize]; if (!tmp) return false; // if (hdr->blockSize >= MAX_BLOCK_SIZE) // return false; if (m_pBuf) delete []m_pBuf; m_pBuf = tmp; memcpy(m_pBuf, block, hdr->blockSize); return true; } bool CStateManager::GetStatePos(DWORD fccHandler, int *pos) { PBYTE pBlock = m_pBuf; // fccCode // statesize (excluding fccCode and statesize itself) // statedata // fccCode // .... if (!m_pBuf) return false; // state data starts after header and WFX int dataToCheck = GetBlockSize() - GetWfxSize() - GetHeaderSize(); pBlock += GetHeaderSize() + GetWfxSize(); *pos = -1; while (dataToCheck >= 8) { if (*((DWORD *)pBlock) == fccHandler) { *pos = GetBlockSize() - dataToCheck; break; } // skip fccHandler pBlock += 4; int stateSize = *((int *)pBlock); // skip stateSize pBlock += 4; // skip state pBlock += stateSize; dataToCheck -= stateSize; } return *pos > 0; } bool CStateManager::GetState(DWORD fccHandler, PBYTE *pBlock, int *blockSize) { int statePos; if (GetStatePos(fccHandler, &statePos)) { // statePos marks to the fccHandler // skip the fccHandler and size *blockSize = *(int *)(m_pBuf + statePos + 4); statePos += 8; // Get the state size *pBlock = m_pBuf + statePos; return true; } else return false; } bool CStateManager::SetToMemoryBlock(PBYTE block) { if (!block || !m_pBuf) return false; memcpy(block, m_pBuf, GetBlockSize()); return true; } bool CStateManager::SetWfx(WAVEFORMATEX *wfx, int wfxSize) { int statesize; if (!m_pBuf) Reset(); statesize = GetBlockSize() - GetHeaderSize() - GetWfxSize(); PBYTE newBlock = new BYTE[GetBlockSize() - GetWfxSize() + wfxSize]; memcpy(newBlock, m_pBuf, GetHeaderSize()); if (wfxSize) memcpy(newBlock + GetHeaderSize(), wfx, wfxSize); // copy state data for each codec memcpy(newBlock + GetHeaderSize() + wfxSize, m_pBuf + GetHeaderSize() + GetWfxSize(), statesize); delete []m_pBuf; m_pBuf = newBlock; SetBlockSize(statesize + GetHeaderSize() + wfxSize); SetWfxSize(wfxSize); return true; } void CStateManager::Reset() { if (m_pBuf) delete []m_pBuf; m_pBuf = new BYTE[sizeof(TStateHeader)]; ((TStateHeader *)m_pBuf)->Mark = AVI_BLOCK_MARK; ((TStateHeader *)m_pBuf)->blockSize = GetHeaderSize(); ((TStateHeader *)m_pBuf)->wfxSize = 0; ((TStateHeader *)m_pBuf)->fccHandler = 0; ((TStateHeader *)m_pBuf)->lQuality = 100; ((TStateHeader *)m_pBuf)->lKeyRate = 0; ((TStateHeader *)m_pBuf)->lDataRate = 0; ((TStateHeader *)m_pBuf)->hadid = 0; ((TStateHeader *)m_pBuf)->HQAudioCompression = true; } bool CStateManager::SetState(DWORD fccHandler, PBYTE block, int blockSize) { int statePos; if (!m_pBuf) Reset(); if (m_pBuf) { if (GetStatePos(fccHandler, &statePos)) { // we have a state for this format. Delete it. // statePos marks to the fccHandler // Get the state size int stateSize = *((int *)(m_pBuf + statePos + 4)); // prepare a new memory block PBYTE newBlock = new BYTE[GetBlockSize() - stateSize - 8]; // copy all states up to the one we want to delete memcpy(newBlock, m_pBuf, statePos); memcpy(newBlock + statePos, m_pBuf + statePos + stateSize + 8, GetBlockSize() - statePos - stateSize - 8); delete []m_pBuf; m_pBuf = newBlock; SetBlockSize(GetBlockSize() - stateSize - 8); } PBYTE newBlock = new BYTE[GetBlockSize() + blockSize + 8]; memcpy(newBlock, m_pBuf, GetBlockSize()); // create new state *(DWORD *)(newBlock + GetBlockSize()) = fccHandler; *(int *)(newBlock + GetBlockSize() + 4) = blockSize; // copy new state memcpy(newBlock + GetBlockSize() + 8, block, blockSize); // swap blocks // delete actual delete []m_pBuf; m_pBuf = newBlock; SetBlockSize(GetBlockSize() + blockSize + 8); return true; } else return false; }