EVOLUTION-MANAGER
Edit File: oggRingbuffer.cpp
/* * Ringbuffer to prebuffer an ogg file * * Copyright (C) 2005-2008 Joern Seger * * This program 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. * This program 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* History: 01 2008: initial version is taken from the streamnik server project (JS) */ #include <iostream> #include <string.h> #include <stdlib.h> #include "oggRingbuffer.h" #include "oggHeader.h" OggRingbuffer::OggRingbuffer(unsigned int buffersize) :ringbuffer(buffersize) { } OggRingbuffer::OggRingbuffer(unsigned char* data, unsigned int len) :ringbuffer(data, len) { } OggRingbuffer::~OggRingbuffer() { } bool OggRingbuffer::getNextPageLength(unsigned int& length, int pageNum) { lock(); int tmpend = end; int tmpend2 = end; int tmpused = used; length = 0; for (; pageNum; pageNum--) { tmpend = tmpend2; if (tmpused < (int) sizeof(OggHeader)) { unlock(); return(false); } // test is this aligned? char starter[5]; for (unsigned int i=0; i<5; ++i) { starter[i] = fifo[tmpend]; tmpend+=1; tmpend%=size; } if (strncmp(starter, "OggS", 4) != 0) { unlock(); std::cerr << "OggRingbuffer::getNextPageLength: ERROR ogg packet not aligned\n"; dump(); abort(); return (false); } tmpend += sizeof(OggHeader)-6; // jup to the segment table tmpend %= size; unsigned int readsegments = fifo[tmpend]; tmpend += 1; tmpend %= size; length += sizeof(OggHeader) + readsegments; if (tmpused < (int)(sizeof(OggHeader)+readsegments)) { unlock(); return(false); } for (unsigned int i=0; i<readsegments; ++i) { length += fifo[tmpend]; tmpend += 1; tmpend %= size; } if (tmpused < (int)length) { unlock(); return(false); } tmpused -= length; tmpend2 = end + length; tmpend2 %= size; } unlock(); return(true); } bool OggRingbuffer::getNextPages(unsigned char*& data, unsigned int& length, unsigned int size) { if (!used) return(false); if (!getNextPageLength(length,size)) return(false); if (!data) data = new unsigned char[length]; if (length != getData(data, length)) return(false); return(true); } bool OggRingbuffer::getNextPage(unsigned char*& data, unsigned int& length) { return(getNextPages(data, length, 1)); } void OggRingbuffer::dump() { for (uint32 c(0); c<used; ++c) { if ((c%16) == 0) std::cerr << std::endl; std::cerr << " " << std::hex; if (fifo[(c+begin)%size] < 16) std::cerr << "0"; std::cerr << (unsigned int)fifo[(c+begin)%size]; } std::cerr << std::dec << std::endl; }