oggvideotools-0.9.1/src/base/mediaRepository.cpp000664 001750 001750 00000002343 12763227102 022171 0ustar00embedembed000000 000000 /* * MediaRepository is a baseclass for all communication interfaces * (e.g. files, tcp, rtp and http streams) * * Copyright (C) 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. * */ #include "mediaRepository.h" MediaRepository::MediaRepository() : MediaUnit(MediaUnit::read, std::string("")), repositoryAvailable(false) { } MediaRepository::MediaRepository(MediaDirection_t type, const std::string name) : MediaUnit(type, name), repositoryAvailable(false) { } MediaRepository::~MediaRepository() { } bool MediaRepository::isAvailable() { return(repositoryAvailable); } oggvideotools-0.9.1/testsuite/testoggThumb.sh000775 001750 001750 00000000505 12763227102 021647 0ustar00embedembed000000 000000 #!/bin/sh ../build/src/binaries/oggThumb -t 0.4,0.7,1 -s200x0 -n ducks_%.png ../testvideos/ducks_take_off_444_720p25.ogg ../build/src/binaries/oggThumb -t 0.4,0.7,1 -s0x200 -n aspect_%.png ../testvideos/pixel_aspect_ratio.ogg ../build/src/binaries/oggThumb -t 0.4,0.7,1,200 -n stockholm_%.png ../testvideos/stockholm-vfr.ogg oggvideotools-0.9.1/src/base/oggRingbuffer.cpp000664 001750 001750 00000010326 12763227102 021600 0ustar00embedembed000000 000000 /* * 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 #include #include #include "oggRingbuffer.h" #include "oggHeader.h" #include "exception.h" #include "oggPage.h" #include "log.h" OggRingbuffer::OggRingbuffer(uint32_t buffersize) :ringbuffer(buffersize) { } //OggRingbuffer::OggRingbuffer(uint8_t* data, uint32_t len) // :ringbuffer(data, len) //{ //} OggRingbuffer::~OggRingbuffer() { } bool OggRingbuffer::getNextPageLength(uint32_t& length, int pageNum) { lock(); int tmpend = end; int tmpused = used; length = 0; for (; pageNum; pageNum--) { logger.debug() << "get new page no " << pageNum << " available data is "<< tmpused << std::endl; uint32_t tmplen = 0; if (tmpused < (int) sizeof(OggHeader)) { unlock(); return(false); } // test is this aligned? char starter[5]; for (uint32_t i=0; i<5; ++i) { starter[i] = fifo[(tmpend+i)%size]; logger.debug() << "data " << std::hex << "0x" << (int)starter[i] << " ("<& data, uint32_t& length, uint32_t size) { if (!used) return(false); if (!getNextPageLength(length,size)) return(false); if (length != getData(data, length)) return(false); return(true); } //bool OggRingbuffer::getNextPage(uint8_t*& data, uint32_t& length) //{ // return(getNextPages(data, length, 1)); //} bool OggRingbuffer::getNextPage(std::vector& data, uint32_t& length) { return(getNextPages(data, length, 1)); } void OggRingbuffer::dump() { for (uint32 c(0); c #include #include "vorbisExtractor.h" #include "vorbisStreamParameter.h" #include "oggHeader.h" #include "vorbisHeader.h" #include "log.h" VorbisExtractor::VorbisExtractor() { } VorbisExtractor::~VorbisExtractor() { } bool VorbisExtractor::_extract(uint8* data, ExtractorInformation& info) { StreamType* streaminfo = (StreamType*) (data); VorbisHeader* vorbisHeader = (VorbisHeader*) (data + sizeof(StreamType)); /* if this is not a vorbis header, return with an error */ if ((streaminfo->headerType != 0x01) || (strncmp(streaminfo->typeName, "vorbis", 6) != 0)) { logger.error() << "VorbisExtractor::_extract: This page is not a vorbis bos\n"; return(false); } // first extract the parameters std::shared_ptr param = std::make_shared(); param->channels = vorbisHeader->audioChannels; param->samplerate = vorbisHeader->sampleRate; param->datarate = vorbisHeader->bitrateNom; param->datarateMin = vorbisHeader->bitrateMin; param->datarateMax = vorbisHeader->bitrateMax; param->block0 = 1<blocksize0; param->block1 = 1<blocksize1; info.parameter = param; /* set the ogg type and the number of header packets */ info.type = OggType::vorbis; info.numOfHeaderPackets = 3; // the first three packets are headers return(true); } bool VorbisExtractor::extract(OggPage& oggPage, ExtractorInformation& information) { /* if this is not a Begin Of Stream page, return immediately */ if (!oggPage->isBOS()) { logger.error() << "VorbisPosInterpreter::extract: This page is not a BOS (Begin Of Stream) page\n"; return(false); } uint8_t* dataPtr = &(oggPage->data())[0]; /* get the information starting points within the raw data */ OggHeader* oggHeader = (OggHeader*) dataPtr; uint8* data = dataPtr + sizeof(OggHeader) + oggHeader->tableSegments; if (!_extract(data, information)) return(false); information.serialNo = oggHeader->serial; return(true); } bool VorbisExtractor::extract(OggPacket& packet, ExtractorInformation& information) { /// if this is not a Begin Of Stream page, return immediately if (!packet->isBOS()) { logger.error() << "VorbisPosInterpreter::extract: This page is not a BOS (Begin Of Stream) page\n"; return(false); } return _extract(packet->data(), information); } oggvideotools-0.9.1/src/effect/pictureBlend.cpp000664 001750 001750 00000005212 12763227102 021752 0ustar00embedembed000000 000000 // // C++ Implementation: pictureBlend // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #include "pictureBlend.h" #include "exception.h" PictureBlend::PictureBlend() { } PictureBlend::~PictureBlend() { } RGBPlane PictureBlend::crossfade(RGBPlane & plane1, RGBPlane & plane2, float velocity) { if ((plane1->width != plane2->width) || (plane1->height != plane2->height)) throw OggException("can not crossfade, planes not matching"); uint32 size = plane1->width*plane1->height*4; RGBPlane retPlane(plane1->width, plane1->height); uint32 pixel1; uint32 pixel2; uint32 newPixel; for (uint32 i(0); iplane[i]; pixel2 = plane2->plane[i]; newPixel = (uint32)(pixel1*(1.0-velocity) + pixel2*velocity); if (newPixel> 0xFF) newPixel = 0xFF; retPlane->plane[i] = (uint8)newPixel; /* green */ pixel1 = plane1->plane[i+1]; pixel2 = plane2->plane[i+1]; newPixel = (uint32)(pixel1*(1.0-velocity) + pixel2*velocity); if (newPixel> 0xFF) newPixel = 0xFF; retPlane->plane[i+1] = (uint8)newPixel; /* blue */ pixel1 = plane1->plane[i+2]; pixel2 = plane2->plane[i+2]; newPixel = (uint32)(pixel1*(1.0-velocity) + pixel2*velocity); if (newPixel> 0xFF) newPixel = 0xFF; retPlane->plane[i+2] = (uint8)newPixel; } return (retPlane); } RGBPlane PictureBlend::alphaBlend(RGBPlane& origPlane, RGBPlane & alphaPlane, float intensity) { float factor; uint32 position; uint32 pixel1; uint32 pixel2; uint32 newPixel; RGBPlane retPlane(origPlane->width, origPlane->height); uint32 positionAlpha; for (uint32 j(0); j < origPlane->height; ++j) for (uint32 i(0); i < origPlane->width; ++i) { // if the alpha plane is smaller than the original plane, just copy the data if ((iwidth) && (jheight)) { position = 4*(j*origPlane->width+i); positionAlpha = 4*(j*alphaPlane->width+i); factor = intensity*((127-alphaPlane->plane[positionAlpha+3])*1.0)/127.0; for (uint32 k(0); k<3; ++k) { pixel1 = origPlane->plane[position+k]; pixel2 = alphaPlane->plane[positionAlpha+k]; newPixel = (uint32)(pixel1 * (1.0-factor) + pixel2 * factor ); if (newPixel> 0xFF) newPixel = 0xFF; retPlane->plane[position+k] = (uint8)newPixel; } } else { position = j*origPlane->width+i; ((uint32*)(retPlane->plane))[position] = ((uint32*)(origPlane->plane))[position]; } } return (retPlane); } oggvideotools-0.9.1/src/main/audioConverter.cpp000664 001750 001750 00000006356 12763227102 022025 0ustar00embedembed000000 000000 #include "audioConverter.h" #include #include #include "libresample/libresample.h" #include "log.h" AudioConverter::AudioConverter() : channelData(0), tmp(0), handle(0), used(0), ratio(0), channels(0) { } AudioConverter::~AudioConverter() { } void AudioConverter::initResample(uint8 _channels, double _ratio) { ratio = _ratio; channels = _channels; handle = (void **) new char[channels * sizeof(void *)]; channelData = new float*[channels]; tmp = new float*[channels]; for (uint8 c=0; c we want stereo and have mono if ((channels == 2) && (packet->getChannels() == 1)) { for (uint32 pos(0); pos < packet->getLength(); ++pos) channelData[0][used+pos] = packet->getDataOfChannel(0)[pos]; for (uint32 pos(0); pos < packet->getLength(); ++pos) channelData[1][used+pos] = packet->getDataOfChannel(0)[pos]; } // downmix -> we want mono and have stereo if ((channels == 1) && (packet->getChannels() == 2)) { for (uint32 pos(0); pos < packet->getLength(); ++pos) { channelData[0][used+pos] = packet->getDataOfChannel(0)[pos]*0.5 + packet->getDataOfChannel(1)[pos]*0.5; if (channelData[0][used+pos]> 1.0) channelData[0][used+pos] = 1.0; } } // plane copy if (channels == packet->getChannels()) { for (uint32 c(0); c < channels; ++c) for (uint32 pos(0); pos < packet->getLength(); ++pos) channelData[c][used+pos] = packet->getDataOfChannel(c)[pos]; } if (ratio == 1.0) { length = packet->getLength(); AudioPacketInternal* newInternalPacket = new AudioPacketInternal(channels, length); for (uint32 i(0); isetDataOfChannel(i,channelData[i]); } resampled = AudioPacket(newInternalPacket); return(true); } uint32 availableSamples = used+packet->getLength(); int32 inUsed=0; // do resampling for (uint32 i(0); isetDataOfChannel(i,tmp[i]); } resampled = AudioPacket(newInternalPacket); // save data used = availableSamples-inUsed; for (uint32 i(0); i < used; ++i) { for (uint32 ch(0); ch 0); } return(true); } bool AudioConverter::resampleflush(AudioPacket & resampled) { if (used==0) return(false); logger.error() << "AudioConverter::resampleflush: not implemented "<, (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #include "effector.h" Effector::Effector() { } Effector::~Effector() { } oggvideotools-0.9.1/src/main/000775 001750 001750 00000000000 12763227102 016316 5ustar00embedembed000000 000000 oggvideotools-0.9.1/src/base/000775 001750 001750 00000000000 12763227352 016313 5ustar00embedembed000000 000000 oggvideotools-0.9.1/src/ovt_kate/CMakeLists.txt000664 001750 001750 00000000241 12763227102 021743 0ustar00embedembed000000 000000 SET ( LIBRARY_KATE_SRC katePosInterpreter.cpp kateStreamParameter.cpp kateExtractor.cpp ) ADD_LIBRARY ( ovtkate ${LIBRARY_KATE_SRC} ) oggvideotools-0.9.1/docs/mkThumbs.html000664 001750 001750 00000003735 12763227102 020223 0ustar00embedembed000000 000000 Content-type: text/html Man page of MKTHUMBS

MKTHUMBS

Section: User Manuals (1)
Updated: JAN 2010
Index Return to Main Contents
 

NAME

mkThumbs - script to create thumbnails from an ogg video file  

SYNOPSIS

mkThumbs file.ogv <number of thumbs> <additional options>  

DESCRIPTION

mkThumbs creates a series of thumbnails over a video file with regards to the video length.

 

EXAMPLE

mkThumb myvideo.ogv 10

creates 10 thumbnails across the video file.

mkThumb myvideo.ogv 10 -s0x200 -opng

creates 10 thumbnails across the video file with a height of 200 pixel and in PNG format.

 

AUTHOR

Joern Seger <yorn at gmx dot net>

 

SEE ALSO

oggCut(1), oggJoin(1), oggSplit(1), oggResize(1), oggSlideshow(1), oggThumb(1), oggSilence(1)
 

Index

NAME
SYNOPSIS
DESCRIPTION
EXAMPLE
AUTHOR
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 09:28:30 GMT, January 10, 2010 oggvideotools-0.9.1/src/effect/shiftblendEffect.cpp000664 001750 001750 00000005731 12763227102 022577 0ustar00embedembed000000 000000 /* * shiftEffect.cpp * * Created on: 16.03.2014 * Author: seger */ #include "shiftblendEffect.h" #include #include #include #include "pictureBlend.h" #include "pictureResize.h" #include "log.h" #include "effectorVisitor.h" ShiftblendEffect::ShiftblendEffect() :state(unconfigured), framecounter(0) { } ShiftblendEffect::~ShiftblendEffect() { } bool ShiftblendEffect::available() { return((state!=unavailable) && (state!=unconfigured)); } void ShiftblendEffect::accept(EffectorVisitor& visitor) const { visitor.visit(*this); } Effector& ShiftblendEffect::operator >>(RGBPlane& plane) { switch (state) { case shifting: { doShift(plane); break; } case presentation: { doPresentation(plane); break; } default: { logger.error() << "no frame available\n"; break; } } return(*this); } void ShiftblendEffect::configure(ShiftConfig& _config) { framecounter = 0; config = _config; if (config.first) { lastPlane = RGBPlane(config.outputWidth, config.outputHeight); /* blank the plane */ uint32 planesize = config.outputWidth*config.outputHeight*4; // 3 Colors + Alpha channel memset(lastPlane->plane, 0x00, planesize); } /* resize the picture to the correct size */ presentationPlane = PictureResize::reframe(config.origPlane, config.outputWidth, config.outputHeight); logger.debug() << "Picture size: "<< presentationPlane->width<<" x "<width <<" -> frame size "< config.blindLength) { logger.debug() << "Presenting -- \n"; state = presentation; } } void ShiftblendEffect::doPresentation(RGBPlane& plane) { plane = presentationPlane; framecounter++; if (framecounter > config.sequenceLength) { lastPlane = presentationPlane; state = unavailable; } } oggvideotools-0.9.1/src/ovt_vorbis/vorbisExtractor.h000664 001750 001750 00000000670 12763227102 023142 0ustar00embedembed000000 000000 #ifndef VORBISEXTRACTOR_H_ #define VORBISEXTRACTOR_H_ #include "streamExtractor.h" class VorbisExtractor : public StreamExtractor { public: VorbisExtractor(); virtual ~VorbisExtractor(); bool _extract(uint8* data, ExtractorInformation& info); virtual bool extract(OggPage& page, ExtractorInformation& information); virtual bool extract(OggPacket& packet, ExtractorInformation& information); }; #endif /*VORBISEXTRACTOR_H_*/ oggvideotools-0.9.1/src/ovt_vorbis/vorbisStreamParameter.h000664 001750 001750 00000001104 12763227102 024254 0ustar00embedembed000000 000000 #ifndef VORBISSTREAMPARAMETER_H_ #define VORBISSTREAMPARAMETER_H_ #include "definition.h" #include "streamParameter.h" class VorbisStreamParameter : public StreamParameter { public: uint32 channels; uint32 samplerate; uint32 datarate; uint32 datarateMax; uint32 datarateMin; uint32 datarateWin; uint32 block0; uint32 block1; VorbisStreamParameter(); virtual ~VorbisStreamParameter(); virtual bool operator==(const StreamParameter& param); virtual std::string toString(); virtual StreamParameter* clone(); }; #endif /*VORBISSTREAMPARAMETER_H_*/ oggvideotools-0.9.1/src/misc/crc.cpp000664 001750 001750 00000010113 12763227102 017574 0ustar00embedembed000000 000000 /* * CRC creation class (static method) * * Copyright (C) 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. * */ #include "crc.h" static const unsigned int crc_lookup[256]= { 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9, 0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005, 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61, 0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd, 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9, 0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75, 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011, 0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd, 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039, 0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5, 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81, 0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d, 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49, 0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95, 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1, 0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d, 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae, 0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072, 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16, 0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca, 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde, 0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02, 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066, 0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba, 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e, 0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692, 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6, 0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a, 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e, 0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2, 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686, 0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a, 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637, 0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb, 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f, 0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53, 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47, 0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b, 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff, 0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623, 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7, 0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b, 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f, 0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3, 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7, 0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b, 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f, 0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3, 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640, 0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c, 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8, 0x68860bfd,0x6c47164a,0x61043093,0x65c52d24, 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30, 0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec, 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088, 0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654, 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0, 0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c, 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18, 0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4, 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0, 0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c, 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668, 0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4 }; Crc::Crc () {} Crc::~Crc() {} unsigned int Crc::create(unsigned char* data, unsigned int length) { /* this is the usual ethernet CRC algorithm */ unsigned int crc_reg(0); for (unsigned int i = 0; i < length; ++i) crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^data[i]]; return (crc_reg); } oggvideotools-0.9.1/src/exception.h000664 001750 001750 00000000314 12763227102 017537 0ustar00embedembed000000 000000 #ifndef EXCEPTION_H #define EXCEPTION_H #include class OggException : public std::runtime_error { public: OggException(const std::string & msg) : std::runtime_error(msg) {} }; #endif oggvideotools-0.9.1/src/libresample/README.txt000664 001750 001750 00000006521 12763227102 021373 0ustar00embedembed000000 000000 libresample Real-time library interface by Dominic Mazzoni Based on resample-1.7: http://www-ccrma.stanford.edu/~jos/resample/ License: LGPL - see the file LICENSE.txt for more information History: This library is not the highest-quality resampling library available, nor is it the most flexible, nor is it the fastest. But it is pretty good in all of these regards, and it is quite portable. The best resampling library I am aware of is libsamplerate by Erik de Castro Lopo. It's small, fast, and very high quality. However, it uses the GPL for its license (with commercial options available) and I needed a more free library. So I wrote this library, using the LGPL resample-1.7 library by Julius Smith as a basis. Resample-1.7 is a fixed-point resampler, and as a result has only limited precision. I rewrote it to use single-precision floating-point arithmetic instead and increased the number of filter coefficients between time steps significantly. On modern processors it can resample in real time even with this extra overhead. Resample-1.7 was designed to read and write from files, so I removed all of that code and replaced it with an API that lets you pass samples in small chunks. It should be easy to link to resample-1.7 as a library. Changes in version 0.1.3: * Fixed two bugs that were causing subtle problems on Intel x86 processors due to differences in roundoff errors. * Prefixed most function names with lrs and changed header file from resample.h to libresample.h, to avoid namespace collisions with existing programs and libraries. * Added resample_dup (thanks to Glenn Maynard) * Argument to resample_get_filter_width takes a const void * (thanks to Glenn Maynard) * resample-sndfile clips output to -1...1 (thanks to Glenn Maynard) Usage notes: - If the output buffer you pass is too small, resample_process may not use any input samples because its internal output buffer is too full to process any more. So do not assume that it is an error just because no input samples were consumed. Just keep passing valid output buffers. - Given a resampling factor f > 1, and a number of input samples n, the number of output samples should be between floor(n - f) and ceil(n + f). In other words, if you resample 1000 samples at a factor of 8, the number of output samples might be between 7992 and 8008. Do not assume that it will be exactly 8000. If you need exactly 8000 outputs, pad the input with extra zeros as necessary. License and warranty: All of the files in this package are Copyright 2003 by Dominic Mazzoni . This library was based heavily on Resample-1.7, Copyright 1994-2002 by Julius O. Smith III , all rights reserved. Permission to use and copy is granted subject to the terms of the "GNU Lesser General Public License" (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or any later version. In addition, Julius O. Smith III requests that a copy of any modified files be sent by email to jos@ccrma.stanford.edu so that he may incorporate them into the CCRMA version. This library 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 Lesser General Public License for more details. oggvideotools-0.9.1/docs/oggTranscode.1000664 001750 001750 00000011540 12763227102 020235 0ustar00embedembed000000 000000 .TH OGGTRANSCODE 1 "JAN 2010" Linux "User Manuals" .SH NAME oggTranscode \- transcodes ogg files in multiple ways .SH SYNOPSIS .B oggTranscode [options] inputfile.ogv outputfile.ogv .SH DESCRIPTION .B oggTranscode can resize an ogg file (ogg, oga or ogv) in multiple ways: It can change the video frame size, change datarate for the video and/or audio streams contained in the ogg file and it can also change the video frame rate or audio sample rate. Additionally, since version 0.8 .B oggTranscode can add any ogg comment and png\(hypictures with an alpha channel can be rendered into the video at any time period before and after the resizing process. .B oggTranscode was previously called .B oggResize. .SH OPTIONS .IP \-s Sets the size of the video frame. The size is given as .B x. At default, the video frame size keeps the same. .I Example: \-s 320x240 .IP \-d Sets the datarate in byte per seconds for the video encoder (theora). This meant to be a upper threshold. So the file may be smaller than assumed. If not set, the datarate of the original stream is used. .I Example: \-d 1024000 .IP \-D Sets the datarate in byte per seconds for the audio encoder (vorbis). If not set, the datarate of the original stream is used. .I Example: -D 64000 .IP \-f Sets the frame rate of the video with numinator and demoninator and is the pictures per second. If only one number is given, the denominator is set to 1. If not set, the framerate of the original video is used. .I Example: \-f 25:2 .IP \-F Sets the sample frequency (sample rate) of the audio data in Hertz. If the sample frequency does not match the one with the original file, resamling is invoked. .I Example: \-F 32000 .IP \-c Adds comments to the video (theora) stream. Comments are given by a pair of type and value in the form 'type=value'. More than one comment can be concatenated with a semicolon. It is recommended to use apostrophes as the command line may use the semicolon as a seperator. .I Example: \-c 'AUTHOR=yorn;DATE=03.07.09' .IP \-C Adds comments to the audio (vorbis) stream. Comments are given by a pair of type and value in the form 'type=value'. More than one comment can be concatenated with a semicolon. It is recommended to use apostrophes as the command line may use the semicolon as a seperator. .I Example: \-C 'AUTHOR=yorn;DATE=03.07.09' .IP \-q Specifies the quality for the resizing process. Values can be chosen between 1 (best quality, with slight bluring) and 6 (worst quality). The default value is 2. .I Example: \-q1 .IP \-p This option is meant to help creating a preview of a film. The number given with this option defines the number of frames, that are omitted. E.g. if a film has 24 frames per second and \-p24 is given, the newly created video shows the video 24 times faster as only every 24th frame is used. This option can be combined with the option \-f to control the framerate. With both options nice video previews can be created. If \-p is used, the audio stream is ignored. .I Example: \-p 24 .IP \-a Adds a picture to the video frame before it is resized. The expression for the picture appearances: .B [,[,[,s]]] .B startTime in seconds - value can be a floating point. Default .B startTime is 0 .B endTime in seconds - value can be a floating point. default .B endTime is \-1, which is the end of the stream duration default .B s ist not set. If .B s is set, the picture slides in smoothly. More than one picture can be included. To concatenate the expressions use the colon. If the appearance time overlap, the pictures are placed on one another, so the last picture is the uppest layer. .I Example: \-a etwas.png,2,7,s:etwasneues.png,5,10 .IP \-A Adds a picture to the video frame after it is resized. The syntax follows the same expression as with option \-a. .SH EXAMPLE .I oggTranscode \-s320x240 \-d512000 orig.ogv new.ogv Converts a the video .B orig.ogv to the video .B new.ogv with the new frame size 320x240. If there was an audio stream within the orig.ogv file, it is copied into the new file. .I oggTranscode \-D64000 \-F16000 \-N1 orig.ogv new.ogv Converts only the audio stream of file .B orig.ogv to a sample rate of 16kHz, a datarate of 64 kBit/s and a mono channel. The video stream is copied as is. .I oggTranscode \-s300x200 \-D32000 \-d1024000 \-A etwas.png,2,7,s:etwasneues.png,5,10 orig.ogv new.ogv Converts the audio and video stream and adds the alpha channel picture .B etwas.png to the video from second 2 to second 7 with a smooth fade in and fade out. Additionally the alpha channel picture .B etwasneues.png is placed on top of the video frame from second 5 to second 10 without any fading. .SH AUTHOR Joern Seger .SH "SEE ALSO" .BR oggCut (1), .BR oggCat (1), .BR oggJoin (1), .BR oggSplit (1), .BR oggSlideshow (1), .BR oggThumb (1), .BR oggSilence (1) oggvideotools-0.9.1/src/libresample/000775 001750 001750 00000000000 12763227102 017671 5ustar00embedembed000000 000000 oggvideotools-0.9.1/src/ovt_theora/theoraHeader.h000664 001750 001750 00000001076 12763227102 022314 0ustar00embedembed000000 000000 #ifndef THEORAHEADER_H #define THEORAHEADER_H struct TheoraHeader { char vmaj; char vmin; char vrev; uint16 fmbw; uint16 fmbh; uint32 picw:24; uint32 pich:24; char picx; char picy; uint32 frn; uint32 frd; uint32 parn:24; uint32 pard:24; char cs; uint32 nombr:24; // its little endian // and network byte order union { struct { uint16 reserved:3; uint16 pf:2; uint16 kfgshift:5; uint16 qual:6; } lenbo; uint16 pleaseconvert; } un; } __attribute__ ((packed)); #endif oggvideotools-0.9.1/src/th_helper.h000664 001750 001750 00000001373 12763227102 017521 0ustar00embedembed000000 000000 #ifndef TH_HELPER_H #define TH_HELPER_H //#ifdef HAVE_THEORAENC || HAVE_THEORADEC #include #include #include "definition.h" inline void th_clean_ycbcr(th_ycbcr_buffer& theoraPictureBuffer) { #ifdef HAVE_BZERO bzero(theoraPictureBuffer, sizeof(th_img_plane)*3); #else // with the right alignment, this could be much faster ... I hope for the compiler to do that :-/ for (int i(0); i #include int main(int argc, char* argv[]) { OggDecoder decoder; { // create a packet, that is valid in the eyes of the decoder std::vector packet; OggHeader header; memset(&header, 0, sizeof(OggHeader)); header.ogg[0] = 'O'; header.ogg[1] = 'g'; header.ogg[2] = 'g'; header.ogg[3] = 'S'; header.tableSegments = 2; uint8_t* hdr_ptr = (uint8_t*)&header; packet.insert(packet.end(), &hdr_ptr[0], &hdr_ptr[sizeof(OggHeader)]); /* add the segments table */ packet.push_back(255); packet.push_back(1); /* add all the data (that is 0xc5) */ for (uint32_t i(0); i < 256; ++i) { packet.push_back(0xc5); } RawMediaPacket rmp = createRawMediaPacket(); rmp->setData(packet, false); decoder << rmp; } OggPage page; decoder >> page; std::vector pg_data = page->data(); uint32_t cnt; for (auto i : pg_data) { std::cout << " 0x"< #include #include #include typedef struct { float *Imp; float *ImpD; float LpScl; UWORD Nmult; UWORD Nwing; double minFactor; double maxFactor; UWORD XSize; float *X; UWORD Xp; /* Current "now"-sample pointer for input */ UWORD Xread; /* Position to put new samples */ UWORD Xoff; UWORD YSize; float *Y; UWORD Yp; double Time; } rsdata; void *resample_dup(const void * handle) { const rsdata *cpy = (const rsdata *)handle; rsdata *hp = (rsdata *)malloc(sizeof(rsdata)); hp->minFactor = cpy->minFactor; hp->maxFactor = cpy->maxFactor; hp->Nmult = cpy->Nmult; hp->LpScl = cpy->LpScl; hp->Nwing = cpy->Nwing; hp->Imp = (float *)malloc(hp->Nwing * sizeof(float)); memcpy(hp->Imp, cpy->Imp, hp->Nwing * sizeof(float)); hp->ImpD = (float *)malloc(hp->Nwing * sizeof(float)); memcpy(hp->ImpD, cpy->ImpD, hp->Nwing * sizeof(float)); hp->Xoff = cpy->Xoff; hp->XSize = cpy->XSize; hp->X = (float *)malloc((hp->XSize + hp->Xoff) * sizeof(float)); memcpy(hp->X, cpy->X, (hp->XSize + hp->Xoff) * sizeof(float)); hp->Xp = cpy->Xp; hp->Xread = cpy->Xread; hp->YSize = cpy->YSize; hp->Y = (float *)malloc(hp->YSize * sizeof(float)); memcpy(hp->Y, cpy->Y, hp->YSize * sizeof(float)); hp->Yp = cpy->Yp; hp->Time = cpy->Time; return (void *)hp; } void *resample_open(int highQuality, double minFactor, double maxFactor) { double *Imp64; double Rolloff, Beta; rsdata *hp; UWORD Xoff_min, Xoff_max; int i; /* Just exit if we get invalid factors */ if (minFactor <= 0.0 || maxFactor <= 0.0 || maxFactor < minFactor) { #if DEBUG fprintf(stderr, "libresample: " "minFactor and maxFactor must be positive real numbers,\n" "and maxFactor should be larger than minFactor.\n"); #endif return 0; } hp = (rsdata *)malloc(sizeof(rsdata)); hp->minFactor = minFactor; hp->maxFactor = maxFactor; if (highQuality) hp->Nmult = 35; else hp->Nmult = 11; hp->LpScl = 1.0; hp->Nwing = Npc*(hp->Nmult-1)/2; /* # of filter coeffs in right wing */ Rolloff = 0.90; Beta = 6; Imp64 = (double *)malloc(hp->Nwing * sizeof(double)); lrsLpFilter(Imp64, hp->Nwing, 0.5*Rolloff, Beta, Npc); hp->Imp = (float *)malloc(hp->Nwing * sizeof(float)); hp->ImpD = (float *)malloc(hp->Nwing * sizeof(float)); for(i=0; iNwing; i++) hp->Imp[i] = Imp64[i]; /* Storing deltas in ImpD makes linear interpolation of the filter coefficients faster */ for (i=0; iNwing-1; i++) hp->ImpD[i] = hp->Imp[i+1] - hp->Imp[i]; /* Last coeff. not interpolated */ hp->ImpD[hp->Nwing-1] = - hp->Imp[hp->Nwing-1]; free(Imp64); /* Calc reach of LP filter wing (plus some creeping room) */ Xoff_min = ((hp->Nmult+1)/2.0) * MAX(1.0, 1.0/minFactor) + 10; Xoff_max = ((hp->Nmult+1)/2.0) * MAX(1.0, 1.0/maxFactor) + 10; hp->Xoff = MAX(Xoff_min, Xoff_max); /* Make the inBuffer size at least 4096, but larger if necessary in order to store the minimum reach of the LP filter and then some. Then allocate the buffer an extra Xoff larger so that we can zero-pad up to Xoff zeros at the end when we reach the end of the input samples. */ hp->XSize = MAX(2*hp->Xoff+10, 4096); hp->X = (float *)malloc((hp->XSize + hp->Xoff) * sizeof(float)); hp->Xp = hp->Xoff; hp->Xread = hp->Xoff; /* Need Xoff zeros at begining of X buffer */ for(i=0; iXoff; i++) hp->X[i]=0; /* Make the outBuffer long enough to hold the entire processed output of one inBuffer */ hp->YSize = (int)(((double)hp->XSize)*maxFactor+2.0); hp->Y = (float *)malloc(hp->YSize * sizeof(float)); hp->Yp = 0; hp->Time = (double)hp->Xoff; /* Current-time pointer for converter */ return (void *)hp; } int resample_get_filter_width(const void *handle) { const rsdata *hp = (const rsdata *)handle; return hp->Xoff; } int resample_process(void *handle, double factor, float *inBuffer, int inBufferLen, int lastFlag, int *inBufferUsed, /* output param */ float *outBuffer, int outBufferLen) { rsdata *hp = (rsdata *)handle; float *Imp = hp->Imp; float *ImpD = hp->ImpD; float LpScl = hp->LpScl; UWORD Nwing = hp->Nwing; BOOL interpFilt = FALSE; /* TRUE means interpolate filter coeffs */ int outSampleCount; UWORD Nout, Ncreep, Nreuse; int Nx; int i, len; #if DEBUG fprintf(stderr, "resample_process: in=%d, out=%d lastFlag=%d\n", inBufferLen, outBufferLen, lastFlag); #endif /* Initialize inBufferUsed and outSampleCount to 0 */ *inBufferUsed = 0; outSampleCount = 0; if (factor < hp->minFactor || factor > hp->maxFactor) { #if DEBUG fprintf(stderr, "libresample: factor %f is not between " "minFactor=%f and maxFactor=%f", factor, hp->minFactor, hp->maxFactor); #endif return -1; } /* Start by copying any samples still in the Y buffer to the output buffer */ if (hp->Yp && (outBufferLen-outSampleCount)>0) { len = MIN(outBufferLen-outSampleCount, hp->Yp); for(i=0; iY[i]; outSampleCount += len; for(i=0; iYp-len; i++) hp->Y[i] = hp->Y[i+len]; hp->Yp -= len; } /* If there are still output samples left, return now - we need the full output buffer available to us... */ if (hp->Yp) return outSampleCount; /* Account for increased filter gain when using factors less than 1 */ if (factor < 1) LpScl = LpScl*factor; for(;;) { /* This is the maximum number of samples we can process per loop iteration */ #ifdef DEBUG printf("XSize: %d Xoff: %d Xread: %d Xp: %d lastFlag: %d\n", hp->XSize, hp->Xoff, hp->Xread, hp->Xp, lastFlag); #endif /* Copy as many samples as we can from the input buffer into X */ len = hp->XSize - hp->Xread; if (len >= (inBufferLen - (*inBufferUsed))) len = (inBufferLen - (*inBufferUsed)); for(i=0; iX[hp->Xread + i] = inBuffer[(*inBufferUsed) + i]; *inBufferUsed += len; hp->Xread += len; if (lastFlag && (*inBufferUsed == inBufferLen)) { /* If these are the last samples, zero-pad the end of the input buffer and make sure we process all the way to the end */ Nx = hp->Xread - hp->Xoff; for(i=0; iXoff; i++) hp->X[hp->Xread + i] = 0; } else Nx = hp->Xread - 2 * hp->Xoff; #ifdef DEBUG fprintf(stderr, "new len=%d Nx=%d\n", len, Nx); #endif if (Nx <= 0) break; /* Resample stuff in input buffer */ if (factor >= 1) { /* SrcUp() is faster if we can use it */ Nout = lrsSrcUp(hp->X, hp->Y, factor, &hp->Time, Nx, Nwing, LpScl, Imp, ImpD, interpFilt); } else { Nout = lrsSrcUD(hp->X, hp->Y, factor, &hp->Time, Nx, Nwing, LpScl, Imp, ImpD, interpFilt); } #ifdef DEBUG printf("Nout: %d\n", Nout); #endif hp->Time -= Nx; /* Move converter Nx samples back in time */ hp->Xp += Nx; /* Advance by number of samples processed */ /* Calc time accumulation in Time */ Ncreep = (int)(hp->Time) - hp->Xoff; if (Ncreep) { hp->Time -= Ncreep; /* Remove time accumulation */ hp->Xp += Ncreep; /* and add it to read pointer */ } /* Copy part of input signal that must be re-used */ Nreuse = hp->Xread - (hp->Xp - hp->Xoff); for (i=0; iX[i] = hp->X[i + (hp->Xp - hp->Xoff)]; #ifdef DEBUG printf("New Xread=%d\n", Nreuse); #endif hp->Xread = Nreuse; /* Pos in input buff to read new data into */ hp->Xp = hp->Xoff; /* Check to see if output buff overflowed (shouldn't happen!) */ if (Nout > hp->YSize) { #ifdef DEBUG printf("Nout: %d YSize: %d\n", Nout, hp->YSize); #endif fprintf(stderr, "libresample: Output array overflow!\n"); return -1; } hp->Yp = Nout; /* Copy as many samples as possible to the output buffer */ if (hp->Yp && (outBufferLen-outSampleCount)>0) { len = MIN(outBufferLen-outSampleCount, hp->Yp); for(i=0; iY[i]; outSampleCount += len; for(i=0; iYp-len; i++) hp->Y[i] = hp->Y[i+len]; hp->Yp -= len; } /* If there are still output samples left, return now, since we need the full output buffer available */ if (hp->Yp) break; } return outSampleCount; } void resample_close(void *handle) { rsdata *hp = (rsdata *)handle; free(hp->X); free(hp->Y); free(hp->Imp); free(hp->ImpD); free(hp); } oggvideotools-0.9.1/src/ovt_kate/katePosInterpreter.cpp000664 001750 001750 00000006563 12763227102 023556 0ustar00embedembed000000 000000 #include "katePosInterpreter.h" #include "kateStreamParameter.h" #include "log.h" #include #include KatePosInterpreter::KatePosInterpreter() : granuleShift(0), granulerateNumerator(1), granulerateDenominator(1) { } KatePosInterpreter::~KatePosInterpreter() { } uint32 KatePosInterpreter::getGranulerateNumerator() { return(granulerateNumerator); } uint32 KatePosInterpreter::getGranulerateDenominator() { return(granulerateDenominator); } uint8 KatePosInterpreter::getGranuleShift() { return(granuleShift); } void KatePosInterpreter::extractFramePos(int64 granulePosition, int64& base, int64& offset) { base = granulePosition>>granuleShift; uint64 mask(1); mask <<= granuleShift; mask -= 1; offset = (granulePosition&mask); } void KatePosInterpreter::initialize(StreamParameter* _param) { KateStreamParameter* param = dynamic_cast(_param); if (!param) { logger.error() << "KatePosInterpreter::initialize: parameter not set correctly\n"; return; } granuleShift = param->granuleShift; granulerateNumerator = param->granulerateNum; granulerateDenominator = param->granulerateDenom; initialized = true; return; } double KatePosInterpreter::getTime(int64 granulePos) { if (!initialized) { logger.error() << "KatePosInterpreter::initialize: The position interpreter is not initialized yet\n"; return(-2); } if (granulePos == -1) return(-1); int64 base; int64 offset; extractFramePos(granulePos, base, offset); double time = (granulerateDenominator*1.0/granulerateNumerator*1.0)*(base+offset); return(time); } #if 0 KatePosInterpreter& KatePosInterpreter::operator++() { actualGranulePosition+=1; return(*this); } #endif #if 0 GranulePosInterpreter& TheoraPosInterpreter::operator+=(GranulePosInterpreter& _otherPosition) { if (typeid(_otherPosition) != typeid(*this)) { logger.error() << "GranulePosInterpreter::operator+=: type is not matching\n"; return(*this); } TheoraPosInterpreter* otherPosition = static_cast(&_otherPosition); if ((keyframeShift != otherPosition->keyframeShift) || (framerateNumerator != otherPosition->framerateNumerator) || (framerateDenominator != otherPosition->framerateDenominator)) { logger.error() << "GranulePosInterpreter::operator+=: granulePositions does not match in shift value or framerate\n"; return(*this); } if ((actualGranulePosition < 0) || (otherPosition->actualGranulePosition < 0)) { logger.error() << "GranulePosInterpreter::operator+=: one or both granulePositions are not valid\n"; return(*this); } int64 ownPos1; int32 ownPos2; extractFramePos(actualGranulePosition, ownPos1, ownPos2); int64 otherPos1; int32 otherPos2; extractFramePos(otherPosition->actualGranulePosition, otherPos1, otherPos2); ownPos1 += (otherPos1 + otherPos2); actualGranulePosition = ((ownPos1<granulepos(); if (granpos >= 0) { actualGranulePosition = packet->granulepos(); packet->setGranulepos(actualGranulePosition); } } GranulePosInterpreter& KatePosInterpreter::operator-=(GranulePosInterpreter& position) { logger.error() << "GranulePosInterpreter& operator-=: not implemented\n"; return(*this); } oggvideotools-0.9.1/src/binaries/oggCat.cpp000664 001750 001750 00000051531 12763227102 021103 0ustar00embedembed000000 000000 /* * oggCat is a command line tool, to concatenate video streams * * Copyright (C) 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. * */ #ifdef __WIN32 #define __GNU_LIBRARY__ #include "../win32/getopt_win.h" #endif #include #include #include #include #include #include #include "definition.h" #include "helper.h" #include "fileRepository.h" #include "oggPacket.h" #include "streamMux.h" #include "streamSerializer.h" #include "cmdlineextractor.h" #include "theoraStreamParameter.h" #include "vorbisStreamParameter.h" #include "wishList.h" #include "hookHandler.h" #include "videoHook.h" #include "audioHook.h" #include "exception.h" #include "log.h" void printHelpScreen(const std::string& progName) { logger.error() << "usage: " << progName << " [options]" << " [ [ ... ] ]\n" << " or: [options] -o [ [ ... ] ]\n" << " -- package and version \"" << PACKAGE_STRING << "\"\n\n" << "Options:\n" << " -p presize cutting (-pa for audio only)\n" << " -d datarate of output stream\n" << " -q video quality of output stream\n" << " -D datarate of output audio stream\n" << " -Q audio quality of output stream\n" << " -s video size (e.g. 240x160)\n" << " -f video framerate\n" << " -F audio Sample rate\n" << " -N channel numbers\n" << " -x no existens check for output file (for interactive usage)\n" << " -o output file (alternative - if set, the first name is an input file!)\n" << " -rv reencode video stream\n"<< "\n"; } void analyseVideoTranscoding(WishList& wishList, std::shared_ptr theoraConfigInput, std::shared_ptr theoraConfigOutput) { /* first we believe the output should be equal for all * parameters that are not explicitly changed */ *theoraConfigOutput.get() = *theoraConfigInput.get(); if (wishList.changeVideoDatarate) { if (theoraConfigInput->videoBitrate != wishList.videoDatarate) { theoraConfigOutput->videoBitrate = wishList.videoDatarate; theoraConfigOutput->videoQuality = 0; } } if (wishList.changeVideoQuality) { if (theoraConfigInput->videoQuality != wishList.videoQuality) { theoraConfigOutput->videoBitrate = 0; theoraConfigOutput->videoQuality = wishList.videoQuality; } } if (wishList.changeSize) { if ( (theoraConfigInput->pictureX != wishList.width ) || (theoraConfigInput->pictureY != wishList.height ) || (theoraConfigInput->aspectRatioNum != 1 ) || (theoraConfigInput->aspectRatioDenom != 1 )) { theoraConfigOutput->pictureX = wishList.width; theoraConfigOutput->pictureY = wishList.height; theoraConfigOutput->calculateFrame(); /* no reason for using another aspect ratio than 1:1, are there? */ theoraConfigOutput->aspectRatioDenom = 1; theoraConfigOutput->aspectRatioNum = 1; } } if (wishList.changeFramerate) { if ( ( (theoraConfigOutput->framerateNum != wishList.framerateNum ) || (theoraConfigOutput->framerateDenom != wishList.framerateDenom ) ) && ( (theoraConfigOutput->framerateNum*1.0 ) / (theoraConfigOutput->framerateDenom*1.0 ) != (wishList.framerateNum*1.0 ) / (wishList.framerateDenom*1.0 ) )) { theoraConfigOutput->framerateNum = wishList.framerateNum; theoraConfigOutput->framerateDenom = wishList.framerateDenom; } } } void analyseAudioTranscoding(WishList& wishList, std::shared_ptr vorbisConfigInput, std::shared_ptr vorbisConfigOutput) { /* first we believe the output should be equal for all * parameters, that are not explicitly changed */ *vorbisConfigOutput.get() = *vorbisConfigInput.get(); if (wishList.changeAudioDatarate) { if (vorbisConfigOutput->datarate != wishList.audioDatarate) { vorbisConfigOutput->datarate = wishList.audioDatarate; } } if (wishList.changeAudioSamplerate) { if (vorbisConfigOutput->samplerate != wishList.audioSamplerate) { vorbisConfigOutput->samplerate = wishList.audioSamplerate; } } if (wishList.changeAudioChannels) { if (vorbisConfigOutput->channels != wishList.audioChannels) { vorbisConfigOutput->channels = wishList.audioChannels; } } return; } int oggCatCmd(int argc, char* argv[]) { std::string programName(argv[0]); std::string outputFile; WishList wishList; std::vector videoComments; bool withVideoComments( false); std::vector audioComments; bool withAudioComments( false); bool reencodeVideo(false); // bool reencodeAudio(true); is always used bool existenceTest(true); srand((uint) time(0)); int opt; while ((opt = getopt(argc, argv, "hp:d:q:o:D:s:f:F:N:tC:c:r:x")) != EOF) switch (opt) { case 'h': case '?': printHelpScreen(programName); exit(-1); case 'o': outputFile = std::string(optarg); break; case 'd': wishList.videoDatarate = CmdlineExtractor::atoi(optarg); wishList.changeVideoDatarate = true; break; case 'D': wishList.audioDatarate = CmdlineExtractor::atoi(optarg); wishList.changeAudioDatarate = true; break; case 'q': wishList.videoQuality = CmdlineExtractor::atoi(optarg); wishList.changeVideoQuality = true; break; case 's': { std::deque framesize; CmdlineExtractor::extractUint32(framesize, optarg, 'x'); if (framesize.size() != 2) { logger.error() << "please specify the size in the following way: -s320x480\n"; exit( -1); } wishList.width = framesize[0]; wishList.height = framesize[1]; wishList.changeSize = true; break; } case 'f': { std::deque framerate; CmdlineExtractor::extractUint32(framerate, optarg, ':'); if (framerate.size() == 1) { wishList.framerateNum = framerate[0]; wishList.framerateDenom = 1; wishList.changeFramerate = true; break; } if (framerate.size() == 2) { wishList.framerateNum = framerate[0]; wishList.framerateDenom = (framerate[1] == 0 ) ? 1 : framerate[1]; wishList.changeFramerate = true; break; } logger.error() << "please specify the framerate in the following way -f25:2 or -f24\n"; exit( -1); break; } case 'F': wishList.audioSamplerate = CmdlineExtractor::atoi(optarg); wishList.changeAudioSamplerate = true; break; case 'N': wishList.audioChannels = CmdlineExtractor::atoi(optarg); wishList.changeAudioChannels = true; break; case 't': wishList.stretch = true; break; case 'c': withVideoComments = true; CmdlineExtractor::extractCommentPairs(videoComments, optarg, ';', '='); break; case 'C': withAudioComments = true; CmdlineExtractor::extractCommentPairs(audioComments, optarg, ';', '='); break; case 'r': switch (optarg[0]) { // case 'a': // reencodeAudio = true; // break; case 'v': reencodeVideo = true; break; } break; case 'x': existenceTest = false; break; default: logger.error() << "option \"-" << opt << "\" is unknown" << std::endl; } argc -= optind; argv += optind; /* There are two possibilities to get the output file * "old" version is via -o option. In this case the output file is * not m_empty. In the other case the output file is given as the first * argument (except the options). */ if (outputFile.empty()) { if (argc > 1) { outputFile = std::string(argv[0]); argc -= 1; argv += 1; } else { printHelpScreen(programName); exit(-1); } } if (existenceTest && check_file_exists(outputFile)) exit(0); if (argc < 2) { printHelpScreen(programName); exit(-1); } logger.debug() << "Output file is : "< originalConfigList; StreamSerializer* serializer = new StreamSerializer; if (!serializer->open(baseFile)) { logger.error() << "Can not open file <" << baseFile << ">\n"; exit(-1); } /* read the stream configuration */ serializer->getStreamConfig(originalConfigList); /* we create a vector for the input stream and set every * value to 255 (means: ignore this stream). * If the stream is used, the value added is the stream, where this * input stream should be mapped to */ std::vector streamMap; streamMap.resize(originalConfigList.size(), 255); /* These are the information ordered, by the stream IDs from the input stream */ std::vector > hookList; std::vector muxerInformation; bool foundTheora(false); bool foundVorbis(false); uint8 streamCounter( 0); uint32 startInputfiles(1); /* create the first resize round */ for (uint32 i=0; i theoraEncoderConfig; std::shared_ptr theoraDecoderConfig; std::shared_ptr vHook = std::make_shared(streamCounter, false, true ); if (reencodeVideo) vHook->forceReencoding(); /* here, we configure things, that do not change * the transcoding process (alpha blend etc) */ VideoHook::Config videoHookConfig; videoHookConfig.stretch = wishList.stretch; /* configure the video hook */ vHook->configureProcess(videoHookConfig); hookList.push_back(vHook); /* We only need these information for the information printout */ std::vector decoderComments; /* configure encoder config (StreamConfig/OggComment here) */ vHook->setDecoderConfig(decoderConfig, decoderComments); /* grap the information extracted by the decoder */ theoraDecoderConfig = std::dynamic_pointer_cast(decoderConfig.parameter); /* create a config for the output stream and keep a pointer */ theoraEncoderConfig = std::make_shared(); analyseVideoTranscoding(wishList, theoraDecoderConfig, theoraEncoderConfig); if (reencodeVideo) theoraEncoderConfig->calculateFrame(); if (!withVideoComments) videoComments = decoderComments; /* add the pointer to the configuration */ encoderConfig.parameter = theoraEncoderConfig; /* the decoder Comments are used as well in case, keepComments * is set within the HookHandler */ vHook->setEncoderConfig(encoderConfig, videoComments); /* the configuration ID must match the stream ID */ muxerInformation.push_back(encoderConfig); /* calculate how to handle the input, to create the correct output */ vHook->initAndConnect(); /* set the stream ID, to which this stream should be maped to */ streamMap[i] = streamCounter; // theoraStreamID = streamCounter; streamCounter++; } else { logger.warning() << "oggCat found more than one theora stream, only the first stream is handled\n"; } continue; } if (decoderConfig.type == OggType::vorbis) { if (!foundVorbis) { StreamConfig encoderConfig; std::shared_ptr vorbisEncoderConfig; std::shared_ptr vorbisDecoderConfig; foundVorbis = true; std::shared_ptr aHook = std::make_shared(streamCounter, false, true ); hookList.push_back(aHook); /* We only need these information for the information printout */ std::vector decoderComments; /* configure encoder config (StreamConfig/OggComment here) */ aHook->setDecoderConfig(decoderConfig, decoderComments); /* create a config for this stream */ vorbisEncoderConfig = std::make_shared(); /* */ vorbisDecoderConfig = std::dynamic_pointer_cast(decoderConfig.parameter); /* */ encoderConfig.parameter = vorbisEncoderConfig; analyseAudioTranscoding(wishList, vorbisDecoderConfig, vorbisEncoderConfig); if (!withAudioComments) audioComments = decoderComments; /* the decoder Comments are used as well in case, keepComments * is set within the HookHandler */ aHook->setEncoderConfig(encoderConfig, audioComments); /* calculate how to handle the input, to create the correct output */ aHook->initAndConnect(); muxerInformation.push_back(encoderConfig); /* set the stream ID, to which this stream should be maped to */ streamMap[i] = streamCounter; // vorbisStreamID = streamCounter; streamCounter++; } else { logger.warning() << "oggCat found more than one vorbis stream, only the first stream is handled\n"; } continue; } // logger.error() // << "There is actually no stream handler available to resize this stream \n"; } logger.info() << "Output Configuration: " << std::endl << "--------------------- " << std::endl; for (uint32 i(0); i< hookList.size(); ++i) { logger.info() << hookList[i]->encoderConfiguration() << std::endl; } logger.info() << "Mapping\n"; for (uint32 i(0); iavailable() ) { time = serializer->getNextPacket(packet); logger.info() << " " << time << " \r"; uint32 hookStreamID = streamMap[packet->getStreamNo()]; if (hookStreamID == 255) continue; HookHandler& hook(*hookList[hookStreamID]); hook << packet; while (hook.available()) { hook >> packet; streamCreate << packet; } } logger.info() << "\n"; // end of the road delete serializer; // handle the other files given with the arguments list for (uint32 j(startInputfiles); j<(uint32)argc; ++j) { StreamSerializer serializer; /* try to open the file. If file is not available switch to the next one */ std::string filename(argv[j]); if (!serializer.open(filename)) { logger.error() << "Can not open file <" << filename << ">\n"; continue; } logger.info() << "Concatenating file <"<"< ConfigList; /* read the stream configuration of the actual file */ serializer.getStreamConfig(ConfigList); foundTheora = false; foundVorbis = false; /* create a new stream Map */ streamMap.clear(); streamMap.resize(ConfigList.size(), 255); for (uint32 l( 0); lgetType() == OggType::theora) && !foundTheora) { foundTheora = true; // logger.debug() << "Theora found ("<< l <<") -> "<(*hookList[k]); /* We only need these information for the information printout */ std::vector decoderComments; /* configure encoder config (StreamConfig/OggComment here) */ vHook.setDecoderConfig(decoderConfig, decoderComments); /* as not every stream is de- and encoded, the encoder * may be confused */ vHook.resetEncoder(); /* calculate how to handle the input, to create the correct output */ vHook.initAndConnect(); /* set the stream ID, to which this stream should be maped to */ streamMap[l] = (uint8)k; newStreamCounter++; } continue; } } if (decoderConfig.type == OggType::vorbis) { /* run through the stream map to find the original stream, * this stream should be mapped to */ for (uint32 k(0); kgetType() == OggType::vorbis) && !foundVorbis) { foundVorbis = true; // logger.debug() << "Vorbis found ("<< l <<") -> "<(*hookList[k]); /* We only need these information for the information printout */ std::vector decoderComments; /* configure encoder config (StreamConfig/OggComment here) */ aHook.setDecoderConfig(decoderConfig, decoderComments); /* calculate how to handle the input, to create the correct output */ aHook.initAndConnect(); /* set the stream ID, to which this stream should be maped to */ streamMap[l] = (uint8)k; newStreamCounter++; } continue; } // logger.error() // << "There is actually no stream handler available to resize this stream \n"; } } if (streamCounter != newStreamCounter) { logger.error() << "File <"< does not carry enough streams\n"; continue; } logger.info() << "Mapping\n"; for (uint32 i(0); igetStreamNo()]; if (hookStreamID == 255) continue; HookHandler& hook(*hookList[hookStreamID]); hook << packet; while (hook.available()) { hook >> packet; streamCreate << packet; } } serializer.close(); } /* flush all data */ for (uint32 i(0); iflush(); while (hookList[i]->available()) { (*hookList[i]) >> packet; streamCreate << packet; } } /* set end of stream and do everything neccessary */ streamCreate.setEndOfStream(); streamCreate.close(); logger.info() << std::endl; return (0); } int main(int argc, char* argv[]) { try { return oggCatCmd(argc, argv); } catch (OggException & e) { logger.error() << "Fatal error: " << e.what() << std::endl; return -1; } } oggvideotools-0.9.1/src/binaries/oggSplit.cpp000664 001750 001750 00000011127 12763227102 021464 0ustar00embedembed000000 000000 /* * oggSplit will demultiplex a number of video and audio streams from an ogg file * * Copyright (C) 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. * */ #include #include #include #include #include #include "fileRepository.h" #include "rawMediaPacket.h" #include "oggDecoder.h" #include "oggEncoder.h" #include "oggStreamDecoder.h" #include "oggBOSExtractorFactory.h" #include "exception.h" #include "log.h" struct OutputUnit { OggEncoder encoder; FileRepository repository; }; void printHelpScreen(const std::string& progName) { logger.error() << "usage: " << progName << " \n" << " -- package and version \"" << PACKAGE_STRING << "\"\n\n" << "oggSplit demultiplexes an ogg file into its streams.\n" << "Every stream is placed into a single file, which are\n" << "called theora_.ogg or vorbis_.ogg.\n" << "The serial number is the unique ogg serial number of\n" << "this stream.\n\n"; } int oggSplitCmd(int argc, char* argv[]) { if (argc != 2) { printHelpScreen(argv[0]); exit(-1); } std::string help("-h"); if (help == argv[1]) { printHelpScreen(argv[0]); exit(-1); } /* open the m_repository in this easy example, it is a simple file */ FileRepository repository(argv[1], MediaUnit::read); /* open the file to write the new stream */ std::map outputFileList; RawMediaPacket rawDecoderPacket; OggDecoder oggDecoder; /* run through the m_repository until there is no data left */ while (!repository.isEndOfFile()) { /* extract a raw data bunch from the file .. */ repository >> rawDecoderPacket; /* .. and insert it into the ogg decoder */ oggDecoder << rawDecoderPacket; /* are there any complete ogg Pages available ? */ while (oggDecoder.isAvailable()) { OggPage oggPage; /* grap the next page */ oggDecoder >> oggPage; /* what ID has this page / what stream does this page belongs to */ uint32 serialID = oggPage->serialno(); /* if this is the start of a stream, create a m_repository file for it */ if (oggPage->isBOS()) { std::stringstream filename; switch (OggBOSExtractorFactory::getStreamType(oggPage)) { case OggType::theora: filename << "theora_" << std::hex << serialID << std::dec << ".ogv"; break; case OggType::vorbis: filename << "vorbis_" << std::hex << serialID << std::dec << ".oga"; break; case OggType::kate: filename << "kate_" << std::hex << serialID << std::dec << ".ogv"; break; default: logger.warning() << "unknown type ID "<< std::hex << serialID << std::dec <<"\n"; filename << "unknown_" << std::hex << serialID << std::dec << ".ogv"; } logger.info() << "creating file <"<\n"; outputFileList[serialID].repository = FileRepository( filename.str(), MediaUnit::write); outputFileList[serialID].encoder = OggEncoder(); } /* if this is a simple page, insert it into the decoder it belongs to */ outputFileList[serialID].encoder << oggPage; while (outputFileList[serialID].encoder.isAvailable()) { RawMediaPacket rawOutput; /* extract the raw packets */ outputFileList[serialID].encoder >> rawOutput; outputFileList[serialID].repository << rawOutput; } if (oggPage->isEOS()) outputFileList[serialID].repository.close(); } } repository.close(); return (0); } int main(int argc, char* argv[]) { try { return oggSplitCmd(argc, argv); } catch (OggException & e) { logger.error() << "Fatal error: " << e.what() << std::endl; return -1; } } oggvideotools-0.9.1/src/base/mediaOutputDecoder.h000664 001750 001750 00000001205 12763227102 022241 0ustar00embedembed000000 000000 #ifndef MEDIAOUTPUTDECODER_H_ #define MEDIAOUTPUTDECODER_H_ #include "definition.h" #include "oggPacket.h" #include "oggComment.h" #include "mediaDecoder.h" #include "streamConfig.h" class MediaOutputDecoder : public MediaDecoder { protected: uint8 streamID; public: MediaOutputDecoder(const uint8 _streamID = 0); virtual ~MediaOutputDecoder(); virtual void initDecoder(StreamConfig& config, std::vector& commentList) = 0; virtual MediaOutputDecoder& operator<<(OggPacket packet) = 0; virtual uint32 getPositionOfNextPacket() = 0; uint8 getStreamNo() const; }; #endif /*MEDIAOUTPUTDECODER_H_*/ oggvideotools-0.9.1/src/base/oggPacket.h000664 001750 001750 00000005421 12763227102 020363 0ustar00embedembed000000 000000 /* * OggPacket will carry all relevant information of an ogg packet * * Copyright (C) 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. * */ #ifndef OGGPACKET_H_ #define OGGPACKET_H_ #include #include #include #ifdef HAVE_LIBOGG #include #endif #include "definition.h" //#include "refObject.h" #include "oggTypes.h" class OggPacketInternal; typedef std::shared_ptr OggPacket; class OggPacketInternal : public std::enable_shared_from_this { public: enum class PacketType { normal, bos, eos }; protected: ogg_packet m_oggPacket; /* information about the stream type and the stream No */ OggType m_streamType; uint8 m_streamNo; bool m_streamHeader; public: OggPacketInternal(); OggPacketInternal(const ogg_packet& ogg_p); OggPacketInternal(uint8* data, uint32 length, uint32 packetNo, int64 granulePos=-1, PacketType packetType = PacketType::normal); OggPacketInternal(std::vector data, uint32 packetNo, int64 granulePos, PacketType packetType); virtual ~OggPacketInternal(); OggPacket clone(); OggPacket getPtr(); static OggPacket create(uint8* data, uint32 length, uint32 packetNo, int64 granulePos=-1, PacketType packetType = PacketType::normal); int64 granulepos(); void setGranulepos(int64 pos); uint32 getPacketNo(); uint8 getStreamNo(); OggType getStreamType(); ogg_packet* getUnderlayingOggPacketPtr() { return &m_oggPacket; } // void cleanPacketPtr() { m_oggPacket.packet = 0; /* no delete */ } void setStreamType(OggType type); void setStreamNo(uint8 streamNo); void setStreamHeader(); bool isBOS(); bool isEOS(); bool isStreamHeader(); void setBOS(); void unsetBOS(); void setEOS(); void unsetEOS(); void setPacketno(int64_t no) { m_oggPacket.packetno = no; } void liboggDelivery(); uint32 length(); uint8* data(); /* ogg_packet toLibogg(); void fromLibogg(ogg_packet packet); */ std::string toString(uint8 level); }; #endif /*OGGPACKET_H_*/ oggvideotools-0.9.1/src/misc/ringbuffer.h000664 001750 001750 00000003550 12763227102 020632 0ustar00embedembed000000 000000 /* * simple ring buffer * * 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. * */ #ifndef ringbuffer_h #define ringbuffer_h #include #include class ringbuffer { protected: //unsigned char* fifo; std::vector fifo; uint32_t size; uint32_t used; uint32_t begin; //! first available sign uint32_t end; //! oldest packet void lock() {} void unlock() {} public: ringbuffer(uint32_t buffersize = 8000); // ringbuffer(uint8_t* rawdata, uint32_t len); ~ringbuffer(); // uint32_t addData(const unsigned char* data, uint32_t len); uint32_t getData(unsigned char* data, uint32_t len); uint32_t getAvailable(); uint32_t getUsed(); // read newest nBytes // uint32_t peekBack(unsigned char* data, uint32_t len); // read oldest nBytes // uint32_t peekFront(unsigned char* data, uint32_t len); // delete the oldest len bytes uint32_t inc(uint32_t len); void clean(); uint32_t addData(const std::vector &data, uint32_t len); uint32_t getData(std::vector &data, uint32_t len); uint32_t peekBack(std::vector &data, uint32_t len); uint32_t peekFront(std::vector &data, uint32_t len); }; #endif oggvideotools-0.9.1/src/main/videoHook.cpp000664 001750 001750 00000024360 12763227102 020756 0ustar00embedembed000000 000000 #include #include #include "videoHook.h" #include "theoraDecoder.h" #include "theoraEncoder.h" #include "rgbPlane.h" #include "pictureLoader.h" #include "pictureResize.h" #include "pictureBlend.h" #include "th_helper.h" #include "exception.h" #include "log.h" VideoHook::Config::Config() : stretch(false), trimDatarateOrQuality(false), quality(3), preview(1) { } VideoHook::VideoHook(uint8 outStreamID, const bool copy, const bool keepComments) : HookHandler(copy, keepComments), framerateDecoder(1), framerateEncoder(1), aspectCorrection(1), time(0), nextTime(0), timeOffset(0), intensityStair(1), changeSize(false) { config.stretch = false; // Try to keep the aspect ratio config.quality = 3; // use good quality for resizing config.preview = 1; // don't use any preview functionality // we create the decoder/encoder pair, // even if we don't need them // specially the encoder may be needed later, if the // input comes from another source outputDecoder.reset(new TheoraDecoder); inputEncoder.reset(new TheoraEncoder(outStreamID)); th_clean_ycbcr(outycbcr); th_clean_ycbcr(inycbcr); } VideoHook::~VideoHook() { th_free_ycbcr(outycbcr); // th_free_ycbcr(inycbcr); } HookHandler& VideoHook::operator<<(OggPacket& packet) { if (!outputDecoder) throw OggException("VideoHook::callHook: no outputDecoder given"); if (!inputEncoder) throw OggException("VideoHook::callHook: no inputEncoder given"); TheoraDecoder& decoder = static_cast(*outputDecoder.get()); TheoraEncoder& encoder = static_cast(*inputEncoder.get()); // What is the best way to receive the time?! // best way may be to recalculate the time due to the number of packets // and the framerate time = (inPacketCounter*framerateEncoder) + timeOffset; nextTime = (outPacketCounter*framerateDecoder) + timeOffset; // logger.debug() << "Time "<setStreamNo(encoder.getStreamNo()); // in case, this is just a packet transfer, we need to create // the correct position if (TheoraPosInterpreter::packetIsKeyframe(packet)) posCreator.addKeyframe(); else ++posCreator; packet->setGranulepos(posCreator.getPosition()); outPacketCounter++; packetList.push_back(packet); } else { try { decoder << packet; decoder >> inycbcr; while ( (uint64)(time*1000.0+0.5) >= (uint64)(nextTime*1000.0+0.5) ) { inPlane = PictureLoader::importYCrCb_theora ( inycbcr, decoder.getWidth(), decoder.getHeight(), decoder.getInfo().pic_x, decoder.getInfo().pic_y, decoder.getInfo().pixel_fmt ); /* should be an alpha blend applied before resizing */ if ( !config.blendListBefore.empty() ) { alphaBlend ( time, inPlane, config.blendListBefore ); } if ( changeSize ) { if (config.stretch) inPlane = PictureResize::resize ( inPlane, encoder.width(), encoder.height(), config.quality ); else inPlane = PictureResize::reframe ( inPlane, encoder.width(), encoder.height(), config.quality, 0, aspectCorrection ); } /* should be an alpha blend applied after resizing? */ if ( !config.blendListAfter.empty() ) { alphaBlend ( time, inPlane, config.blendListAfter ); } if ( ( !config.blendListBefore.empty() ) || ( !config.blendListAfter.empty() ) || changeSize ) { /* there are changes written to the outycbcr */ PictureLoader::exportYCrCb_theora ( inPlane, outycbcr, encoder.getInfo().pixel_fmt ); if (inPacketCounter%config.preview == 0) encoder << outycbcr; } else { /* use the original data */ if (outPacketCounter%config.preview == 0) encoder << inycbcr; } if (encoder.isAvailable()) { outPacketCounter++; encoder >> packet; if (TheoraPosInterpreter::packetIsKeyframe(packet)) posCreator.addKeyframe(); else ++posCreator; packet->setGranulepos(posCreator.getPosition()); packetList.push_back(packet); nextTime = (outPacketCounter*framerateDecoder) + timeOffset; } } // logger.debug() << std::endl; } catch (std::exception & e) { logger.error() << "Exception: " << e.what(); } } return(*this); } void VideoHook::setEncoderConfig(StreamConfig& config, std::vector& commentList) { HookHandler::setEncoderConfig(config, commentList); posCreator.initialize(config.parameter.get()); } void VideoHook::resetEncoder() { TheoraEncoder& encoder = static_cast(*inputEncoder); encoder.reset(); } void VideoHook::initAndConnect() { // maybe we could copy the stream even, when it's not strictly // specified // at this point every thing must be configured. // So the comparison could take place TheoraDecoder& decoder = static_cast(*outputDecoder.get()); TheoraEncoder& encoder = static_cast(*inputEncoder.get()); /* if this is a reinitialisation, remember the offset */ timeOffset = time; inPacketCounter = 0; outPacketCounter = 0; if (!config.blendListAfter.empty() || !config.blendListBefore.empty()) reencode = true; /* if it is ok, that we do a reencoding, than we could trim the output */ if (!copyOnly) { /* if both stream configurations are equal, they could be copied */ copy = (decoder.getInfo() == encoder.getInfo()) && !reencode; /* maybe only the datarate/quality is different in this case, we can copy the * stream. But maybe somebody wants to trim the datarate/quality. In this case * we do not copy (very difficult ;-)*/ /* if the picture size is different, we need to resize the video */ if ((decoder.getInfo().pic_width != encoder.getInfo().pic_width) || (decoder.getInfo().pic_height != encoder.getInfo().pic_height)) changeSize = true; /* if the aspect ratio is different, we also need resizing */ if ((decoder.getInfo().aspect_numerator != encoder.getInfo().aspect_numerator) || (decoder.getInfo().aspect_denominator != encoder.getInfo().aspect_denominator)) changeSize = true; /* calculate the framerate Input and framerate Output */ if (decoder.getInfo().fps_denominator > 0) framerateDecoder = decoder.getInfo().fps_numerator*1.0/decoder.getInfo().fps_denominator; else framerateDecoder = 1; if (encoder.getInfo().fps_denominator > 0) framerateEncoder = encoder.getInfo().fps_numerator*1.0/encoder.getInfo().fps_denominator; else framerateEncoder = 1; // logger.debug() << "changeing framerate from "<< framerateInput<<" to "<& blendList) { for (uint32 i( 0); i= blendList[i].startTime) { if (blendList[i].smooth) { blendList[i].state = BlendElement::blend_slideIn; } else { blendList[i].intensity = 1.0; blendList[i].state = BlendElement::blend_on; } } } break; case BlendElement::blend_slideIn: { blendList[i].intensity += intensityStair; if (blendList[i].intensity >= 1.0) { blendList[i].state = BlendElement::blend_on; blendList[i].intensity = 1.0; } } break; case BlendElement::blend_on: { if ( (blendList[i].endTime > 0.0 ) && (time >= blendList[i].endTime )) { if (blendList[i].smooth) { blendList[i].state = BlendElement::blend_slideOut; } else { blendList[i].intensity = 0.0; blendList[i].state = BlendElement::blend_end; } } } break; case BlendElement::blend_slideOut: { blendList[i].intensity -= intensityStair; if (blendList[i].intensity <= 0.0) { blendList[i].state = BlendElement::blend_end; blendList[i].intensity = 0.0; } } break; case BlendElement::blend_end: { /* do nothing */ } break; } if ( (blendList[i].state != BlendElement::blend_end ) && (blendList[i].state != BlendElement::blend_off )) inPlane = PictureBlend::alphaBlend(inPlane, blendList[i].picture, blendList[i].intensity); } } void VideoHook::flush() { } OggType VideoHook::getType() const { return(OggType::theora); } static bool operator==(const th_info& info1, const th_info& info2) { return ( (info1.aspect_denominator == info2.aspect_denominator) && (info1.aspect_numerator == info2.aspect_numerator) && (info1.colorspace == info2.colorspace) && (info1.fps_denominator == info2.fps_denominator ) && (info1.fps_numerator == info2.fps_numerator) && (info1.frame_height == info2.frame_height) && (info1.frame_width == info2.frame_width) && (info1.keyframe_granule_shift == info2.keyframe_granule_shift) && (info1.pic_height == info2.pic_height) && (info1.pic_width == info2.pic_width) && (info1.pic_x == info2.pic_x) && (info1.pic_y == info2.pic_y) && (info1.pixel_fmt == info2.pixel_fmt) && (info1.quality == info2.quality) && (info1.target_bitrate == info2.target_bitrate) ); } static bool operator!=(const th_info& info1, const th_info& info2) { return (!(info1==info2)); } oggvideotools-0.9.1/src/ovt_kate/kateExtractor.cpp000664 001750 001750 00000005030 12763227102 022530 0ustar00embedembed000000 000000 #include #include #include "kateExtractor.h" #include "definition.h" #include "oggTypes.h" #include "oggHeader.h" #include "kateHeader.h" #include "kateStreamParameter.h" #include "katePosInterpreter.h" #include "log.h" KateExtractor::KateExtractor() { } KateExtractor::~KateExtractor() { } bool KateExtractor::_extract(uint8* data, ExtractorInformation& info) { StreamType* streaminfo = (StreamType*) (data); KateHeader* kateHeader = (KateHeader*) (data + sizeof(StreamType)); /* if this is not a kate header, return with an error */ if ((streaminfo->headerType != 0x80) || (memcmp(streaminfo->typeName, "kate\0\0\0", 7) != 0)) { // TODO: no size of the passed data, the above could overflow (on read) logger.error() << "KatePosInterpreter::initialize: This page is not a kate bos\n"; return(false); } // first extract the parameters std::shared_ptr param(new KateStreamParameter); param->granulerateNum = (kateHeader->granulerateNumerator); param->granulerateDenom = (kateHeader->granulerateDenominator); param->granuleShift = kateHeader->granuleShift; param->language = std::string(kateHeader->language, 16); param->category = std::string(kateHeader->category, 16); /* are there any old info stored, then delete them */ info.parameter = param; /* set the ogg type and the number of header packets */ info.type = OggType::kate; info.numOfHeaderPackets = kateHeader->numHeaders; return(true); } bool KateExtractor::extract(OggPage& oggPage, ExtractorInformation& information) { /* if this is not a Begin Of Stream page, return immediately */ if (!oggPage->isBOS()) { logger.error() << "KatePosInterpreter::extract: This page is not a BOS (Begin Of Stream) page\n"; return(false); } uint8_t* dataPtr = &(oggPage->data())[0]; /* get the information starting points within the raw data */ OggHeader* oggHeader = (OggHeader*) dataPtr; uint8* data = dataPtr + sizeof(OggHeader) + oggHeader->tableSegments; if (_extract(data, information) == false) return(false); information.serialNo = oggHeader->serial; return(true); } bool KateExtractor::extract(OggPacket& packet, ExtractorInformation& information) { // if this is not a Begin Of Stream page, return immediately if (!packet->isBOS()) { logger.error() << "TheoraPosInterpreter::extract: This packet is not a BOS (Begin Of Stream) page\n"; return(false); } if (_extract(packet->data(), information) == false) return(false); return(true); } oggvideotools-0.9.1/src/main/CMakeLists.txt000664 001750 001750 00000000417 12763227102 021060 0ustar00embedembed000000 000000 SET ( LIBRARY_MAIN_SRC audioConverter.cpp audioHook.cpp hookHandler.cpp videoHook.cpp oggBOSExtractorFactory.cpp streamMux.cpp streamSerializer.cpp cmdlineextractor.cpp ) ADD_LIBRARY ( ovtmain ${LIBRARY_MAIN_SRC} ) oggvideotools-0.9.1/docs/oggSilence.html000664 001750 001750 00000004343 12763227102 020504 0ustar00embedembed000000 000000 Content-type: text/html Man page of OGGSILENCE

OGGSILENCE

Section: User Manuals (1)
Updated: JAN 2010
Index Return to Main Contents
 

NAME

oggSilence - creates a silence period in vorbis format  

SYNOPSIS

oggSilence [options] outfile.ogg  

DESCRIPTION

oggSilence creates a vorbis file with a silence duration which length is specified by the -l option.  

OPTIONS

-l
Duration of the silence in ms. Default: 60000

Example: -l 5000

-r
Sample rate of the output file in Hz. Default: 44100

Example: -r 16000

-d
Data rate of the silence file in bit/s. Default: 64000

Example: -d 64000

-n
Number of output channels. Default: 2

Example: -n 2

 

EXAMPLE

oggSilence -d 32000 -r 16000 -n 2 -l 10000 silence.ogg

 

AUTHOR

Joern Seger <yorn at gmx dot net>  

SEE ALSO

oggCut(1), oggCat(1), oggJoin(1), oggSplit(1), oggTranscode(1), oggSlideshow(1), oggThumb(1)
 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
EXAMPLE
AUTHOR
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 09:28:30 GMT, January 10, 2010 oggvideotools-0.9.1/src/ovt_theora/theoraPosInterpreter.h000664 001750 001750 00000002013 12763227102 024101 0ustar00embedembed000000 000000 #ifndef THEORAPOSINTERPRETER_H_ #define THEORAPOSINTERPRETER_H_ #include "definition.h" #include "granulePosInterpreter.h" class TheoraPosInterpreter : public GranulePosInterpreter { protected: uint8 keyframeShift; uint32 framerateNumerator; uint32 framerateDenominator; public: TheoraPosInterpreter(); virtual ~TheoraPosInterpreter(); void extractFramePos(int64 granulePosition, int64& keyframePosition, int32& intraframePosition); uint32 getFramerateNumerator(); uint32 getFramerateDenominator(); uint8 getKeyframeShift(); virtual void initialize(StreamParameter* parameter); virtual double getTime(int64 granulePos); TheoraPosInterpreter& operator++(); void addKeyframe(); static bool packetIsKeyframe(OggPacket& packet); virtual void setStreamPosition(OggPacket& packet); virtual GranulePosInterpreter& operator+=(GranulePosInterpreter& position); virtual GranulePosInterpreter& operator-=(GranulePosInterpreter& position); }; #endif /*THEORAPOSINTERPRETER_H_*/ oggvideotools-0.9.1/src/ovt_kate/kateStreamParameter.cpp000664 001750 001750 00000004001 12763227102 023646 0ustar00embedembed000000 000000 #include #include #include "kateStreamParameter.h" #include "log.h" KateStreamParameter::KateStreamParameter() { } KateStreamParameter::~KateStreamParameter() { } bool KateStreamParameter::operator==(const StreamParameter& _param) { StreamParameter* _param_unconst = const_cast(&_param); KateStreamParameter* param = dynamic_cast(_param_unconst); if (!param) return(false); if (granuleShift != param->granuleShift) { logger.error() << "kate parameter compare: the granule shift is not matching\n"; return(false); } if ((granulerateNum != param->granulerateNum) || (granulerateDenom != param->granulerateDenom)) { logger.error() << "kate parameter compare: granulerate does not match: " << granulerateNum << "/" << param->granulerateDenom << " != " << param->granulerateNum << "/" << param->granulerateDenom << std::endl; return(false); } if (language != param->language) { logger.error() << "kate parameter compare: language does not match: " << language << param->language << std::endl; return(false); } if (category != param->category) { logger.error() << "kate parameter compare: category does not match: " << category << param->category << std::endl; return(false); } return(true); } std::string KateStreamParameter::toString() { std::stringstream stream; stream << std::endl; stream << "Language : " << language << "\n"; stream << "Category : " << category << "\n"; stream << "Granulerate : " << granulerateNum/granulerateDenom << "\n"; stream << std::endl; return(stream.str()); } StreamParameter* KateStreamParameter::clone() { // create a clone KateStreamParameter* streamParameter = new KateStreamParameter(); // copy the original data to the clone (*streamParameter) = (*this); // return the clone return(streamParameter); } oggvideotools-0.9.1/src/theoraVideoPacket.h000664 001750 001750 00000003267 12763227102 021154 0ustar00embedembed000000 000000 /* * theoraVideoPacket * * Copyright (C) 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. * */ #ifndef THEORAVIDEOPACKET_H_ #define THEORAVIDEOPACKET_H_ #ifdef HAVE_CONFIG_H #include "config.h" #else #warning only use with autotools #endif #ifdef HAVE_LIBTHEORA #include #include "refObject.h" #include "definition.h" class VideoData { public: yuv_buffer yuvBuffer; uint64 granulePosition; double time; bool keyframe; }; class TheoraVideoPacket : public RefObject { public: TheoraVideoPacket(); TheoraVideoPacket(TheoraVideoPacket& packet); virtual ~TheoraVideoPacket(); TheoraVideoPacket& operator=(const TheoraVideoPacket& packet); uint64 getGranulePosition(); double getTime(); bool isKeyFrame(); yuv_buffer& getYuvBuffer(); void setGranulePosition(uint64 position); void setTime(double picTime); void setKeyFrame(bool isFrame); void setYuvBuffer(yuv_buffer& buffer); }; #endif #endif /*THEORAVIDEOPACKET_H_*/ oggvideotools-0.9.1/src/effect/lowpassEffect.cpp000664 001750 001750 00000005334 12763227102 022144 0ustar00embedembed000000 000000 // // C++ Implementation: lowpassEffect // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #include "lowpassEffect.h" #include #include #include "pictureResize.h" #include "log.h" #include "effectorVisitor.h" LowpassEffect::LowpassEffect() : state(unconfigured) { } LowpassEffect::~LowpassEffect() { } void LowpassEffect::configure(LowPassPictureConfig & _config) { config = _config; framecounter = 0; factor = 0.5; presentationPlane = PictureResize::reframe(config.origPlane, config.outputWidth, config.outputHeight); if (config.first) state = presentation; else state = blindIn; } Effector & LowpassEffect::operator >>(RGBPlane & plane) { switch (state) { case blindIn: { doBlindIn(plane); break; } case blindOut: { doBlindOut(plane); break; } case presentation: { doPresentation(plane); break; } default: { logger.error() << "LowpassEffect: no frame available\n"; break; } } } void LowpassEffect::doBlindIn(RGBPlane & plane) { uint32 n = (config.blindLength - framecounter); float filterValue = n*1.0/(config.blindLength*1.0);//1.0/(2.0+(n*1.0/(config.blindLength*1.0)*100.0)); //powf(factor,n); // logger.debug() << " -- blindin - fr "<< framecounter <<" fa "< config.blindLength) { state = presentation; } } void LowpassEffect::doPresentation(RGBPlane & plane) { plane = presentationPlane; //.reframe(config.outputWidth, config.outputHeight); framecounter++; if (framecounter > (config.sequenceLength - config.blindLength)) { if (!config.last) { state = blindOut; } else { if (framecounter >= config.sequenceLength) { state = unavailable; } } } } void LowpassEffect::doBlindOut(RGBPlane & plane) { uint32 n = (framecounter - (config.sequenceLength - config.blindLength)); float filterValue = n*1.0/(config.blindLength*1.0);//1.0/(2.0+(n*1.0/(config.blindLength*1.0)*100.0)); //powf(factor,n); logger.debug() << " -- blindout - fr "<< framecounter <<" fa "<= config.sequenceLength) { state = unavailable; } } bool LowpassEffect::available() { return((state != unavailable) && (state != unconfigured)); } void LowpassEffect::accept(EffectorVisitor& visitor) const { visitor.visit(*this); } oggvideotools-0.9.1/cpackInfo/README.txt000664 001750 001750 00000000222 12763227102 020172 0ustar00embedembed000000 000000 This package brings you the following Ogg Video Tools: * oggCat * oggCut * oggSplit * oggJoin * oggLength * oggThumb * oggTranscode * oggLength oggvideotools-0.9.1/src/effect/pictureBlend.h000664 001750 001750 00000001030 12763227102 021411 0ustar00embedembed000000 000000 // // C++ Interface: pictureBlend // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #ifndef PICTUREBLEND_H #define PICTUREBLEND_H #include "rgbPlane.h" /** @author Yorn */ class PictureBlend { public: PictureBlend(); virtual ~PictureBlend(); static RGBPlane alphaBlend(RGBPlane& picture, RGBPlane& alphaPic, float intensity); static RGBPlane crossfade(RGBPlane& plane1, RGBPlane& plane2, float velocity); }; #endif oggvideotools-0.9.1/src/libresample/config.h000664 001750 001750 00000000405 12763227102 021306 0ustar00embedembed000000 000000 /* src/config.h. Generated automatically by configure. */ /* Run configure to generate config.h automatically on any system supported by GNU autoconf. For all other systems, use this file as a template to create config.h */ #define HAVE_INTTYPES_H 1 oggvideotools-0.9.1/src/effect/effectorTypes.h000664 001750 001750 00000004705 12763227102 021627 0ustar00embedembed000000 000000 // // C++ Interface: effectortypes // // Description: // Enumeration of effector types and a a specialized EffectorVisitor that // allows for a more effective effector type detection than dynamic_cast<>. // // Copyright (C) 2010 Bjarne Juul Pasgaard // // 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. #ifndef EFFECTORTYPES_H #define EFFECTORTYPES_H #include "effector.h" #include "effectorVisitor.h" /// @brief Enumeration of the available effector types. enum EffectorType { KenBurns, ///< Ken Burns effect Crossfade, ///< Cross fading Plain, ///< Plain pictures Blur, ///< Bluring at changeover Shift, ///< Shift left effect ShiftBlend ///< Shift and blend left effect }; // Forward declarations class KenBurnsEffect; class Crossfader; class LowpassEffect; class PlainPicture; class ShiftEffect; class ShiftblendEffect; /// @brief A functor that determines the type of an /// effector specialization. /// /// This is an alternative to dynamic_cast<>, but is often /// far more effective and has the advantage of a known /// constant-time complexity (in contrast to dynamic_cast<>). class GetEffectorType : protected EffectorVisitor { public: /// @brief The entry point of the functor. /// /// @param effector The effector to determine the type of. /// /// @return The type of the supplied effector. EffectorType operator()(const Effector& effector); virtual ~GetEffectorType() {} protected: // Overridden base class methods virtual void visit(const KenBurnsEffect&); virtual void visit(const Crossfader&); virtual void visit(const LowpassEffect&); virtual void visit(const PlainPicture&); virtual void visit(const ShiftEffect&); virtual void visit(const ShiftblendEffect&); protected: EffectorType t; }; #endif oggvideotools-0.9.1/src/misc/helper.cpp000664 001750 001750 00000000713 12763227102 020311 0ustar00embedembed000000 000000 #include "helper.h" #include #include bool check_file_exists (std::string& filename) { bool exists(false); std::string answer; std::ifstream fin; fin.open (filename.c_str()); if (fin.fail()) return(false); fin.close(); std::cerr << "The file <"< exists, overwrite? "; std::cin >> answer; if (answer == "yes" || answer =="y" || answer == "Yes" || answer == "Y" ) return(false); return(true); } oggvideotools-0.9.1/src/main/videoHook.h000664 001750 001750 00000003152 12763227102 020417 0ustar00embedembed000000 000000 #ifndef VIDEOHOOK_H_ #define VIDEOHOOK_H_ // #include #include "hookHandler.h" #include "theoraDecoder.h" #include "theoraEncoder.h" #include "rgbPlane.h" #include "theoraPosInterpreter.h" #include "blendElement.h" class VideoHook : public HookHandler { public: class Config { public: bool stretch; bool trimDatarateOrQuality; uint32 quality; uint32 preview; std::vector blendListBefore; std::vector blendListAfter; Config(); }; private: Config config; /* precalculations from known values */ double framerateDecoder; double framerateEncoder; double aspectCorrection; double time; double nextTime; double timeOffset; double intensityStair; bool copy; bool changeSize; RGBPlane inPlane; TheoraPosInterpreter posCreator; th_ycbcr_buffer inycbcr; th_ycbcr_buffer outycbcr; VideoHook(); void alphaBlend(double time, RGBPlane& inPlane, std::vector& blendList); public: VideoHook(uint8 outStreamID, const bool copy=true, const bool keepComments=true); virtual ~VideoHook(); void configureProcess(Config& config); virtual void setEncoderConfig(StreamConfig& config, std::vector& commentList); virtual void resetEncoder(); virtual HookHandler& operator<<(OggPacket& packet); virtual void initAndConnect(); virtual OggType getType() const; virtual void flush(); }; static bool operator==(const th_info& info1, const th_info& info2); static bool operator!=(const th_info& info1, const th_info& info2); #endif /*VIDEOHOOK_H_*/ oggvideotools-0.9.1/src/binaries/oggJoin.cpp000664 001750 001750 00000014755 12763227102 021302 0ustar00embedembed000000 000000 /* * oggJoin will multiplex a number of video and audiostreams to one ogg file * * Copyright (C) 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. * */ #include #include #include #include #include "fileRepository.h" #include "oggDecoder.h" #include "oggEncoder.h" #include "oggStreamDecoder.h" #include "vorbisPosInterpreter.h" #include "theoraPosInterpreter.h" #include "oggPage.h" #include "oggBOSExtractorFactory.h" #include "exception.h" #include "log.h" struct JoinElement { FileRepository repository; OggDecoder decoder; GranulePosInterpreter* position; OggPage nextPage; bool closed; }; bool getNextPage(JoinElement* element, OggPage& page) { if (element->decoder.isAvailable()) { /* if there is a packet available, get it */ element->decoder >> page; return(true); } /* there is actually no packet available, so grap a data * bunch and transfer it into the decoder and see if we can * then extract a packet */ while (element->decoder.isEmpty()) { /* if we can not grap any more data, return false */ if (element->repository.isEndOfFile()) { element->closed = true; return(false); } /* transfer a new raw packet */ RawMediaPacket rawPacket; element->repository >> rawPacket; element->decoder << rawPacket; } element->decoder >> page; return(true); } void printHelpScreen(const std::string& progName) { logger.error() << "usage: " << progName << " [ [ ... ] ]\n" << " -- package and version \"" << PACKAGE_STRING << "\"\n\n" << "oggJoin will multiplex a number of ogg streams into \n" << "one file. Actually every stream must be placed in a \n" << "single file.\n\n"; } int oggJoinCmd(int argc, char* argv[]) { std::string help("-h"); if ((argc > 1) && (help == argv[1])) { printHelpScreen(argv[0]); exit(-1); } if (argc < 3) { printHelpScreen(argv[0]); exit(-1); } std::vector decoderList; /* open the m_repository and encoder for the joined file */ FileRepository outRepository = FileRepository(argv[1], MediaUnit::write); OggEncoder oggEncoder; /* run through the file list given by the command line */ for (uint32 i(2); i < (uint32)argc; ++i) { /* create a new element for one stream */ JoinElement* newElement = new JoinElement; newElement->closed = false; newElement->repository = FileRepository(argv[i], MediaUnit::read); /* if we can not open the file, do not insert it in the decoder list */ if (newElement->repository.isEndOfFile()) { logger.warning() << "Warning: can not open file <"< for reading\n\n"; delete newElement; } else { /* get the first packet bunch from the file and place it into the decoder */ RawMediaPacket packet; newElement->repository >> packet; newElement->decoder << packet; /* there must be at least the bos page */ OggPage page; newElement->decoder >> page; ExtractorInformation config; if (!OggBOSExtractorFactory::extractInformation(page,config)) { logger.warning() << "Warning: <"< is not a valid ogg file"; newElement->repository.close(); delete newElement; continue; } newElement->position = OggBOSExtractorFactory::extractPositionInterpreter(config); /* if we found a valid stream, create the rest of the infrastructure */ if (newElement->position != 0) { /* insert the BOS page into the new file (the first pages must be the BOS * pages) */ oggEncoder << page; /* request the next page */ getNextPage(newElement, newElement->nextPage); decoderList.push_back(newElement); } else { logger.warning() << "Warning: can not interpret ogg stream\n"; /* we can not interpret the granual position of this stream, * so we close it */ newElement->repository.close(); delete newElement; } } } if (decoderList.empty()) { logger.error() << "Error: could not open any stream - abort\n"; exit(-1); } uint32 closeCounter(0); /* run through the different streams and assemble them until there are no more pages */ while (closeCounter < decoderList.size()) { double smallestTime(-10); uint32 smallestID(0); /* find the element, that should be inserted into the new file */ for (uint32 i(0); iclosed) continue; double testTime(decoderList[i]->position->getTime(decoderList[i]->nextPage->granulepos())); if ((smallestTime < -9) || (smallestTime > testTime)) { smallestTime = testTime; smallestID = i; } } /* insert the next page into the new file */ oggEncoder << decoderList[smallestID]->nextPage; /* try to get the next page */ if (!getNextPage(decoderList[smallestID], decoderList[smallestID]->nextPage)) { /* if this was the last page in this stream, clean up */ decoderList[smallestID]->closed = true; decoderList[smallestID]->repository.close(); delete decoderList[smallestID]->position; closeCounter++; } while (oggEncoder.isAvailable()) { RawMediaPacket outPacket; oggEncoder >> outPacket; outRepository << outPacket; } } /* cleanup the heap */ for (uint32 i(0); i.ogv: This is the video stream encoded with the theora codec. The is the stream ID that is created by the encoder to uniquely identify this stream. .I vorbis_.oga: This is the audio stream encoded with the vorbis codec. The is the stream ID that is created by the encoder to uniquely identify this stream. .I unknown_.ogv: This is an unknown stream, that could not be interpreted. The is the stream ID that is created by the encoder to uniquely identify this stream. All files are fully playable with your favoured video or audio player (except the streams, that are uninterpreted). .SH AUTHOR Joern Seger .SH "SEE ALSO" .BR oggCut (1), .BR oggCat (1), .BR oggJoin (1), .BR oggTranscode (1), .BR oggSlideshow (1), .BR oggThumb (1), .BR oggSilence (1) oggvideotools-0.9.1/src/base/mediaUnit.h000664 001750 001750 00000002777 12763227102 020411 0ustar00embedembed000000 000000 /* * MediaUnit is a baseclass for all media transfer units * * Copyright (C) 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. * */ #ifndef MEDIAUNIT_H_ #define MEDIAUNIT_H_ #include //#include "MediaConfig.h" //! Base class for the media processing units /*! This abstract class is the base class for all following classes, that process media data * A MediaUnit object is able to receive packets and to send * following classes, that process media data * The idea is to connect one mediaUnit Object with * another by using connectFront and connectBack. */ class MediaUnit { public: enum MediaDirection_t { write, read, readwrite }; protected: std::string name; MediaDirection_t mediaDirection; public: MediaUnit(MediaDirection_t type, const std::string name); virtual ~MediaUnit(); }; #endif /*MEDIAUNIT_H_*/ oggvideotools-0.9.1/src/base/streamExtractor.h000664 001750 001750 00000003051 12763227102 021643 0ustar00embedembed000000 000000 #ifndef STREAMEXTRACTOR_H_ #define STREAMEXTRACTOR_H_ #include "oggPage.h" #include "oggPacket.h" #include "streamParameter.h" #include "granulePosInterpreter.h" //! This is a baseclass for the configuration of a stream /*! This class can be derived by more specific stream information * For the decoding process, parameter is created while the decoder * is initialized * For the encoding process, the parameter pointer must carry a * valid parameter list. * The parameter list is always owned by the ExtractorInformation class * and will be deleted when the ExtractorInformation object destructor is * called */ class ExtractorInformation { public: ExtractorInformation(); ExtractorInformation(const ExtractorInformation& extractorInfo); ~ExtractorInformation(); //! Type of stream (e.g. ogg_vorbis, ogg_theora, ogg_speex) OggType type; //! stream serial number (random number required by ogg) uint32 serialNo; //! The first page/packet gives detailed information of the stream std::shared_ptr parameter; //! the number of header packets must be identified by the stream type uint8 numOfHeaderPackets; ExtractorInformation& operator=(const ExtractorInformation& extractorInfo); }; class StreamExtractor { public: StreamExtractor(); virtual ~StreamExtractor(); virtual bool extract(OggPage& page, ExtractorInformation& information) = 0; virtual bool extract(OggPacket& packet, ExtractorInformation& information) = 0; }; #endif /*STREAMEXTRACTOR_H_*/ oggvideotools-0.9.1/scripts/000775 001750 001750 00000000000 12763227102 016272 5ustar00embedembed000000 000000 oggvideotools-0.9.1/src/base/mediaInputEncoder.cpp000664 001750 001750 00000000353 12763227102 022410 0ustar00embedembed000000 000000 #include "mediaInputEncoder.h" MediaInputEncoder::MediaInputEncoder(const uint8 _streamNo) : streamNo(_streamNo) { } MediaInputEncoder::~MediaInputEncoder() { } uint32 MediaInputEncoder::getStreamNo() const { return(streamNo); }oggvideotools-0.9.1/src/base/bufferRepository.cpp000664 001750 001750 00000001225 12763227102 022361 0ustar00embedembed000000 000000 #include "bufferRepository.h" BufferRepository::BufferRepository(const std::string& name) : MediaRepository(MediaUnit::readwrite, name) { } BufferRepository::~BufferRepository() { } MediaUnit& BufferRepository::operator<<(RawMediaPacket& packet) { buffer.push_back(packet); return(*this); } MediaUnit& BufferRepository::operator>>(RawMediaPacket& packet) { if (!buffer.empty()) { packet = buffer.front(); buffer.pop_front(); } return(*this); } bool BufferRepository::isAvailable() { return(!buffer.empty()); } uint32 BufferRepository::getBunchSize() { return(0); } void BufferRepository::setBunchSize(uint32 size) { return; } oggvideotools-0.9.1/src/ovt_vorbis/000775 001750 001750 00000000000 12763227352 017575 5ustar00embedembed000000 000000 oggvideotools-0.9.1/src/base/mediaConverter.cpp000664 001750 001750 00000005500 12763227102 021757 0ustar00embedembed000000 000000 /* * MediaConverter is the base class for all subsequent decoders * and encoders * * Copyright (C) 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. * */ #include #include "mediaConverter.h" #include "log.h" MediaConverter::MediaConverter() : mediaConverterState(mdec_free) { } MediaConverter::~MediaConverter() { } void MediaConverter::setInitialized() { if (mediaConverterState == mdec_free) mediaConverterState = mdec_initialized; else logger.error() << "MediaConverter::setInitialized(): double initalization\n"; } void MediaConverter::setConfigured() { if (mediaConverterState < mdec_configured) mediaConverterState = mdec_configured; else logger.error() << "MediaConverter::setConfigured(): decoder is configured\n"; } void MediaConverter::setAvailable() { if ((mediaConverterState >= mdec_configured) && (mediaConverterState <= mdec_available)) mediaConverterState = mdec_available; else logger.error() << "MediaConverter::setAvailable(): decoder is not configured or has ended\n"; } void MediaConverter::setEmpty() { if ((mediaConverterState == mdec_configured) || (mediaConverterState == mdec_available) || (mediaConverterState == mdec_empty)) mediaConverterState = mdec_empty; else logger.error() << "MediaConverter::setEmpty(): decoder not configured correctly\n"; } void MediaConverter::setEndOfStream() { if (mediaConverterState > mdec_initialized) mediaConverterState = mdec_endofStream; else logger.error() << "MediaConverter::setEndOfStream(): decoder not initialized\n"; } void MediaConverter::setFree() { mediaConverterState = mdec_free; } bool MediaConverter::isInitialized() { return(mediaConverterState > mdec_free); } bool MediaConverter::isConfigured() { return(mediaConverterState > mdec_initialized); } bool MediaConverter::isAvailable() { return(mediaConverterState == mdec_available); } bool MediaConverter::isEmpty() { return( (mediaConverterState == mdec_initialized) || (mediaConverterState == mdec_empty) || (mediaConverterState == mdec_configured)); } bool MediaConverter::isEndOfStream() { return(mediaConverterState == mdec_endofStream); } oggvideotools-0.9.1/src/base/fileRepository.cpp000664 001750 001750 00000006101 12763227102 022025 0ustar00embedembed000000 000000 /* * FileRepository is used to read or write a local file * * Copyright (C) 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. * */ #include #include #include // #include .. later #include "rawMediaPacket.h" #include "fileRepository.h" #include "exception.h" #include "log.h" FileRepository::FileRepository() : MediaRepository(read, "FileRepository"), fileDescriptor(0), filename(""), bunchSize(4096), eof(true) { } FileRepository::FileRepository(const std::string& _filename, MediaDirection_t type) : MediaRepository(type, "FileRepository"), filename(_filename), bunchSize(4096), eof(false) { eof = true; if (mediaDirection == write) { if ((fileDescriptor = fopen(filename.c_str(), "wb")) == 0) logger.error() << name << "::open failed: " << strerror(errno) << "\n"; else { repositoryAvailable = true; eof = false; } } else { if ((fileDescriptor = fopen(filename.c_str(), "rb")) == 0) logger.error() << name << "::open failed: " << strerror(errno) << "\n"; else { repositoryAvailable = true; eof = false; } } } FileRepository::~FileRepository() { } void FileRepository::close() { if (fileDescriptor) { fclose(fileDescriptor); fileDescriptor = 0; repositoryAvailable = false; } } void FileRepository::setBunchSize(uint32 _bunchSize) { bunchSize = _bunchSize; } uint32 FileRepository::getBunchSize() { return(bunchSize); } bool FileRepository::isEndOfFile() { return(eof); } MediaUnit& FileRepository::operator<<(RawMediaPacket& packet) { if ((mediaDirection == write) && (repositoryAvailable == true)) { if (fwrite(&(packet->getData())[0],1,packet->getSize(),fileDescriptor) != packet->getSize()) { throw OggException(name+"::operator<<: "+strerror(errno)); } } return(*this); } MediaUnit& FileRepository::operator>>(RawMediaPacket& packet) { uint32 readBytes; std::vector buffer(bunchSize); if (mediaDirection == read) { if ((readBytes = fread(buffer.data(),1,bunchSize,fileDescriptor)) < 0) { logger.error() << name << "::operator>>: "<< strerror(errno) << "\n"; return(*this); } if (buffer.size() > readBytes) buffer.resize(readBytes); packet = std::make_shared(buffer, false); // do not create copy if (readBytes < bunchSize) { repositoryAvailable = false; eof = true; } } return (*this); } oggvideotools-0.9.1/cpackInfo/ReadMe.rtf000664 001750 001750 00000002440 12763227102 020352 0ustar00embedembed000000 000000 {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf460 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \paperw11900\paperh16840\margl1440\margr1440\vieww9000\viewh8400\viewkind0 \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \f0\fs28 \cf0 The Ogg Video Package contains the following tools:\ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural \cf0 \ \pard\tx560\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \b \cf0 oggCat\ oggCut\ oggJoin\ oggSplit\ oggLength\ oggThumb\ oggTranscode\ oggSlideshow\ oggSilence \b0 \ \pard\tx720\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li940\fi-940\ql\qnatural\pardirnatural \cf0 \ \pard\tx560\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \cf0 For information how to use the tools, please visit\ {\field{\*\fldinst{HYPERLINK "http://en.flossmanuals.net/TheoraCookbook/"}}{\fldrslt http://en.flossmanuals.net/TheoraCookbook/}}\ and\ {\field{\*\fldinst{HYPERLINK "http://dev.streamnik.de/oggvideotools.html"}}{\fldrslt http://dev.streamnik.de/oggvideotools.html}}\ \ Have much fun - Yorn}oggvideotools-0.9.1/cpackInfo/Welcome.rtf000664 001750 001750 00000001305 12763227102 020607 0ustar00embedembed000000 000000 {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf460 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \paperw11900\paperh16840\margl1440\margr1440\vieww7640\viewh8460\viewkind0 \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \f0\fs36 \cf0 Welcome to the \ \b\fs48 Ogg Video Tools \b0\fs36 \ Installer Package\ \ \fs24 This Installer will guide you through the installation process\ \ This Installer Package is brought to you by streamnik\ for more information, please visit us under \ \ {\field{\*\fldinst{HYPERLINK "http://dev.streamnik.de/oggvideotools.html"}}{\fldrslt http://dev.streamnik.de/oggvideotools.html}}\ }oggvideotools-0.9.1/src/base/streamParameter.cpp000664 001750 001750 00000000156 12763227102 022146 0ustar00embedembed000000 000000 #include "streamParameter.h" StreamParameter::StreamParameter() { } StreamParameter::~StreamParameter() { } oggvideotools-0.9.1/src/ovt_kate/kateExtractor.h000664 001750 001750 00000000663 12763227102 022204 0ustar00embedembed000000 000000 #ifndef KATEEXTRACTOR_H_ #define KATEEXTRACTOR_H_ #include "streamExtractor.h" class KateExtractor : public StreamExtractor { public: KateExtractor(); virtual ~KateExtractor(); bool _extract(uint8* data, ExtractorInformation& information); virtual bool extract(OggPage& page, ExtractorInformation& information); virtual bool extract(OggPacket& packet, ExtractorInformation& information); }; #endif /*KATEEXTRACTOR_H_*/ oggvideotools-0.9.1/src/ovt_theora/theoraEncoder.h000664 001750 001750 00000002324 12763227102 022500 0ustar00embedembed000000 000000 #ifndef THEORAENCODER_H_ #define THEORAENCODER_H_ #ifdef HAVE_CONFIG_H #include "config.h" #else #warning only use with autotools #endif #ifdef HAVE_LIBTHEORAENC #include #include #include #include #include "oggPacket.h" #include "oggComment.h" #include "mediaInputEncoder.h" #include "theoraStreamParameter.h" #include "streamConfig.h" class TheoraEncoder : public MediaInputEncoder { protected: uint64 packetCounter; th_enc_ctx* theoraState; th_comment theoraComment; th_info theoraInfo; std::list packetList; void createHeader(std::vector& headerList, std::vector& oggComments); public: TheoraEncoder(uint8 streamNo = 0); virtual ~TheoraEncoder(); virtual MediaInputEncoder& operator>>(OggPacket& packet); MediaInputEncoder& operator<<(th_ycbcr_buffer buffer); virtual void configureEncoder(StreamConfig& config, std::vector& oggComments); uint32 width() const; uint32 height() const; th_info& getInfo(); virtual std::string configuration() const; virtual void reset(); }; #endif /* HAVE_LIBTHEORAENC */ #endif /*THEORAENCODER_H_*/ oggvideotools-0.9.1/src/binaries/000775 001750 001750 00000000000 12763227352 017175 5ustar00embedembed000000 000000 oggvideotools-0.9.1/src/ovt_vorbis/vorbisDecoder.h000664 001750 001750 00000002242 12763227102 022531 0ustar00embedembed000000 000000 #ifndef vorbisDecoder_h #define vorbisDecoder_h #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_LIBVORBIS #include #include #include #include "definition.h" #include "mediaOutputDecoder.h" #include "audioPacket.h" class VorbisDecoder : public MediaOutputDecoder { protected: vorbis_info vorbisInfo; vorbis_dsp_state vorbisDspState; vorbis_block vorbisBlock; vorbis_comment vorbisComment; std::list packetList; uint8 initCount; uint32 packetCount; uint64 sampleCounter; public: VorbisDecoder(uint8 streamID = 0); virtual ~VorbisDecoder(); virtual void initDecoder(StreamConfig& config, std::vector& oggComments); // virtual std::string getInfoString(); vorbis_info& getInfo(); vorbis_comment& getComment(); virtual MediaOutputDecoder& operator<<(OggPacket packet); VorbisDecoder& operator>>(AudioPacket& audioPacket); virtual void clear(); virtual double getTimeOfNextPacket(); virtual uint32 getPositionOfNextPacket() { return packetCount; } virtual std::string configuration() const; }; #endif // WITH_LIBVORBIS #endif oggvideotools-0.9.1/src/base/refObject.h000664 001750 001750 00000006101 12763227102 020356 0ustar00embedembed000000 000000 /* * RefObject class to reduce complete object copy actions * * 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. * */ #ifndef refObject_h #define refObject_h //! class to keep refences instead of copies /*! This class keeps track of an dynamically allocated memory on the heap. On object copy, only the object pointer is copied and an additionally reference counter is incremented. On object elemination, the object is deleted only in case that no one has still a refence to this object. (Code is inspired by Bjarne Stoustrup) This code is obsoleted by the boost smart pointers, however, actually I do not plan to create a dependency to boost */ template class RefObject { protected: unsigned int* refCounter; C* objPtr; public: RefObject(); RefObject(C* objPtr); RefObject(const RefObject& obj); virtual ~RefObject(); RefObject& operator=(const RefObject& obj); C* operator->(); C* obj(); void obj(C* object); }; /* Implementation Part */ template inline RefObject::RefObject() : refCounter(new unsigned int), objPtr(new C) { (*refCounter) = 1; } template inline RefObject::RefObject(C* objPtr) : refCounter(new unsigned int), objPtr(objPtr) { (*refCounter) = 1; } template inline RefObject::RefObject(const RefObject& refObj) : refCounter(refObj.refCounter), objPtr(refObj.objPtr) { if (this == &refObj) return; (*refCounter)++; } template inline RefObject::~RefObject() { (*refCounter)--; if ((*refCounter) == 0) { delete refCounter; delete objPtr; } } template inline RefObject& RefObject::operator=(const RefObject& refObj) { if (this == &refObj) return(*this); (*refCounter)--; if ((*refCounter) == 0) { delete refCounter; delete objPtr; } refCounter = refObj.refCounter; objPtr = refObj.objPtr; (*refCounter)++; return(*this); } template inline C* RefObject::obj() { return(objPtr); } template inline C* RefObject::operator->() { return(objPtr); } template inline void RefObject::obj(C* ptr) { delete objPtr; objPtr = ptr; /* reference pointer is not touched DANGER: think - do you really want to use this method? */ } #endif // refObject_h oggvideotools-0.9.1/INSTALL000664 001750 001750 00000000347 12763227102 015640 0ustar00embedembed000000 000000 Installation has changed to cmake, so the installation process is much easier than before: create a build directory: > mkdir build > cd build and execute cmake and make: > cmake .. > make > sudo make install and you are done!oggvideotools-0.9.1/src/effect/effectorVisitor.h000664 001750 001750 00000003170 12763227102 022155 0ustar00embedembed000000 000000 // // C++ Interface: effectorvisitor // // Description: // A visitor (in accordance with the visitor design patter) for // specializations of the Effector class. // // Copyright (C) 2010 Bjarne Juul Pasgaard // // 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. #ifndef EFFECTORVISITOR_H #define EFFECTORVISITOR_H // Forward declarations class KenBurnsEffect; class Crossfader; class LowpassEffect; class PlainPicture; class ShiftEffect; class ShiftblendEffect; /// @brief A visitor of Effector specialisations /// /// This class takes the role of a visitor in accordance with the /// visitor design pattern. class EffectorVisitor { public: virtual ~EffectorVisitor() {}; virtual void visit(const KenBurnsEffect&); virtual void visit(const Crossfader&); virtual void visit(const LowpassEffect&); virtual void visit(const PlainPicture&); virtual void visit(const ShiftEffect&); virtual void visit(const ShiftblendEffect&); }; #endif oggvideotools-0.9.1/src/base/oggComment.cpp000664 001750 001750 00000000125 12763227102 021105 0ustar00embedembed000000 000000 #include "oggComment.h" OggComment::OggComment() { } OggComment::~OggComment() { } oggvideotools-0.9.1/src/misc/000775 001750 001750 00000000000 12763227102 016325 5ustar00embedembed000000 000000 oggvideotools-0.9.1/src/base/mediaConverter.h000664 001750 001750 00000004371 12763227102 021431 0ustar00embedembed000000 000000 /* * MediaConverter is the base class for all subsequent decoders * and encoders * * Copyright (C) 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. * */ #ifndef MEDIACONVERTER_H_ #define MEDIACONVERTER_H_ #include //! MediaConverter is a baseclass for all decoders /*! The MediaConverter class is used with a defined decoder or encoder. It mainly implements a state machine, which holds the actual decoder/encoder state information: #- mdec_free: the decoder is uninitialized #- mdec_initialized: the decoder is initialized, i.e. the stream has a defined stream type or stream ID #- mdec_configured: the stream is able to give information about the stream, that is processed (stream header is read) #- mdec_available: the stream is able to provide output data (e.g. a video picture etc.) #- mdec_empty: there is actually no data available for output #- mdec_endofStream: the end of a stream has been detected */ class MediaConverter { protected: enum MediaConverterState { mdec_free, mdec_initialized, mdec_configured, mdec_empty, mdec_available, mdec_endofStream }; private: MediaConverterState mediaConverterState; protected: void setInitialized(); void setConfigured(); void setAvailable(); void setEmpty(); void setFree(); public: MediaConverter(); virtual ~MediaConverter(); void setEndOfStream(); bool isInitialized(); bool isConfigured(); bool isAvailable(); bool isEmpty(); bool isEndOfStream(); virtual std::string configuration() const { return (std::string("")); } virtual void reset() {} }; #endif /*MEDIACONVERTER_H_*/ oggvideotools-0.9.1/src/ovt_theora/CMakeLists.txt000664 001750 001750 00000000366 12763227102 022311 0ustar00embedembed000000 000000 SET ( LIBRARY_THEORA_SRC theoraEncoder.cpp theoraDecoder.cpp theoraExtractor.cpp theoraPosInterpreter.cpp theoraStreamParameter.cpp ) # theoraConfig.cpp ADD_LIBRARY ( ovttheora ${LIBRARY_THEORA_SRC} ) oggvideotools-0.9.1/src/base/oggDecoder.cpp000664 001750 001750 00000010720 12763227102 021052 0ustar00embedembed000000 000000 /* * OggDecoder * * Copyright (C) 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. * */ #include #include #include #include "oggDecoder.h" #include "oggHeader.h" #include "log.h" #include "exception.h" #define min(a,b) (((a)<(b))?(a):(b)); OggDecoder::OggDecoder() : m_oggRingbuffer(71000) // max page size plus 4KB read size { setConfigured(); } OggDecoder::~OggDecoder() { } void OggDecoder::clear() { /* nothing to be done here */ } void OggDecoder::getNextPages() { while (1) { uint32 length(0); if (length = getNextPageLength()) { logger.debug() << "getNextPage: length="<>(OggPage& page) { if (isAvailable()) { page = m_oggPageList.front(); m_oggPageList.pop(); if (m_oggPageList.empty()) setEmpty(); } else logger.error() << "OggDecoder::operator>>: no page available, insert a packet first\n"; return(*this); } uint32 OggDecoder::space() { return (uint32_t) (m_oggRingbuffer.capacity()-m_oggRingbuffer.size()); } uint32_t OggDecoder::getNextPageLength() { uint32_t availLength = (uint32_t) m_oggRingbuffer.size(); logger.debug() << "get new page length (if one) " << std::endl; if (availLength < (int) sizeof(OggHeader)) { return (0); } // test is this aligned? char starter[5]; uint32_t pos; for (pos = 0; pos < 5; ++pos) { starter[pos] = m_oggRingbuffer[pos]; logger.debug() << "data " << std::hex << "0x" << (int) starter[pos] << " (" << std::dec << starter[pos] << ")\n"; } if (strncmp(starter, "OggS", 4) != 0) { logger.debug() << "Error: ogg string is " << std::hex << "0x" << (int) starter[0] << " 0x" << (int) starter[1] << " 0x" << (int) starter[2] << " 0x" << (int) starter[3] << " 0x" << (int) starter[4] << std::endl; throw OggException("OggRingbuffer::getNextPageLength: ERROR ogg packet not aligned"); } if ('\0' != starter[4]) { throw OggException("OggRingbuffer::getNextPageLength: ERROR unsupported stream structure version"); } //pos = sizeof(OggHeader) - 1; // jump to the segment table uint32_t readsegments = m_oggRingbuffer[26]; logger.debug() << "there are " << readsegments << " segments available in this packet"; if (availLength < (int) (sizeof(OggHeader) + readsegments)) { return (0); } // what is the data length uint32_t data_length(0); uint32_t header_offset(sizeof(OggHeader)); for (uint32_t i = 0; i < readsegments; ++i) { data_length += m_oggRingbuffer[header_offset + i]; } uint32_t overallLength = data_length + header_offset + readsegments; return (overallLength<=availLength?overallLength:0); }oggvideotools-0.9.1/src/misc/CMakeLists.txt000664 001750 001750 00000000210 12763227102 021056 0ustar00embedembed000000 000000 SET ( LIBRARY_MISC_SRC ringbuffer.cpp log.cpp helper.cpp crc.cpp ) ADD_LIBRARY ( ovtmisc ${LIBRARY_MISC_SRC} ) oggvideotools-0.9.1/docs/oggDump.html000664 001750 001750 00000005231 12763227102 020024 0ustar00embedembed000000 000000 Content-type: text/html Man page of OGGDUMP

OGGDUMP

Section: User Manuals (1)
Updated: JAN 2010
Index Return to Main Contents
 

NAME

oggDump - prints out information of ogg video files (.ogv, .ogg or oga)  

SYNOPSIS

oggDump [options] outfile.ogv  

DESCRIPTION

OggDump gives detailed information about an ogg video file and prints these information with a given detail level.

Ogg files consist of a number of streams (video and audio). From the Ogg-container perspective, the streams are devided into pages. These pages usually have nearly the same size. The pages can be printed out with the -g option.

From the stream perspective, every stream consists of packets. These packets carry a bunch of compressed audio samples in case of a vorbis stream or one video frame in case of a theora video stream. These packets could be of variable length and are places into the ogg pages. To toString the packets, use the -p option.

 

OPTIONS

-g
Dumps the stream pages of the file.

-p
Dumps the stream packets.

-l
<level>. Set the dump level (1-5). Default is 5, which means all information are printed.

-s
Prompt for the stream that should be dumped. All other streams are ignored and will not be printed.

-o
<file> Write the dump information to a file.

 

AUTHOR

Joern Seger <yorn at gmx dot net>

 

SEE ALSO

