Ogg support fixed and re-added. Squash of various commits made by Wouter Spruit.
This commit is contained in:
parent
142ef73f6c
commit
a47504b5cb
17 changed files with 944 additions and 456 deletions
|
@ -163,7 +163,7 @@ namespace Mist {
|
|||
|
||||
void Output::negotiatePushTracks() {
|
||||
int i = 0;
|
||||
for (std::map<int, DTSC::Track>::iterator it = meta_out.tracks.begin(); it != meta_out.tracks.end() && i < 5; it++){
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = meta_out.tracks.begin(); it != meta_out.tracks.end() && i < 5; it++){
|
||||
negotiateWithBuffer(it->first);
|
||||
i++;
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ namespace Mist {
|
|||
}
|
||||
}
|
||||
if (!found){
|
||||
for (std::map<int,DTSC::Track>::iterator trit = myMeta.tracks.begin(); trit != myMeta.tracks.end(); trit++){
|
||||
for (std::map<unsigned int,DTSC::Track>::iterator trit = myMeta.tracks.begin(); trit != myMeta.tracks.end(); trit++){
|
||||
if (trit->second.codec == (*itc).asStringRef()){
|
||||
genCounter++;
|
||||
found = true;
|
||||
|
@ -326,7 +326,7 @@ namespace Mist {
|
|||
}
|
||||
}
|
||||
if (!found){
|
||||
for (std::map<int,DTSC::Track>::iterator trit = myMeta.tracks.begin(); trit != myMeta.tracks.end(); trit++){
|
||||
for (std::map<unsigned int,DTSC::Track>::iterator trit = myMeta.tracks.begin(); trit != myMeta.tracks.end(); trit++){
|
||||
if (trit->second.codec == (*itc).asStringRef()){
|
||||
selectedTracks.insert(trit->first);
|
||||
found = true;
|
||||
|
@ -438,8 +438,8 @@ namespace Mist {
|
|||
return;
|
||||
}
|
||||
char id[100];
|
||||
sprintf(id, "%s%lu_%d", streamName.c_str(), trackId, pageNum);
|
||||
curPages[trackId].init(std::string(id),26 * 1024 * 1024);
|
||||
snprintf(id, 100, "%s%lu_%d", streamName.c_str(), trackId, pageNum);
|
||||
curPages[trackId].init(id, 26 * 1024 * 1024);
|
||||
if (!(curPages[trackId].mapped)){
|
||||
DEBUG_MSG(DLVL_FAIL, "Initializing page %s failed", curPages[trackId].name.c_str());
|
||||
return;
|
||||
|
@ -448,7 +448,7 @@ namespace Mist {
|
|||
}
|
||||
|
||||
/// Prepares all tracks from selectedTracks for seeking to the specified ms position.
|
||||
void Output::seek(long long pos){
|
||||
void Output::seek(unsigned long long pos){
|
||||
sought = true;
|
||||
firstTime = Util::getMS() - pos;
|
||||
if (!isInitialized){
|
||||
|
@ -457,16 +457,16 @@ namespace Mist {
|
|||
buffer.clear();
|
||||
currentPacket.null();
|
||||
updateMeta();
|
||||
DEBUG_MSG(DLVL_MEDIUM, "Seeking to %llims", pos);
|
||||
DEBUG_MSG(DLVL_MEDIUM, "Seeking to %llums", pos);
|
||||
for (std::set<long unsigned int>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
|
||||
seek(*it, pos);
|
||||
}
|
||||
}
|
||||
|
||||
bool Output::seek(int tid, long long pos, bool getNextKey){
|
||||
bool Output::seek(unsigned int tid, unsigned long long pos, bool getNextKey){
|
||||
loadPageForKey(tid, getKeyForTime(tid, pos) + (getNextKey?1:0));
|
||||
if (!curPages.count(tid) || !curPages[tid].mapped){
|
||||
DEBUG_MSG(DLVL_DEVEL, "Aborting seek to %llims in track %d, not available.", pos, tid);
|
||||
DEBUG_MSG(DLVL_DEVEL, "Aborting seek to %llums in track %u, not available.", pos, tid);
|
||||
return false;
|
||||
}
|
||||
sortedPageInfo tmp;
|
||||
|
@ -724,7 +724,7 @@ namespace Mist {
|
|||
}
|
||||
if (trackMap.size()){
|
||||
for (std::map<int, int>::iterator it = trackMap.begin(); it != trackMap.end() && tNum < 5; it++){
|
||||
int tId = it->second;
|
||||
unsigned int tId = it->second;
|
||||
char * thisData = playerConn.getData() + (6 * tNum);
|
||||
thisData[0] = ((tId >> 24) & 0xFF);
|
||||
thisData[1] = ((tId >> 16) & 0xFF);
|
||||
|
@ -736,7 +736,7 @@ namespace Mist {
|
|||
}
|
||||
}else{
|
||||
for (std::set<unsigned long>::iterator it = selectedTracks.begin(); it != selectedTracks.end() && tNum < 5; it++){
|
||||
int tId = *it;
|
||||
unsigned int tId = *it;
|
||||
char * thisData = playerConn.getData() + (6 * tNum);
|
||||
thisData[0] = ((tId >> 24) & 0xFF);
|
||||
thisData[1] = ((tId >> 16) & 0xFF);
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace Mist {
|
|||
}
|
||||
return (time == rhs.time && tid < rhs.tid);
|
||||
}
|
||||
int tid;
|
||||
unsigned int tid;
|
||||
long long unsigned int time;
|
||||
unsigned int offset;
|
||||
};
|
||||
|
@ -53,8 +53,8 @@ namespace Mist {
|
|||
//non-virtual generic functions
|
||||
int run();
|
||||
void stats();
|
||||
void seek(long long pos);
|
||||
bool seek(int tid, long long pos, bool getNextKey = false);
|
||||
void seek(unsigned long long pos);
|
||||
bool seek(unsigned int tid, unsigned long long pos, bool getNextKey = false);
|
||||
void stop();
|
||||
void setBlocking(bool blocking);
|
||||
long unsigned int getMainSelectedTrack();
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Mist {
|
|||
audioTrack = 0;
|
||||
JSON::Value & vidCapa = capa["codecs"][0u][0u];
|
||||
JSON::Value & audCapa = capa["codecs"][0u][1u];
|
||||
for (std::map<int,DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
for (std::map<unsigned int,DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
for (JSON::ArrIter itb = vidCapa.ArrBegin(); itb != vidCapa.ArrEnd(); itb++){
|
||||
if (it->second.codec == (*itb).asStringRef()){
|
||||
videoTracks.insert(it->first);
|
||||
|
|
|
@ -10,14 +10,14 @@ namespace Mist {
|
|||
result << "#EXTM3U\r\n";
|
||||
int audioId = -1;
|
||||
std::string audioName;
|
||||
for (std::map<int,DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
for (std::map<unsigned int,DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
if (it->second.codec == "AAC"){
|
||||
audioId = it->first;
|
||||
audioName = it->second.getIdentifier();
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (std::map<int,DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
for (std::map<unsigned int,DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
if (it->second.codec == "H264"){
|
||||
int bWidth = it->second.bps * 2;
|
||||
if (audioId != -1){
|
||||
|
@ -266,7 +266,7 @@ namespace Mist {
|
|||
return 1;
|
||||
}
|
||||
//loop trough all the tracks
|
||||
for (std::map<int,DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
for (std::map<unsigned int,DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
//return "too late" if one track is past this point
|
||||
if (ms < it->second.firstms){
|
||||
return -1;
|
||||
|
|
|
@ -295,13 +295,13 @@ namespace Mist {
|
|||
"MajorVersion=\"2\" "
|
||||
"MinorVersion=\"0\" "
|
||||
"TimeScale=\"10000000\" ";
|
||||
std::deque<std::map<int, DTSC::Track>::iterator> audioIters;
|
||||
std::deque<std::map<int, DTSC::Track>::iterator> videoIters;
|
||||
std::deque<std::map<unsigned int, DTSC::Track>::iterator> audioIters;
|
||||
std::deque<std::map<unsigned int, DTSC::Track>::iterator> videoIters;
|
||||
long long int maxWidth = 0;
|
||||
long long int maxHeight = 0;
|
||||
long long int minWidth = 99999999;
|
||||
long long int minHeight = 99999999;
|
||||
for (std::map<int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++) {
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++) {
|
||||
if (it->second.codec == "AAC") {
|
||||
audioIters.push_back(it);
|
||||
}
|
||||
|
@ -343,7 +343,7 @@ namespace Mist {
|
|||
"Chunks=\"" << (*audioIters.begin())->second.keys.size() << "\" "
|
||||
"Url=\"Q({bitrate},{CustomAttributes})/A({start time})\">\n";
|
||||
int index = 0;
|
||||
for (std::deque<std::map<int, DTSC::Track>::iterator>::iterator it = audioIters.begin(); it != audioIters.end(); it++) {
|
||||
for (std::deque<std::map<unsigned int, DTSC::Track>::iterator>::iterator it = audioIters.begin(); it != audioIters.end(); it++) {
|
||||
Result << "<QualityLevel "
|
||||
"Index=\"" << index << "\" "
|
||||
"Bitrate=\"" << (*it)->second.bps * 8 << "\" "
|
||||
|
@ -388,7 +388,7 @@ namespace Mist {
|
|||
"DisplayWidth=\"" << maxWidth << "\" "
|
||||
"DisplayHeight=\"" << maxHeight << "\">\n";
|
||||
int index = 0;
|
||||
for (std::deque<std::map<int, DTSC::Track>::iterator>::iterator it = videoIters.begin(); it != videoIters.end(); it++) {
|
||||
for (std::deque<std::map<unsigned int, DTSC::Track>::iterator>::iterator it = videoIters.begin(); it != videoIters.end(); it++) {
|
||||
//Add video qualities
|
||||
Result << "<QualityLevel "
|
||||
"Index=\"" << index << "\" "
|
||||
|
@ -450,7 +450,7 @@ namespace Mist {
|
|||
|
||||
void OutHSS::initialize() {
|
||||
Output::initialize();
|
||||
for (std::map<int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++) {
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++) {
|
||||
for (std::deque<DTSC::Key>::iterator it2 = it->second.keys.begin(); it2 != it->second.keys.end(); it2++) {
|
||||
keyTimes[it->first].insert(it2->getTime());
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace Mist {
|
|||
if (H.GetVar("callback") != ""){jsonp = H.GetVar("callback");}
|
||||
if (H.GetVar("jsonp") != ""){jsonp = H.GetVar("jsonp");}
|
||||
initialize();
|
||||
for (std::map<int,DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
for (std::map<unsigned int,DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
if (it->second.type == "meta" ){
|
||||
selectedTracks.insert(it->first);
|
||||
}
|
||||
|
|
208
src/output/output_progressive_ogg.cpp
Normal file
208
src/output/output_progressive_ogg.cpp
Normal file
|
@ -0,0 +1,208 @@
|
|||
#include "output_progressive_ogg.h"
|
||||
#include <mist/bitstream.h>
|
||||
#include <mist/defines.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Mist {
|
||||
OutProgressiveOGG::OutProgressiveOGG(Socket::Connection & conn) : HTTPOutput(conn){
|
||||
realTime = 0;
|
||||
}
|
||||
|
||||
OutProgressiveOGG::~OutProgressiveOGG(){}
|
||||
|
||||
void OutProgressiveOGG::init(Util::Config * cfg){
|
||||
HTTPOutput::init(cfg);
|
||||
capa["name"] = "OGG";
|
||||
capa["desc"] = "Enables HTTP protocol progressive streaming.";
|
||||
capa["deps"] = "HTTP";
|
||||
capa["url_rel"] = "/$.ogg";
|
||||
capa["url_match"] = "/$.ogg";
|
||||
capa["codecs"][0u][0u].append("theora");
|
||||
capa["codecs"][0u][1u].append("vorbis");
|
||||
capa["codecs"][0u][1u].append("opus");
|
||||
capa["methods"][0u]["handler"] = "http";
|
||||
capa["methods"][0u]["type"] = "html5/video/ogg";
|
||||
capa["methods"][0u]["priority"] = 8ll;
|
||||
capa["methods"][0u]["nolive"] = 1;
|
||||
}
|
||||
|
||||
void OutProgressiveOGG::sendNext(){
|
||||
unsigned int track = currentPacket.getTrackId();
|
||||
|
||||
|
||||
OGG::oggSegment newSegment;
|
||||
currentPacket.getString("data", newSegment.dataString);
|
||||
// if (currentPacket.getTime() > 315800){// && currentPacket.getTime() < 316200){
|
||||
//INFO_MSG("Found a packet of time %llu, size: %d", currentPacket.getTime(), newSegment.dataString.size());
|
||||
//}
|
||||
pageBuffer[track].totalFrames = ((double)currentPacket.getTime() / (1000000.0f / myMeta.tracks[track].fpks)) + 1.5; //should start at 1. added .5 for rounding.
|
||||
// INFO_MSG("track: %u totalFrames %llu timestamp: %llu totalframe value: %f", track, pageBuffer[track].totalFrames, currentPacket.getTime(), ((double)currentPacket.getTime() / (1000000.0f / myMeta.tracks[track].fpks)) + 1);
|
||||
|
||||
if (pageBuffer[track].codec == OGG::THEORA){
|
||||
newSegment.isKeyframe = currentPacket.getFlag("keyframe");
|
||||
if (newSegment.isKeyframe == true){
|
||||
pageBuffer[track].sendTo(myConn);//send data remaining in buffer (expected to fit on a page), keyframe will allways start on new page
|
||||
// INFO_MSG("segments left in buffer: %d", pageBuffer[track].oggSegments.size());
|
||||
pageBuffer[track].lastKeyFrame = pageBuffer[track].totalFrames;
|
||||
}
|
||||
newSegment.framesSinceKeyFrame = pageBuffer[track].totalFrames - pageBuffer[track].lastKeyFrame;
|
||||
newSegment.lastKeyFrameSeen = pageBuffer[track].lastKeyFrame;
|
||||
// theora::frame tmpFrame;
|
||||
// tmpFrame.read(newSegment.dataString.data(),newSegment.dataString.size());
|
||||
// INFO_MSG("FTYPE: %d ISKEYFRAME: %d",tmpFrame.getFTYPE(),newSegment.isKeyframe );
|
||||
}
|
||||
|
||||
newSegment.frameNumber = pageBuffer[track].totalFrames;
|
||||
newSegment.timeStamp = currentPacket.getTime();
|
||||
|
||||
pageBuffer[track].oggSegments.push_back(newSegment);
|
||||
|
||||
if (pageBuffer[track].codec == OGG::VORBIS){
|
||||
pageBuffer[track].vorbisStuff();//this updates lastKeyFrame
|
||||
}
|
||||
|
||||
// while (pageBuffer[track].oggSegments.size()){
|
||||
//pageBuffer[track].sendTo(myConn);
|
||||
//}
|
||||
while (pageBuffer[track].shouldSend()){
|
||||
pageBuffer[track].sendTo(myConn);
|
||||
}
|
||||
}
|
||||
|
||||
bool OutProgressiveOGG::onFinish(){
|
||||
for (std::map<long long unsigned int, OGG::Page>::iterator it = pageBuffer.begin(); it != pageBuffer.end(); it++){
|
||||
it->second.setHeaderType(OGG::EndOfStream);
|
||||
it->second.sendTo(myConn);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool OutProgressiveOGG::parseInit(std::string & initData, std::deque<std::string> & output){
|
||||
std::string temp;
|
||||
unsigned int index = 0;
|
||||
if (initData[0] == 0x02){ //"special" case, requires interpretation similar to table
|
||||
if (initData.size() < 7){
|
||||
FAIL_MSG("initData size too tiny (size: %lu)", initData.size());
|
||||
return false;
|
||||
}
|
||||
unsigned int len1 = 0 ;
|
||||
unsigned int len2 = 0 ;
|
||||
index = 1;
|
||||
while (initData[index] == 255){ //get len 1
|
||||
len1 += initData[index++];
|
||||
}
|
||||
len1 += initData[index++];
|
||||
|
||||
while (initData[index] == 255){ //get len 1
|
||||
len2 += initData[index++];
|
||||
}
|
||||
len2 += initData[index++];
|
||||
|
||||
if (initData.size() < (len1 + len2 + 4)){
|
||||
FAIL_MSG("initData size too tiny (size: %lu)", initData.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
temp = initData.substr(index, len1);
|
||||
output.push_back(temp);
|
||||
index += len1;
|
||||
temp = initData.substr(index, len2);
|
||||
output.push_back(temp);
|
||||
index += len2;
|
||||
temp = initData.substr(index); //remainder of string:
|
||||
output.push_back(temp); //add data to output deque
|
||||
} else {
|
||||
if (initData.size() < 7){
|
||||
FAIL_MSG("initData size too tiny (size: %lu)", initData.size());
|
||||
return false;
|
||||
}
|
||||
unsigned int len = 0;
|
||||
for (unsigned int i = 0; i < 3; i++){
|
||||
temp = initData.substr(index, 2);
|
||||
len = (((unsigned int)temp[0]) << 8) | (temp[1]); //2 bytes len
|
||||
index += 2; //start of data
|
||||
if (index + len > initData.size()){
|
||||
FAIL_MSG("index+len > initData size");
|
||||
return false;
|
||||
}
|
||||
temp = initData.substr(index, len);
|
||||
output.push_back(temp); //add data to output deque
|
||||
index += len;
|
||||
INFO_MSG("init data len[%d]: %d ", i, len);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OutProgressiveOGG::sendHeader(){
|
||||
HTTP_S.Clean(); //make sure no parts of old requests are left in any buffers
|
||||
HTTP_S.SetHeader("Content-Type", "video/ogg");
|
||||
HTTP_S.protocol = "HTTP/1.0";
|
||||
myConn.SendNow(HTTP_S.BuildResponse("200", "OK")); //no SetBody = unknown length - this is intentional, we will stream the entire file
|
||||
|
||||
std::map<int, std::deque<std::string> > initData;
|
||||
|
||||
OGG::oggSegment newSegment;
|
||||
for (std::set<long unsigned int>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
|
||||
parseInit(myMeta.tracks[*it].init, initData[*it]);
|
||||
if (myMeta.tracks[*it].codec == "theora"){ //get size and position of init data for this page.
|
||||
pageBuffer[*it].codec = OGG::THEORA;
|
||||
pageBuffer[*it].totalFrames = 1; //starts at frame number 1, according to weird offDetectMeta function.
|
||||
std::string tempStr = initData[*it][0];
|
||||
theora::header tempHead((char *)tempStr.c_str(), 42);
|
||||
pageBuffer[*it].split = tempHead.getKFGShift();
|
||||
INFO_MSG("got theora KFG shift: %d", pageBuffer[*it].split); //looks OK.
|
||||
} else if (myMeta.tracks[*it].codec == "vorbis"){
|
||||
pageBuffer[*it].codec = OGG::VORBIS;
|
||||
pageBuffer[*it].totalFrames = 0;
|
||||
pageBuffer[*it].sampleRate = myMeta.tracks[*it].rate;
|
||||
pageBuffer[*it].prevBlockFlag = -1;
|
||||
vorbis::header tempHead((char *)initData[*it][0].data(), initData[*it][0].size());
|
||||
pageBuffer[*it].blockSize[0] = std::min(tempHead.getBlockSize0(), tempHead.getBlockSize1());
|
||||
pageBuffer[*it].blockSize[1] = std::max(tempHead.getBlockSize0(), tempHead.getBlockSize1());
|
||||
char audioChannels = tempHead.getAudioChannels(); //?
|
||||
vorbis::header tempHead2((char *)initData[*it][2].data(), initData[*it][2].size());
|
||||
pageBuffer[*it].vorbisModes = tempHead2.readModeDeque(audioChannels);//getting modes
|
||||
} else if (myMeta.tracks[*it].codec == "opus"){
|
||||
pageBuffer[*it].totalFrames = 0; //?
|
||||
pageBuffer[*it].codec = OGG::OPUS;
|
||||
}
|
||||
pageBuffer[*it].clear(OGG::BeginOfStream, 0, *it, 0); //CREATES a (map)pageBuffer object, *it = id, pagetype=BOS
|
||||
newSegment.dataString = initData[*it][0];
|
||||
pageBuffer[*it].oggSegments.push_back(newSegment);
|
||||
pageBuffer[*it].sendTo(myConn, 0); //granule position of 0
|
||||
}
|
||||
for (std::set<long unsigned int>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
|
||||
newSegment.dataString = initData[*it][1];
|
||||
pageBuffer[*it].oggSegments.push_back(newSegment);
|
||||
newSegment.dataString = initData[*it][2];
|
||||
pageBuffer[*it].oggSegments.push_back(newSegment);
|
||||
while (pageBuffer[*it].oggSegments.size()){
|
||||
pageBuffer[*it].sendTo(myConn, 0); //granule position of 0
|
||||
}
|
||||
}
|
||||
sentHeader = true;
|
||||
}
|
||||
|
||||
void OutProgressiveOGG::onRequest(){
|
||||
if (HTTP_R.Read(myConn)){
|
||||
DEBUG_MSG(DLVL_DEVEL, "Received request %s", HTTP_R.getUrl().c_str());
|
||||
if (HTTP_R.GetVar("audio") != ""){
|
||||
selectedTracks.insert(JSON::Value(HTTP_R.GetVar("audio")).asInt());
|
||||
}
|
||||
if (HTTP_R.GetVar("video") != ""){
|
||||
selectedTracks.insert(JSON::Value(HTTP_R.GetVar("video")).asInt());
|
||||
}
|
||||
parseData = true;
|
||||
wantRequest = false;
|
||||
HTTP_R.Clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
28
src/output/output_progressive_ogg.h
Normal file
28
src/output/output_progressive_ogg.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include "output_http.h"
|
||||
#include <mist/ogg.h>
|
||||
#include <mist/http_parser.h>
|
||||
|
||||
namespace Mist {
|
||||
class OutProgressiveOGG : public HTTPOutput {
|
||||
public:
|
||||
OutProgressiveOGG(Socket::Connection & conn);
|
||||
~OutProgressiveOGG();
|
||||
static void init(Util::Config * cfg);
|
||||
void onRequest();
|
||||
void sendNext();
|
||||
void sendHeader();
|
||||
bool onFinish();
|
||||
bool parseInit(std::string & initData, std::deque<std::string> & output);
|
||||
protected:
|
||||
HTTP::Parser HTTP_R;//Received HTTP
|
||||
HTTP::Parser HTTP_S;//Sent HTTP
|
||||
std::map <long long unsigned int, OGG::Page > pageBuffer; //OGG specific variables
|
||||
};
|
||||
}
|
||||
|
||||
typedef Mist::OutProgressiveOGG mistOut;
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue