EVOLUTION-MANAGER
Edit File: theoraPosInterpreter.cpp
#include "theoraPosInterpreter.h" #include "theoraStreamParameter.h" #include <iostream> #include <typeinfo> 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<TheoraStreamParameter*>(_param); if (!param) { std::cerr << "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()) { std::cerr << "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)) { std::cerr << "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 oggPacket) { StreamType* streamInformation = (StreamType*) (oggPacket.data()); TheoraHeader* theoraHeader = (TheoraHeader*) (oggPacket.data() + sizeof(StreamType)); if ((streamInformation->headerType != 0x80) || (strncmp(streamInformation->typeName, "theora", 6) != 0)) { std::cerr << "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) { std::cerr << "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); // std::cerr << "time extractor: "<<granulePos<<" ("<<pos1<<":"<<pos2<<") -> "<<time<<"s \n"; return(time); } void TheoraPosInterpreter::addKeyframe() { /* The first keyframe is 0 */ // if (actualGranulePosition == 0) { // actualGranulePosition = 1<<keyframeShift; // return; // } int64 pos1; int32 pos2; extractFramePos(actualGranulePosition, pos1, pos2); pos1 += (pos2 + 1); actualGranulePosition = pos1<<keyframeShift; } TheoraPosInterpreter& TheoraPosInterpreter::operator++() { actualGranulePosition+=1; return(*this); } GranulePosInterpreter& TheoraPosInterpreter::operator+=(GranulePosInterpreter& _otherPosition) { if (typeid(_otherPosition) != typeid(*this)) { std::cerr << "GranulePosInterpreter::operator+=: type is not matching\n"; return(*this); } TheoraPosInterpreter* otherPosition = static_cast<TheoraPosInterpreter*>(&_otherPosition); if ((keyframeShift != otherPosition->keyframeShift) || (framerateNumerator != otherPosition->framerateNumerator) || (framerateDenominator != otherPosition->framerateDenominator)) { std::cerr << "GranulePosInterpreter::operator+=: granulePositions does not match in shift value or framerate\n"; return(*this); } if ((actualGranulePosition < 0) || (otherPosition->actualGranulePosition < 0)) { std::cerr << "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<<keyframeShift)|(ownPos2)); return(*this); } bool TheoraPosInterpreter::packetIsKeyframe(OggPacket& packet) { // is there any data available if (packet.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) { std::cerr << "GranulePosInterpreter& operator-=: not implemented\n"; return(*this); }