oggCut(1), oggJoin(1), oggSplit(1), oggTranscode^(1), oggSlideshow(1), oggThumb(1), oggSilence(1)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
AUTHOR
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 09:28:30 GMT, January 10, 2010 oggvideotools-0.9.1/src/binaries/oggTranscode.cpp000664 001750 001750 00000052504 12763227102 022317 0ustar00embedembed000000 000000 /* * oggResize creates a resized video * * Copyright (C) 2008-2009 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. * */ #ifdef __WIN32 #define __GNU_LIBRARY__ #include "../win32/getopt_win.h" #endif #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "definition.h" #include "helper.h" #include "rgbPlane.h" #include "pictureBlend.h" #include "pictureLoader.h" #include "oggComment.h" #include "videoHook.h" #include "audioHook.h" #include "fileRepository.h" #include "streamSerializer.h" #include "streamMux.h" #include "cmdlineextractor.h" #include "wishList.h" #include "exception.h" #include "log.h" void printHelpScreen(const std::string& progname) { logger.error() << "usage: "< new frame size\n" << " -f video framerate in frames per second\n" << " -F audio samplerate in Hz\n" << " -d video datarate in Bit/s\n" << " -D audio datarate in Bit/s\n" << " -q theora video quality\n" << " -N audio channels\n" << " -a add png with alpha channel on top of a frame\n" << " before the resize process \n" << " form: file.png[,[,[,s]]]\n" << " start and end time is in seconds and can be a floating point\n" << " -A add png with alpha channel on top of a frame\n" << " after the resize process (same parameters as -a)\n" << " -p only use every th packet to create the new video\n" << " -c comments for the video stream\n" << " -C comments for the audio stream\n" << " -x do not ask for overwriting output file\n" << " -rv force reencode video stream\n" << " -ra force reencode audio stream\n" << " -Q resize quality (1=best/slow; 6=worst/fast)\n" << " -t stretch picture to new size\n\n"; } void readPictures(std::vector& blendList) { for (uint32 i(0); i < blendList.size(); ++i) { RGBPlane plane; try { PictureLoader::load ( plane, blendList[i].getPictureName() ); blendList[i].setPicturePlane( plane ); } catch (std::exception & e) { logger.error() << "Error: " << e.what() << std::endl; } } } /* you can create a alpha blend object with the following option * -a picturex.png,1.23,2.34;picturey.png,5.12,7,s */ void alphaBlend(double time, RGBPlane& inPlane, std::vector& blendList, float intensityStair) { for (uint32 i( 0); i= blendList[i].startTime) { if (blendList[i].smooth) { blendList[i].state = BlendElement::blend_slideIn; } else { blendList[i].intensity = 1.0; blendList[i].state = BlendElement::blend_on; } } } break; case BlendElement::blend_slideIn: { blendList[i].intensity += intensityStair; if (blendList[i].intensity >= 1.0) { blendList[i].state = BlendElement::blend_on; blendList[i].intensity = 1.0; } } break; case BlendElement::blend_on: { if ( (blendList[i].endTime > 0.0 ) && (time >= blendList[i].endTime )) { if (blendList[i].smooth) { blendList[i].state = BlendElement::blend_slideOut; } else { blendList[i].intensity = 0.0; blendList[i].state = BlendElement::blend_end; } } } break; case BlendElement::blend_slideOut: { blendList[i].intensity -= intensityStair; if (blendList[i].intensity <= 0.0) { blendList[i].state = BlendElement::blend_end; blendList[i].intensity = 0.0; } } break; case BlendElement::blend_end: { /* do nothing */ } break; } if ( (blendList[i].state != BlendElement::blend_end ) && (blendList[i].state != BlendElement::blend_off )) inPlane = PictureBlend::alphaBlend(inPlane, blendList[i].picture, blendList[i].intensity); } } void analyseVideoTranscoding(WishList& wishList, std::shared_ptr theoraConfigInput, std::shared_ptr theoraConfigOutput) { /* first we believe the output should be equal for all * parameters that are not explicitly changed */ *theoraConfigOutput.get() = *theoraConfigInput.get(); if (wishList.changeVideoDatarate) { if (theoraConfigInput->videoBitrate != wishList.videoDatarate) { theoraConfigOutput->videoBitrate = wishList.videoDatarate; theoraConfigOutput->videoQuality = 0; } } if (wishList.changeVideoQuality) { if (theoraConfigInput->videoQuality != wishList.videoQuality) { theoraConfigOutput->videoBitrate = 0; theoraConfigOutput->videoQuality = wishList.videoQuality; } } if (wishList.changeSize) { if ( (theoraConfigInput->pictureX != wishList.width ) || (theoraConfigInput->pictureY != wishList.height ) || (theoraConfigInput->aspectRatioNum != 1 ) || (theoraConfigInput->aspectRatioDenom != 1 )) { theoraConfigOutput->pictureX = wishList.width; theoraConfigOutput->pictureY = wishList.height; theoraConfigOutput->frameX = (theoraConfigOutput->pictureX+15)&~0xF; theoraConfigOutput->frameY = (theoraConfigOutput->pictureY+15)&~0xF; // We force the offset to be even. // This ensures that the chroma samples align properly with the luma // samples. theoraConfigOutput->frameXOffset = ((theoraConfigOutput->frameX - theoraConfigOutput->pictureX)/2)&~1; theoraConfigOutput->frameYOffset = ((theoraConfigOutput->frameY - theoraConfigOutput->pictureY)/2)&~1; /* no reason for using another aspect ratio than 1:1, are there? */ theoraConfigOutput->aspectRatioDenom = 1; theoraConfigOutput->aspectRatioNum = 1; } } if (wishList.changeFramerate) { if ( ( (theoraConfigOutput->framerateNum != wishList.framerateNum ) || (theoraConfigOutput->framerateDenom != wishList.framerateDenom ) ) && ( (theoraConfigOutput->framerateNum*1.0 ) / (theoraConfigOutput->framerateDenom*1.0 ) != (wishList.framerateNum*1.0 ) / (wishList.framerateDenom*1.0 ) )) { theoraConfigOutput->framerateNum = wishList.framerateNum; theoraConfigOutput->framerateDenom = wishList.framerateDenom; } } } void analyseAudioTranscoding(WishList& wishList, std::shared_ptr vorbisConfigInput, std::shared_ptr vorbisConfigOutput) { /* first we believe the output should be equal for all * parameters, that are not explicitly changed */ *vorbisConfigOutput.get() = *vorbisConfigInput.get(); if (wishList.changeAudioDatarate) { if (vorbisConfigOutput->datarate != wishList.audioDatarate) { vorbisConfigOutput->datarate = wishList.audioDatarate; } } if (wishList.changeAudioSamplerate) { if (vorbisConfigOutput->samplerate != wishList.audioSamplerate) { vorbisConfigOutput->samplerate = wishList.audioSamplerate; } } if (wishList.changeAudioChannels) { if (vorbisConfigOutput->channels != wishList.audioChannels) { vorbisConfigOutput->channels = wishList.audioChannels; } } return; } int oggTranscodeCmd(int argc, char* argv[]) { bool copyTheora( true); bool copyVorbis( true); WishList wishList; std::vector videoComments; std::vector audioComments; bool forceVideoReencode(false); bool forceAudioReencode(true); bool existenceTest(true); std::vector blendListBefore; std::vector blendListAfter; std::string programName(argv[0]); std::string inputFile; std::string outputFile; srand( (int) time(0) ); int opt; while ( (opt = getopt(argc, argv, "hs:f:d:tD:c:C:N:F:a:A:q:p:xr:o:Q:") ) != EOF) switch (opt) { case 'h': case '?': printHelpScreen(programName); exit( -1); case 'a': { CmdlineExtractor::extractBlend(blendListBefore, optarg, ':', ','); copyTheora = false; } break; case 'A': { CmdlineExtractor::extractBlend(blendListAfter, optarg, ':', ','); copyTheora = false; } break; case 'Q': { uint8 _quality = boost::lexical_cast(optarg); if (_quality < 1) _quality = 1; if (_quality > 5) _quality = 5; // non linear switch (_quality) { case 1: wishList.quality = 2; break; case 2: wishList.quality = 3; break; case 3: wishList.quality = 4; break; case 4: wishList.quality = 6; break; case 5: wishList.quality = 10; break; } break; } case 'q': { wishList.changeVideoQuality = true; wishList.videoQuality = boost::lexical_cast(optarg); break; } case 's': { std::deque framesize; CmdlineExtractor::extractUint32(framesize, optarg, 'x'); if (framesize.size() != 2) { logger.error() << "please specify the size in the following way: -s320x480\n"; exit( -1); } wishList.changeSize = true; wishList.width = framesize[0]; wishList.height = framesize[1]; } break; case 'f': { std::deque framerate; CmdlineExtractor::extractUint32(framerate, optarg, ':'); if (framerate.size() == 1) { wishList.changeFramerate = true; wishList.framerateNum = framerate[0]; wishList.framerateDenom = 1; break; } if (framerate.size() == 2) { wishList.changeFramerate = true; wishList.framerateNum = framerate[0]; wishList.framerateDenom = (framerate[1] == 0 ) ? 1 : framerate[1]; break; } logger.error() << "please specify the framerate in the following way -f25:2 or -f24\n"; exit( -1); } break; case 'd': wishList.changeVideoDatarate = true; wishList.videoDatarate = boost::lexical_cast(optarg); break; case 'D': wishList.changeAudioDatarate = true; wishList.audioDatarate = boost::lexical_cast(optarg); break; case 'c': CmdlineExtractor::extractCommentPairs(videoComments, optarg, ';', '='); break; case 'C': CmdlineExtractor::extractCommentPairs(audioComments, optarg, ';', '='); break; case 'N': wishList.changeAudioChannels = true; wishList.audioChannels = boost::lexical_cast(optarg); if ( (wishList.audioChannels != 1 ) && (wishList.audioChannels != 2 )) wishList.changeAudioChannels = false; break; case 'F': wishList.changeAudioSamplerate = true; wishList.audioSamplerate = boost::lexical_cast(optarg); break; case 't': wishList.stretch = true; break; case 'p': wishList.preview = boost::lexical_cast(optarg); wishList.ignoreVorbis = true; break; case 'r': if (optarg[0] == 'v') forceVideoReencode = true; if (optarg[0] == 'a') forceAudioReencode = true; break; case 'x': existenceTest = false; break; case 'o': outputFile = std::string(optarg); break; } argc -= optind; argv += optind; if (existenceTest && check_file_exists(outputFile)) exit(0); if (outputFile.empty() && (argc == 2)) { inputFile = std::string(argv[0]); outputFile = std::string(argv[1]); } else { if (!outputFile.empty() && (argc == 1)) inputFile = std::string(argv[0]); else { printHelpScreen(programName); return ( -1 ); } } /* create configuration */ StreamSerializer inStream; if ( !inStream.open(inputFile) ) { logger.error() << "can not open file <"<\n"; return ( -1 ); } /* load all png pictures that should later be used */ for (uint32 i(0); i demuxerInformation; /* read in the stream configuration that are avalable in this stream * The information, we need is the stream ID and the corresponding * stream type everything else is not needed */ inStream.getStreamConfig(demuxerInformation); /* Please notice! */ /* At this time, the stream Information are extracted from the header * in further analysation, we will replace these information * by the more accurate information created by the decoder */ /* we create a vector for the input stream and set every * value to 255 (means: ignore this stream). * If the stream is used, the value added is the stream, where this * input stream should be mapped to */ std::vector streamMap; streamMap.resize(demuxerInformation.size(), 255); /* These are the information ordered, by the stream IDs from the input stream */ std::vector > hookList; std::vector muxerInformation; bool foundTheora( false); bool foundVorbis( false); uint8 streamCounter( 0); FileRepository* repository = new FileRepository( outputFile, MediaUnit::write ); for (uint32 i( 0); i theoraEncoderConfig; std::shared_ptr theoraDecoderConfig; std::shared_ptr vHook = std::make_shared(streamCounter, false, true ); /* configure the video hook */ vHook->configureProcess(videoHookConfig); hookList.push_back(vHook); /* We only need these information for the information printout */ std::vector decoderComments; /* configure encoder config (StreamConfig/OggComment here) */ vHook->setDecoderConfig(decoderConfig, decoderComments); /* grap the information extracted by the decoder */ theoraDecoderConfig = std::dynamic_pointer_cast(decoderConfig.parameter); /* create a config for the output stream and keep a pointer */ theoraEncoderConfig = std::make_shared(); /* add the pointer to the configuration */ encoderConfig.parameter = theoraEncoderConfig; analyseVideoTranscoding(wishList, theoraDecoderConfig, theoraEncoderConfig); if (forceVideoReencode) vHook->forceReencoding(); /* the decoder Comments are used as well in case, keepComments * is set within the HookHandler */ vHook->setEncoderConfig(encoderConfig, videoComments); /* calculate how to handle the input, to create the correct output */ vHook->initAndConnect(); /* the configuration ID must match the stream ID */ muxerInformation.push_back(encoderConfig); /* set the stream ID, to which this stream should be maped to */ streamMap[i] = streamCounter; streamCounter++; } else { logger.warning() << "oggResize found more than one theora stream, only the first stream is handled\n"; } continue; } if (decoderConfig.type == OggType::vorbis) { if (!foundVorbis) { StreamConfig encoderConfig; std::shared_ptr vorbisEncoderConfig; std::shared_ptr vorbisDecoderConfig; foundVorbis = true; std::shared_ptr aHook = std::make_shared(streamCounter, false, true ); hookList.push_back(aHook); /* We only need these information for the information printout */ std::vector decoderComments; /* configure encoder config (StreamConfig/OggComment here) */ aHook->setDecoderConfig(decoderConfig, decoderComments); /* create a config for this stream */ vorbisEncoderConfig = std::make_shared(); /* */ vorbisDecoderConfig = std::dynamic_pointer_cast(decoderConfig.parameter); /* */ encoderConfig.parameter = vorbisEncoderConfig; analyseAudioTranscoding(wishList, vorbisDecoderConfig, vorbisEncoderConfig); /* the decoder Comments are used as well in case, keepComments * is set within the HookHandler */ aHook->setEncoderConfig(encoderConfig, videoComments); /* calculate how to handle the input, to create the correct output */ aHook->initAndConnect(); muxerInformation.push_back(encoderConfig); /* set the stream ID, to which this stream should be maped to */ streamMap[i] = streamCounter; streamCounter++; } else { logger.warning() << "oggResize found more than one vorbis stream, only the first stream is handled\n"; } continue; } logger.warning() << "There is actually no stream handler available to resize stream "<< decoderConfig.streamNo<<"\n"; } /* configure stream hook */ logger.info() << "Input Configuration: " << std::endl << "-------------------- " << std::endl; for (uint32 i(0); i< hookList.size(); ++i) { logger.info() << hookList[i]->decoderConfiguration() << std::endl; } logger.info() << "Output Configuration: " << std::endl << "--------------------- " << std::endl; for (uint32 i(0); i< hookList.size(); ++i) { logger.info() << hookList[i]->encoderConfiguration() << std::endl; } StreamMux streamCreate ( repository ); streamCreate.configureStreams ( muxerInformation ); streamCreate.recreatePacketPosition(false); /* run through the stream */ OggPacket packet; double time; while (inStream.available() ) { time = inStream.getNextPacket(packet); logger.info() << " "<getStreamNo()]; if (hookStreamID == 255) continue; HookHandler& hook(*hookList[hookStreamID]); hook << packet; while (hook.available()) { hook >> packet; streamCreate << packet; } } /* flush all data */ for (uint32 i(0); iflush(); while (hookList[i]->available()) { (*hookList[i]) >> packet; streamCreate << packet; } } /* set end of stream and do everything neccessary */ streamCreate.setEndOfStream(); streamCreate.close(); inStream.close(); logger.info() << std::endl; return(0); } int main(int argc, char* argv[]) { try { return oggTranscodeCmd(argc, argv); } catch (OggException & e) { logger.error() << "Fatal error: " << e.what() << std::endl; return -1; } } oggvideotools-0.9.1/src/binaries/oggDump.cpp000664 001750 001750 00000022474 12763227102 021305 0ustar00embedembed000000 000000 /* * oggDump will dump out an ogg file either by packets or by pages * * Copyright (C) 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. * */ #ifdef __WIN32 #define __GNU_LIBRARY__ #include "../win32/getopt_win.h" #endif #include #include #include #include #include #include #include #include #include "fileRepository.h" #include "rawMediaPacket.h" #include "oggDecoder.h" #include "oggEncoder.h" #include "oggStreamDecoder.h" #include "oggPacket.h" #include "oggBOSExtractorFactory.h" #include "streamSerializer.h" #include "exception.h" #include "log.h" struct OutputUnit { OggEncoder encoder; FileRepository repository; }; void printHelp(std::string programName) { logger.error() << "usage <"< [options] file" << std::endl; logger.error() << "Options are:\n" << " -h : help screen \n" << " -g : dump pages \n" << " -p : dump packets \n" << " -l : information depth; default: 5 (most information)\n" << " -s : promt for streams to dump\n" << " -o : output dump information to a file\n"; } void dumpPacketof(std::string& file, uint8 dumpLevel, bool promptForStreams, std::string& outFilename) { /* open the first file to be read */ std::vector configList; StreamSerializer serializer; std::ofstream outStream; /* if there is a filename given, write the data to this file */ if (!outFilename.empty()) outStream.open(outFilename.c_str()); if (!serializer.open(file)) { logger.error() << "Can not open file <" << file << ">\n"; exit(-1); } /* read the stream configuration */ serializer.getStreamConfig(configList); std::vector outputStreamNo; for (uint32 i(0); itoString(); if (promptForStreams) { std::cout << "Dump this stream? (y/n) \n"; char answer; std::cin >> answer; if (answer != 'Y' && answer != 'y') outputStreamNo.push_back(configList[i].streamNo); std::cout << answer << "\n"; } } OggPacket packet; double _time; bool print; while (serializer.available()) { _time = serializer.getNextPacket(packet); print = true; for (uint32 i(0); igetStreamNo()) print = false; if (!print) continue; if (outFilename.empty()) { std::cout << "\nTime: " << _time; std::cout << packet->toString(dumpLevel); } else { outStream << "\nTime: " << _time; outStream << packet->toString(dumpLevel); } } } int oggDumpCmd(int argc, char* argv[]) { /* default values * for the command line arguments */ uint8 dumpLevel(5); std::string outFilename(""); bool dumpPages(false); bool dumpPackets(false); bool promptForStreams(false); std::string programName(argv[0]); int opt; while ((opt = getopt(argc, argv, "hgpl:so:")) != EOF) switch (opt) { case 'h': printHelp(argv[0]); exit(-1); case 'g': dumpPages = true; break; case 'p': dumpPackets = true; break; case 's': promptForStreams = true; break; case 'o': outFilename = std::string(optarg); break; case 'l': dumpLevel = atoi(optarg); // yes, I know the atoi bug break; } argc -= optind; argv += optind; std::string analysisFile; if (argc == 1) analysisFile = std::string(argv[0]); else { printHelp(programName); exit(-1); } if ((!dumpPages) && (!dumpPackets)) { logger.error() << "Specify whether you want to dump pages, packet or both by -g and/or -p\n"; exit(-1); } if (dumpPackets) { dumpPacketof(analysisFile, dumpLevel, promptForStreams, outFilename); return(0); } std::ofstream outStream; /* if there is a filename given, write the data to this file */ if (!outFilename.empty()) outStream.open(outFilename.c_str()); /* open the m_repository in this easy example, it is a simple file */ FileRepository repository(analysisFile, MediaUnit::read); OggDecoder oggDecoder; std::map oggStreamDecoderList; std::vector bosPages; /* run through the m_repository until there is no data left */ while (!repository.isEndOfFile()) { RawMediaPacket rawDecoderPacket; /* extract a raw data bunch from the file .. */ repository >> rawDecoderPacket; /* .. and insert it into the ogg decoder */ oggDecoder << rawDecoderPacket; /* are there any complete ogg Pages available ? */ while (oggDecoder.isAvailable()) { OggPage oggPage; /* grap the next page */ oggDecoder >> oggPage; /* what ID has this page / what stream does this page belongs to */ uint32 serialID = oggPage->serialno(); if (oggPage->isBOS()) { bool addPage(false); switch (OggBOSExtractorFactory::getStreamType(oggPage)) { case OggType::theora: { std::cout << "Found theora stream with ID= 0x" << std::hex << serialID << std::dec << std::endl; if (promptForStreams) { std::cout << "Dump this stream? (y/n) \n"; char answer; std::cin >> answer; if (answer == 'Y' || answer == 'y') addPage = true; std::cout << answer << "\n"; } else addPage = true; } break; case OggType::vorbis: { std::cout << "Found vorbis stream with ID= 0x" << std::hex << serialID << std::dec << std::endl; if (promptForStreams) { std::cout << "Dump this stream? (y/n) "; char answer; std::cin >> answer; if (answer == 'Y' || answer == 'y') addPage = true; std::cout << answer << "\n"; } else addPage = true; } break; case OggType::kate: { std::cout << "Found kate stream with ID= 0x" << std::hex << serialID << std::dec << std::endl; if (promptForStreams) { std::cout << "Dump this stream? (y/n) "; char answer; std::cin >> answer; if (answer == 'Y' || answer == 'y') addPage = true; std::cout << answer << "\n"; } else addPage = true; } break; default: { std::cout << "Found unknown stream with ID= 0x" << std::hex << serialID << std::dec << std::endl; if (promptForStreams) { std::cout << "Dump this stream? (y/n) \n"; char answer; std::cin >> answer; if (answer == 'Y' || answer == 'y') addPage = true; std::cout << answer << "\n"; } else addPage = true; } break; } if (addPage) { oggStreamDecoderList[serialID] = OggStreamDecoder(); oggStreamDecoderList[serialID] << oggPage; bosPages.push_back(oggPage); } } else { /* does the user want to dump this stream */ if (oggStreamDecoderList.find(serialID) != oggStreamDecoderList.end()) { if (dumpPages) { std::string outputString; // are there any bos pages, then toString them first if (!bosPages.empty()) { for (uint32 j(0); jtoString(dumpLevel); bosPages.clear(); } outputString += oggPage->toString(dumpLevel); if (outFilename.empty()) std::cout << outputString; else outStream << outputString; } } } } } /* close all files */ repository.close(); if (!outFilename.empty()) outStream.close(); return (0); } int main(int argc, char* argv[]) { //logger.setLevel(OggLog::LOG_DEBUG); try { return oggDumpCmd(argc, argv); } catch (OggException & e) { logger.error() << "Fatal error: " << e.what() << std::endl; return -1; } } oggvideotools-0.9.1/src/ovt_kate/000775 001750 001750 00000000000 12763227102 017206 5ustar00embedembed000000 000000 oggvideotools-0.9.1/src/libresample/libresample.h000664 001750 001750 00000002165 12763227102 022345 0ustar00embedembed000000 000000 /********************************************************************** resample.h Real-time library interface by Dominic Mazzoni Based on resample-1.7: http://www-ccrma.stanford.edu/~jos/resample/ License: LGPL - see the file LICENSE.txt for more information **********************************************************************/ #ifndef LIBRESAMPLE_INCLUDED #define LIBRESAMPLE_INCLUDED #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ void *resample_open(int highQuality, double minFactor, double maxFactor); void *resample_dup(const void *handle); int resample_get_filter_width(const void *handle); int resample_process(void *handle, double factor, float *inBuffer, int inBufferLen, int lastFlag, int *inBufferUsed, float *outBuffer, int outBufferLen); void resample_close(void *handle); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* LIBRESAMPLE_INCLUDED */ oggvideotools-0.9.1/src/ovt_theora/theoraDecoder.cpp000664 001750 001750 00000027014 12763227102 023024 0ustar00embedembed000000 000000 /* * TheoraDecoder wrapper * * Copyright (C) 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. * */ #include "theoraDecoder.h" #include #ifdef HAVE_LIBTHEORADEC #include "theoraStreamParameter.h" #include "exception.h" #include #include #include #include #include #include #include "exception.h" #include "log.h" TheoraDecoder::TheoraDecoder(uint8 _streamID) : MediaOutputDecoder(_streamID), setupInfo(NULL), theoraDecState(NULL), initCount(0) { } TheoraDecoder::~TheoraDecoder() { clear(); } void TheoraDecoder::clear() { if (isConfigured()) { /* delete all packets, that may be left within the queue */ packetList.clear(); /* clean up everything regarding the decoding process */ th_setup_free(setupInfo); setupInfo=0; th_decode_free(theoraDecState); theoraDecState=0; th_info_clear(&theoraInfo); th_comment_clear(&theoraComment); setFree(); } } void TheoraDecoder::initDecoder(StreamConfig& config, std::vector& oggComments) { if (isConfigured()) throw OggException("TheoraDecoder::initDecoder: could not configure twice"); /* initialize the info and comment handler structs */ th_info_init(&theoraInfo); th_comment_init(&theoraComment); /* initialize the packet counter */ packetCount = 0; /* configure the decoders */ for (uint8 i(0); igetUnderlayingOggPacketPtr()); if (retVal <= 0) { // TODO: cleanup everything that has been set up until now th_comment_clear(&theoraComment); if (retVal == 0) { // There was a video packet in config.headerList. This should not happen, // because we only read 3 packets (numOfHeaderPackets) throw OggException("TheoraDecoder::initDecoder: unexpected video packet"); } else { reportTheoraError(retVal); } } } /* extract the comments */ for (uint8 i(0); iINT_MAX/theoraInfo.frame_width) || ((theoraInfo.frame_width*theoraInfo.frame_height) >= maxVideoPlaneSize)) { throw OggException("TheoraDecoder::initDecoder: could not set up decoder, frame is too big"); } theoraDecState = th_decode_alloc(&theoraInfo, setupInfo); if (theoraDecState == NULL) { throw OggException("TheoraDecoder::initDecoder: th_decode_alloc failed"); } TheoraStreamParameter& theoraConfig = dynamic_cast(*config.parameter.get()); theoraConfig.aspectRatioDenom = theoraInfo.aspect_denominator; theoraConfig.aspectRatioNum = theoraInfo.aspect_numerator; theoraConfig.colorspace = (TheoraStreamParameter::ColorSpace) theoraInfo.colorspace; theoraConfig.framerateDenom = theoraInfo.fps_denominator; theoraConfig.framerateNum = theoraInfo.fps_numerator; theoraConfig.pictureX = theoraInfo.pic_width; theoraConfig.pictureY = theoraInfo.pic_height; theoraConfig.frameX = theoraInfo.frame_width; theoraConfig.frameY = theoraInfo.frame_height; theoraConfig.frameXOffset = theoraInfo.pic_x; theoraConfig.frameYOffset = theoraInfo.pic_y; theoraConfig.keyframeShift = theoraInfo.keyframe_granule_shift; theoraConfig.pixel_fmt = (TheoraStreamParameter::PixFormat) theoraInfo.pixel_fmt; theoraConfig.videoBitrate = theoraInfo.target_bitrate; theoraConfig.videoQuality = theoraInfo.quality; /* set the state machine */ setConfigured(); } MediaOutputDecoder& TheoraDecoder::operator<<(OggPacket packet) { /* if the stream is not initialized, initialize the first structs */ if (!isConfigured()) throw OggException("TheoraDecoder::initDecoder: Theora decoder is not configured"); /* while inserting data into the stream, we do not * decode. We just store the packets and will decode them * on demand */ packetList.push_back(packet); /* has there not been a packet in the queue before */ if (isEmpty()) { /* set the internal state */ setAvailable(); } /* count the video packets, to have a gimps of the actual position */ packetCount++; return(*this); } bool TheoraDecoder::isNextPacketKeyframe() { return ((th_packet_iskeyframe(packetList.front()->getUnderlayingOggPacketPtr()) == 1)); } bool TheoraDecoder::isPacketKeyframe(OggPacket packet) { return ((th_packet_iskeyframe(packet->getUnderlayingOggPacketPtr()) == 1)); } uint32 TheoraDecoder::getPositionOfNextPacket() { if (isEmpty()) return (0xFFFFFFFF); return (packetCount - packetList.size()); } TheoraDecoder& TheoraDecoder::operator>>(th_ycbcr_buffer& picture) { if (!isConfigured()) throw OggException("TheoraDecoder::operator>>: Theora decoder is not configured"); if (isEmpty()) throw OggException("TheoraDecoder::operator>>: No packet available"); /* get the first packet from the packet list */ OggPacket packet = packetList.front(); packetList.pop_front(); /* insert the packet into the theora decoder */ ogg_int64_t dummy; int result; result = th_decode_packetin(theoraDecState, packet->getUnderlayingOggPacketPtr(), &dummy); if (result != 0 && result != TH_DUPFRAME) { reportTheoraError(result); } /* finally decode the picture */ result = th_decode_ycbcr_out(theoraDecState, picture); if (result != 0) { reportTheoraError(result); } if (packetList.empty()) { setEmpty(); } return(*this); } /*std::string TheoraDecoder::getInfoString() { std::stringstream stream; if (!isConfigured()) { logger.error() << "TheoraDecoder::operator>>: Theora Stream is not initialized\n"; return (stream.str()); } stream << std::endl; stream << "Size : " << theoraInfo.pic_width << ":" << theoraInfo.pic_height << " (Frame Size : " << theoraInfo.frame_width << ":" << theoraInfo.frame_height << " ; Offset: "<>(RGBPlane& plane); virtual bool available(); virtual void accept(EffectorVisitor& visitor) const; }; #endif /* SHIFTEFFECT_H_ */ oggvideotools-0.9.1/src/base/streamConfig.h000664 001750 001750 00000001177 12763227102 021104 0ustar00embedembed000000 000000 #ifndef STREAMCONFIG_H_ #define STREAMCONFIG_H_ #include #include "oggPacket.h" #include "streamExtractor.h" /* this configuration gives all information, that the outside world needs * to know about the streams */ class StreamConfig : public ExtractorInformation { public: //! Id of the stream (starts from 0 and is incremented by every new stream) int8 streamNo; //! Every stream needs some header packets, which are stored here /*! at least one "Begin of Stream" packet and maybe some additional packets. These * will all be stored here */ std::vector headerList; }; #endif oggvideotools-0.9.1/000775 001750 001750 00000000000 12763227262 014612 5ustar00embedembed000000 000000 oggvideotools-0.9.1/src/misc/helper.h000664 001750 001750 00000000255 12763227102 017757 0ustar00embedembed000000 000000 #ifndef helper_h #define helper_h #include //! returns true, if file exists and should not be overwritten bool check_file_exists (std::string& filename); #endif oggvideotools-0.9.1/src/base/oggEncoder.cpp000664 001750 001750 00000005441 12763227102 021070 0ustar00embedembed000000 000000 /* * OggEncoder * * Copyright (C) 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. * */ #include #include #include "oggEncoder.h" #include "log.h" PageBufferElement::PageBufferElement() : time(-1), empty(true), interpreter(0) { } PageBufferElement::~PageBufferElement() { } OggEncoder::OggEncoder() : withBuffer(false) { setConfigured(); } OggEncoder::~OggEncoder() { } /* void OggEncoder::createJitterBuffer(uint8 numOfStreams) { if (numOfStreams) { oggBuffer.resize(numOfStreams); withBuffer = true; } } */ void OggEncoder::flush() { } void OggEncoder::serializePage(OggPage& page) { rawPacketList.push_back(std::make_shared(page->data(), true)); setAvailable(); } void OggEncoder::insertNextPage(OggPage& page) { } OggEncoder& OggEncoder::operator<<(OggPage page) { if (!withBuffer) { serializePage(page); return(*this); } /* uint8 m_streamNo(page->getStreamNo()); double time(oggBuffer[m_streamNo].interpreter->getTime(page->granulepos())); double nextTime(-2); uint8 nextStreamNo(0); while(!oggBuffer[m_streamNo].m_empty) { // find the next packet to send out for(uint32 i(0); i oggBuffer[i].time)) { nextTime = oggBuffer[i].time; nextStreamNo = i; } } // write page to the output buffer serializePage(oggBuffer[nextStreamNo].page); // ... and mark the buffer as m_empty oggBuffer[nextStreamNo].m_empty = true; } // insert the page into the buffer oggBuffer[m_streamNo].page = page; oggBuffer[m_streamNo].time = time; oggBuffer[m_streamNo].m_empty = false; */ return(*this); } OggEncoder& OggEncoder::operator>>(RawMediaPacket& packet) { if (isEmpty()) { logger.error() << "OggEncoder::operator>>: no packet available\n"; return(*this); } packet = rawPacketList.front(); rawPacketList.pop_front(); if (rawPacketList.empty()) setEmpty(); return(*this); } oggvideotools-0.9.1/testvideos/getVideos.sh000775 001750 001750 00000001372 12763227102 021267 0ustar00embedembed000000 000000 #!/bin/sh wget http://v2v.cc/~j/theora_testsuite/320x240.ogg wget http://v2v.cc/~j/theora_testsuite/320x240.ogv wget http://v2v.cc/~j/theora_testsuite/pixel_aspect_ratio.ogg wget http://v2v.cc/~j/theora_testsuite/videotestsrc-720x576-16-15.ogg wget http://v2v.cc/~j/theora_testsuite/322x242_not-divisible-by-sixteen-framesize.ogg # wget http://v2v.cc/~j/theora_testsuite/chained_streams.ogg wget http://v2v.cc/~j/theora_testsuite/mobile_itu601_i_422.ogg wget http://v2v.cc/~j/theora_testsuite/ducks_take_off_444_720p25.ogg wget http://v2v.cc/~j/theora_testsuite/stockholm-vfr.ogg wget http://v2v.cc/~j/theora_testsuite/offset_test.ogv wget http://v2v.cc/~j/theora_testsuite/sign_irene_cif-3qi-b.ogg wget http://v2v.cc/~j/theora_testsuite/chroma_siting_test.ogv oggvideotools-0.9.1/src/ovt_vorbis/vorbisEncoder.h000664 001750 001750 00000002057 12763227102 022547 0ustar00embedembed000000 000000 #ifndef VORBISENCODER_H_ #define VORBISENCODER_H_ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_LIBVORBIS #include #include #include #include #include "mediaInputEncoder.h" #include "oggPacket.h" #include "audioPacket.h" #include "oggComment.h" #include "vorbisStreamParameter.h" #include "streamConfig.h" class VorbisEncoder : public MediaInputEncoder { protected: vorbis_info vorbisInfo; vorbis_comment vorbisComment; vorbis_dsp_state vorbisState; vorbis_block vorbisBlock; // OggPacket packet; std::list packetList; uint64 pktCnt; public: VorbisEncoder(uint8 streamNo); virtual ~VorbisEncoder(); virtual MediaInputEncoder& operator>>(OggPacket& packet); MediaInputEncoder& operator<<(AudioPacket& aPacket); virtual void configureEncoder(StreamConfig& streamConf, std::vector& oggComments); void flush(); vorbis_info& getInfo(); virtual std::string configuration() const; }; #endif /* HAVE_LIBVORBIS */ #endif /* VORBISENCODER_H_*/ oggvideotools-0.9.1/src/ovt_theora/theoraExtractor.cpp000664 001750 001750 00000006334 12763227102 023434 0ustar00embedembed000000 000000 #include #include #include "theoraExtractor.h" #include "oggHeader.h" #include "theoraHeader.h" #include "theoraStreamParameter.h" #include "log.h" TheoraExtractor::TheoraExtractor() { } TheoraExtractor::~TheoraExtractor() { } bool TheoraExtractor::_extract(uint8* data, ExtractorInformation& info) { StreamType* streaminfo = (StreamType*) (data); TheoraHeader* theoraHeader = (TheoraHeader*) (data + sizeof(StreamType)); /* if this is not a theora header, return with an error */ if ((streaminfo->headerType != 0x80) || (strncmp(streaminfo->typeName, "theora", 6) != 0)) { logger.error() << "TheoraPosInterpreter::initialize: This page is not a theora bos\n"; return(false); } // first extract the parameters std::shared_ptr param = std::make_shared(); // for all the calculation, we need to convert some fields theoraHeader->un.pleaseconvert = convert16(theoraHeader->un.pleaseconvert); param->framerateNum = convert32(theoraHeader->frn); param->framerateDenom = convert32(theoraHeader->frd); param->pictureX = convert24(theoraHeader->picw); param->pictureY = convert24(theoraHeader->pich); param->aspectRatioNum = convert24(theoraHeader->parn); param->aspectRatioDenom = convert24(theoraHeader->parn); param->frameX = convert16(theoraHeader->fmbw)*16; param->frameY = convert16(theoraHeader->fmbh)*16; param->frameXOffset = theoraHeader->picx; param->frameYOffset = theoraHeader->picy; param->videoQuality = theoraHeader->un.lenbo.qual; param->videoBitrate = convert24(theoraHeader->nombr); param->keyframeShift = theoraHeader->un.lenbo.kfgshift; param->colorspace = (TheoraStreamParameter::ColorSpace) theoraHeader->cs; param->pixel_fmt = (TheoraStreamParameter::PixFormat) theoraHeader->un.lenbo.pf; // to have the original packet, we recover the data theoraHeader->un.pleaseconvert = convert16(theoraHeader->un.pleaseconvert); info.parameter = param; /* set the ogg type and the number of header packets */ info.type = OggType::theora; info.numOfHeaderPackets = 3; // the first three packets are headers return(true); } bool TheoraExtractor::extract(OggPage& oggPage, ExtractorInformation& information) { /* if this is not a Begin Of Stream page, return immediately */ if (!oggPage->isBOS()) { logger.error() << "TheoraPosInterpreter::extract: This page is not a BOS (Begin Of Stream) page\n"; return(false); } uint8_t* dataPtr = &(oggPage->data())[0]; /* get the information starting points within the raw data */ OggHeader* oggHeader = (OggHeader*) dataPtr; uint8* data = dataPtr + sizeof(OggHeader) + oggHeader->tableSegments; if (!_extract(data, information)) return(false); information.serialNo = oggHeader->serial; return(true); } bool TheoraExtractor::extract(OggPacket& packet, ExtractorInformation& information) { // if this is not a Begin Of Stream page, return immediately if (!packet->isBOS()) { logger.error() << "TheoraPosInterpreter::extract: This packet is not a BOS (Begin Of Stream) page\n"; return(false); } return _extract(packet->data(), information); } oggvideotools-0.9.1/src/main/oggBOSExtractorFactory.h000664 001750 001750 00000001554 12763227102 023040 0ustar00embedembed000000 000000 #ifndef OGGBOSEXTRACTORFACTORY_H_ #define OGGBOSEXTRACTORFACTORY_H_ #include "oggTypes.h" #include "granulePosInterpreter.h" //#include "oggMediaStream.h" #include "streamExtractor.h" class OggBOSExtractorFactory { public: OggBOSExtractorFactory(); virtual ~OggBOSExtractorFactory(); /* static MediaDecoder* createStreamDecoder(ExtractorInformation& information); static MediaDecoder* createStreamEncoder(ExtractorInformation& information); */ static bool extractInformation(OggPage& page, ExtractorInformation& information); static bool extractInformation(OggPacket& packet, ExtractorInformation& information); static GranulePosInterpreter* extractPositionInterpreter(ExtractorInformation& information); static OggType getStreamType(OggPage& page); static OggType getStreamType(OggPacket& packet); }; #endif /*OGGBOSEXTRACTORFACTORY_H_*/ oggvideotools-0.9.1/src/effect/basePlane.cpp000664 001750 001750 00000001042 12763227102 021221 0ustar00embedembed000000 000000 // // C++ Implementation: basePlane // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #include "basePlane.h" BasePlane::BasePlane() : width(0), height(0), plane(0) { } BasePlane::BasePlane(uint32 _width, uint32 _height, uint32 color) : width(_width), height(_height), plane(new uint8[_height*_width*4]) { uint32* ptr((uint32*)plane); for (uint32 i(0); i<(_height*_width); ++i) ptr[i] = color; } BasePlane::~BasePlane() { delete[] plane; } oggvideotools-0.9.1/src/ovt_kate/kateHeader.h000664 001750 001750 00000001062 12763227102 021413 0ustar00embedembed000000 000000 #ifndef KATEHEADER_H_ #define KATEHEADER_H_ struct KateHeader { uint8 magic0; uint8 reserved0; uint8 versionMajor; uint8 versionMinor; uint8 numHeaders; uint8 textEncoding; uint8 textDirectionality; uint8 reserved1; uint8 granuleShift; uint16 canvasWidthShift:4; uint16 canvasWidthBase:12; uint16 canvasHeightShift:4; uint16 canvasHeightBase:12; uint32 reserved2; uint32 granulerateNumerator; uint32 granulerateDenominator; char language[16]; char category[16]; } __attribute__ ((packed)); #endif /*KATEHEADER_H_*/ oggvideotools-0.9.1/src/binaries/oggCut.cpp000664 001750 001750 00000021152 12763227102 021123 0ustar00embedembed000000 000000 /* * oggCut is a command line tool, to cut a video stream * * Copyright (C) 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. * */ #ifdef __WIN32 #define __GNU_LIBRARY__ #include "../win32/getopt_win.h" #endif #include #include #include #include #include #include #include "fileRepository.h" #include "streamSerializer.h" #include "streamMux.h" #include "oggEncoder.h" #include "oggStreamEncoder.h" #include "exception.h" #include "log.h" struct ListElement { double time; OggPacket packet; ListElement(double _time, OggPacket _packet) : time(_time), packet(_packet) { } }; static std::list packetList; static double bufferTime(0.5); // buffer 500 ms uint32 _atoi(const char* data) { std::stringstream stream; uint32 value; stream << data; stream >> value; return(value); } void printHelpScreen(const std::string& progName) { logger.error() << "usage: "<< progName << "[options] \n" << "or : "<< progName << "[options] -i -o \n" << " -- package and version \"" << PACKAGE_STRING << "\"\n\n" << "Options are:\n" << " -s time : Start time in milliseconds from start\n" << " if no start time is given, 0 is assumed\n" << " -e time : End time in milliseconds\n" << " if no end time or -1 is given, the end of the\n" << " file is assumed\n" << " -l length : Length of the cut area\n" << " -i input : Input file (alternative) \n" << " -o output : Output file (alternative) \n"; } void bufferedOutput(StreamMux& streamMux, double time, OggPacket packet) { ListElement elem(time, packet); std::list::iterator iter(packetList.begin()); while ((iter != packetList.end()) && (elem.time < iter->time)) ++iter; packetList.insert(iter, elem); double lastTime(packetList.front().time); while ((lastTime - packetList.back().time) > bufferTime) { streamMux << packetList.back().packet; packetList.pop_back(); } } void flushBuffer(StreamMux& streamMux) { while (!packetList.empty()) { streamMux << packetList.back().packet; packetList.pop_back(); } } /* TODO: take offset into account * The offset should be taken into account, so that the audio stream is * exactly as long as the video. * */ int oggCutCmd(int argc, char* argv[]) { int32 startTime(0); int32 endTime(-1); int32 length(-1); std::string inputFile; std::string outputFile; std::string programName(argv[0]); srand(time(0)); int opt; while ((opt = getopt(argc, argv, "hi:o:s:e:l:")) != EOF) switch (opt) { case 'h': printHelpScreen(programName); exit(-1); case 'i': inputFile = std::string(optarg); break; case 'o': outputFile = std::string(optarg); break; case 's': startTime = _atoi(optarg); break; case 'e': endTime = _atoi(optarg); break; case 'l': length = _atoi(optarg); // yes, I know the atoi bug break; } argc -= optind; argv += optind; if ((argc > 2)) { printHelpScreen(programName); exit (-1); } if (argc > 0) { inputFile = std::string(argv[0]); } if (argc > 1) { outputFile = std::string(argv[1]); } /* Handle wrong parameter and parameter combinations */ if (inputFile.empty() || outputFile.empty()) { printHelpScreen(programName); exit (-1); } if (startTime < 0) { logger.error() << "Error: start time is invalid\n"; exit (-1); } if ((endTime > 0) && (length > 0)) { logger.warning() << "Warning: end time and length set, ignoring length\n"; } if (endTime == -1) { if (length > 0) { endTime = startTime + length; } else { if (startTime == 0) { logger.error() << "No need to cut, just use copy!\n"; exit (-1); } } } double startTimeSec(startTime*1.0/1000.0); double endTimeSec(endTime*1.0/1000.0); /* create a stream serializer */ StreamSerializer streamSerializer; bool foundTheora(false); /* try to open the file. If there is no such file, abort with a message */ if (!streamSerializer.open(inputFile)) { logger.error() << "Error: can not open file <"<\n"; exit (-1); } /* create a repository for the new files and give the repository to the stream Muxer */ FileRepository* outfile = new FileRepository(outputFile, MediaUnit::write); StreamMux streamMux(outfile); /* grep the configuration for all streams */ std::vector streamConfigList; streamSerializer.getStreamConfig(streamConfigList); /* create the time synchronizer, which holds the time offset for every stream */ std::vector offset(streamConfigList.size(),0.0); /* Output some stream information and reset the offset */ for (uint32 i(0); itoString(); if (streamConfigList[i].type == OggType::theora) foundTheora = true; offset[i] = -1; } /* configure the output streams */ streamMux.configureStreams(streamConfigList); /* */ OggPacket packet; double time; double beginTime(0); bool startMarker(false); /* copy the stream if the packets are within the cut area * and the first video keyframe has been found */ while (streamSerializer.available()) { /* get the actual packet and it's time information */ /* the time is meant to be the presentation start time */ time = streamSerializer.getNextPacket(packet); #ifdef DEBUG if (packet.getStreamType() == OggType::theora) { logger.debug() << "theora "; } if (packet.getStreamType() == OggType::vorbis) { logger.debug() << "vorbis "; } logger.debug() << time << std::endl; #endif /* look deeper into the packets, if the belong into the cutting * area */ if ((time >= startTimeSec) && (time < endTimeSec)) { /* are we within our cut interval and found the first keyframe? */ if (!startMarker) { /* we are doing packet analysation by ourselfs - may be changed */ if ((!foundTheora) || ((packet->getStreamType() == OggType::theora) &&(!(packet->data()[0] & 0x40)))) { startMarker = true; beginTime = time; offset[packet->getStreamNo()] = time; } } /* have we found the real starting position? */ if (startMarker) { /* if this stream has no offset calculated, do it now */ if (offset[packet->getStreamNo()] < 0) { offset[packet->getStreamNo()] = time; #ifdef DEBUG logger.debug() << "offset for stream No <"<<(int)packet.getStreamNo() <<"> is "<getStreamNo()] - beginTime <getStreamNo()]), packet); } } /* the end of the cut area has reached */ if (time >= endTimeSec) { break; } } /* first flush all buffers to be ordered correct */ flushBuffer(streamMux); /* set the end of the stream and close the file, * which flushed the all internal stream encoder to flush all pages */ streamMux.setEndOfStream(); streamMux.close(); /* close the stream serializer with a big thank you */ streamSerializer.close(); return(0); } int main(int argc, char* argv[]) { try { return oggCutCmd(argc, argv); } catch (OggException & e) { logger.error() << "Fatal error: " << e.what() << std::endl; return -1; } } oggvideotools-0.9.1/src/base/rawMediaPacket.cpp000664 001750 001750 00000003747 12763227102 021704 0ustar00embedembed000000 000000 /* * RawMediaPacket class to carry a raw bunch of data * * 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. * */ #include #include "rawMediaPacket.h" RawMediaPacketInternal::RawMediaPacketInternal() { } RawMediaPacketInternal::RawMediaPacketInternal(std::vector& _data, bool copy) { setData(_data, copy); } RawMediaPacketInternal::~RawMediaPacketInternal() { } const std::vector &RawMediaPacketInternal::getData() { return data; } void RawMediaPacketInternal::setData(std::vector& _data, bool copy) { // data = _data; if (copy) { data = _data; } else { data = std::move(_data); } } uint32 RawMediaPacketInternal::getSize() { return(data.size()); } /*********************************/ //RawMediaPacket::RawMediaPacket() //{ //} //RawMediaPacket::RawMediaPacket(const RawMediaPacket& packet) // : RefObject(packet) //{ //} //RawMediaPacket::RawMediaPacket(RawMediaPacketInternal* m_dataPtr) // : RefObject(m_dataPtr) //{ //} //RawMediaPacket::~RawMediaPacket() //{ //} //uint8* RawMediaPacket::getData(uint32& length) //{ // return(objPtr->getData(length)); //} //uint8* RawMediaPacket::getData() //{ // return(objPtr->getData()); //} //uint32 RawMediaPacket::size() //{ // return(objPtr->size()); //} oggvideotools-0.9.1/src/binaries/oggLength.cpp000664 001750 001750 00000006425 12763227102 021617 0ustar00embedembed000000 000000 /* * oggLength is a command line tool, to return the length of an ogg file * * Copyright (C) 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. * */ #ifdef __WIN32 #define __GNU_LIBRARY__ #include "../win32/getopt_win.h" #endif #include #include #include #include #include "fileRepository.h" #include "streamSerializer.h" #include "exception.h" #include "log.h" void printHelpScreen(std::string& progName) { logger.error() << "usage: " << progName << " \n"; } int oggLengthCmd(int argc, char* argv[]) { std::string inputFile; std::string programName(argv[0]); bool printVorbisExtra(false); bool printTheoraExtra(false); int opt; while ((opt = getopt(argc, argv, "hvtVT")) != EOF) switch (opt) { case 'h': printHelpScreen(programName); exit(-1); case 'v': case 'V': printVorbisExtra = true; break; case 't': case 'T': printTheoraExtra = true; break; } argc -= optind; argv += optind; if (argc == 1) inputFile = std::string(argv[0]); else { printHelpScreen(programName); exit(-1); } /* create the stream serializer */ StreamSerializer streamSerializer; /* open the file */ if (!streamSerializer.open(inputFile)) { logger.error() << "Error: can not open file <"<\n"; exit(-1); } /* create the headers */ std::vector streamConfigList; streamSerializer.getStreamConfig(streamConfigList); // for (uint32 i(0); itoString(); // } OggPacket packet; double timeVorbis; double timeTheora; double time; double retTime(-1); /* copy the stream if the packets are within the cut area * and the first video keyframe has been found */ while (streamSerializer.available()) { time = streamSerializer.getNextPacket(packet); if (time < 0) { break; } else if (packet->getStreamType() == OggType::theora) timeTheora = time; if (packet->getStreamType() == OggType::vorbis) timeVorbis = time; retTime = time; } std::cout << (int)(retTime*1000) << std::endl; if (printVorbisExtra) std::cout << " Vorbis End-Time (packet basis): " << (int)(timeVorbis*1000) << std::endl; if (printTheoraExtra) std::cout << " Theora End-Time : " << (int)(timeTheora*1000) << std::endl; return((int)(retTime*1000)); } int main(int argc, char* argv[]) { try { return oggLengthCmd(argc, argv); } catch (OggException & e) { logger.error() << "Fatal error: " << e.what() << std::endl; return -1; } } oggvideotools-0.9.1/src/effect/basePlane.h000664 001750 001750 00000001061 12763227102 020667 0ustar00embedembed000000 000000 // // C++ Interface: basePlane // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #ifndef BASEPLANE_H #define BASEPLANE_H #include "definition.h" /** BasePlane contains the picture information (width, height and picture plane) @author Yorn */ class BasePlane { public: uint32 width; uint32 height; uint8* plane; BasePlane(); BasePlane(uint32 _width, uint32 _height, uint32 color = 0x00000000 ); virtual ~BasePlane(); }; #endif oggvideotools-0.9.1/src/ovt_theora/theoraEncoder.cpp000664 001750 001750 00000024303 12763227102 023034 0ustar00embedembed000000 000000 /* * TheoraEncoder wrapper * * Copyright (C) 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. * */ #include "theoraEncoder.h" #ifdef HAVE_LIBTHEORADEC #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "exception.h" #include "log.h" TheoraEncoder::TheoraEncoder(uint8 _streamNo) : MediaInputEncoder(_streamNo), packetCounter(0) { th_comment_init(&theoraComment); } TheoraEncoder::~TheoraEncoder() { if (isConfigured()) th_encode_free(theoraState); th_info_clear(&theoraInfo); th_comment_clear(&theoraComment); } void TheoraEncoder::createHeader(std::vector& headerList, std::vector& oggComments) { int32 encodeRetID(1); th_comment_add_tag(&theoraComment,"ENCODER",PACKAGE_STRING); /* add other comments */ for (uint32 i(0); i 0) { ogg_packet tmpPkt; encodeRetID = th_encode_flushheader(theoraState, &theoraComment, &tmpPkt); //packet->getUnderlayingOggPacketPtr()); if (encodeRetID == TH_EFAULT) throw OggException("TheoraEncoder::operator <<: encoder or packet are NULL"); // ost::slog(ost::Slog::levelDebug) << "TheoraEncoder:: inserting header/n"; if (encodeRetID > 0) { OggPacket packet = std::make_shared(tmpPkt); #ifdef DEBUG logger.debug() << "Theora Packet Number: "<< packet.packetno << "reset to 0" << std::endl; #endif packet->setStreamType(OggType::theora); packet->setStreamNo(streamNo); packet->setStreamHeader(); packet->setPacketno(0); headerList.push_back(packet); } } } void TheoraEncoder::reset() { if (isConfigured()) { th_encode_free(theoraState); theoraState = th_encode_alloc(&theoraInfo); } } void TheoraEncoder::configureEncoder(StreamConfig& streamConf, std::vector& oggComments) { if (isConfigured()) throw OggException("TheoraEncoder::configureEncoder: can't configure encoder twice"); TheoraStreamParameter& config = dynamic_cast(*streamConf.parameter.get()); // Theora has a divisible-by-sixteen restriction for the encoded video size // scale the frame size up to the nearest /16 and calculate offsets config.frameX = (config.pictureX+15)&~0xF; config.frameY = (config.pictureY+15)&~0xF; // We force the offset to be even. // This ensures that the chroma samples align properly with the luma // samples. // config.frameXOffset = ((config.frameX - config.pictureX)/2)&~1; // config.frameYOffset = ((config.frameY - config.pictureY)/2)&~1; // config.frameXOffset = 0; // config.frameYOffset = 0; // let's initialize the theora encoder th_info_init(&theoraInfo); theoraInfo.pic_width = config.pictureX; theoraInfo.pic_height = config.pictureY; theoraInfo.frame_width = config.frameX; theoraInfo.frame_height = config.frameY; theoraInfo.pic_x = config.frameXOffset; theoraInfo.pic_y = config.frameYOffset; theoraInfo.fps_numerator = config.framerateNum; theoraInfo.fps_denominator = config.framerateDenom; theoraInfo.aspect_numerator = config.aspectRatioNum; theoraInfo.aspect_denominator = config.aspectRatioDenom; switch ( config.colorspace ) { case TheoraStreamParameter::ITU_470M: theoraInfo.colorspace = TH_CS_ITU_REC_470M; break; case TheoraStreamParameter::ITU_470BG: theoraInfo.colorspace = TH_CS_ITU_REC_470BG; break; default: theoraInfo.colorspace = TH_CS_UNSPECIFIED; break; } switch (config.pixel_fmt) { case TheoraStreamParameter::pf_420: theoraInfo.pixel_fmt = TH_PF_420; break; case TheoraStreamParameter::pf_422: theoraInfo.pixel_fmt = TH_PF_422; break; case TheoraStreamParameter::pf_444: theoraInfo.pixel_fmt = TH_PF_444; break; default: theoraInfo.pixel_fmt = TH_PF_420; // most likly this format break; } theoraInfo.target_bitrate = config.videoBitrate; theoraInfo.quality = config.videoQuality; theoraInfo.keyframe_granule_shift = config.keyframeShift; // 6 bit to distinguish interframes // TODO: Pixel Format should be available in config /* create a new theora encoder handle */ theoraState = th_encode_alloc(&theoraInfo); if (theoraState) setConfigured(); else throw OggException("TheoraEncoder::setConfig: Parameters invalid"); createHeader(streamConf.headerList, oggComments); streamConf.serialNo = (uint32) rand(); streamConf.streamNo = streamNo; streamConf.type = OggType::theora; streamConf.numOfHeaderPackets = (uint8) streamConf.headerList.size(); // reset the packet counter if encoder is reconfigured packetCounter = 0; } MediaInputEncoder& TheoraEncoder::operator >>(OggPacket& packet) { if (packetList.empty()) throw OggException("TheoraEncoder::operator >>: No PacketAvailable"); packet = packetList.front(); packetList.pop_front(); packet->setPacketno(packetCounter++); if (packetList.empty()) setEmpty(); return(*this); } MediaInputEncoder& TheoraEncoder::operator <<(th_ycbcr_buffer buffer) { if (!isConfigured()) throw OggException("TheoraEncoder::operator <<: codec not configured"); int32 errID; if ((errID = th_encode_ycbcr_in(theoraState, buffer)) != 0) { if (errID == TH_EFAULT) throw OggException("TheoraEncoder::operator <<: encoder or video buffer is NULL"); if (errID == TH_EINVAL) { logger.debug() << "Size of picture "< 0) { ogg_packet _packet; encodeRetID = th_encode_packetout(theoraState, 0, &_packet); /* Spec says: * _op An ogg_packet structure to fill. All of the elements of this structure will be set, * including a pointer to the video data. The memory for the video data is owned by libtheoraenc, * and may be invalidated when the next encoder function is called. * This means, data may be lost and cannot be used in a packet list, so we need to copy, * this really kills performance ... */ if (encodeRetID > 0) { OggPacket packet = std::make_shared(_packet); #ifdef DEBUG logger.debug() << "Theora Packet Number: "<< packet.packetno<setStreamType(OggType::theora); packet->setStreamNo(streamNo); packetList.push_back(packet); } } if (encodeRetID == TH_EFAULT) throw OggException("TheoraEncoder::operator <<: encoder or packet are NULL"); setAvailable(); return(*this); } uint32 TheoraEncoder::width() const { return(theoraInfo.pic_width); } uint32 TheoraEncoder::height() const { return(theoraInfo.pic_height); } th_info& TheoraEncoder::getInfo() { return(theoraInfo); } std::string TheoraEncoder::configuration() const { std::stringstream stream; stream << "Theora Encoder Configuration:"<, (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #include "rgbPlane.h" RGBPlane::RGBPlane() { } RGBPlane::~RGBPlane() { } RGBPlane::RGBPlane(uint32 width, uint32 height, uint32 color) : RefObject(new BasePlane(width, height, color)) { } oggvideotools-0.9.1/src/ovt_kate/katePosInterpreter.h000664 001750 001750 00000001617 12763227102 023216 0ustar00embedembed000000 000000 #ifndef KATEPOSINTERPRETER_H_ #define KATEPOSINTERPRETER_H_ #include "definition.h" #include "granulePosInterpreter.h" class KatePosInterpreter : public GranulePosInterpreter { protected: uint8 granuleShift; uint32 granulerateNumerator; uint32 granulerateDenominator; void extractFramePos(int64 granulePosition, int64& base, int64& offset); public: KatePosInterpreter(); virtual ~KatePosInterpreter(); uint32 getGranulerateNumerator(); uint32 getGranulerateDenominator(); uint8 getGranuleShift(); virtual void initialize(StreamParameter* parameter); virtual double getTime(int64 granulePos); //KatePosInterpreter& operator++(); virtual void setStreamPosition(OggPacket& packet); //virtual GranulePosInterpreter& operator+=(GranulePosInterpreter& position); virtual GranulePosInterpreter& operator-=(GranulePosInterpreter& position); }; #endif /*KATEPOSINTERPRETER_H_*/ oggvideotools-0.9.1/src/base/oggRingbuffer.h000664 001750 001750 00000002753 12763227102 021252 0ustar00embedembed000000 000000 /* * Ringbuffer to prebuffer an ogg file * * Copyright (C) 2005-2009 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) */ #ifndef oggRingbuffer_h #define oggRingbuffer_h #include "ringbuffer.h" #include "oggHeader.h" class OggRingbuffer : public ringbuffer { protected: void dump(); public: OggRingbuffer(uint32_t buffersize = 64000); OggRingbuffer(uint8_t* data, uint32_t len); ~OggRingbuffer(); bool getNextPageLength(uint32_t& length, int pageNum=1); bool getNextPage(uint8_t*& data, uint32_t& length); bool getNextPages(uint8_t*& data, uint32_t& length, uint32_t pageNum); bool getNextPages(std::vector &data, uint32_t &length, uint32_t size); bool getNextPage(std::vector &data, uint32_t &length); }; #endif oggvideotools-0.9.1/src/ovt_theora/theoraStreamParameter.h000664 001750 001750 00000001644 12763227102 024221 0ustar00embedembed000000 000000 #ifndef THEORASTREAMPARAMETER_H_ #define THEORASTREAMPARAMETER_H_ #include "definition.h" #include "streamParameter.h" class TheoraStreamParameter : public StreamParameter { public: enum PixFormat { pf_420, pf_rsvd, pf_422, pf_444 }; enum ColorSpace { unspecified, ITU_470M, ITU_470BG }; uint32 pictureX; uint32 pictureY; uint32 frameX; uint32 frameY; uint32 frameXOffset; uint32 frameYOffset; uint32 aspectRatioNum; uint32 aspectRatioDenom; uint32 framerateNum; uint32 framerateDenom; uint32 videoQuality; uint32 videoBitrate; uint8 keyframeShift; PixFormat pixel_fmt; ColorSpace colorspace; TheoraStreamParameter(); virtual ~TheoraStreamParameter(); virtual bool operator==(const StreamParameter& param); virtual std::string toString(); virtual StreamParameter* clone(); void calculateFrame(); }; #endif /*THEORASTREAMPARAMETER_H_*/ oggvideotools-0.9.1/src/effect/pictureResize.cpp000664 001750 001750 00000051776 12763227102 022207 0ustar00embedembed000000 000000 // // C++ Implementation: pictureResize // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #include "pictureResize.h" #include #include #include #include #include "exception.h" #include "log.h" #define INIT_CLIP int32 tmp #define CLIP(x,n) tmp = (int32)(x+0.5); \ if (tmp > 255) n=255; \ else if (tmp < 0) n=0; \ else n = (uint8)(tmp); #define MIN(x,y) (((x)<(y))?(x):(y)) #define MAX(x,y) (((x)<(y))?(y):(x)) PictureResize::PictureResize() { } PictureResize::~PictureResize() { } uint32 PictureResize::calculateKernelValue(RGBPlane& pic, float posX, float posY, float radius, bool p) { radius = sqrt(radius); uint32 xStart(MAX(0,posX-radius+0.5)); uint32 xEnd(MIN(posX+radius+0.5,(float)pic->width)); uint32 yStart(MAX(0,posY-radius+0.5)); uint32 yEnd(MIN(posY+radius+0.5,(float)pic->height)); float weightsCounter(0); float valueRed(0); float valueGreen(0); float valueBlue(0); float tmpWeight; float tmpDistance; uint32 position; uint32 positionHeight; #ifdef DEBUG uint32 counter1(0); uint32 overall(0); if (p) { logger.debug() << "kernel calculation at position "<"<width; for (uint32 j(xStart); j distance " < distance " < 4*pic->width*pic->height) { logger.error() << "Error: calculating for Position "<width << " x " << pic->height<<" Kernel window: "< "<plane[position]*tmpWeight; valueGreen += pic->plane[position+1]*tmpWeight; valueBlue += pic->plane[position+2]*tmpWeight; weightsCounter += tmpWeight; } } #ifdef DEBUG if (p) logger.debug() << " Unused: "<width)); uint32 yStart(MAX(0,posY-radius+0.5)); uint32 yEnd(MIN(posY+radius+0.5,(float)pic->height)); uint32 radiusF(radius+0.51); uint32 weightsCounter(0); uint32 valueRed(0); uint32 valueGreen(0); uint32 valueBlue(0); int32 tmpWeight; uint32 tmpDistance; uint32 position; uint32 positionHeight; uint32 posXF = (uint32)(posX+0.5); uint32 posYF = (uint32)(posY+0.5); uint32 factor(1); uint32 factorCounter(0); uint32 size(((xEnd-xStart)*(yEnd-yStart))); if (size > 128) { factor = size / 32; } #ifdef DEBUG uint32 counter1(0); uint32 overall(0); if (p) { logger.debug() << "kernel calculation at position "<"<width; tmpDistance = (i-posYF)*(i-posYF) + (j-posXF)*(j-posXF); tmpDistance = (uint32)(sqrt(tmpDistance)+0.5); tmpWeight = getWeightFix(tmpDistance, radiusF); #ifdef DEBUG overall++; #endif if (tmpWeight <= 0) { #ifdef DEBUG if (p) { logger.debug() << " Pos: "< distance " < distance " < 4*pic->width*pic->height) { logger.debug() << "Error: calculating for Position "<width << " x "<< pic->height <<" Kernel window: "< "<plane[position]*tmpWeight; valueGreen += pic->plane[position+1]*tmpWeight; valueBlue += pic->plane[position+2]*tmpWeight; weightsCounter += tmpWeight; } #ifdef DEBUG if (p) logger.debug() << " Unused: "<plane[4*(posYF*pic->width+posXF)]; RGB[1] = pic->plane[4*(posYF*pic->width+posXF)+1]; RGB[2] = pic->plane[4*(posYF*pic->width+posXF)+2]; } return (retValue); } float PictureResize::getWeight(float distance, float radius) { // should be a sinc /* -> lets save time on the expence of security * if ((radius <= 0) || (distance > radius)) * return(0); */ return (1.0 - distance/radius); // return(1.0 - sqrt(distance)/sqrt(radius)); } int32 PictureResize::getWeightFix(uint32 distance, uint32 radius) { // should be a sinc /* -> lets save time on the expence of security * if ((radius <= 0) || (distance > radius)) * return(0); */ return (1000 - distance*1000/radius); } RGBPlane PictureResize::kernelLowpass(RGBPlane& picture, float radius) { RGBPlane retPlane(picture->width, picture->height); float kernelRadius((1.0-radius)*picture->height/4.0); kernelRadius *= kernelRadius; if (kernelRadius < 0.708) // sqrt(0.5) this is the lease radius size, a picture can be kernelRadius = 0.708; uint32 heightAddition; for (uint32 i(0); iheight; ++i) { heightAddition = 4*i*picture->width; for (uint32 j(0); jwidth; ++j) { uint32* _plane = (uint32*)(&retPlane->plane[heightAddition + 4*j]); (*_plane) = calculateKernelValueFix(picture, j, i, kernelRadius); } } // logger.debug() << " DONE ! \n"; return (retPlane); } uint32 PictureResize::linearInterpolation(RGBPlane pic, float x, float y) { uint32 pixelDistance = 4; uint32 pos_x1 = (int)(x); uint32 pos_x2 = (int)(x+1.0); uint32 pos_y1 = (int)(y); uint32 pos_y2 = (int)(y+1.0); if (pos_x2 >= pic->width) pos_x2 = pic->width-1; if (pos_y2 >= pic->height) pos_y2 = pic->height-1; float part_x = (float)(x - pos_x1); float part_y = (float)(y - pos_y1); float value_x1y1; float value_x1y2; float value_x2y1; float value_x2y2; float inter_x1y1_x1y2; float inter_x2y1_x2y2; float endpoint; uint32 retValue(0); uint8* RGB = (uint8*)(&retValue); /* red */ value_x1y1 = pic->plane[pixelDistance*(pos_y1*pic->width+pos_x1)]; value_x1y2 = pic->plane[pixelDistance*(pos_y2*pic->width+pos_x1)]; value_x2y1 = pic->plane[pixelDistance*(pos_y1*pic->width+pos_x2)]; value_x2y2 = pic->plane[pixelDistance*(pos_y2*pic->width+pos_x2)]; inter_x1y1_x1y2 = (value_x1y2-value_x1y1)*part_y + value_x1y1; inter_x2y1_x2y2 = (value_x2y2-value_x2y1)*part_y + value_x2y1; endpoint = (inter_x2y1_x2y2 - inter_x1y1_x1y2) * part_x + inter_x1y1_x1y2 + 0.5; if (endpoint > 255) endpoint = 255; if (endpoint < 0) endpoint = 0; RGB[0] = (uint8)endpoint; /* green */ value_x1y1 = pic->plane[pixelDistance*(pos_y1*pic->width+pos_x1)+1]; value_x1y2 = pic->plane[pixelDistance*(pos_y2*pic->width+pos_x1)+1]; value_x2y1 = pic->plane[pixelDistance*(pos_y1*pic->width+pos_x2)+1]; value_x2y2 = pic->plane[pixelDistance*(pos_y2*pic->width+pos_x2)+1]; inter_x1y1_x1y2 = (value_x1y2-value_x1y1)*part_y + value_x1y1; inter_x2y1_x2y2 = (value_x2y2-value_x2y1)*part_y + value_x2y1; endpoint = (inter_x2y1_x2y2 - inter_x1y1_x1y2) * part_x + inter_x1y1_x1y2 + 0.5; if (endpoint > 255) endpoint = 255; if (endpoint < 0) endpoint = 0; RGB[1] = (uint8)endpoint; /* blue */ value_x1y1 = pic->plane[pixelDistance*(pos_y1*pic->width+pos_x1)+2]; value_x1y2 = pic->plane[pixelDistance*(pos_y2*pic->width+pos_x1)+2]; value_x2y1 = pic->plane[pixelDistance*(pos_y1*pic->width+pos_x2)+2]; value_x2y2 = pic->plane[pixelDistance*(pos_y2*pic->width+pos_x2)+2]; inter_x1y1_x1y2 = (value_x1y2-value_x1y1)*part_y + value_x1y1; inter_x2y1_x2y2 = (value_x2y2-value_x2y1)*part_y + value_x2y1; endpoint = (inter_x2y1_x2y2 - inter_x1y1_x1y2) * part_x + inter_x1y1_x1y2 + 0.5; if (endpoint > 255) endpoint = 255; if (endpoint < 0) endpoint = 0; RGB[2] = (uint8)endpoint; /* ALPHA */ value_x1y1 = pic->plane[pixelDistance*(pos_y1*pic->width+pos_x1)+3]; value_x1y2 = pic->plane[pixelDistance*(pos_y2*pic->width+pos_x1)+3]; value_x2y1 = pic->plane[pixelDistance*(pos_y1*pic->width+pos_x2)+3]; value_x2y2 = pic->plane[pixelDistance*(pos_y2*pic->width+pos_x2)+3]; inter_x1y1_x1y2 = (value_x1y2-value_x1y1)*part_y + value_x1y1; inter_x2y1_x2y2 = (value_x2y2-value_x2y1)*part_y + value_x2y1; endpoint = (inter_x2y1_x2y2 - inter_x1y1_x1y2) * part_x + inter_x1y1_x1y2 + 0.5; if (endpoint > 255) endpoint = 255; if (endpoint < 0) endpoint = 0; RGB[3] = (uint8)endpoint; return (retValue); } RGBPlane PictureResize::resize(RGBPlane& picture, uint32 width, uint32 height, uint8 quality) { RGBPlane retPlane(width, height); float resizeFactorX(((float)picture->width)/((float)retPlane->width)); float resizeFactorY(((float)picture->height)/((float)retPlane->height)); float radius((resizeFactorX*resizeFactorX + resizeFactorY*resizeFactorY) /(0.5*quality)); uint32 heightAddition; if (radius < 0.708) radius = 0.708; #ifdef DEBUG logger.debug() << "Resizing from "<width<<" : "<height <<" to "<width<<" : "<height<<"\n"; logger.debug() << "using resizefactor "< 1.6)) { logger.debug() << "\nKernel\n"; for (uint32 i(0); i< retPlane->height; ++i) { heightAddition = i*retPlane->width; for (uint32 j(0); j < retPlane->width; ++j) { #ifdef DEBUG if ((j==100) && (i==100)) p=true; else p=false; #endif ((uint32*)(retPlane->plane))[j+heightAddition] = calculateKernelValue(picture, j *resizeFactorX, i *resizeFactorY, radius, p); } } } else { logger.debug() << "\nLinear\n"; for (uint32 i(0); i< retPlane->height; ++i) { heightAddition = i*retPlane->width; for (uint32 j(0); j < retPlane->width; ++j) { #ifdef DEBUG if ((j==100) && (i==100)) p=true; else p=false; #endif ((uint32*)(retPlane->plane))[j+heightAddition] = linearInterpolation(picture, j *resizeFactorX, i *resizeFactorY); } } } return (retPlane); } RGBPlane PictureResize::resize(RGBPlane& picture, float resizeFactorX, float resizeFactorY, uint8 quality) { RGBPlane retPlane(picture->width*resizeFactorX, picture->height*resizeFactorY); float radius((resizeFactorX*resizeFactorX + resizeFactorY*resizeFactorX)/(0.5*quality)); uint32 heightAddition; if (radius < 1.2) // sqrt(0.5) this is the lease radius size, a picture can be radius = 1.2; // if (radius < 0.708) // sqrt(0.5) this is the lease radius size, a picture can be // radius = 0.708; bool p(false); logger.debug() << "\n\nKernel\n\n"; for (uint32 i(0); i< retPlane->height; ++i) { heightAddition = i*retPlane->width; for (uint32 j(0); j < retPlane->width; ++j) { if ((i==100) && (j==100)) p=true; else p=false; ((uint32*)(retPlane->plane))[j+heightAddition] = calculateKernelValue(picture, ((float)j) *resizeFactorX, ((float)i)*resizeFactorY, radius); } } return (retPlane); } RGBPlane PictureResize::resize(RGBPlane& picture, float resizeFactor, uint8 quality) { return (resize(picture, resizeFactor, resizeFactor, quality)); } RGBPlane PictureResize::reframe(RGBPlane & picture, uint32 width, uint32 height, uint8 quality, uint32 background, double aspectCorrection) { if ((picture->width == width) && (picture->height == height)) return (picture); if (((picture->width == width) || (picture->height == height)) && aspectCorrection > 0.999 && aspectCorrection < 1.0001 ) return reframe_fixed(picture, width, height, background); RGBPlane newPlane(width, height); uint32 planesize(width*height); // fill the plane with the given background uint32* plPtr((uint32*)(newPlane->plane)); for (uint32 i(0); iheight*newPlane->width)/((float)picture->width*aspectCorrection)) < ((float)newPlane->height)) { // we work with a height offset offsetY = (uint32) ((((float)newPlane->height) - (((float)(picture->height * newPlane->width)) /((float)picture->width*aspectCorrection)))/2.0+0.5); offsetX = 0; resizeFactor = (((float)picture->width*aspectCorrection/(float)newPlane->width)); //((float)newPlane->width)/((float)width); } else { // we work with a width offset offsetY = 0; offsetX = (uint32) ((((float)newPlane->width) - (((float)(picture->width*aspectCorrection *newPlane->height)) /((float)picture->height)))/2.0+0.5); resizeFactor = (((float)picture->height/(float)newPlane->height)); //((float)newPlane->height)/((float)picture->height); } #ifdef DEBUG logger.debug() << "Reframe - OffsetX: "<height-offsetY); ++i) { for (uint32 j(offsetX); j <(newPlane->width-offsetX); ++j) { position_new = (((float)i)*newPlane->width+j); ((uint32*)(newPlane->plane))[position_new] = calculateKernelValue(picture, resizePlaneCounterX, resizePlaneCounterY, radius); resizePlaneCounterX += (resizeFactor/aspectCorrection); } resizePlaneCounterY += resizeFactor; resizePlaneCounterX = 0; } return (newPlane); } RGBPlane PictureResize::reframe_fixed(RGBPlane & picture, uint32 width, uint32 height, uint32 background) { std::cout << "fixed reframe (from " << picture->width <<":"<height<<" to " << width << ":"<width > width || picture->height > height) throw OggException("picture too big"); if ((picture->width == width) && (picture->height == height)) return (picture); RGBPlane newPlane(width, height); uint32 planesize(width*height); // fill the plane with the given background uint32* plPtr((uint32*)(newPlane->plane)); for (uint32 i(0); iplane)); uint32 offsetX((width - picture->width)/2); uint32 offsetY((height - picture->height)/2); std::cout << "offset: X=" << offsetX << " offset Y=" << offsetY << std::endl; for (uint32 i(0); iheight; ++i) { uint heightAddNew = (i+offsetY)*width; uint heightAddOrig = i*picture->width; for (uint32 j(0); j < picture->width; ++j) { plPtr[heightAddNew+offsetX+j] = plPtrOrig[heightAddOrig+j]; } } return (newPlane); } RGBPlane PictureResize::subframe(RGBPlane & picture, uint32 newWidth, uint32 newHeight, float offsetWidth, float offsetHeight, float scaleFactor, uint8 quality) { if (((((float)newWidth)/scaleFactor)+offsetWidth> picture->width) || ((((float)newHeight) /scaleFactor)+offsetHeight> picture->height)) { logger.error() << "new width: "<width <height < 1.6)) { for (uint32 i(0); i < newHeight; ++i) { heightAddition = i*newWidth; for (uint32 j(0); j < newWidth; ++j) { ((uint32*)(retPlane->plane))[j+heightAddition] = calculateKernelValue(picture, ((float)j) *resizeFactor+offsetWidth, ((float)i) *resizeFactor+offsetHeight, radius); } } } else { for (uint32 i(0); i < newHeight; ++i) { heightAddition = i*newWidth; for (uint32 j(0); j < newWidth; ++j) { ((uint32*)(retPlane->plane))[j+heightAddition] = linearInterpolation(picture, ((float)j) *resizeFactor +offsetWidth, ((float)i)*resizeFactor +offsetHeight); } } } return (retPlane); } RGBPlane PictureResize::concatenate(RGBPlane& picture1, RGBPlane& picture2, RGBPlane& picture3) { if (picture1.getHeight() != picture2.getHeight()) { logger.error() << picture1.getHeight() <<" " <plane)+width*hcnt*2; uint32* pic1RgbaPlane = ((uint32*)picture1->plane)+width*hcnt; uint32* pic2RgbaPlane = ((uint32*)picture2->plane)+width*hcnt; memcpy(retRgbaPlane, pic1RgbaPlane, width*sizeof(uint32)); memcpy(retRgbaPlane+width, pic2RgbaPlane, width*sizeof(uint32)); } return retPlane; } oggvideotools-0.9.1/src/main/cmdlineextractor.cpp000664 001750 001750 00000024003 12763227102 022370 0ustar00embedembed000000 000000 // // C++ Implementation: cmdlineextractor // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #include "cmdlineextractor.h" #include #include #include #include #include #include "definition.h" #include "oggComment.h" #include "pictureLoader.h" #include "log.h" #include "effectorTypes.h" CmdlineExtractor::CmdlineExtractor() { } CmdlineExtractor::~CmdlineExtractor() { } void CmdlineExtractor::extractCommentPairs(std::vector& list, const std::string& _argument, char tokenSeparator, char commentSeparator) { std::string argument(_argument); std::stringstream str; std::string substr; // delete all invalid data std::size_t pos; while ((pos = argument.find_first_not_of(validTextChars)) != std::string::npos) { #ifdef DEBUG logger.debug() << "Erasing sign <"< - it is invalid\n"; #endif argument.erase(pos, 1); } // if there is no argument given, the first frame will be created as a thumbnail if (argument.empty()) { return; } str << argument; while (!str.eof()) { getline(str, substr, tokenSeparator); std::size_t commentSeparatorPos; if ((commentSeparatorPos = substr.find_first_of(commentSeparator)) != std::string::npos) { OggComment comment; comment.tag = substr.substr(0, commentSeparatorPos); comment.value = substr.substr(commentSeparatorPos + 1, std::string::npos); list.push_back(comment); // logger.debug() << "Found pair "<& list, const std::string& _argument, char seperator) { std::string argument(_argument); std::stringstream str; std::string substr; // delete all invalid data std::size_t pos; while ((pos = argument.find_first_not_of(validChars)) != std::string::npos) { #ifdef DEBUG logger.debug() << "erasing <"<\n"; #endif argument.erase(pos, 1); } // if there is no argument given, the first frame will be created as a thumbnail if (argument.empty()) { list.push_back(0); return; } str << argument; uint32 value(0); while (!str.eof()) { std::stringstream part; getline(str, substr, seperator); part << substr; part >> value; list.push_back(value); } } void CmdlineExtractor::extractBlend(std::vector& list, const std::string& _argument, char tokenSeparator, char valueSeparator) { std::string argument(_argument); std::stringstream str; std::string substr; // delete all invalid data std::size_t pos; while ((pos = argument.find_first_not_of(validTextChars)) != std::string::npos) { argument.erase(pos, 1); } // if there is no argument given, the first frame will be created as a thumbnail if (argument.empty()) { return; } str << argument; while (!str.eof()) { getline(str, substr, tokenSeparator); /* extract picture name */ std::size_t valueSeparatorPos = substr.find_first_of(valueSeparator); std::string filename = substr.substr(0, valueSeparatorPos); /* extract all extra data if some (start time, end time, smoothing)*/ double startTime(0); double endTime(-1); bool smooth(false); std::stringstream tmp; /* are there any other information given? */ if (valueSeparatorPos != std::string::npos) { /* analysing start time */ substr = substr.substr(valueSeparatorPos + 1); valueSeparatorPos = substr.find_first_of(valueSeparator); tmp << substr.substr(0, valueSeparatorPos); tmp >> startTime; tmp.clear(); if (valueSeparatorPos != std::string::npos) { /* analysing start time */ substr = substr.substr(valueSeparatorPos + 1); valueSeparatorPos = substr.find_first_of(valueSeparator); tmp << substr.substr(0, valueSeparatorPos); tmp >> endTime; if (valueSeparatorPos != std::string::npos) { /* analysing start time */ substr = substr.substr(valueSeparatorPos + 1); if (substr.substr(0, valueSeparator) == "s") smooth = true; } } } BlendElement elem(filename, startTime, endTime, smooth); // elem.loadPicture(); list.push_back(elem); } #ifdef DEBUG for (uint32 i( 0); i> value; return (value); } float CmdlineExtractor::atof(const std::string& _argument) { std::stringstream stream; float value; stream << _argument; stream >> value; return (value); } uint32 CmdlineExtractor::getNextUint32(std::string& argument, char tokenSeparator) { uint32 retValue(0); if (!argument.empty()) { std::stringstream tmp; std::size_t tokenPosition(argument.find_first_of(tokenSeparator)); tmp << argument.substr(0, tokenPosition); tmp >> retValue; argument = argument.substr(tokenPosition + 1); } return (retValue); } float CmdlineExtractor::getNextFloat(std::string& argument, char tokenSeparator) { float retValue(0.0); if (!argument.empty()) { std::stringstream tmp; std::size_t tokenPosition(argument.find_first_of(tokenSeparator)); tmp << argument.substr(0, tokenPosition); tmp >> retValue; argument = argument.substr(tokenPosition + 1); } return (retValue); } std::string CmdlineExtractor::getNextString(std::string& argument, char tokenSeparator) { std::string retValue(0); if (!argument.empty()) { std::stringstream tmp; std::size_t tokenPosition(argument.find_first_of(tokenSeparator)); tmp << argument.substr(0, tokenPosition); tmp >> retValue; argument = argument.substr(tokenPosition + 1); } return (retValue); } void CmdlineExtractor::extractSlideshow(const std::string& _argument, char tokenSeparator, SlideshowElement& slideshowElement) { /* A full specified picture would look like this (speparator is ",") * name.jpg:,, * This should go into a creator factory later: * start and end position is written as ,, * The X and Y Position is from the left upper corner. The Zoom is 1 if * the pixel is just copy. In that case, the subframe is as big is the * outgoing frame */ std::string argument(_argument); std::stringstream tmp; // delete all invalid data std::size_t pos; while ((pos = argument.find_first_not_of(validTextChars)) != std::string::npos) { argument.erase(pos, 1); } // if there is no argument given, the first frame will be created as a thumbnail if (argument.empty()) { return; } /* extract picture name */ std::size_t tokenPosition(argument.find_first_of(tokenSeparator)); slideshowElement.filename = argument.substr(0, tokenPosition); std::string substr = argument.substr(tokenPosition + 1); /* extract length */ // if (tokenPosition != std::string::npos) { // std::string substr = argument.substr(tokenPosition + 1); // tokenPosition = substr.find_first_of(tokenSeparator); // tmp << substr.substr(0, tokenPosition); // tmp >> slideshowElement.duration; // substr = substr.substr(tokenPosition + 1); // std::cout << substr << std::endl; // if (tokenPosition != std::string::npos) { // tokenPosition = substr.find_first_of(tokenSeparator); // std::string typeName(substr.substr(0, tokenPosition)); // std::cout << substr << std::endl; // // if ((typeName == "kb") || (typeName == "KB") // || (typeName == "KenBurns") || (typeName == "kenburns")) // slideshowElement.type = KenBurns; // // if ((typeName == "p") || (typeName == "pl") || (typeName == "plain") // || (typeName == "Plain")) // slideshowElement.type = Plain; // // if ((typeName == "cf") || (typeName == "crossfade") // || (typeName == "CF") || (typeName == "Crossfade")) // slideshowElement.type = Crossfade; // // if ((typeName == "bl") || (typeName == "b") || (typeName == "B") // || (typeName == "blur") || (typeName == "bluring")) // slideshowElement.type = Blur; substr = substr.substr(tokenPosition + 1); if (tokenPosition != std::string::npos) { std::cout << "F " << substr << std::endl; slideshowElement.startPosX = getNextUint32(substr, tokenSeparator); std::cout << substr << std::endl; slideshowElement.startPosY = getNextUint32(substr, tokenSeparator); std::cout << substr << std::endl; slideshowElement.startZoom = getNextFloat(substr, tokenSeparator); std::cout << substr << std::endl; slideshowElement.endPosX = getNextUint32(substr, tokenSeparator); std::cout << substr << std::endl; slideshowElement.endPosY = getNextUint32(substr, tokenSeparator); std::cout << substr << std::endl; slideshowElement.endZoom = getNextFloat(substr, tokenSeparator); } // } //} } void CmdlineExtractor::extractCrossSequence(std::vector& list, const std::string& _argument, char tokenSeparator) { std::string argument(_argument); // delete all invalid data std::size_t pos; while ((pos = argument.find_first_not_of(validTextChars)) != std::string::npos) { argument.erase(pos, 1); } while (!argument.empty()) list.push_back(getNextString(argument, tokenSeparator)); return; } oggvideotools-0.9.1/src/main/streamMux.h000664 001750 001750 00000006050 12763227102 020455 0ustar00embedembed000000 000000 /* * streamMux will multiplex a number streams to one ogg file * * Copyright (C) 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. * */ #ifndef STREAMMUX_H_ #define STREAMMUX_H_ #include #include #include "definition.h" #include "oggPacket.h" #include "oggEncoder.h" #include "oggStreamEncoder.h" #include "granulePosInterpreter.h" #include "mediaRepository.h" class MuxStreamEntry { public: /* entry information */ bool used; /* stream information */ StreamConfig streamConfig; OggStreamEncoder* streamEncoder; GranulePosInterpreter* posInterpreter; /* packet information */ OggPage nextPage; double nextTime; bool empty; uint32 lastPacketNo; /* stream buffer information */ int bufferElemCounter; MuxStreamEntry(); MuxStreamEntry(StreamConfig& config, OggStreamEncoder* streamEncoder, GranulePosInterpreter* posInterpreter); virtual ~MuxStreamEntry(); }; //! streamMux creates a new ogg media stream /*! This object awaits a m_repository with the constructor, which informs * the object about where to write the information to. * Additional it awaits a vector of Stream Config information to set up * the header and the granule position correctly. * From that moment, the StreamMux object receives OggPackets which are * placed into the media stream with the correct packaging. * */ class StreamMux { protected: struct OutputElement { OggPage page; double time; OutputElement(OggPage _page, double _time) : page(_page), time(_time) {} }; double m_timeOfLastPage; bool m_redoTiming; OggEncoder m_oggEncoder; MediaRepository* m_repository; std::vector m_streamList; //std::list m_outputPageList; std::list m_outputPageList; bool allBuffersEmpty(); void writeToRepository(); void writeToOggEncoder(); void flushOggEncoder(); bool findAndInsertNextPage(); void insertHeader(); void handleNextPage(OggPage& page, uint8 streamNo); public: StreamMux(MediaRepository* repository); virtual ~StreamMux(); void configureStreams(std::vector& config); void setEndOfStream(); StreamMux& operator<<(OggPacket& page); void recreatePacketPosition(bool redoTiming); void close(); }; #endif /*STREAMMUX_H_*/ oggvideotools-0.9.1/docs/oggJoin.1000664 001750 001750 00000002424 12763227102 017213 0ustar00embedembed000000 000000 .TH OGGJOIN 1 "JAN 2010" Linux "User Manuals" .SH NAME oggJOIN \- multiplexes ogg streams (.ogv, .ogg or oga) .SH SYNOPSIS .B oggJoin outfile.ogv file1.ogv file2.ogg .SH DESCRIPTION .B oggJoin merges ogg audio (vorbis) and ogg video (theora) files into one single ogg file. This is often also called multiplexing. The first file given with the command is the output file. The following files are the files (usually a video and an audio stream) that should be placed into the new file as parallel streams. This is done on a per page basis and is very efficient and fast. As oggJoin uses it's own timestamp creation method, both streams start exactly at start time '0'. This is always the case even if the original files started at a different time (due to internal timing information). So the video and audio streams are always synchronized. This helps using files from different live stream sources or cuted material. In case of unknown stream types (other than theora or vorbis), there is actually (as of version 0.8) no timing interpreter available. So you can not use these streams for multiplexing. .SH AUTHOR Joern Seger .SH "SEE ALSO" .BR oggCut (1), .BR oggCat (1), .BR oggSplit (1), .BR oggTranscode (1), .BR oggSlideshow (1), .BR oggThumb (1), .BR oggSilence (1)oggvideotools-0.9.1/src/main/audioHook.h000664 001750 001750 00000001445 12763227102 020415 0ustar00embedembed000000 000000 #ifndef AUDIOHOOK_H_ #define AUDIOHOOK_H_ #include "hookHandler.h" #include "audioConverter.h" #include "audioPacket.h" #include "vorbisDecoder.h" #include "vorbisEncoder.h" class AudioHook : public HookHandler { private: bool changeAudioSamplerate; bool changeChannel; bool copy; AudioConverter converter; AudioPacket audioPacket; AudioHook(); public: AudioHook(uint8 outStreamID, const bool copy, const bool keepComments); virtual ~AudioHook(); virtual HookHandler& operator<<(OggPacket& packet); virtual void initAndConnect(); virtual void flush(); virtual OggType getType() const; }; static bool operator==(const vorbis_info& info1, const vorbis_info& info2); static bool operator!=(const vorbis_info& info1, const vorbis_info& info2); #endif /*AUDIOHOOK_H_*/ oggvideotools-0.9.1/src/misc/crc.h000664 001750 001750 00000001726 12763227102 017253 0ustar00embedembed000000 000000 /* * CRC creation class (static method) * * Copyright (C) 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. * */ #ifndef crc_h #define crc_h class Crc { public: typedef unsigned long Type; public: Crc (); virtual ~Crc(); static unsigned int create(unsigned char* data, unsigned int length); }; #endif oggvideotools-0.9.1/src/base/mediaInputEncoder.h000664 001750 001750 00000001052 12763227102 022052 0ustar00embedembed000000 000000 #ifndef MEDIAINPUTENCODER_H_ #define MEDIAINPUTENCODER_H_ #include "mediaEncoder.h" #include "streamConfig.h" #include "oggPacket.h" #include "oggComment.h" class MediaInputEncoder : public MediaEncoder { protected: uint8 streamNo; public: MediaInputEncoder(const uint8 streamNo); virtual ~MediaInputEncoder(); virtual MediaInputEncoder& operator>>(OggPacket& packet) = 0; virtual void configureEncoder(StreamConfig& config, std::vector& oggComments) = 0; uint32 getStreamNo() const; }; #endif /*MEDIAINPUTENCODER_H_*/ oggvideotools-0.9.1/src/effect/blendElement.h000664 001750 001750 00000001630 12763227102 021375 0ustar00embedembed000000 000000 // // C++ Interface: blendElement // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #ifndef BLENDELEMENT_H #define BLENDELEMENT_H #include #include "rgbPlane.h" /** @author Yorn */ class BlendElement { public: enum BlendState { blend_off, blend_slideIn, blend_on, blend_slideOut, blend_end }; std::string pictureName; RGBPlane picture; double startTime; double endTime; bool smooth; bool unavailable; BlendState state; float intensity; BlendElement(); BlendElement ( const std::string& pictureName, double _startTime, double _endTime, bool _smooth ); std::string getPictureName() const; void setPicturePlane(const RGBPlane& plane); void setUnavailable(); virtual ~BlendElement(); }; #endif oggvideotools-0.9.1/src/effect/plainPicture.cpp000664 001750 001750 00000003230 12763227102 021767 0ustar00embedembed000000 000000 // // C++ Implementation: PlainPicture // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #include #include "plainPicture.h" #include "pictureResize.h" #include "pictureLoader.h" #include #include "log.h" #include "effectorVisitor.h" PlainPicture::PlainPicture() : Effector(), state(unconfigured), framecounter(0) { } PlainPicture::~PlainPicture() { } Effector & PlainPicture::operator >>(RGBPlane & plane) { if (!available()) return(*this); plane = presentationPlane; framecounter++; if (framecounter > config.sequenceLength) { state = unavailable; } return(*this); } void PlainPicture::configure(PlainPictureConfig & _config) { framecounter = 0; config = _config; logger.debug() << "PlanePicture::configure: "<< config.origPlane->width << "x" << config.origPlane->height<<" -> " <width != config.outputWidth) || (config.origPlane->height != config.outputHeight)) { logger.debug() << "reframing"<width << "x"<height< #include "streamSerializer.h" #include "fileRepository.h" #include "oggBOSExtractorFactory.h" #include "log.h" StreamEntry::StreamEntry() : streamDecoder(0), posInterpreter(0), nextTime(-1), endOfStream(false), empty(true) { } StreamEntry::StreamEntry(StreamConfig& config, OggStreamDecoder* sDecoder) : streamConfig(config), streamDecoder(sDecoder), posInterpreter(0), nextTime(-1), endOfStream(false), empty(true) { } StreamEntry::~StreamEntry() { } bool StreamEntry::allHeadersCollected() { return(streamConfig.numOfHeaderPackets == streamConfig.headerList.size()); } StreamSerializer::StreamSerializer() : initState(created), repository(0), oggDecoder(new OggDecoder), streamEndCounter(0) { } StreamSerializer::~StreamSerializer() { close(); } bool StreamSerializer::open(std::string& datasource) { // actually only file repository = new FileRepository(datasource, MediaUnit::read); /* has there been a problem with opening the file */ if (!repository->isAvailable()) return (false); initState = reposOpened; // extract the streams bool retValue = extractStreams(); // fill one packet to every stream item std::map::iterator it(streamList.begin()); for (; it != streamList.end(); ++it) { StreamEntry& entry = it->second; fillStreams(); insertNextPacket(entry); } return (retValue); } bool StreamSerializer::open(MediaRepository* _repository) { // actually only file repository = _repository; /* has there been a problem with opening the file */ if (!repository->isAvailable()) return (false); initState = reposOpened; bool retValue = extractStreams(); // fill one packet to every stream item std::map::iterator it(streamList.begin()); for (; it != streamList.end(); ++it) { StreamEntry& entry = it->second; fillStreams(); insertNextPacket(entry); } return (retValue); } bool StreamSerializer::extractStreams() { RawMediaPacket rawPacket; OggPage oggPage; OggPacket oggPacket; int8 streamCounter = 0; while (repository->isAvailable()) { /* extract a raw data bunch from the file and place it into the ogg decoder */ (*repository) >> rawPacket; (*oggDecoder) << rawPacket; /* if there is a complete ogg page available, grab it */ while (oggDecoder->isAvailable()) { (*oggDecoder) >> oggPage; /* what ID has this page / to what stream does this page belong to */ uint32 serialID = oggPage->serialno(); /* if this is a "begin of stream" packet, * create a new stream decoder instance */ if (oggPage->isBOS()) { StreamEntry entry; /* get all the relevant information from the stream */ OggBOSExtractorFactory::extractInformation(oggPage, entry.streamConfig); entry.streamConfig.streamNo = streamCounter++; /* create the stream encoder */ entry.streamDecoder = new OggStreamDecoder; entry.posInterpreter = OggBOSExtractorFactory::extractPositionInterpreter(entry.streamConfig); streamList[serialID] = entry; // insert the first page *(streamList[serialID].streamDecoder) << oggPage; } else { // insert the next page OggPacket oggPacket; StreamEntry& entry = streamList[serialID]; OggStreamDecoder& streamDecoder = *(entry.streamDecoder); streamDecoder << oggPage; /* as long as we need headers and there are packets available * fill the header list */ while ((!entry.allHeadersCollected()) && (entry.streamDecoder->isAvailable())) { /* if the list of header packets is not completed, add * the next packet to the list */ streamDecoder >> oggPacket; entry.streamConfig.headerList.push_back(oggPacket); } /* find out, if all header packets have been found */ bool allStreamsReady(true); std::map::iterator it(streamList.begin()); for (; it != streamList.end(); ++it) { if (!it->second.allHeadersCollected()) { allStreamsReady = false; break; } } if (allStreamsReady) return (true); } } } logger.error() << "StreamSerializer::extractStreams(): extracter was not able to grab all stream header\n"; return (false); } void StreamSerializer::getStreamConfig(std::vector& packetList) { std::map::iterator it(streamList.begin()); fillStreams(); // it is a bit difficult, we need the original folge packetList.resize(streamList.size()); for (; it != streamList.end(); ++it) { StreamEntry& entry = it->second; packetList[entry.streamConfig.streamNo] = entry.streamConfig; } } void StreamSerializer::close() { delete oggDecoder; oggDecoder = 0; /* close the m_repository */ if (repository) { repository->close(); delete repository; repository = 0; } std::map::iterator it = streamList.begin(); /* delete all list entries */ for (; it != streamList.end(); ++it) { StreamEntry entry = it->second; delete entry.streamDecoder; delete entry.posInterpreter; // if (entry.streamConfig.parameter) // delete entry.streamConfig.parameter; /* we do not need to delete the header List * it is controled by the refObject structure */ } streamList.clear(); } bool StreamSerializer::fillPage() { RawMediaPacket rawPacket; OggPage oggPage; while (1==1) { // is there no packet available within the ogg page decoder while (!oggDecoder->isAvailable()) { // is there any data bunch available from the m_repository? if (!repository->isAvailable()) { // if there is no more data at the m_repository, there is an error // in the stream/file return (false); } // get a bunch of raw data and place it into the ogg page decoder *repository >> rawPacket; *oggDecoder << rawPacket; // repeat this until there is at least one page available } // get the next ogg page *oggDecoder >> oggPage; // find out to what stream this packet belongs and forget the // page if the stream has not been configured befor if (streamList.find(oggPage->serialno()) == streamList.end()) continue; // get the stream item for easier access StreamEntry& item = streamList[oggPage->serialno()]; // insert the ogg page into the right stream decoder *(item.streamDecoder) << oggPage; return (true); } } /* method is called to be sure, that there is at least one packet in every stream * or the stream has finished */ bool StreamSerializer::fillStreams() { /* are there no more packets to process, return false */ if (streamEndCounter == streamList.size()) return (false); std::map::iterator it = streamList.begin(); // ensure that every stream can deliver at least one packet or // the stream has been ended for (; it != streamList.end(); ++it) { // create a local reference for easier access StreamEntry& item = it->second; // if this stream has ended, do not fill this stream any more if (item.endOfStream) continue; // if there is no packet available within this particular stream // try to get more input while (!item.streamDecoder->isAvailable()) { // if the stream has not ended, fill up the stream // if the stream has ended, increment the end counter if (item.streamDecoder->isEndOfStream()) { break; } else { if (!fillPage()) { logger.error() << "StreamSerializer::fillStreams: stream ended without an end-of-stream indicator\n"; return (false); } } } } return (true); } void StreamSerializer::insertNextPacket(StreamEntry& entry) { // insert next packet into the streamEntry if (entry.streamDecoder->isEndOfStream()) { // if the stream has ended, set a marker if (entry.endOfStream == false) { entry.endOfStream = true; entry.empty = true; // logger.debug() << "Stream <"<getSerialNo()<< std::dec<<"> has ended \n"; streamEndCounter++; } // entry.endOfStream = true; } else { // get the next packet from this stream decoder OggPacket newPacket; *(entry.streamDecoder) >> newPacket; // set some additional data newPacket->setStreamType(entry.streamConfig.type); newPacket->setStreamNo(entry.streamConfig.streamNo); // if there is a position interpreter, use it to set the time // else set the time to 0 if (entry.posInterpreter) { // logger.debug() << "granpos stream: "<granulepos(); if (newPacket->granulepos() == -1) { entry.posInterpreter->setStreamPosition(newPacket); entry.nextTime = entry.posInterpreter->getActTime(); } else { int64 grPos = newPacket->granulepos(); // the interpreter needs to be pushed forward entry.posInterpreter->setStreamPosition(newPacket); newPacket->setGranulepos(grPos); entry.nextTime = entry.posInterpreter->getTime(newPacket->granulepos()); } // logger.debug() << " calc: "<granulepos()<::iterator it = streamList.begin(); /* delete all list entries */ for (; it != streamList.end(); ++it) { StreamEntry& entry = it->second; /* if this stream has ended, continue with the next stream */ if (entry.endOfStream) continue; /* if this is the first packet in this round, take it * as a reference else compare both times */ if ((time < 0) || ((!entry.empty) && (entry.nextTime < time))) { time = entry.nextTime; nextStreamID = it->first; } } if (time > -1) { /* copy the next packet to the requested one */ packet = streamList[nextStreamID].nextPacket; if (fillStreams()) insertNextPacket(streamList[nextStreamID]); else streamEndCounter = streamList.size(); } return (time); } oggvideotools-0.9.1/src/effect/lowpassEffect.h000664 001750 001750 00000002216 12763227102 021605 0ustar00embedembed000000 000000 // // C++ Interface: lowpassEffect // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #ifndef LOWPASSEFFECT_H #define LOWPASSEFFECT_H #include "effector.h" /** @author Yorn */ class LowpassEffect : public Effector { public: class LowPassPictureConfig { public: bool first; bool last; uint32 sequenceLength; /* in frames */ uint32 blindLength; /* in frames */ uint32 outputWidth; uint32 outputHeight; RGBPlane origPlane; }; protected: enum State { unconfigured, blindIn, presentation, blindOut, unavailable }; State state; RGBPlane presentationPlane; uint32 framecounter; float factor; LowPassPictureConfig config; void doBlindIn(RGBPlane& plane); void doBlindOut(RGBPlane& plane); void doPresentation(RGBPlane& plane); public: LowpassEffect(); virtual ~LowpassEffect(); void configure(LowPassPictureConfig& config); virtual Effector& operator>>(RGBPlane& plane); virtual bool available(); virtual void accept(EffectorVisitor& visitor) const; }; #endif oggvideotools-0.9.1/src/libresample/configtemplate.h000664 001750 001750 00000000306 12763227102 023042 0ustar00embedembed000000 000000 /* Run configure to generate config.h automatically on any system supported by GNU autoconf. For all other systems, use this file as a template to create config.h */ #undef HAVE_INTTYPES_H oggvideotools-0.9.1/src/base/mediaDecoder.cpp000664 001750 001750 00000001606 12763227102 021360 0ustar00embedembed000000 000000 /* * MediaDecoder is the base class for all subsequent decoders * * Copyright (C) 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. * */ #include "mediaDecoder.h" MediaDecoder::MediaDecoder() { } MediaDecoder::~MediaDecoder() { } oggvideotools-0.9.1/ChangeLog000664 001750 001750 00000006320 12763227102 016356 0ustar00embedembed000000 000000 Version 0.1: initial Version added oggDump added oggSplit Version 0.2: added oggJoin added oggCut Version 0.3: added oggCat added configure script (thanks to John Jolly at Novell) changed oggCut to be able to Cut audio only files Version 0.4: added oggLength added workaround for ogg-Skeleton added library classes to decode theora files added oggScroll to scroll through the video frames Version 0.5: updates for gcc 4.3 (done by Matt Domsch ) configure script updates (done by Matt Domsch ) started doxygen sourcecode documentation documentation pdf-File with detailed information about the tools Version 0.6: added oggSlideshow added oggThumb handling for huge files > 4GB implemented packet order with oggCut has been fixed and cleaned up ogg type in BOS packet is completely analysed added support for kate-streams (done by ogg.k.ogg.k) Version 0.7: added OggResize bugfix for wrong size in oggThumb, which causes a green border support for more recent gcc compilers Version 0.7a: minor bugfixes: - random number generator is always initialized with a random seed - command line options harmonized (e.g. -s is always size) handling for corrupt End-Of-Stream markers scripts for easy creation of thumbnails and slideshows with sound documentation update Version 0.7b: minor bugfixes: - oggCut packet handling - oggSlideshow helpscreen Added Additions for windows compilations Version 0.8: - man pages included - reworked rgb plane handling (e.g. video size != multiple of 16) - comment handling in oggResize and oggSlideshow - oggSlideshow: bluring changeover effect - added oggSilence (silence vorbis stream generator) - oggResize: - filters for better quality for resizing - audio resizing (samplerate, datarate, channels) - omitting frames for "fast" films and previews - adding PNG logos with alpha channel - Bugfixes: flush-mechanism for ogg pages in ogg muxer corrected - testing for memory leaks Version 0.8a: - Handling of zero size packets - correct compiling of small packets into pages (packaging exactly 255 segments per page) - renaming oggResize to oggTranscode - oggCat can handle different video and audio files (complete rewrite) - internal: video and audio hook for oggCat and oggTranscode - timing, stream No. and stream type in oggDump packet dump output - reworked manpages - switch to cmake - oggScroll is no longer supported (libSDL is not needed any more!) and will not be installed - mkSlideshow is not supported any more and will not be installed - cleanup mkThumb (bug #2925128) - thanks to jferlito - integrated fixes from Tim Starling (advanced exception handling, logging etc) - oggSlideshow returns with -1 if no picture was found - prefix walkthrough for KenBurns effect - Documentation pdf is outdated and therefir not shiped with the source package any more google can help much better - release creation reworked - configure reworked and added to trunk Version 0.9: - Bug in oggRingbuffer fixed (Thanks to Bjarne) -> solved problems with ffmpeg ogg implementation - Manpage cleanup - fix for gcc 4.7 (used in Fedora 17) Version 0.9.1 - changed over to C++11 and boost (in some minor places). - Cleanup a lot of things to fit ogg/theora/vorbis API again. oggvideotools-0.9.1/src/libresample/resample_defs.h000664 001750 001750 00000003264 12763227102 022660 0ustar00embedembed000000 000000 /********************************************************************** resample_defs.h Real-time library interface by Dominic Mazzoni Based on resample-1.7: http://www-ccrma.stanford.edu/~jos/resample/ License: LGPL - see the file LICENSE.txt for more information **********************************************************************/ #ifndef __RESAMPLE_DEFS__ #define __RESAMPLE_DEFS__ #if !defined(WIN32) && !defined(__CYGWIN__) #include "config.h" #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef PI #define PI (3.14159265358979232846) #endif #ifndef PI2 #define PI2 (6.28318530717958465692) #endif #define D2R (0.01745329348) /* (2*pi)/360 */ #define R2D (57.29577951) /* 360/(2*pi) */ #ifndef MAX #define MAX(x,y) ((x)>(y) ?(x):(y)) #endif #ifndef MIN #define MIN(x,y) ((x)<(y) ?(x):(y)) #endif #ifndef ABS #define ABS(x) ((x)<0 ?(-(x)):(x)) #endif #ifndef SGN #define SGN(x) ((x)<0 ?(-1):((x)==0?(0):(1))) #endif #if HAVE_INTTYPES_H #include typedef char BOOL; typedef int32_t WORD; typedef uint32_t UWORD; #else typedef char BOOL; typedef int WORD; typedef unsigned int UWORD; #endif #ifdef DEBUG #define INLINE #else #define INLINE inline #endif /* Accuracy */ #define Npc 4096 /* Function prototypes */ int lrsSrcUp(float X[], float Y[], double factor, double *Time, UWORD Nx, UWORD Nwing, float LpScl, float Imp[], float ImpD[], BOOL Interp); int lrsSrcUD(float X[], float Y[], double factor, double *Time, UWORD Nx, UWORD Nwing, float LpScl, float Imp[], float ImpD[], BOOL Interp); #endif oggvideotools-0.9.1/src/base/granulePosInterpreter.cpp000664 001750 001750 00000000550 12763227102 023353 0ustar00embedembed000000 000000 #include "granulePosInterpreter.h" GranulePosInterpreter::GranulePosInterpreter() : initialized(false), actualGranulePosition(0) { } GranulePosInterpreter::~GranulePosInterpreter() { } int64 GranulePosInterpreter::getPosition() { return(actualGranulePosition); } double GranulePosInterpreter::getActTime() { return(getTime(actualGranulePosition)); } oggvideotools-0.9.1/docs/oggLength.html000664 001750 001750 00000004053 12763227102 020341 0ustar00embedembed000000 000000 Content-type: text/html Man page of OGGLENGTH

OGGLENGTH

Section: User Manuals (1)
Updated: JAN 2010
Index Return to Main Contents
 

NAME

oggLength - gives the length of an ogg video/audio file  

SYNOPSIS

oggLength [options] inputfile.ogv  

DESCRIPTION

oggLength analyses an ogg audio/video file and gives the duration of a file. If there is more than one stream available, the end time position of the longest stream is printed. The return value is given by milliseconds.

oggLength does not care for skeleton information.

 

OPTIONS

-v
prints out the length of the vorbis stream.

-t
prints out the length of the theora stream.

 

AUTHOR

Joern Seger <yorn at gmx dot net>

 

SEE ALSO

oggCut(1), oggJoin(1), oggSplit(1), oggTranscode(1), oggSlideshow(1), oggThumb(1), oggSilence(1)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
AUTHOR
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 09:28:30 GMT, January 10, 2010 oggvideotools-0.9.1/docs/oggTranscode.html000664 001750 001750 00000014521 12763227102 021043 0ustar00embedembed000000 000000 Content-type: text/html Man page of OGGTRANSCODE

OGGTRANSCODE

Section: User Manuals (1)
Updated: JAN 2010
Index Return to Main Contents
 

NAME

oggTranscode - transcodes ogg files in multiple ways  

SYNOPSIS

oggTranscode [options] inputfile.ogv outputfile.ogv  

DESCRIPTION

oggTranscode can resize an ogg file (ogg, oga or ogv) in multiple ways: It can change the video frame size, change datarate for the video and/or audio streams contained in the ogg file and it can also change the video frame rate or audio sample rate.

Additionally, since version 0.8 oggTranscode can add any ogg comment and png-pictures with an alpha channel can be rendered into the video at any time period before and after the resizing process.

oggTranscode was previously called oggResize.

 

OPTIONS

-s
Sets the size of the video frame. The size is given as <width>x<height>. At default, the video frame size keeps the same.

Example: -s 320x240

-d
Sets the datarate in byte per seconds for the video encoder (theora). This meant to be a upper threshold. So the file may be smaller than assumed. If not set, the datarate of the original stream is used.

Example: -d 1024000

-D
Sets the datarate in byte per seconds for the audio encoder (vorbis). If not set, the datarate of the original stream is used.

Example: -D 64000

-f
Sets the frame rate of the video with numinator and demoninator and is the pictures per second. If only one number is given, the denominator is set to 1. If not set, the framerate of the original video is used.

Example: -f 25:2

-F
Sets the sample frequency (sample rate) of the audio data in Hertz. If the sample frequency does not match the one with the original file, resamling is invoked.

Example: -F 32000

-c

Adds comments to the video (theora) stream. Comments are given by a pair of type and value in the form 'type=value'. More than one comment can be concatenated with a semicolon. It is recommended to use apostrophes as the command line may use the semicolon as a seperator.

Example: -c 'AUTHOR=yorn;DATE=03.07.09'

-C
Adds comments to the audio (vorbis) stream. Comments are given by a pair of type and value in the form 'type=value'. More than one comment can be concatenated with a semicolon. It is recommended to use apostrophes as the command line may use the semicolon as a seperator.

Example: -C 'AUTHOR=yorn;DATE=03.07.09'

-q
Specifies the quality for the resizing process. Values can be chosen between 1 (best quality, with slight bluring) and 6 (worst quality). The default value is 2.

Example: -q1

-p
This option is meant to help creating a preview of a film. The number given with this option defines the number of frames, that are omitted. E.g. if a film has 24 frames per second and -p24 is given, the newly created video shows the video 24 times faster as only every 24th frame is used. This option can be combined with the option -f to control the framerate. With both options nice video previews can be created. If -p is used, the audio stream is ignored.

Example: -p 24

-a
Adds a picture to the video frame before it is resized. The expression for the picture appearances:

<picture1.png>[,<startTime>[,<endTime>[,s]]]

default startTime is 0

default endTime is -1, which is the end of the stream duration

default s ist not set. If s is set, the picture slides in smoothly.

More than one picture can be included. To concatenate the expressions use the colon. If the appearance time overlap, the pictures are placed on one another, so the last picture is the uppest layer.

Example: -a etwas.png,2,7,s:etwasneues.png,5,10

-A
Adds a picture to the video frame after it is resized.

The syntax follows the same expression as with option -a.

 

EXAMPLE

oggTranscode -s320x240 -d512000 orig.ogv new.ogv

Converts a the video orig.ogv to the video new.ogv with the new frame size 320x240. If there was an audio stream within the orig.ogv file, it is copied into the new file.

oggTranscode -D64000 -F16000 -N1 orig.ogv new.ogv

Converts only the audio stream of file orig.ogv to a sample rate of 16kHz, a datarate of 64 kBit/s and a mono channel. The video stream is copied as is.

oggTranscode -s300x200 -D32000 -d1024000 -A etwas.png,2,7,s:etwasneues.png,5,10 orig.ogv new.ogv

Converts the audio and video stream and adds the alpha channel picture etwas.png to the video from second 2 to second 7 with a smooth fade in and fade out. Additionally the alpha channel picture etwasneues.png is placed on top of the video frame from second 5 to second 10 without any fading.

 

AUTHOR

Joern Seger <yorn at gmx dot net>  

SEE ALSO

oggCut(1), oggCat(1), oggJoin(1), oggSplit(1), oggSlideshow(1), oggThumb(1), oggSilence(1)
 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
EXAMPLE
AUTHOR
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 09:28:30 GMT, January 10, 2010 oggvideotools-0.9.1/src/effect/crossfader.h000664 001750 001750 00000002057 12763227102 021136 0ustar00embedembed000000 000000 // // C++ Interface: crossfader // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #ifndef CROSSFADER_H #define CROSSFADER_H #include "effector.h" /** @author Yorn */ class Crossfader : public Effector { public: class CrossfaderConfig { public: bool first; uint32 sequenceLength; /* in frames */ uint32 blindLength; /* in frames */ uint32 outputWidth; uint32 outputHeight; RGBPlane origPlane; }; RGBPlane presentationPlane; protected: enum State { unconfigured, crossfade, presentation, unavailable }; State state; RGBPlane lastPlane; uint32 framecounter; CrossfaderConfig config; void doCrossfade(RGBPlane& plane); void doPresentation(RGBPlane& plane); public: Crossfader(); ~Crossfader(); void configure(CrossfaderConfig& config); virtual Effector& operator>>(RGBPlane& plane); virtual bool available(); virtual void accept(EffectorVisitor& visitor) const; }; #endif oggvideotools-0.9.1/NEWS000664 001750 001750 00000000000 12763227102 015270 0ustar00embedembed000000 000000 oggvideotools-0.9.1/COPYING000664 001750 001750 00000035435 12763227102 015650 0ustar00embedembed000000 000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally toString such an announcement, your work based on the Program is not required to toString an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS oggvideotools-0.9.1/src/binaries/oggSilence.cpp000664 001750 001750 00000011642 12763227102 021755 0ustar00embedembed000000 000000 /* * oggSilence is a command line tool, to create silence vorbis files * * Copyright (C) 2009 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. * */ #ifdef __WIN32 #define __GNU_LIBRARY__ #include "../win32/getopt_win.h" #endif #include #include #include #include #include #include #include #include "vorbisEncoder.h" #include "streamMux.h" #include "fileRepository.h" #include "oggComment.h" #include "cmdlineextractor.h" #include "exception.h" #include "log.h" #define BUNCHSIZE 512 void printHelpScreen(std::string& name) { logger.error() << "usage "< -n -r -l \n"; } AudioPacket getSilencePacket(uint32 channels, uint32 length) { float silence[length]; for (uint32 i(0); isetDataOfChannel(j, silence); // funny stack stuff ;-) return(AudioPacket(internal)); } int oggSilenceCmd( int argc, char* argv[] ) { VorbisEncoder encoder(0); AudioPacket audioPacket; AudioPacket lastAudioPacket; uint32 samplerate(44100); uint32 channels(2); uint32 datarate(64000); uint32 length(60000); // 1 minute /* Initialisation */ std::string outputFile; std::string programName(argv[0]); srand(time(0)); int opt; while ((opt = getopt(argc, argv, "ho:d:n:r:l:")) != EOF) switch (opt) { case 'h': printHelpScreen(programName); exit(-1); case 'd': datarate = CmdlineExtractor::atoi(optarg); break; case 'o': outputFile = std::string(optarg); break; case 'n': channels = CmdlineExtractor::atoi(optarg); break; case 'r': samplerate = CmdlineExtractor::atoi(optarg); break; case 'l': length = CmdlineExtractor::atoi(optarg); break; } argc -= optind; argv += optind; if ((argc > 1)) { printHelpScreen(programName); exit (-1); } if (argc > 0) { outputFile = std::string(argv[0]); } /* Handle wrong parameter and parameter combinations */ if (outputFile.empty()) { printHelpScreen(programName); exit (-1); } StreamMux muxer(new FileRepository(outputFile, MediaUnit::write)); muxer.recreatePacketPosition(false); /* configure encoder */ std::shared_ptr config = std::make_shared(); config->datarate = datarate; config->channels = channels; config->samplerate = samplerate; StreamConfig streamConfig; streamConfig.parameter = config; std::vector comments; // none try { encoder.configureEncoder(streamConfig, comments); } catch (std::exception & e) { logger.error() << e.what() << std::endl; exit(-1); } catch (...) { //logger.error() << what(); exit(-1); } logger.error() << "Creating ogg file with the following parameters\n"<toString(); /* there is only one stream in this file */ std::vector configList; configList.push_back(streamConfig); /* configure the muxer */ muxer.configureStreams(configList); uint32 completeSamples((float)length/1000.0*samplerate); /* create one silence packet */ audioPacket = getSilencePacket(channels, BUNCHSIZE); if (completeSamples%BUNCHSIZE != 0) { lastAudioPacket = getSilencePacket(channels, completeSamples%BUNCHSIZE); } OggPacket packet; for (uint32 i(0); i> packet; muxer << packet; } } logger.debug() << "\n"; if (completeSamples%BUNCHSIZE != 0) { logger.debug() << "\nwrite last frame with "<> packet; muxer << packet; } muxer.setEndOfStream(); muxer.close(); return(0); } int main(int argc, char* argv[]) { try { return oggSilenceCmd(argc, argv); } catch (OggException & e) { logger.error() << "Fatal error: " << e.what() << std::endl; return -1; } } oggvideotools-0.9.1/docs/Doxyfile000664 001750 001750 00000021430 12763227102 017241 0ustar00embedembed000000 000000 # Doxyfile 1.5.5 #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = OggVideoTools PROJECT_NUMBER = 0.4 OUTPUT_DIRECTORY = /Users/jornseger/workspace/OggVideoTools/doxygen CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = YES STRIP_FROM_PATH = STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 ALIASES = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO SIP_SUPPORT = NO DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES TYPEDEF_HIDES_STRUCT = NO #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = YES EXTRACT_PRIVATE = YES EXTRACT_STATIC = YES EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_DIRECTORIES = NO FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = ../src INPUT_ENCODING = UTF-8 FILE_PATTERNS = RECURSIVE = YES EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXCLUDE_SYMBOLS = EXAMPLE_PATH = EXAMPLE_PATTERNS = EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = YES INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES REFERENCES_LINK_SOURCE = YES USE_HTAGS = NO VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = NO COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = NO GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" DOCSET_BUNDLE_ID = org.doxygen.Project HTML_DYNAMIC_SECTIONS = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NONE TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = YES LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = YES USE_PDFLATEX = YES LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = NO XML_OUTPUT = xml XML_SCHEMA = XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES MSCGEN_PATH = /Applications/Doxygen.app/Contents/Resources/ HIDE_UNDOC_RELATIONS = YES HAVE_DOT = NO CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = /Applications/Doxygen.app/Contents/Resources/ DOTFILE_DIRS = DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO oggvideotools-0.9.1/docs/CMakeLists.txt000664 001750 001750 00000001046 12763227102 020274 0ustar00embedembed000000 000000 SET ( MAN_SRC oggTranscode.1 oggSlideshow.1 oggThumb.1 oggSplit.1 oggJoin.1 oggCut.1 oggCat.1 oggSilence.1 oggDump.1 oggLength.1 mkThumbs.1 ) SET ( HTML_SRC oggTranscode.html oggSlideshow.html oggThumb.html oggSplit.html oggJoin.html oggCut.html oggCat.html oggSilence.html oggDump.html oggLength.html mkThumbs.html ) IF ( $ENV{MAKE_PACKAGE} ) INSTALL ( FILES ${MAN_SRC} DESTINATION doc ) INSTALL ( FILES ${HTML_SRC} DESTINATION doc ) ELSE ( $ENV{MAKE_PACKAGE} ) INSTALL ( FILES ${MAN_SRC} DESTINATION man/man1 ) ENDIF ( $ENV{MAKE_PACKAGE} ) oggvideotools-0.9.1/src/base/oggPage.cpp000664 001750 001750 00000014407 12763227102 020367 0ustar00embedembed000000 000000 /* * OggPage will carry all relevant information of an ogg page * * Copyright (C) 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. * */ #include #include #include "oggPage.h" #include "oggHeader.h" #include "crc.h" /* OggPageInternal */ OggPageInternal::OggPageInternal() : m_dataPtr(0), m_headerLength(0), m_bodyLength(0), m_streamNo(255), m_empty(true) { } OggPageInternal::OggPageInternal(std::vector& _dataPtr, uint32 _headerLength, uint32 _bodyLength) : m_headerLength(_headerLength), m_bodyLength(_bodyLength), m_streamNo(255), m_empty(false) { m_dataPtr = _dataPtr; } OggPageInternal::~OggPageInternal() { } bool OggPageInternal::isContinued() { return(((OggHeader*)(&m_dataPtr[0]))->pack_type); } void OggPageInternal::setContinued() { ((OggHeader*)(&m_dataPtr[0]))->pack_type = 1; } bool OggPageInternal::isBOS() { return(((OggHeader*)(&m_dataPtr[0]))->page_type); } bool OggPageInternal::isEOS() { return(((OggHeader*)(&m_dataPtr[0]))->last); } void OggPageInternal::setBOS() { ((OggHeader*)(&m_dataPtr[0]))->page_type = 1; } void OggPageInternal::unsetBOS() { ((OggHeader*)(&m_dataPtr[0]))->page_type = 0; } void OggPageInternal::setEOS() { ((OggHeader*)(&m_dataPtr[0]))->last = 1; } void OggPageInternal::unsetEOS() { ((OggHeader*)(&m_dataPtr[0]))->last = 0; } void OggPageInternal::setStreamNo(uint8 streamNo) { m_streamNo = streamNo; } uint8 OggPageInternal::getStreamNo() { return(m_streamNo); } uint32 OggPageInternal::version() { return(((OggHeader*)(&m_dataPtr[0]))->version); } uint32 OggPageInternal::packets() { uint32 segments(((OggHeader*)(&m_dataPtr[0]))->tableSegments); uint32 packets(0); uint8* oggPtr=&m_dataPtr[0]+sizeof(OggHeader); for (uint32 i(0); iposition); } uint32 OggPageInternal::serialno() { return(((OggHeader*)(&m_dataPtr[0]))->serial); } uint32 OggPageInternal::pageno() { return(((OggHeader*)(&m_dataPtr[0]))->pageNo); } uint32 OggPageInternal::length() { return(m_headerLength + m_bodyLength); } std::vector& OggPageInternal::data() { return(m_dataPtr); } bool OggPageInternal::isEmpty() { return(m_empty); } void OggPageInternal::createCRC() { OggHeader* hdr = (OggHeader*)(&m_dataPtr[0]); hdr->checksum = 0; hdr->checksum = Crc::create(&m_dataPtr[0], length()); } OggPage OggPageInternal::clone() { OggPage page; if (!m_dataPtr.empty()) { page = std::make_shared(m_dataPtr, m_headerLength, m_bodyLength); } return page; } OggPage OggPageInternal::create(std::vector& data, uint32_t headerLength, uint32_t bodyLength) { OggPage page; if (length() > 0) { page = std::make_shared(data, headerLength, bodyLength); } return page; } OggPage OggPageInternal::getPtr() { return shared_from_this(); } /* toString levels: * 0) only data length information * 1) header information * 2) additional header information * 3) header dump * 4) body dump */ std::string OggPageInternal::toString(uint8 level) { std::stringstream retStream; retStream << "Ogg Page: header length = " << std::dec << m_headerLength << " and body length = " << std::dec << m_bodyLength << std::endl; if (level < 1) return(retStream.str()); OggHeader* header = (OggHeader*)(&m_dataPtr[0]); retStream << "Header Information:" << "\n\tOgg Version : " << (uint32)header->version << "\n\tSerial No : 0x" << std::hex << header->serial << std::dec << "\n\tPacket Type : "; if (header->pack_type) retStream << "continued packet"; else retStream << "fresh packet"; retStream << "\n\tPage Type : "; if (header->page_type) retStream << "begin of stream marker"; else retStream << "normal page"; retStream << "\n\tLast Page : "; if (header->last) retStream << "end of stream marker"; else retStream << "normal page"; retStream << "\n\tGranule Position : " << header->position << "(0x" << std::hex << header->position << std::dec << ")"; retStream << "\n\tPage Number : " << header->pageNo; retStream << "\n\tChecksum : 0x" << std::hex << header->checksum << std::dec; retStream << "\n\tTable Segments : " << (uint32) header->tableSegments; retStream << std::endl << std::endl; if (level < 2) return(retStream.str()); retStream << "Segments:"; for (uint32 c(0); ctableSegments; ++c) { if ((c%16) == 0) retStream << std::endl; retStream << " "<< std::hex; if (((unsigned int) (m_dataPtr[c+sizeof(OggHeader)])) < 16) retStream << "0"; retStream << (unsigned int) (m_dataPtr[c+sizeof(OggHeader)]); } retStream << std::endl << std::endl; if (level < 3) return(retStream.str()); retStream << "Header Hex dump: "; for (uint32 c(0); c #endif #include #include #include #include #include #include #include #include #include "fileRepository.h" #include "streamSerializer.h" #include "theoraDecoder.h" #include "theoraStreamParameter.h" #include "oggComment.h" #include "rgbPlane.h" #include "pictureLoader.h" #include "pictureResize.h" #include "exception.h" #include "log.h" const std::string validChars("0123456789,.x"); void extractUint32(std::deque& list, const std::string& _argument, char seperator) { std::string argument(_argument); std::stringstream str; std::string substr; // if there is no argument given, the first frame will be created as a thumbnail if (argument.empty()) { list.push_back(0); return; } // delete all invalid data std::size_t pos; while ((pos = argument.find_first_not_of(validChars)) != std::string::npos) { logger.debug() << "erasing <"<\n"; argument.erase(pos,1); } str << argument; uint32 value(0); while (!str.eof()) { std::stringstream part; getline(str, substr, seperator); part << substr; part >> value; list.push_back(value); } } void extractUint32Sort(std::deque& list, const std::string& _argument, char seperator) { std::string argument(_argument); std::stringstream str; std::string substr; std::priority_queue _list; // if there is no argument given, the first frame will be created as a thumbnail if (argument.empty()) { list.push_back(0); return; } // delete all invalid data std::size_t pos; while ((pos = argument.find_first_not_of(validChars)) != std::string::npos) { logger.debug() << "erasing <"<\n"; argument.erase(pos,1); } str << argument; uint32 value(0); while (!str.eof()) { std::stringstream part; getline(str, substr, seperator); part << substr; part >> value; _list.push(value); } while (!_list.empty()) { list.push_front(_list.top()); _list.pop(); } } void extractDoubleSort(std::deque& list, const std::string& _argument, char seperator) { std::string argument(_argument); std::stringstream str; std::string substr; std::priority_queue _list; // if there is no argument given, the first frame will be created as a thumbnail if (argument.empty()) { list.push_back(0); return; } std::size_t pos; while ((pos = argument.find_first_not_of(validChars)) != std::string::npos) argument.erase(pos); str << argument; double value(0); while (!str.eof()) { std::stringstream part; getline(str, substr, seperator); part << substr; part >> value; _list.push(value); } while (!_list.empty()) { list.push_front(_list.top()); _list.pop(); } } void writeActualFrame(TheoraDecoder& decoder, std::deque& packetList, const std::string& name, uint32 width, uint32 height) { th_ycbcr_buffer picture; RGBPlane plane; if (!TheoraDecoder::isPacketKeyframe(packetList[0])) { logger.error() << "first packet is not a keyframe\n"; return; // could not happen ;-) } for (uint32 i(0); i> picture; } plane = PictureLoader::importYCrCb_theora(picture, decoder.getWidth(), decoder.getHeight(), decoder.getInfo().pic_x, decoder.getInfo().pic_y, decoder.getInfo().pixel_fmt); PictureLoader::save(plane, name, width, height); } std::string getThumbname(const std::string& filename, const std::string& forcedThumbname, const std::string& extension, uint32& counter, uint32 reqCount) { std::stringstream thumbname; if (forcedThumbname.empty()) { std::size_t filenamestart = filename.find_last_of('/'); std::size_t filenamelength = filename.find_last_of('.'); if (filenamestart == std::string::npos) filenamestart = 0; else filenamestart++; if ((filenamelength != std::string::npos) && (filenamelength > filenamestart)) filenamelength = filenamelength - filenamestart; else filenamelength = std::string::npos; thumbname << filename.substr(filenamestart,filenamelength); thumbname << "_" << counter++ << extension; } else if (reqCount == 1) { thumbname << forcedThumbname; thumbname << extension; } else { std::size_t replacePos = forcedThumbname.find_first_of('%'); if (replacePos != std::string::npos ) { thumbname << forcedThumbname.substr(0, replacePos); thumbname << (counter++); thumbname << forcedThumbname.substr(replacePos + 1); } else { thumbname << forcedThumbname; } thumbname << extension; } return(thumbname.str()); } void printHelpScreen(std::string& prog) { logger.error() << "\nusage: "< : create thumbnail from frame at time position time1, time2, time3 second\n" << " -f : create thumbnail from frame number frameNo1, frameNo2, frameNo3\n" << " -s x : resize to given values (if one argument is set to 0, it is calculated to meet the aspect ratio)\n" << " -o : formats are jpg or png\n" << " -n : force output filename\n" << "The filename could be given with a %, which will be replaced by the actual picture number\n" << "\n\n"; } int oggThumbCmd(int argc, char* argv[]) { std::deque timePosList; std::deque frameNoList; uint32 width(0); uint32 height(0); uint32 requestedFrameCount(0); std::string programName(argv[0]); std::string extension(".jpg"); std::string forcedThumbname; int opt; enum { opt_help = 256, opt_verbose }; //#ifdef with_eclipse_CDTBUG option longOpts[] = { { /* name: */ "help" , /* has_arg: */ 0, /* flag: */ NULL, /* val: */ opt_help }, { /* name: */ "verbose", /* has_arg: */ 1, /* flag: */ NULL, /* val: */ opt_verbose } }; //#endif while ((opt = getopt_long(argc, argv, "hf:t:s:o:n:v:", longOpts, NULL)) != EOF) switch (opt) { case '?': case 'h': case opt_help: printHelpScreen(programName); return -1; case 'f': extractUint32Sort(frameNoList, optarg, ','); break; case 't': extractDoubleSort(timePosList,optarg, ','); break; case 's': { std::deque framesize; extractUint32(framesize, optarg, 'x'); if (framesize.size() != 2) { logger.error() << "please specify the size in the following way: -s320x480\n"; return -1; } width = framesize[0]; height = framesize[1]; } break; case 'o': extension = optarg; extension = "." + extension; break; case 'n': forcedThumbname = optarg; std::size_t extendPos; if ((extendPos = forcedThumbname.find_last_of(".")) != std::string::npos) { extension = forcedThumbname.substr(extendPos); forcedThumbname = forcedThumbname.substr(0,extendPos); } logger.debug() << "Forced thumbnail name is "<> verbosity; if (tempStream.fail() || verbosity < 0 || verbosity > 3) { logger.error() << "Error: Invalid verbosity \"" << optarg << "\"\n"; return(-1); } switch (verbosity) { case 0: logger.setLevel(OggLog::LOG_ERROR); break; case 1: logger.setLevel(OggLog::LOG_WARNING); break; case 2: logger.setLevel(OggLog::LOG_INFO); break; case 3: logger.setLevel(OggLog::LOG_DEBUG); } } break; } } argc -= optind; argv += optind; requestedFrameCount = frameNoList.size() + timePosList.size(); if (argc == 0) { logger.error() << "Please specify at least one ogg file\n"; return -1; } logger.info() << "Creating thumbs under the following option:\n"; if (!timePosList.empty()) { logger.info() << "Frames at time (in seconds): "; for (uint32 i(0); i tmptimePosList = timePosList; std::deque tmpframeNoList = frameNoList; if (forcedThumbname.empty()) counter=0; if (!streamSerializer.open(filename)) { logger.error() << "Error: can not open file <"<\n"; continue; } uint8 theoraStreamNo(0); /* create the headers */ std::vector streamConfigList; streamSerializer.getStreamConfig(streamConfigList); std::vector oggComments; /* Output some stream information */ for (uint32 i(0); i(*streamConfigList[i].parameter.get()); theoraDecoder.initDecoder(streamConfigList[i], oggComments); logger.info() << "Info:\n" << theoraDecoder.configuration()< 0 && theoraDecoder.getInfo().aspect_denominator > 0) aspectCorrection = (theoraDecoder.getInfo().aspect_numerator*1.0)/(theoraDecoder.getInfo().aspect_denominator*1.0); else aspectCorrection = 1; if ((width == 0) && (height == 0)) { width = theoraConfig.pictureX * aspectCorrection; //theoraConfig.frameX; height = theoraConfig.pictureY; //theoraConfig.frameY; } else { if (height == 0) height = (uint32)((width * theoraConfig.pictureY*1.0)/(theoraConfig.pictureX*aspectCorrection*1.0) + 0.5); else if (width == 0) width = (uint32)((height * theoraConfig.pictureX*aspectCorrection*1.0)/(theoraConfig.pictureY*1.0) +0.5); } logger.info() << "width: "<\n"; continue; } if (foundTheora > 2) logger.warning() << "Found more than one theora stream in file <"< using first stream\n"; /* set up first time/frame */ double nextTime; uint32 nextFrame; bool noMoreTime(false); bool noMoreFrame(false); if (tmpframeNoList.empty()) { nextFrame = std::numeric_limits::max(); noMoreFrame = true; } else { nextFrame = tmpframeNoList.front(); tmpframeNoList.pop_front(); } if (tmptimePosList.empty()) { nextTime = std::numeric_limits::max(); noMoreTime = true; } else { nextTime = tmptimePosList.front(); tmptimePosList.pop_front(); } std::deque packetList; double time; OggPacket packet; while (streamSerializer.available()) { // get the next packet time = streamSerializer.getNextPacket(packet); // is this packet a theora frame if (packet->getStreamType() != OggType::theora) continue; // write actual time logger.info() << "\r "<getPacketNo()) { if (tmpframeNoList.empty()) { nextFrame = std::numeric_limits::max(); noMoreFrame = true; } else { nextFrame = tmpframeNoList.front(); tmpframeNoList.pop_front(); } std::string thumbname = getThumbname(filename, forcedThumbname, extension, counter, requestedFrameCount); logger.info() << "writing "<= nextTime) { if (tmptimePosList.empty()) { nextTime = std::numeric_limits::max(); noMoreTime = true; } else { nextTime = tmptimePosList.front(); tmptimePosList.pop_front(); } std::string thumbname = getThumbname(filename, forcedThumbname, extension, counter, requestedFrameCount); logger.info() << "writing "< class OggComment { public: OggComment(); virtual ~OggComment(); std::string tag; std::string value; }; #endif /*OGGCOMMENT_H_*/ oggvideotools-0.9.1/src/base/mediaEncoder.cpp000664 001750 001750 00000000472 12763227102 021372 0ustar00embedembed000000 000000 #include "mediaEncoder.h" MediaEncoder::MediaEncoder() : useFixBunches(0), bunchsize(false) { } MediaEncoder::~MediaEncoder() { } void MediaEncoder::setBunchsize(uint32 _bunchsize) { bunchsize = _bunchsize; useFixBunches = true; } void MediaEncoder::useVariableBunches() { useFixBunches = false; } oggvideotools-0.9.1/src/misc/log.cpp000664 001750 001750 00000001227 12763227102 017614 0ustar00embedembed000000 000000 #include "log.h" #include OggLog logger; void OggLog::setLevel(Severity newLevel) { currentLevel = newLevel; } OggLog::Severity OggLog::getLevel() const { return currentLevel; } std::ostream & OggLog::error() const { return getStream(LOG_ERROR); } std::ostream & OggLog::warning() const { return getStream(LOG_WARNING); } std::ostream & OggLog::info() const { return getStream(LOG_INFO); } std::ostream & OggLog::debug() const { return getStream(LOG_DEBUG); } std::ostream & OggLog::getStream(Severity severity) const { if (severity >= currentLevel) { return std::cerr; } else { return (std::ostream&)fakeStream; } } oggvideotools-0.9.1/src/effect/rgbPlane.h000664 001750 001750 00000001207 12763227102 020531 0ustar00embedembed000000 000000 // // C++ Interface: rgbPlane // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #ifndef RGBPLANE_H #define RGBPLANE_H #include "refObject.h" #include "basePlane.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif /** @author Yorn */ class RGBPlane : public RefObject { public: RGBPlane(); RGBPlane(uint32 width, uint32 height, uint32 color = 0x00000000 ); virtual ~RGBPlane(); const uint32 getWidth() const { return objPtr->width; } const uint32 getHeight() const { return objPtr->height; } }; #endif oggvideotools-0.9.1/src/effect/shiftEffect.cpp000664 001750 001750 00000005320 12763227102 021564 0ustar00embedembed000000 000000 /* * shiftEffect.cpp * * Created on: 16.03.2014 * Author: seger */ #include "shiftEffect.h" #include #include #include #include "pictureBlend.h" #include "pictureResize.h" #include "log.h" #include "effectorVisitor.h" ShiftEffect::ShiftEffect() :state(unconfigured), framecounter(0) { } ShiftEffect::~ShiftEffect() { } bool ShiftEffect::available() { return((state!=unavailable) && (state!=unconfigured)); } void ShiftEffect::accept(EffectorVisitor& visitor) const { visitor.visit(*this); } Effector& ShiftEffect::operator >>(RGBPlane& plane) { switch (state) { case shifting: { doShift(plane); break; } case presentation: { doPresentation(plane); break; } default: { logger.error() << "no frame available\n"; break; } } return(*this); } void ShiftEffect::configure(ShiftConfig& _config) { framecounter = 0; config = _config; if (config.first) { lastPlane = RGBPlane(config.outputWidth, config.outputHeight); /* blank the plane */ uint32 planesize = config.outputWidth*config.outputHeight*4; // 3 Colors + Alpha channel memset(lastPlane->plane, 0x00, planesize); } /* resize the picture to the correct size */ presentationPlane = PictureResize::reframe(config.origPlane, config.outputWidth, config.outputHeight); logger.debug() << "Picture size: "<< presentationPlane->width<<" x "<width <<" -> frame size "< config.blindLength) { logger.debug() << "Presenting -- \n"; state = presentation; } } void ShiftEffect::doPresentation(RGBPlane& plane) { plane = presentationPlane; framecounter++; if (framecounter > config.sequenceLength) { lastPlane = presentationPlane; state = unavailable; } } oggvideotools-0.9.1/src/base/oggPacket.cpp000664 001750 001750 00000016330 12763227102 020717 0ustar00embedembed000000 000000 /* * OggPacket will carry all relevant information of an ogg packet * * Copyright (C) 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. * */ #include #include #include #include #include "oggPacket.h" OggPacketInternal::OggPacketInternal() : m_streamType(OggType::unknown), m_streamNo(255), m_streamHeader(false) { // create a packet without any extra data memset(&m_oggPacket,0, sizeof(m_oggPacket)); m_oggPacket.granulepos = -1; } OggPacketInternal::OggPacketInternal(const ogg_packet& pkt) : m_streamType(OggType::unknown), m_streamNo(255), m_streamHeader(false) { m_oggPacket = pkt; // it is unclear, who is the owner of the data!? uint8_t* tmp = new uint8_t [pkt.bytes]; memcpy(tmp, pkt.packet, pkt.bytes); m_oggPacket.packet = tmp; } OggPacketInternal::OggPacketInternal(uint8 *data, uint32 length, uint32 packetNo, int64 granulePos, PacketType packetType) : m_streamType(OggType::unknown), m_streamNo(255), m_streamHeader(false) { uint8_t* tmp_data(0); tmp_data = new uint8_t[length]; memcpy(tmp_data, data, length); m_oggPacket.packet = tmp_data; m_oggPacket.bytes = length; m_oggPacket.b_o_s = 0; m_oggPacket.e_o_s = 0; m_oggPacket.granulepos = granulePos; m_oggPacket.packetno = packetNo; switch (packetType) { case PacketType::bos: m_oggPacket.b_o_s = 256; break; case PacketType::eos: m_oggPacket.e_o_s = 256; break; default: { } } } OggPacketInternal::OggPacketInternal(std::vector data, uint32 packetNo, int64 granulePos, PacketType packetType) : m_streamType(OggType::unknown), m_streamNo(255), m_streamHeader(false) { uint8_t* tmp_data(0); if (data.size() > 0) { tmp_data = new uint8_t[data.size()]; memcpy(tmp_data, &data[0], data.size()); } m_oggPacket.packet = tmp_data; m_oggPacket.bytes = data.size(); m_oggPacket.b_o_s = 0; m_oggPacket.e_o_s = 0; m_oggPacket.granulepos = granulePos; m_oggPacket.packetno = packetNo; switch (packetType) { case PacketType::bos: m_oggPacket.b_o_s = 256; break; case PacketType::eos: m_oggPacket.e_o_s = 256; break; default: { } } } OggPacket OggPacketInternal::clone() { OggPacket pkt = std::make_shared(m_oggPacket); /* a bit nasty, as ogg_packet is c */ // uint8* data = new uint8[m_oggPacket.bytes]; // memcpy(data, m_oggPacket.packet, m_oggPacket.bytes); // // PacketType packetType(PacketType::normal); // // if (m_oggPacket.b_o_s) // packetType = PacketType::bos; // // if (m_oggPacket.e_o_s) // packetType = PacketType::eos; // // OggPacket pkt = std::make_shared(data, m_oggPacket.bytes, m_oggPacket.packetno, m_oggPacket.granulepos, packetType); // // pkt->m_streamNo = m_streamNo; // pkt->m_streamType = m_streamType; // pkt->m_streamHeader = m_streamHeader; return pkt; } void OggPacketInternal::liboggDelivery() { uint8_t* tmp(new uint8_t [m_oggPacket.bytes]); memcpy(tmp, m_oggPacket.packet, m_oggPacket.bytes); m_oggPacket.packet = tmp; // libtheora/libvorbis or whatever - do whatever is neccessary with your memory // I have my copy to use it wherever I like ;-) } OggPacket OggPacketInternal::getPtr() { return shared_from_this(); } OggPacket OggPacketInternal::create(uint8 *data, uint32 length, uint32 packetNo, int64 granulePos, OggPacketInternal::PacketType packetType) { return std::make_shared(data, length, packetNo, granulePos, packetType); } OggPacketInternal::~OggPacketInternal() { if (!m_streamHeader) delete[] m_oggPacket.packet; } int64 OggPacketInternal::granulepos() { return m_oggPacket.granulepos; } void OggPacketInternal::setGranulepos(int64 pos) { m_oggPacket.granulepos = pos; } void OggPacketInternal::setStreamHeader() { m_streamHeader = true; } bool OggPacketInternal::isStreamHeader() { return m_streamHeader; } uint32 OggPacketInternal::getPacketNo() { return m_oggPacket.packetno; } uint32 OggPacketInternal::length() { return (uint32) m_oggPacket.bytes; } bool OggPacketInternal::isBOS() { return m_oggPacket.b_o_s != 0; } bool OggPacketInternal::isEOS() { return m_oggPacket.e_o_s != 0; } void OggPacketInternal::setBOS() { m_oggPacket.b_o_s = 1; } void OggPacketInternal::setEOS() { m_oggPacket.e_o_s = 1; } void OggPacketInternal::unsetBOS() { m_oggPacket.b_o_s = 0; } void OggPacketInternal::unsetEOS() { m_oggPacket.e_o_s = 0; } /* ogg_packet OggPacketInternal::toLibogg() { return(*objPtr); } */ uint8 OggPacketInternal::getStreamNo() { return m_streamNo; } OggType OggPacketInternal::getStreamType() { return m_streamType; } void OggPacketInternal::setStreamNo(uint8 no) { m_streamNo = no; } void OggPacketInternal::setStreamType(OggType type) { m_streamType = type; } uint8* OggPacketInternal::data() { return m_oggPacket.packet; } /* toString levels: * 1) only data length information * 2) header information * 3) additional header information * 4) header dump * 5) body dump */ std::string OggPacketInternal::toString(uint8 level) { std::stringstream retStream; retStream << "\nOgg Packet: packet length = " << m_oggPacket.bytes << std::endl; if (level < 1) return(retStream.str()); retStream << "\nHeader Information:" << "\n\tBegin of Stream : "; if (m_oggPacket.b_o_s) retStream << "true"; else retStream << "false"; retStream << "\n\tEnd of Stream : "; if (m_oggPacket.e_o_s) retStream << "true"; else retStream << "false"; retStream << "\n\tGranule Position : " << m_oggPacket.granulepos; retStream << "\n\tPacket Number : " << m_oggPacket.packetno; retStream << std::endl; if (level < 3) return(retStream.str()); retStream << "\n\tStream Number : " << (int)m_streamNo; retStream << "\n\tStream Type : "; switch (m_streamType) { case OggType::vorbis: retStream << "Vorbis"; break; case OggType::theora: retStream << "Theora"; break; case OggType::kate: retStream << "Kate"; break; case OggType::unknown: default: retStream << "unknown"; break; } retStream << std::endl; if (level < 4) return(retStream.str()); retStream << "\nPacket Hex dump:" << std::hex; for (int32 c(0); c= 1.0) libvorbis (>= 1.2.3) -> can both be found here: http://www.xiph.org/downloads/ libgd -> can be found here: http://www.libgd.org/Downloads/ If you have questions regarding the ogg video tools, write a mail (yorn_at_gmx_dot_net) or join the developers mailing list at https://lists.sourceforge.net/lists/listinfo/oggvideotools-users Have fun Yorn oggvideotools-0.9.1/src/misc/log.h000664 001750 001750 00000001371 12763227102 017261 0ustar00embedembed000000 000000 #ifndef LOG_H #define LOG_H #include class FakeStreambuf : public std::streambuf { public: FakeStreambuf() {} }; class FakeStream : public std::ostream { public: FakeStreambuf buf; FakeStream() : std::ostream(&buf) {} }; class OggLog { public: enum Severity { LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR }; OggLog() : currentLevel(LOG_INFO) {} void setLevel(Severity newLevel); Severity getLevel() const; std::ostream & error() const; std::ostream & warning() const; std::ostream & info() const; std::ostream & debug() const; std::ostream & getStream(Severity severity) const; protected: Severity currentLevel; FakeStream fakeStream; }; // Global instance extern OggLog logger; #endif oggvideotools-0.9.1/docs/oggDump.1000664 001750 001750 00000002604 12763227102 017221 0ustar00embedembed000000 000000 .TH OGGDUMP 1 "JAN 2010" Linux "User Manuals" .SH NAME oggDump \- prints out information of ogg video files (.ogv, .ogg or oga) .SH SYNOPSIS .B oggDump [options] file.ogv .SH DESCRIPTION .B OggDump gives detailed information about an ogg video file and prints these information with a given detail level. Ogg files consist of a number of streams (video and audio). From the Ogg-container perspective, the streams are devided into pages. These pages usually have nearly the same size. The pages can be printed out with the -g option. From the stream perspective, every stream consists of packets. These packets carry a bunch of compressed audio samples in case of a vorbis stream or one video frame in case of a theora video stream. These packets could be of variable length and are places into the ogg pages. To toString the packets, use the -p option. .SH OPTIONS .IP \-g Dumps the stream pages of the file. .IP \-p Dumps the stream packets. .IP \-l .B . Set the dump level (1-5). Default is 5, which means all information are printed. .IP \-s Prompt for the stream that should be dumped. All other streams are ignored and will not be printed. .IP \-o .B Write the dump information to a file. .SH AUTHOR Joern Seger .SH "SEE ALSO" .BR oggCut (1), .BR oggJoin (1), .BR oggSplit (1), .BR oggTranscode^ (1), .BR oggSlideshow (1), .BR oggThumb (1), .BR oggSilence (1) oggvideotools-0.9.1/src/ovt_vorbis/vorbisHeader.h000664 001750 001750 00000000502 12763227102 022351 0ustar00embedembed000000 000000 #ifndef VORBISHEADER_H_ #define VORBISHEADER_H_ struct VorbisHeader { uint32 version; uint8 audioChannels; uint32 sampleRate; uint32 bitrateMax; uint32 bitrateNom; uint32 bitrateMin; uint8 blocksize0:4; uint8 blocksize1:4; uint8 framing; //? } __attribute__ ((packed)); #endif /*VORBISHEADER_H_*/ oggvideotools-0.9.1/src/base/oggPage.h000664 001750 001750 00000004744 12763227102 020037 0ustar00embedembed000000 000000 /* * OggPage will carry all relevant information of an ogg page * * Copyright (C) 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. * */ #ifndef OGGPAGE_H_ #define OGGPAGE_H_ #include #include #include #include #include "definition.h" /// class to store one ogg page /** this class is easy to handle, as it only carries the * data area that starts with "OggS". **/ class OggPageInternal; typedef std::shared_ptr OggPage; class OggPageInternal : public std::enable_shared_from_this { protected: //! pointer to the packet data std::vector m_dataPtr; uint32 m_headerLength; uint32 m_bodyLength; uint8 m_streamNo; bool m_empty; public: OggPageInternal(); OggPageInternal(std::vector& data, uint32 headerLength, uint32 bodyLength); ~OggPageInternal(); //! Is this page continued ? bool isContinued(); //! Is this page a "Begin of Stream" page ? bool isBOS(); //! Is this page an "End of Stream" page ? /*! Every stream within a file (e.g. audio stream and video stream) has it's own eos flag */ bool isEOS(); bool isEmpty(); void setContinued(); void setEOS(); void unsetEOS(); void setBOS(); void unsetBOS(); /* what ogg version is this stream */ uint32 version(); uint32 packets(); int64 granulepos(); uint32 serialno(); uint32 pageno(); void createCRC(); uint8 getStreamNo(); void setStreamNo(uint8 streamNo); uint32 length(); std::vector& data(); uint32 getHeaderLength() { return m_headerLength; } OggPage clone(); OggPage create(std::vector& data, uint32_t headerLength, uint32_t bodyLength); OggPage getPtr(); std::string toString(uint8 level); }; #endif /*OGGPAGE_H_*/ oggvideotools-0.9.1/cpackInfo/COPYING.rtf000664 001750 001750 00000037146 12763227102 020340 0ustar00embedembed000000 000000 {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf460 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \margl1440\margr1440\vieww11700\viewh13280\viewkind0 \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \f0\fs34 \cf0 GNU GENERAL PUBLIC LICENSE\ Version 2, June 1991 \fs24 \ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural \cf0 \ \b Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.\ \b0 \ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \fs36 \cf0 Preamble \fs24 \ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural \cf0 \ The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General PublicLicense is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too.\ \ When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.\ \ To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you\ distribute copies of the software, or if you modify it.\ \ For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.\ \ We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.\ \ Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.\ \ Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.\ \ The precise terms and conditions for copying, distribution and modification follow.\ \ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \fs30 \cf0 GNU GENERAL PUBLIC LICENSE\ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION \fs34 \ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural \fs24 \cf0 \ 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below,\ refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".\ \ Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.\ \ 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.\ \ You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.\ \ 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:\ \ a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.\ \ b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.\ \ c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally toString such an announcement, your work based on the Program is not required to toString an announcement.)\ \ These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in\ themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based\ on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.\ \ Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.\ \ In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under\ the scope of this License.\ \ 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:\ \ a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,\ \ b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,\ \ c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)\ \ The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include\ anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.\ \ If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.\ \ 4. You may not copy, modify, sublicense, or distribute the Programexcept as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.\ \ 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.\ \ 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.\ \ 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.\ \ If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.\ \ It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.\ \ This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.\ \ 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.\ \ 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.\ \ Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the FreeSoftware Foundation.\ \ 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.\ \ NO WARRANTY\ \ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\ \ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\ \ }oggvideotools-0.9.1/docs/oggThumb.1000664 001750 001750 00000005071 12763227102 017374 0ustar00embedembed000000 000000 .TH OGGTHUMB 1 "JAN 2010" Linux "User Manuals" .SH NAME oggThumb \- creates thumbnails from an ogg video file .SH SYNOPSIS .B oggThumb [options] file1.ogv [ file2.ogv [ file3.ogv [...] ] ] .SH DESCRIPTION .B oggThumb creates Thumbnails from one or more ogg video files, at a given time position or a given frame number. It is also possible to create a series of thumbnails at different time or frame positions. The pictures can be created in JPG or PNG format and can be resized to any given size. The default naming of each thumbnail series follows the following rule: .I _x. Where x starts with 0 and is incremented with every created thumbnail. So the thumbnails are successivly numbered by the appearence order. This is even valid, if time positions and frame numbers are mixed. .SH OPTIONS .IP -t Time at which a thumbnail should be created. More than one thumbnail time can be concatenated by komas. The times can be set by integer or floating point values in seconds. If the time is not exactly matching, the next frame is used. The times don't have to be sorted incrementally. .I Example: \-t 12.4,14.157,13.23 .IP -f Number of a frame that should be created as a thumbnail. More than one thumbnail frame can be concatenated by komas. The frame numbers must be an integers. The frame numbers don't have to be sorted incrementally. .I Example: \-f 12000,13000,11000 .IP -s Picture output size. The thumbnail is created in the size given as x. If you want to include the thumbnails into your webpage and you need to have a fixed width but dynamic height, you can set the dynamic axis to 0. So the aspect ratio of the video frame is kept. This is the same for setting width or height to 0. .I Example: \-s 0x100 .IP -o Output format. This can be png or jpg. The default is jpg. .I Example: \-o png .IP -n Alternative thumbnail picture name. The % can be used within the name to indicate the counter placeholder. In case of more than one video file, the counter continuous throughout the different videos, so that the pictures are not overwritten. If the name has an extension. This extension is used to identify the output picture format. .I Example: \-n myNo_%_thumb .SH EXAMPLE .I oggThumb \-t 10.3,22.4,31.9,43.4,59.4 \-f 1200 \-s 0x100 myFile.ogv .I oggThumb \-f 200,400,300,100 -t 3.54 -n %_thumb.png myfile.ogv mysecondfile.ogv .SH AUTHOR Joern Seger .SH "SEE ALSO" .BR oggCut (1), .BR oggCat (1), .BR oggJoin (1), .BR oggSplit (1), .BR oggTranscode (1), .BR oggSlideshow (1), .BR oggSilence (1)oggvideotools-0.9.1/src/effect/pictureResize.h000664 001750 001750 00000003437 12763227102 021643 0ustar00embedembed000000 000000 // // C++ Interface: pictureResize // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #ifndef PICTURERESIZE_H #define PICTURERESIZE_H #include "definition.h" #include "rgbPlane.h" /** @author Yorn */ class PictureResize { protected: static uint32 calculateKernelValue(RGBPlane& pic, float posX, float posY, float radius, bool p=false); static float getWeight(float distance, float radius); static uint32 calculateKernelValueFix(RGBPlane& pic, float posX, float posY, float radius, bool p=false); static int32 getWeightFix(uint32 distance, uint32 radius); static uint32 linearInterpolation(RGBPlane pic, float x, float y); public: PictureResize(); virtual ~PictureResize(); //! Method transforms the original picture through a lowpass/bluring filter static RGBPlane kernelLowpass(RGBPlane& picture, float radius=1); //! method resizes the picture and stretches if necessary static RGBPlane resize(RGBPlane& picture, uint32 width, uint32 height, uint8 quality=1); static RGBPlane resize(RGBPlane& picture, float factorX, float factorY, uint8 quality=1); static RGBPlane resize(RGBPlane& picture, float factor, uint8 quality=1); //! Method keeps the aspect ratio during resize static RGBPlane reframe(RGBPlane& picture, uint32 width, uint32 height, uint8 quality=1, uint32 background=0, double aspectCorrection=1); static RGBPlane reframe_fixed(RGBPlane & picture, uint32 width, uint32 height, uint32 background); static RGBPlane subframe(RGBPlane& picture, uint32 newWidth, uint32 newHeight, float offsetWidth, float offsetHeight, float resizeFactor, uint8 quality=1); static RGBPlane concatenate(RGBPlane& picture1, RGBPlane& picture2, RGBPlane& picture3); }; #endif oggvideotools-0.9.1/restyle.sh000775 001750 001750 00000000164 12763227102 016632 0ustar00embedembed000000 000000 #!/bin/bash astyle --style=stroustrup -s2 --recursive *.cpp astyle --style=stroustrup -s2 --recursive *.h src/*.h oggvideotools-0.9.1/src/base/oggStreamDecoder.cpp000664 001750 001750 00000013572 12763227102 022236 0ustar00embedembed000000 000000 /* * oggStreamDecoder is a class to extract an ogg packet from an * ogg page stream * * Copyright (C) 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. * */ #include #include #include #include "definition.h" #include "oggHeader.h" #include "oggStreamDecoder.h" #include "exception.h" #include "log.h" OggStreamDecoder::SegmentElement::SegmentElement(uint8* _data, uint32 length) : data(_data), length(length) { } OggStreamDecoder::OggStreamDecoder() { } OggStreamDecoder::~OggStreamDecoder() { clear(); } void OggStreamDecoder::init(OggPage page) { /* if this is not a Begin Of Stream page, do nothing */ if (!page->isBOS()) { logger.error() << "OggStreamDecoder: ogg page is not a begin of stream\n"; return; } m_packetCount = 0; /* extract and remember the serial number of this stream */ m_serialNo = page->serialno(); setConfigured(); } void OggStreamDecoder::clear() { delete[] m_tmpSegment.data; m_tmpSegment.data = 0; m_tmpSegment.length = 0; } uint32 OggStreamDecoder::getSerialNo() { return(m_serialNo); } OggStreamDecoder& OggStreamDecoder::operator<<(OggPage& page) { /* if this stream is not initialized, try to initialize it */ if (!isInitialized()) init(page); /* decode the packets */ if (!isConfigured()) { throw OggException("OggStreamDecoder::operator<<: This stream is not is not configured yet"); } if (page->serialno() != m_serialNo) { throw OggException("OggStreamDecoder::operator<<: page does not belong to this stream"); } /* extract the header */ uint8* data(&(page->data())[0]); OggHeader* header = (OggHeader*)(data); data += sizeof(OggHeader); /* extract the relevant data from the header */ unsigned char tableSegments(header->tableSegments); // extract the segment table uint8* segment = (uint8*) data; data += tableSegments; /* will the last packet be continued on in the next page? */ bool willBeContinued; if (segment[header->tableSegments-1] != 255) willBeContinued = false; else willBeContinued = true; std::vector segmentDataList; // extract pointers to the packets in this page SegmentElement segData(data,0); for (unsigned int i=0; i 1) infoPosition = segmentDataList.size()-2; // now extract the ogg packets itself // every segment in the list is one packet (maybe there is a // remaining part in tmpSegment from the page before and // there might be a segment, that is not finished on this page) for (unsigned int i(0); iisBOS())) packetType = OggPacketInternal::PacketType::bos; if ((i == segmentDataList.size()-1) && (page->isEOS())) packetType = OggPacketInternal::PacketType::eos; if (i == infoPosition) granulePosition = header->position; /* create the packet */ OggPacket packet(new OggPacketInternal(newPacketPtr, overallLength, m_packetCount++, granulePosition, packetType)); delete[] newPacketPtr; m_oggPacketList.push_back(packet); } } if (!m_oggPacketList.empty()) setAvailable(); return(*this); } OggPacket OggStreamDecoder::inspectNextPacket() { OggPacket packet; if (!isAvailable()) { throw OggException("OggStreamDecoder::inspectNextPacket: no packet available"); } // we will not harm the list in any kind packet = m_oggPacketList.front(); return (packet); } OggStreamDecoder& OggStreamDecoder::operator>>(OggPacket& packet) { if (!isAvailable()) { throw OggException("OggStreamDecoder::operator>>: no packet available"); } packet = m_oggPacketList.front(); m_oggPacketList.pop_front(); /* is this the last packet within this stream, * then set the stream status */ if (packet->isEOS()) { setEndOfStream(); } else { if (m_oggPacketList.empty()) { setEmpty(); } } return(*this); } oggvideotools-0.9.1/src/ovt_vorbis/audioPacket.cpp000664 001750 001750 00000003714 12763227102 022530 0ustar00embedembed000000 000000 #include "audioPacket.h" #include #include #include "log.h" AudioPacketInternal::AudioPacketInternal() : pcmData(0), length(0), channels(0) { } AudioPacketInternal::~AudioPacketInternal() { cleanup(); } AudioPacketInternal::AudioPacketInternal(const AudioPacketInternal& packet) : pcmData(0), length(packet.length), channels(packet.channels) { /* create memory region */ initMem(channels, length); /* copy data */ for (uint8 i(0); i= channels) || (pcmData[channel] == 0)) return; memcpy(pcmData[channel], _dataPtr, length*sizeof(float)); } void AudioPacketInternal::cleanup() { if (pcmData != 0) { for (uint8 ch(0); ch #include #include "mediaOutputDecoder.h" #include "mediaInputEncoder.h" #include "oggComment.h" class HookHandler { protected: bool copyOnly; /* specifies, if resize is disallowed */ bool reencode; bool keepComments; uint64 inPacketCounter; uint64 outPacketCounter; std::vector comments; std::unique_ptr outputDecoder; std::unique_ptr inputEncoder; std::deque packetList; public: HookHandler(const bool copy=true, const bool keepComments=true); virtual ~HookHandler(); virtual void setDecoderConfig(StreamConfig& config, std::vector& commentList); virtual void setEncoderConfig(StreamConfig& config, std::vector& commentList); virtual void resetEncoder(); void setCopyOnly(); bool isCopyOnly(); void resetCopyOnly(); void forceReencoding(); void resetForceReencoding(); //! method to compare both configurations and to calculate the reencoding parameters virtual void initAndConnect() = 0; virtual HookHandler& operator<<(OggPacket& packet) = 0; virtual HookHandler& operator>>(OggPacket& packet); virtual OggType getType() const; virtual bool available(); virtual void flush() = 0; virtual std::string decoderConfiguration() const; virtual std::string encoderConfiguration() const; }; inline void HookHandler::setCopyOnly() { copyOnly = true; } inline bool HookHandler::isCopyOnly() { return(copyOnly); } inline void HookHandler::resetCopyOnly() { copyOnly = false; } inline void HookHandler::forceReencoding() { reencode = true; } inline void HookHandler::resetForceReencoding() { reencode = false; } #endif /*HOOKHANDLER_H_*/ oggvideotools-0.9.1/src/effect/CMakeLists.txt000664 001750 001750 00000000656 12763227102 021375 0ustar00embedembed000000 000000 SET ( LIBRARY_VIDEOEFFECT_SRC effector.cpp effectorTypes.cpp effectorVisitor.cpp crossfader.cpp plainPicture.cpp lowpassEffect.cpp kenburnseffect.cpp pictureResize.cpp pictureBlend.cpp pictureLoader.cpp shiftEffect.cpp shiftblendEffect.cpp basePlane.cpp rgbPlane.cpp blendElement.cpp ) ADD_LIBRARY ( ovteffect ${LIBRARY_VIDEOEFFECT_SRC} ) oggvideotools-0.9.1/src/main/cmdlineextractor.h000664 001750 001750 00000003670 12763227102 022044 0ustar00embedembed000000 000000 // // C++ Interface: cmdlineextractor // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #ifndef CMDLINEEXTRACTOR_H #define CMDLINEEXTRACTOR_H #include #include #include #include "definition.h" #include "oggComment.h" #include "blendElement.h" #include "effectorTypes.h" const std::string validChars ( "0123456789,x" ); const std::string validTextChars ( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 /\\.,=;:-_" ); class SlideshowElement { public: std::string filename; float duration; EffectorType type; uint32 startPosX; uint32 startPosY; float startZoom; uint32 endPosX; uint32 endPosY; float endZoom; }; class CmdlineExtractor { public: CmdlineExtractor(); ~CmdlineExtractor(); static void extractCommentPairs ( std::vector& list, const std::string& _argument, char tokenSeparator, char commentSeparator ); static void extractUint32 ( std::deque& list, const std::string& _argument, char seperator ); static void extractBlend ( std::vector& list, const std::string& _argument, char tokenSeparator, char valueSeparator ); static uint32 atoi(const std::string& _argument); static float atof(const std::string& _argument); static uint32 getNextUint32(std::string& substring, char tokenSeparator); static float getNextFloat(std::string& substring, char tokenSeparator); static std::string getNextString(std::string& substring, char tokenSeparator); static void extractSlideshow(const std::string& _argument, char tokenSeparator, SlideshowElement& slideShowElement); static void extractCrossSequence(std::vector& list, const std::string& _argument, char tokenSeparator); }; #endif oggvideotools-0.9.1/build/000775 001750 001750 00000000000 12763227225 015710 5ustar00embedembed000000 000000 oggvideotools-0.9.1/src/main/audioHook.cpp000664 001750 001750 00000007143 12763227102 020751 0ustar00embedembed000000 000000 #include "audioHook.h" #include #include "exception.h" #include "vorbisEncoder.h" #include "vorbisDecoder.h" #include "log.h" AudioHook::AudioHook() {} AudioHook::AudioHook(uint8 outStreamID, const bool copy, const bool keepComments) : HookHandler(copy, keepComments), changeAudioSamplerate(false), changeChannel(false) { // logger.debug() << "Vorbis Encoder stream No "<<(int)outStreamID<(*outputDecoder.get()); VorbisEncoder& encoder = static_cast(*inputEncoder.get()); copy = true; if (!copyOnly) copy = decoder.getInfo() == encoder.getInfo(); if (!copy) { if (decoder.getInfo().channels != encoder.getInfo().channels) changeChannel = true; if (decoder.getInfo().rate != encoder.getInfo().rate) changeAudioSamplerate = true; } converter.closeResample(); converter.initResample(encoder.getInfo().channels, (encoder.getInfo().rate * 1.0 ) / (decoder.getInfo().rate * 1.0 )); } static uint64 cnt(0); HookHandler& AudioHook::operator<<(OggPacket& packet) { if (!outputDecoder) throw OggException("AudioHook::callHook: no outputDecoder given"); if (!inputEncoder) throw OggException("AudioHook::callHook: no inputEncoder given"); VorbisDecoder& decoder = static_cast(*outputDecoder); VorbisEncoder& encoder = static_cast(*inputEncoder); if (copy) { packet->setStreamNo(encoder.getStreamNo()); packetList.push_back(packet); } else { // relevant packet try { decoder << packet; while ( decoder.isAvailable() ) { decoder >> audioPacket; if ( changeAudioSamplerate || changeChannel ) { AudioPacket tmp; if ( converter.resample ( audioPacket,tmp ) ) { encoder << tmp; } } else { encoder << audioPacket; } while ( encoder.isAvailable() ) { OggPacket pckt; encoder >> pckt; packetList.push_back(pckt); } // 16868466 } } catch ( std::exception error ) { logger.error() << "Exception: " << error.what(); } } } void AudioHook::flush() { if (!outputDecoder) throw OggException("AudioHook::callHook: no outputDecoder given"); if (!inputEncoder) throw OggException("AudioHook::callHook: no inputEncoder given"); VorbisDecoder& decoder = static_cast(*outputDecoder); VorbisEncoder& encoder = static_cast(*inputEncoder); /* write resampled data, if there is some */ if (converter.resampleflush(audioPacket)) { if ( audioPacket->getLength() > 0 ) encoder << audioPacket; } encoder.flush(); while ( encoder.isAvailable() ) { OggPacket pckt; encoder >> pckt; packetList.push_back(pckt); } } OggType AudioHook::getType() const { return(OggType::vorbis); } static bool operator==(const vorbis_info& info1, const vorbis_info& info2) { return ((info1.bitrate_lower == info2.bitrate_lower) && (info1.bitrate_nominal == info2.bitrate_nominal) && (info1.bitrate_upper == info2.bitrate_upper) && (info1.bitrate_window == info2.bitrate_window) && (info1.channels == info2.channels) && (info1.rate == info2.rate) ); } static bool operator!=(const vorbis_info& info1, const vorbis_info& info2) { return(!(info1==info2)); } oggvideotools-0.9.1/src/effect/crossfader.cpp000664 001750 001750 00000004246 12763227102 021473 0ustar00embedembed000000 000000 // // C++ Implementation: crossfader // // Description: // // // Author: Yorn , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // #include "crossfader.h" #include #include #include "pictureBlend.h" #include "pictureResize.h" #include "log.h" #include "effectorVisitor.h" Crossfader::Crossfader() : Effector(), state(unconfigured), framecounter(0) { } Crossfader::~Crossfader() { } void Crossfader::configure(CrossfaderConfig& _config) { framecounter = 0; config = _config; if (config.first) { lastPlane = RGBPlane(config.outputWidth, config.outputHeight); /* blank the plane */ uint32 planesize = config.outputWidth*config.outputHeight*4; // 3 Colors + Alpha channel memset(lastPlane->plane, 0x00, planesize); } /* resize the picture to the correct size */ presentationPlane = PictureResize::reframe(config.origPlane, config.outputWidth, config.outputHeight); logger.debug() << "Picture size: "<< presentationPlane->width<<" x "<height <<" -> frame size "< config.blindLength) { state = presentation; } } void Crossfader::doPresentation(RGBPlane & plane) { plane = presentationPlane; framecounter++; if (framecounter > config.sequenceLength) { lastPlane = presentationPlane; state = unavailable; } } bool Crossfader::available() { return((state!=unavailable) && (state!=unconfigured)); } void Crossfader::accept(EffectorVisitor& visitor) const { visitor.visit(*this); } Effector & Crossfader::operator >>(RGBPlane & plane) { switch (state) { case crossfade: { doCrossfade(plane); break; } case presentation: { doPresentation(plane); break; } default: { logger.error() << "KenBurnsEffect: no frame available\n"; break; } } return(*this); } oggvideotools-0.9.1/src/effect/shiftblendEffect.h000664 001750 001750 00000002066 12763227102 022242 0ustar00embedembed000000 000000 /* * ShiftblendEffect.h * * Created on: 16.03.2014 * Author: seger */ #ifndef SHIFTBLENDEFFECT_H_ #define SHIFTBLENDEFFECT_H_ #include "effector.h" class ShiftblendEffect: public Effector { public: class ShiftConfig { public: bool first; uint32 sequenceLength; /* in frames */ uint32 blindLength; /* in frames */ uint32 outputWidth; uint32 outputHeight; enum Type { Left, Right }; Type type; RGBPlane origPlane; }; protected: RGBPlane presentationPlane; enum State { unconfigured, shifting, presentation, unavailable }; State state; RGBPlane lastPlane; RGBPlane shiftPlane; uint32 framecounter; ShiftConfig config; void doShift(RGBPlane& plane); void doPresentation(RGBPlane& plane); public: ShiftblendEffect(); virtual ~ShiftblendEffect(); void configure(ShiftConfig& config); virtual Effector& operator>>(RGBPlane& plane); virtual bool available(); virtual void accept(EffectorVisitor& visitor) const; }; #endif /* ShiftblendEffect_H_ */ oggvideotools-0.9.1/CMakeLists.txt000775 001750 001750 00000014053 12763227102 017351 0ustar00embedembed000000 000000 cmake_minimum_required(VERSION 2.8) PROJECT ( "OggVideoTools" ) SET ( PACKAGE_NAME "oggvideotools" ) SET ( PACKAGE_VERSION "0.9.1" ) SET ( PACKAGE_BUGREPORT "yorn@gmx.net" ) INCLUDE (CheckIncludeFiles) CHECK_INCLUDE_FILES ( bzero.h HAVE_BZERO_H) CHECK_INCLUDE_FILES ( stdint.h HAVE_STDINT_H ) IF ( $ENV{MAKE_PACKAGE} ) find_library ( GD_GD_LIBRARY NAMES bgd.dll ) find_library ( JPEG_GD_LIBRARY NAMES libjpeg.a libjpeg.lib jpeg.lib ) find_library ( PNG_GD_LIBRARY NAMES libpng.a libpng.lib ) find_library ( Z_GD_LIBRARY NAMES libz ) SET ( GD_LIBRARIES ${GD_GD_LIBRARY} ${JPEG_GD_LIBRARY} ${PNG_GD_LIBRARY} ${Z_GD_LIBRARY} ) find_library ( GD_EXTERNAL NAMES bgd.dll ) find_library ( THEORADEC_LIBRARIES NAMES libtheoradec ) find_library ( THEORAENC_LIBRARIES NAMES libtheoraenc ) find_library ( VORBIS_LIBRARIES NAMES libvorbis.a ) find_library ( VORBISENC_LIBRARIES NAMES libvorbisenc.a ) find_library ( OGG_LIBRARIES NAMES libogg.a ) find_path ( OGG_INCLUDE_DIRS ogg/ogg.h ) SET ( HAVE_LIBTHEORAENC 1 CACHE INTERNAL "" ) SET ( HAVE_LIBTHEORADEC 1 CACHE INTERNAL "" ) SET ( HAVE_LIBVORBIS 1 CACHE INTERNAL "" ) SET ( HAVE_LIBVORBISENC 1 CACHE INTERNAL "") SET ( HAVE_LIBOGG 1 CACHE INTERNAL "" ) SET ( HAVE_LIBGD 1 CACHE INTERNAL "" ) SET ( ALL_STATIC_LIBS ${GD_LIBRARIES} ${THEORADEC_LIBRARIES} ${THEORAENC_LIBRARIES} ${VORBIS_LIBRARIES} ${VORBISENC_LIBRARIES} ${OGG_LIBRARIES} ) ELSE ( $ENV{MAKE_PACKAGE} ) FIND_PACKAGE ( PkgConfig ) pkg_check_modules ( THEORADEC theoradec>=1.1 ) pkg_check_modules ( THEORAENC theoraenc>=1.1 ) pkg_check_modules ( VORBIS vorbis>=1.2.3 ) pkg_check_modules ( VORBISENC vorbisenc>=1.2.3 ) pkg_check_modules ( OGG ogg>=1.1.0 ) find_library ( GD_LIBRARY NAMES gd ) ENDIF ( $ENV{MAKE_PACKAGE} ) find_path ( GD_INCLUDE gd.h ) IF ( $ENV{MAKE_PACKAGE} ) MESSAGE ( "Do creating package" ) ELSE ( $ENV{MAKE_PACKAGE} ) SET ( ALL_LIBS ) SET ( STOP_CONFIGURATION ) IF ( THEORAENC_FOUND ) MESSAGE ( STATUS "Theora encoder library found" ) SET ( HAVE_LIBTHEORAENC 1 CACHE INTERNAL "" ) SET ( ALL_LIBS ${ALL_LIBS} ${THEORAENC_LIBRARIES} ) ELSE ( THEORAENC_FOUND ) MESSAGE ( STATUS "ERROR: Theora encoder library NOT found" ) SET ( STOP_CONFIGURATION true ) ENDIF ( THEORAENC_FOUND ) IF ( THEORADEC_FOUND ) MESSAGE ( STATUS "Theora decoder library found" ) SET ( HAVE_LIBTHEORADEC 1 CACHE INTERNAL "" ) SET ( ALL_LIBS ${ALL_LIBS} ${THEORADEC_LIBRARIES} ) ELSE ( THEORADEC_FOUND ) MESSAGE ( STATUS "ERROR: Theora decoder library NOT found" ) SET ( STOP_CONFIGURATION true ) ENDIF ( THEORADEC_FOUND ) IF ( VORBIS_FOUND ) MESSAGE ( STATUS "Vorbis library found" ) SET ( HAVE_LIBVORBIS 1 CACHE INTERNAL "" ) SET ( ALL_LIBS ${ALL_LIBS} ${VORBIS_LIBRARIES} ) ELSE ( VORBIS_FOUND ) MESSAGE ( STATUS "ERROR: Vorbis library NOT found" ) SET ( STOP_CONFIGURATION true ) ENDIF ( VORBIS_FOUND ) IF ( VORBISENC_FOUND ) MESSAGE ( STATUS "Vorbis encoder library found" ) SET ( HAVE_LIBVORBISENC 1 CACHE INTERNAL "") SET ( ALL_LIBS ${ALL_LIBS} ${VORBISENC_LIBRARIES} ) ELSE ( VORBISENC_FOUND ) MESSAGE ( STATUS "ERROR: Vorbis encoder library NOT found" ) SET ( STOP_CONFIGURATION true ) ENDIF ( VORBISENC_FOUND ) IF ( OGG_FOUND ) MESSAGE ( STATUS "ogg library found" ) SET ( HAVE_LIBOGG 1 CACHE INTERNAL "" ) SET ( ALL_LIBS ${ALL_LIBS} ${OGG_LIBRARIES} ) ELSE ( OGG_FOUND ) MESSAGE ( STATUS "ERROR: ogg library NOT found" ) SET ( STOP_CONFIGURATION true ) ENDIF ( OGG_FOUND ) IF ( NOT ${GD_LIBRARY} MATCHES GD_LIBRARY-NOTFOUND ) MESSAGE ( STATUS "GD library and header found" ) SET ( HAVE_LIBGD 1 CACHE INTERNAL "" ) SET ( ALL_LIBS ${ALL_LIBS} ${GD_LIBRARY} ) INCLUDE_DIRECTORIES ( ${GD_INCLUDE} ) ELSE ( NOT ${GD_LIBRARY} MATCHES GD_LIBRARY-NOTFOUND ) MESSAGE ( STATUS "GD library and/or header NOT found" ) # SET ( STOP_CONFIGURATION true ) ENDIF ( NOT ${GD_LIBRARY} MATCHES GD_LIBRARY-NOTFOUND ) IF ( STOP_CONFIGURATION ) MESSAGE ( FATAL_ERROR "Some libraries are missing - stopping configuration" ) ENDIF ( STOP_CONFIGURATION ) ENDIF ( $ENV{MAKE_PACKAGE} ) MESSAGE ( "Creating config.h" ) CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) ADD_DEFINITIONS ( -DHAVE_CONFIG_H ) ADD_DEFINITIONS ( "-DPACKAGE_STRING=\"${PACKAGE_NAME}-${PACKAGE_VERSION}\"" ) ADD_DEFINITIONS ( -D_FILE_OFFSET_BITS=64 -Wno-write-strings ) #ADD_DEFINITIONS ( -DDEBUG ) ADD_DEFINITIONS ( -O0 -g --std=c++0x -fPIC ) IF ( HAVE_LIBGD ) ADD_DEFINITIONS ( -DWITH_GD2LIB ) ENDIF (HAVE_LIBGD ) INCLUDE_DIRECTORIES ( ${CMAKE_BINARY_DIR} ) # HAVE_STDINT_H # HAVE_BZERO_H ADD_SUBDIRECTORY ( src ) ADD_SUBDIRECTORY ( docs ) IF ( NOT WIN32 ) ADD_SUBDIRECTORY ( scripts ) ENDIF ( NOT WIN32 ) # information for packaging INCLUDE ( InstallRequiredSystemLibraries ) SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Ogg Video Tools for video editing") SET(CPACK_PACKAGE_VENDOR "Yorn") SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README") SET(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/cpackInfo/ReadMe.rtf") SET(CPACK_RESOURCE_FILE_WELCOME "${CMAKE_SOURCE_DIR}/cpackInfo/Welcome.rtf") SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/cpackInfo/COPYING.rtf") SET(CPACK_PACKAGE_VERSION_MAJOR "0") SET(CPACK_PACKAGE_VERSION_MINOR "9") SET(CPACK_PACKAGE_VERSION_PATCH "") SET(CPACK_PACKAGE_INSTALL_DIRECTORY "OggVideoTools") IF(WIN32 AND NOT UNIX) # There is a bug in NSI that does not handle full unix paths properly. Make # sure there is at least one set of four (4) backlasshes. # SET(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\InstallIcon.bmp") # SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\MyExecutable.exe") SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} Ogg Video Tools") SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\dev.streamnik.de") SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\dev.streamnik.de") SET(CPACK_NSIS_CONTACT "yorn@gmx.net") SET(CPACK_NSIS_MODIFY_PATH ON) ELSE(WIN32 AND NOT UNIX) SET(CPACK_STRIP_FILES ${EXECUTABLES}) SET(CPACK_SOURCE_STRIP_FILES ${EXECUTABLES} ) ENDIF(WIN32 AND NOT UNIX) SET(CPACK_PACKAGE_EXECUTABLES ${EXECUTABLES} ) INCLUDE(CPack) oggvideotools-0.9.1/scripts/mkSlideshow000775 001750 001750 00000004413 12763227102 020513 0ustar00embedembed000000 000000 #!/bin/sh # # usage: ./mkSlideshow ~/mypicDir/ audiofile.oga outputFile.ogm # # Variables to be changed # # video frame size SIZE="800x450" # # data rate of the outgoing slideshow stream in bit/s DATARATE="2048000" # # presentation time of one picture in seconds PR_TIME="10" # # frame rate in pictures/s FRAMERATE="24" # # reframe picture # This adds black borders to picture to meet the aspect ratio # of the video frame size specified earlier. # With the Ken Burns effect, this is not strictly necessary, # but the sliding may be smoother #REFRAME="-e" or "" REFRAME="-e" # # resample # This option says, how the picture should be loaded (by gdlib) # As the resize mechanism of gdlib is really good, it is used to # bring it do a value "near" the video frame size (usually a bit # bigger). You usually do not see a big difference, if you change # this value :-), so keep it as it is (default = 1.2) RESAMPLE="1.2" # # slideshow type # kb - Ken Burns Effect (sliding and zooming) # p - plain (picture display only, no crossfade between pictures) # cf - crossfade (picture display, crossfading between pictures) TYPE="kb" # # # Temporal file name TMP_VIDEOFILE="slideshow_tmp.ogv" TMP_AUDIOFILE="audio_tmp.oga" if [ $# -ne 3 ] then echo "usage $0 .oga .ogv" exit fi echo echo "Creating a slideshow with the following data" echo echo "Audio file : $2" echo "Created file: $3" echo "Pictures to be presented are:" ls "$1"/*.jpg echo echo "Command line for oggSlideshow is:" echo "oggSlideshow -s $SIZE -d $DATARATE -l $PR_TIME -f $FRAMERATE \ " echo " $REFRAME -r $RESAMPLE -t $TYPE -o $TMP_VIDEOFILE $1/*.jpg " # creating the slideshow oggSlideshow -s $SIZE -d $DATARATE -l $PR_TIME -f $FRAMERATE \ $REFRAME -r $RESAMPLE -t $TYPE -o $TMP_VIDEOFILE "$1"/*.jpg # what is the length of this LENGTHVIDEO=`oggLength $TMP_VIDEOFILE` # # cut the audio file LENGTHAUDIO=`oggLength $2` # # is the audio file to short? last="newfile" if [ $LENGTHVIDEO -gt $LENGTHAUDIO ] then echo "warning slideshow ($LENGTHVIDEO) is longer than your audio file ($LENGTHAUDIO)" exit -1 fi # cutting the audiofile oggCut -l$LENGTHVIDEO -i$2 -o$TMP_AUDIOFILE # # Join audio and video file oggJoin $3 $TMP_VIDEOFILE $TMP_AUDIOFILE # # remove rm -f $TMP_VIDEOFILE $TMP_AUDIOFILE oggvideotools-0.9.1/docs/conv2html.sh000775 001750 001750 00000000332 12763227102 020004 0ustar00embedembed000000 000000 #!/bin/bash # man pages must be installed for i in oggCat oggCut oggJoin oggSplit oggTranscode oggSlideshow oggSilence oggThumb oggDump mkThumbs oggLength do echo "creating $i.html" man2html -f $i.1 > $i.html done oggvideotools-0.9.1/src/ovt_theora/theoraPosInterpreter.cpp000664 001750 001750 00000014313 12763227102 024442 0ustar00embedembed000000 000000 #include "theoraPosInterpreter.h" #include "theoraStreamParameter.h" #include #include #include "log.h" TheoraPosInterpreter::TheoraPosInterpreter() : keyframeShift(6), framerateNumerator(1), framerateDenominator(1) { } TheoraPosInterpreter::~TheoraPosInterpreter() { } uint32 TheoraPosInterpreter::getFramerateNumerator() { return(framerateNumerator); } uint32 TheoraPosInterpreter::getFramerateDenominator() { return(framerateDenominator); } uint8 TheoraPosInterpreter::getKeyframeShift() { return(keyframeShift); } void TheoraPosInterpreter::extractFramePos(int64 granulePosition, int64& keyframePosition, int32& intraframePosition) { keyframePosition = granulePosition>>keyframeShift; uint64 mask(1); mask <<= keyframeShift; mask -= 1; intraframePosition = (granulePosition&mask); } void TheoraPosInterpreter::initialize(StreamParameter* _param) { TheoraStreamParameter* param = dynamic_cast(_param); if (!param) { logger.error() << "TheoraPosInterpreter::initialize: parameter not set correctly\n"; return; } keyframeShift = param->keyframeShift; framerateNumerator = param->framerateNum; framerateDenominator = param->framerateDenom; initialized = true; return; } /* void TheoraPosInterpreter::initialize(OggPage oggPage) { if (!oggPage.isBOS()) { logger.error() << "TheoraPosInterpreter::initialize: This page is not a BOS (Begin Of Stream) page\n"; return; } OggHeader* oggHeader = (OggHeader*) (oggPage.data()); StreamType* streamInformation = (StreamType*) (oggPage.data() + sizeof(OggHeader) + oggHeader->tableSegments); TheoraHeader* theoraHeader = (TheoraHeader*) (oggPage.data() + sizeof(OggHeader) + oggHeader->tableSegments + sizeof(StreamType)); if ((streamInformation->headerType != 0x80) || (strncmp(streamInformation->typeName, "theora", 6) != 0)) { logger.error() << "TheoraPosInterpreter::initialize: This page is not a theora bos\n"; return; } // for all the calculation, we need to convert some fields theoraHeader->un.pleaseconvert = convert16(theoraHeader->un.pleaseconvert); framerateNumerator = convert32(theoraHeader->frn); framerateDenominator = convert32(theoraHeader->frd); keyframeShift = theoraHeader->un.lenbo.kfgshift; // to have the original packet, we recover the data theoraHeader->un.pleaseconvert = convert16(theoraHeader->un.pleaseconvert); initialized = true; } void TheoraPosInterpreter::initialize(OggPacket m_oggPacket) { StreamType* streamInformation = (StreamType*) (m_oggPacket.data()); TheoraHeader* theoraHeader = (TheoraHeader*) (m_oggPacket.data() + sizeof(StreamType)); if ((streamInformation->headerType != 0x80) || (strncmp(streamInformation->typeName, "theora", 6) != 0)) { logger.error() << "TheoraPosInterpreter::initialize: This page is not a theora bos\n"; return; } // for all the calculation, we need to convert some fields theoraHeader->un.pleaseconvert = convert16(theoraHeader->un.pleaseconvert); framerateNumerator = convert32(theoraHeader->frn); framerateDenominator = convert32(theoraHeader->frd); keyframeShift = theoraHeader->un.lenbo.kfgshift; // to have the original packet, we recover the data theoraHeader->un.pleaseconvert = convert16(theoraHeader->un.pleaseconvert); initialized = true; } */ double TheoraPosInterpreter::getTime(int64 granulePos) { if (!initialized) { logger.error() << "TheoraPosInterpreter::initialize: The position interpreter is not initialized yet\n"; return(-2); } if (granulePos == -1) return(-1); int64 pos1; int32 pos2; extractFramePos(granulePos, pos1, pos2); double time = (framerateDenominator*1.0/framerateNumerator*1.0)*(pos1+pos2); // logger.debug() << "time extractor: "< "<(&_otherPosition); if ((keyframeShift != otherPosition->keyframeShift) || (framerateNumerator != otherPosition->framerateNumerator) || (framerateDenominator != otherPosition->framerateDenominator)) { logger.error() << "GranulePosInterpreter::operator+=: granulePositions does not match in shift value or framerate\n"; return(*this); } if ((actualGranulePosition < 0) || (otherPosition->actualGranulePosition < 0)) { logger.error() << "GranulePosInterpreter::operator+=: one or both granulePositions are not valid\n"; return(*this); } int64 ownPos1; int32 ownPos2; extractFramePos(actualGranulePosition, ownPos1, ownPos2); int64 otherPos1; int32 otherPos2; extractFramePos(otherPosition->actualGranulePosition, otherPos1, otherPos2); ownPos1 += (otherPos1 + otherPos2); actualGranulePosition = ((ownPos1<length()<=0) return(false); if (packet->data()[0]&0x80) { return(false); } if (!(packet->data()[0]&0x40)) { return(true); } return(false); } void TheoraPosInterpreter::setStreamPosition(OggPacket& packet) { /* is this a keyframe */ if (packetIsKeyframe(packet)) addKeyframe(); else actualGranulePosition+=1; packet->setGranulepos(actualGranulePosition); } GranulePosInterpreter& TheoraPosInterpreter::operator-=(GranulePosInterpreter& position) { logger.error() << "GranulePosInterpreter& operator-=: not implemented\n"; return(*this); } oggvideotools-0.9.1/src/main/oggBOSExtractorFactory.cpp000664 001750 001750 00000005570 12763227102 023375 0ustar00embedembed000000 000000 #include #include "oggBOSExtractorFactory.h" #include "theoraExtractor.h" #include "vorbisExtractor.h" #include "kateExtractor.h" #include "theoraPosInterpreter.h" #include "vorbisPosInterpreter.h" #include "katePosInterpreter.h" //#include "theoraDecoder.h" //#include "vorbisEncoder.h" OggBOSExtractorFactory::OggBOSExtractorFactory() { } OggBOSExtractorFactory::~OggBOSExtractorFactory() { } /* static MediaDecoder* OggBOSExtractorFactory::createDecoder(OggPage& page) { } static MediaDecoder* OggBOSExtractorFactory::createEncoder(OggPacket& packet) { } */ bool OggBOSExtractorFactory::extractInformation(OggPage& page, ExtractorInformation& information) { switch (getStreamType(page)) { case OggType::theora: { TheoraExtractor extractor; return(extractor.extract(page, information)); } case OggType::vorbis: { VorbisExtractor extractor; return(extractor.extract(page, information)); } case OggType::kate: { KateExtractor extractor; return(extractor.extract(page, information)); } default: break; } /* could not interpret the bos page */ return(false); } bool OggBOSExtractorFactory::extractInformation(OggPacket& packet, ExtractorInformation& information) { switch (getStreamType(packet)) { case OggType::theora: { TheoraExtractor extractor; return(extractor.extract(packet, information)); } case OggType::vorbis: { VorbisExtractor extractor; return(extractor.extract(packet, information)); } case OggType::kate: { KateExtractor extractor; return(extractor.extract(packet, information)); } default: break; } /* could not interpret the bos page */ return(false); } GranulePosInterpreter* OggBOSExtractorFactory::extractPositionInterpreter(ExtractorInformation& info) { GranulePosInterpreter* retPosInterpreter(0); switch (info.type) { case OggType::theora: retPosInterpreter = new TheoraPosInterpreter; break; case OggType::vorbis: retPosInterpreter = new VorbisPosInterpreter; break; case OggType::kate: retPosInterpreter = new KatePosInterpreter; break; default: break; } if (retPosInterpreter) retPosInterpreter->initialize(info.parameter.get()); return(retPosInterpreter); } OggType OggBOSExtractorFactory::getStreamType(OggPage& page) { uint8* type = &(page->data())[0]+page->getHeaderLength(); uint8 i=1; for (; i< to_integral(OggType::maxOggType); ++i) { if (memcmp(type, OggTypeMap[i], MAXIDCHARS) == 0) // if ((*type) == OggTypeMap[i]) return ((OggType)i); } return (OggType::unknown); } OggType OggBOSExtractorFactory::getStreamType(OggPacket& packet) { uint8* type = packet->data(); uint8 i=1; for (; i< to_integral(OggType::maxOggType); ++i) { if (memcmp(type, OggTypeMap[i], MAXIDCHARS) == 0) // if ((*type) == OggTypeMap[i]) return ((OggType)i); } return (OggType::unknown); } oggvideotools-0.9.1/scripts/mkThumbs000775 001750 001750 00000001216 12763227102 020012 0ustar00embedembed000000 000000 #!/bin/sh # This script creates a series of thumbnails from an Ogg/Theora file # usage: # ./mkThumbs file.ogv # # typical: # ./mkThumbs myfile.ogv 10 -s0x200 # This call creates a thumbnail series of 10 pictures with the a height of 200 pixels # if [ $# -lt 2 ] then echo "usage $0