Started ogg support in lib
This commit is contained in:
parent
bec0c12ac6
commit
e3861f9fc6
3 changed files with 288 additions and 2 deletions
|
@ -1,5 +1,5 @@
|
||||||
lib_LTLIBRARIES=libmist-1.0.la
|
lib_LTLIBRARIES=libmist-1.0.la
|
||||||
libmist_1_0_la_SOURCES=amf.h amf.cpp auth.h auth.cpp base64.h base64.cpp config.h config.cpp dtsc.h dtsc.cpp flv_tag.h flv_tag.cpp http_parser.h http_parser.cpp json.h json.cpp procs.h procs.cpp rtmpchunks.h rtmpchunks.cpp socket.h socket.cpp mp4.h mp4.cpp ftp.h ftp.cpp filesystem.h filesystem.cpp stream.h stream.cpp timing.h timing.cpp ts_packet.cpp ts_packet.h converter.cpp converter.h
|
libmist_1_0_la_SOURCES=amf.h amf.cpp auth.h auth.cpp base64.h base64.cpp config.h config.cpp dtsc.h dtsc.cpp flv_tag.h flv_tag.cpp http_parser.h http_parser.cpp json.h json.cpp procs.h procs.cpp rtmpchunks.h rtmpchunks.cpp socket.h socket.cpp mp4.h mp4.cpp ftp.h ftp.cpp filesystem.h filesystem.cpp stream.h stream.cpp timing.h timing.cpp ts_packet.cpp ts_packet.h converter.cpp converter.h ogg.h ogg.cpp
|
||||||
libmist_1_0_la_LDFLAGS = -version-info 5:1:2
|
libmist_1_0_la_LDFLAGS = -version-info 5:1:2
|
||||||
libmist_1_0_la_CPPFLAGS=$(DEPS_CFLAGS) $(global_CFLAGS)
|
libmist_1_0_la_CPPFLAGS=$(DEPS_CFLAGS) $(global_CFLAGS)
|
||||||
libmist_1_0_la_LIBADD=$(DEPS_LIBS) $(CLOCK_LIB)
|
libmist_1_0_la_LIBADD=$(DEPS_LIBS) $(CLOCK_LIB)
|
||||||
|
@ -8,4 +8,4 @@ pkgconfigdir = $(libdir)/pkgconfig
|
||||||
pkgconfig_DATA = mist-1.0.pc
|
pkgconfig_DATA = mist-1.0.pc
|
||||||
|
|
||||||
library_includedir=$(includedir)/mist-1.0/mist
|
library_includedir=$(includedir)/mist-1.0/mist
|
||||||
library_include_HEADERS = amf.h auth.h base64.h config.h dtsc.h flv_tag.h http_parser.h json.h procs.h rtmpchunks.h socket.h mp4.h ftp.h filesystem.h stream.h timing.h nal.h ts_packet.h converter.h
|
library_include_HEADERS = amf.h auth.h base64.h config.h dtsc.h flv_tag.h http_parser.h json.h procs.h rtmpchunks.h socket.h mp4.h ftp.h filesystem.h stream.h timing.h nal.h ts_packet.h converter.h ogg.h
|
||||||
|
|
246
lib/ogg.cpp
Normal file
246
lib/ogg.cpp
Normal file
|
@ -0,0 +1,246 @@
|
||||||
|
#include "ogg.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#define lsb32(offset) data[offset] | data[offset+1] << 8 | data[offset+2] << 16 | data[offset+3] << 24
|
||||||
|
|
||||||
|
namespace OGG{
|
||||||
|
Page::Page(){
|
||||||
|
data = NULL;
|
||||||
|
datasize = 0;
|
||||||
|
dataSum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Page::read(std::string & newData){
|
||||||
|
dataSum = 0;
|
||||||
|
datasize = 0;
|
||||||
|
if (newData.size()<27){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!checkDataSize(27)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(data, newData.c_str(), 27);//copying the header, always 27 bytes
|
||||||
|
if(!checkDataSize(27 + getPageSegments())){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(data + 27, newData.c_str() + 27, getPageSegments());
|
||||||
|
//copying the first part of the page into data, which tells the size of the page
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < getPageSegments(); i++){
|
||||||
|
dataSum += getSegmentTable()[i];
|
||||||
|
}
|
||||||
|
if(!checkDataSize(27 + getPageSegments()+dataSum)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(data + 27 + getPageSegments(), newData.c_str() + 27 + getPageSegments(), dataSum);
|
||||||
|
newData.erase(0, datasize);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
long unsigned int Page::getMagicNumber(){
|
||||||
|
return ntohl(((long unsigned int*)(data))[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Page::setMagicNumber(){
|
||||||
|
if(checkDataSize(4)){
|
||||||
|
memcpy(data, "OggS", 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char Page::getVersion(){
|
||||||
|
return data[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Page::setVersion(char newVal){
|
||||||
|
if(checkDataSize(5)){
|
||||||
|
data[4] = newVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char Page::getHeaderType(){
|
||||||
|
return data[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Page::setHeaderType(char newVal){
|
||||||
|
if(checkDataSize(6)){
|
||||||
|
data[5] = newVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long long unsigned int Page::getGranulePosition(){
|
||||||
|
if(checkDataSize(14)){
|
||||||
|
//switching bit order upon return
|
||||||
|
return ntohl(((long unsigned*)(data+6))[1]) & ((long long unsigned)(ntohl(((long unsigned*)(data+6))[0]) << 32));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Page::setGranulePosition(long long unsigned int newVal){
|
||||||
|
if(checkDataSize(14)){
|
||||||
|
((long unsigned*)(data+6))[1] = htonl(newVal & 0xFFFFFFFF);
|
||||||
|
((long unsigned*)(data+6))[0] = htonl((newVal >> 32) & 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long unsigned int Page::getBitstreamSerialNumber(){
|
||||||
|
//return ntohl(((long unsigned int*)(data+14))[0]);
|
||||||
|
return lsb32(14);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Page::setBitstreamSerialNumber(long unsigned int newVal){
|
||||||
|
if(checkDataSize(18)){
|
||||||
|
((long unsigned *)(data+14))[0] = htonl(newVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long unsigned int Page::getPageSequenceNumber(){
|
||||||
|
return lsb32(18);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Page::setPageSequenceNumber(long unsigned int newVal){
|
||||||
|
if(checkDataSize(22)){
|
||||||
|
((long unsigned *)(data+18))[0] = htonl(newVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long unsigned int Page::getCRCChecksum(){
|
||||||
|
return ntohl(((long unsigned int*)(data+22))[0]);
|
||||||
|
//return lsb32(22);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Page::setCRCChecksum(long unsigned int newVal){
|
||||||
|
if(checkDataSize(26)){
|
||||||
|
((long unsigned *)(data+22))[0] = htonl(newVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char Page::getPageSegments(){
|
||||||
|
return data[26];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Page::setPageSegments(char newVal){
|
||||||
|
data[26] = newVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* Page::getSegmentTable(){
|
||||||
|
return data+27;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::deque<unsigned int> Page::getSegmentTableDeque(){
|
||||||
|
std::deque<unsigned int> retVal;
|
||||||
|
unsigned int temp = 0;
|
||||||
|
char* segmentTable = getSegmentTable();
|
||||||
|
for (unsigned int i = 0; i < getPageSegments(); i++){
|
||||||
|
temp += segmentTable[i];
|
||||||
|
if (segmentTable[i] < 255){
|
||||||
|
retVal.push_back(temp);
|
||||||
|
temp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Page::setSegmentTable(std::vector<unsigned int> layout){
|
||||||
|
unsigned int place = 0;
|
||||||
|
char table[255];
|
||||||
|
for (unsigned int i = 0; i < layout.size(); i++){
|
||||||
|
while (layout[i]>=255){
|
||||||
|
if (place >= 255) return false;
|
||||||
|
table[place] = 255;
|
||||||
|
layout[i] -= 255;
|
||||||
|
place++;
|
||||||
|
}
|
||||||
|
if (place >= 255) return false;
|
||||||
|
table[place] = layout[i];
|
||||||
|
place++;
|
||||||
|
}
|
||||||
|
setSegmentTable(table,place);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Page::setSegmentTable(char* newVal, unsigned int length){
|
||||||
|
if(checkDataSize(27 + length)){
|
||||||
|
memcpy(data + 27, newVal, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char* Page::getFullPayload(){
|
||||||
|
return data + 27 + getPageSegments();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Page::toPrettyString(){
|
||||||
|
std::stringstream r;
|
||||||
|
r << "Size(" << datasize << ")(" << dataSum << ")" << std::endl;
|
||||||
|
r << "Magic_Number: " << std::string(data, 4) << std::endl;
|
||||||
|
r << "Version: " << (int)getVersion() << std::endl;
|
||||||
|
r << "Header_type: " << std::hex << (int)getHeaderType() << std::dec;
|
||||||
|
if (getHeaderType() & 0x01){
|
||||||
|
r << " continued";
|
||||||
|
}
|
||||||
|
if (getHeaderType() & 0x02){
|
||||||
|
r << " bos";
|
||||||
|
}
|
||||||
|
if (getHeaderType() & 0x04){
|
||||||
|
r << " eos";
|
||||||
|
}
|
||||||
|
r << std::endl;
|
||||||
|
r << "Granule_position: " << getGranulePosition() << std::endl;
|
||||||
|
r << "Bitstream_SN: " << getBitstreamSerialNumber() << std::endl;
|
||||||
|
r << "Page_sequence_number: " << getPageSequenceNumber() << std::endl;
|
||||||
|
r << "CRC_checksum: " << std::hex << getCRCChecksum()<< std::dec << std::endl;
|
||||||
|
r << " Calced Checksum: " << std::hex << calcChecksum() << std::dec << std::endl;
|
||||||
|
r << "CRC_checksum write: " << std::hex << getCRCChecksum()<< std::dec << std::endl;
|
||||||
|
r << "Page_segments: " << (int)getPageSegments() << std::endl;
|
||||||
|
r << "SegmentTable: ";
|
||||||
|
std::deque<unsigned int> temp = getSegmentTableDeque();
|
||||||
|
for (std::deque<unsigned int>::iterator i = temp.begin(); i != temp.end(); i++){
|
||||||
|
r << (*i) << " ";
|
||||||
|
}
|
||||||
|
r << std::endl;
|
||||||
|
return r.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
long unsigned int Compute(char* buffer, unsigned int count){
|
||||||
|
long unsigned int m_crc = ~0u;
|
||||||
|
//const unsigned char* ptr = (const unsigned char *) buffer;
|
||||||
|
for (unsigned int i = 0; i < count; i++) {
|
||||||
|
buffer++;
|
||||||
|
m_crc ^= ((unsigned long int)buffer << 24);
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
if (m_crc & 0x80000000) {
|
||||||
|
m_crc = (m_crc << 1) ^ 0x04C11DB7;
|
||||||
|
}else {
|
||||||
|
m_crc <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m_crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
long unsigned int Page::calcChecksum(){
|
||||||
|
long unsigned int retVal = 0;
|
||||||
|
long unsigned int oldChecksum = getCRCChecksum();
|
||||||
|
setCRCChecksum (0);
|
||||||
|
retVal = Compute(data, datasize);
|
||||||
|
setCRCChecksum (oldChecksum);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Page::checkDataSize(unsigned int size){
|
||||||
|
if (size > datasize){
|
||||||
|
void* tmp = realloc(data,size);
|
||||||
|
if (tmp){
|
||||||
|
data = (char*)tmp;
|
||||||
|
datasize = size;
|
||||||
|
return true;
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
lib/ogg.h
Normal file
40
lib/ogg.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#include<string>
|
||||||
|
#include<vector>
|
||||||
|
#include<deque>
|
||||||
|
|
||||||
|
|
||||||
|
namespace OGG{
|
||||||
|
class Page{
|
||||||
|
public:
|
||||||
|
Page();
|
||||||
|
bool read(std::string & newData);
|
||||||
|
long unsigned int getMagicNumber();
|
||||||
|
void setMagicNumber();
|
||||||
|
char getVersion();
|
||||||
|
void setVersion(char newVal = 0);
|
||||||
|
char getHeaderType();
|
||||||
|
void setHeaderType(char newVal);
|
||||||
|
long long unsigned int getGranulePosition();
|
||||||
|
void setGranulePosition(long long unsigned int newVal);
|
||||||
|
long unsigned int getBitstreamSerialNumber();
|
||||||
|
void setBitstreamSerialNumber(long unsigned int newVal);
|
||||||
|
long unsigned int getPageSequenceNumber();
|
||||||
|
void setPageSequenceNumber(long unsigned int newVal);
|
||||||
|
long unsigned int getCRCChecksum();
|
||||||
|
void setCRCChecksum(long unsigned int newVal);
|
||||||
|
char getPageSegments();
|
||||||
|
inline void setPageSegments(char newVal);
|
||||||
|
char* getSegmentTable();
|
||||||
|
std::deque<unsigned int> getSegmentTableDeque();
|
||||||
|
bool setSegmentTable(std::vector<unsigned int> layout);
|
||||||
|
void setSegmentTable(char* newVal, unsigned int length);
|
||||||
|
char* getFullPayload();
|
||||||
|
std::string toPrettyString();
|
||||||
|
private:
|
||||||
|
long unsigned int calcChecksum();
|
||||||
|
char* data;
|
||||||
|
unsigned int datasize;
|
||||||
|
unsigned int dataSum;
|
||||||
|
bool checkDataSize(unsigned int size);
|
||||||
|
};
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue