/* * Copyright (C) 2016-2018 Team Kodi * This file is part of Kodi - https://kodi.tv * * SPDX-License-Identifier: GPL-2.0-or-later * See LICENSES/README.md for more information. */ #include "LinearMemoryStream.h" using namespace KODI; using namespace RETRO; // Pad forward to nearest boundary of bytes #define PAD_TO_CEIL(x, bytes) ((((x) + (bytes)-1) / (bytes)) * (bytes)) CLinearMemoryStream::CLinearMemoryStream() { Reset(); } void CLinearMemoryStream::Init(size_t frameSize, uint64_t maxFrameCount) { Reset(); m_frameSize = frameSize; m_paddedFrameSize = PAD_TO_CEIL(m_frameSize, sizeof(uint32_t)); m_maxFrames = maxFrameCount; } void CLinearMemoryStream::Reset() { m_frameSize = 0; m_paddedFrameSize = 0; m_maxFrames = 0; m_currentFrame.reset(); m_nextFrame.reset(); m_bHasCurrentFrame = false; m_bHasNextFrame = false; m_currentFrameHistory = 0; } void CLinearMemoryStream::SetMaxFrameCount(uint64_t maxFrameCount) { if (maxFrameCount == 0) { Reset(); } else { const uint64_t frameCount = BufferSize(); if (maxFrameCount < frameCount) CullPastFrames(frameCount - maxFrameCount); } m_maxFrames = maxFrameCount; } uint8_t* CLinearMemoryStream::BeginFrame() { if (m_paddedFrameSize == 0) return nullptr; if (!m_bHasCurrentFrame) { if (!m_currentFrame) m_currentFrame.reset(new uint32_t[m_paddedFrameSize]); return reinterpret_cast(m_currentFrame.get()); } if (!m_nextFrame) m_nextFrame.reset(new uint32_t[m_paddedFrameSize]); return reinterpret_cast(m_nextFrame.get()); } const uint8_t* CLinearMemoryStream::CurrentFrame() const { if (m_bHasCurrentFrame) return reinterpret_cast(m_currentFrame.get()); return nullptr; } void CLinearMemoryStream::SubmitFrame() { if (!m_bHasCurrentFrame) { m_bHasCurrentFrame = true; } else if (!m_bHasNextFrame) { m_bHasNextFrame = true; } if (m_bHasNextFrame) { SubmitFrameInternal(); } } uint64_t CLinearMemoryStream::BufferSize() const { return PastFramesAvailable() + (m_bHasCurrentFrame ? 1 : 0); }