Added MPEG library

This commit is contained in:
Erik Zandvliet 2017-07-28 11:43:24 +02:00 committed by Thulinma
parent 5dce70e933
commit 9c2bd38611
4 changed files with 113 additions and 7 deletions

View file

@ -152,6 +152,7 @@ set(libHeaders
${SOURCE_DIR}/lib/mp4_generic.h ${SOURCE_DIR}/lib/mp4_generic.h
${SOURCE_DIR}/lib/mp4.h ${SOURCE_DIR}/lib/mp4.h
${SOURCE_DIR}/lib/mp4_ms.h ${SOURCE_DIR}/lib/mp4_ms.h
${SOURCE_DIR}/lib/mpeg.h
${SOURCE_DIR}/lib/nal.h ${SOURCE_DIR}/lib/nal.h
${SOURCE_DIR}/lib/ogg.h ${SOURCE_DIR}/lib/ogg.h
${SOURCE_DIR}/lib/procs.h ${SOURCE_DIR}/lib/procs.h
@ -200,6 +201,7 @@ set(libSources
${SOURCE_DIR}/lib/mp4_encryption.cpp ${SOURCE_DIR}/lib/mp4_encryption.cpp
${SOURCE_DIR}/lib/mp4_generic.cpp ${SOURCE_DIR}/lib/mp4_generic.cpp
${SOURCE_DIR}/lib/mp4_ms.cpp ${SOURCE_DIR}/lib/mp4_ms.cpp
${SOURCE_DIR}/lib/mpeg.cpp
${SOURCE_DIR}/lib/nal.cpp ${SOURCE_DIR}/lib/nal.cpp
${SOURCE_DIR}/lib/ogg.cpp ${SOURCE_DIR}/lib/ogg.cpp
${SOURCE_DIR}/lib/procs.cpp ${SOURCE_DIR}/lib/procs.cpp

63
lib/mpeg.cpp Normal file
View file

@ -0,0 +1,63 @@
#include "mpeg.h"
namespace Mpeg{
MP2Info parseMP2Header(const std::string &hdr){return parseMP2Header(hdr.c_str());}
MP2Info parseMP2Header(const char *hdr){
MP2Info res;
// mpeg version is on the bits 0x18 of header[1], but only 0x08 is important --> 0 is version 2,
// 1 is version 1
// leads to 2 - value == version, -1 to get the right index for the array
int mpegVersion = 1 - ((hdr[1] >> 3) & 0x01);
// samplerate is encoded in bits 0x0C of header[2];
res.sampleRate = sampleRates[mpegVersion][((hdr[2] >> 2) & 0x03)] * 1000;
res.channels = 2 - (hdr[3] >> 7);
return res;
}
void MPEG2Info::clear(){
width = 0;
height = 0;
fps = 0;
tempSeq = 0;
frameType = 0;
isHeader = false;
}
MPEG2Info parseMPEG2Header(const std::string &hdr){return parseMPEG2Header(hdr.data());}
MPEG2Info parseMPEG2Header(const char *hdr){
MPEG2Info res;
parseMPEG2Header(hdr, res);
return res;
}
bool parseMPEG2Header(const char *hdr, MPEG2Info &mpInfo){
// Check for start code
if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 1){return false;}
if (hdr[3] == 0xB3){// Sequence header
mpInfo.isHeader = true;
mpInfo.width = (hdr[4] << 4) | ((hdr[5] >> 4) & 0x0F);
mpInfo.height = ((hdr[5] & 0x0F) << 8) | hdr[6];
mpInfo.fps = frameRate[hdr[7] & 0x0F];
return true;
}
if (hdr[3] == 0x00){// Picture header
mpInfo.tempSeq = (((uint16_t)hdr[4]) << 2) || (hdr[5] >> 6);
mpInfo.frameType = (hdr[5] & 0x38) >> 3;
return true;
}
// Not parsed
return false;
}
void parseMPEG2Headers(const char *hdr, uint32_t len, MPEG2Info &mpInfo){
mpInfo.clear();
for (uint32_t i = 0; i < len-5; ++i){
parseMPEG2Header(hdr+i, mpInfo);
}
}
MPEG2Info parseMPEG2Headers(const char *hdr, uint32_t len){
MPEG2Info res;
parseMPEG2Headers(hdr, len, res);
return res;
}
}

44
lib/mpeg.h Normal file
View file

@ -0,0 +1,44 @@
#include <stdint.h>
#include <string>
namespace Mpeg{
const static double sampleRates[2][3] ={{44.1, 48.0, 32.0},{22.05, 24.0, 16.0}};
const static int sampleCounts[2][3] ={{374, 1152, 1152},{384, 1152, 576}};
const static int bitRates[2][3][16] ={
{{0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1},
{0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1},
{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1}},
{{0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1},
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1},
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}}};
struct MP2Info{
uint64_t sampleRate;
uint8_t channels;
};
MP2Info parseMP2Header(const std::string &hdr);
MP2Info parseMP2Header(const char *hdr);
const static double frameRate[16] ={
0, 24000.0 / 1001, 24, 25, 30000.0 / 1001, 30, 50, 60000.0 / 1001, 60, 0, 0, 0, 0, 0, 0, 0};
class MPEG2Info{
public:
MPEG2Info(){clear();}
void clear();
uint64_t width;
uint64_t height;
double fps;
uint16_t tempSeq;
uint8_t frameType;
bool isHeader;
};
MPEG2Info parseMPEG2Header(const std::string &hdr);
MPEG2Info parseMPEG2Header(const char *hdr);
bool parseMPEG2Header(const char *hdr, MPEG2Info &mpInfo);
void parseMPEG2Headers(const char *hdr, uint32_t len, MPEG2Info &mpInfo);
MPEG2Info parseMPEG2Headers(const char *hdr, uint32_t len);
}

View file

@ -8,6 +8,7 @@
#include <mist/stream.h> #include <mist/stream.h>
#include <mist/flv_tag.h> #include <mist/flv_tag.h>
#include <mist/defines.h> #include <mist/defines.h>
#include <mist/mpeg.h>
#include "input_mp3.h" #include "input_mp3.h"
@ -70,13 +71,9 @@ namespace Mist {
fread(header, 4, 1, inFile); fread(header, 4, 1, inFile);
fseek(inFile, filePos, SEEK_SET); fseek(inFile, filePos, SEEK_SET);
//mpeg version is on the bits 0x18 of header[1], but only 0x08 is important --> 0 is version 2, 1 is version 1 Mpeg::MP2Info mp2Info = Mpeg::parseMP2Header(header);
//leads to 2 - value == version, -1 to get the right index for the array myMeta.tracks[1].rate = mp2Info.sampleRate;
int mpegVersion = 1 - ((header[1] >> 3) & 0x01); myMeta.tracks[1].channels = mp2Info.channels;
//samplerate is encoded in bits 0x0C of header[2];
myMeta.tracks[1].rate = sampleRates[mpegVersion][((header[2] >> 2) & 0x03)] * 1000;
myMeta.tracks[1].channels = 2 - ( header[3] >> 7);
getNext(); getNext();
while (thisPacket){ while (thisPacket){