Fixes and improvements to various MP4 library functions, by Oswald de Bruin.
This commit is contained in:
parent
17f3a37454
commit
97b8adf41e
2 changed files with 305 additions and 81 deletions
|
@ -764,9 +764,10 @@ namespace MP4 {
|
||||||
char * p = getData();
|
char * p = getData();
|
||||||
char * max_p = p + getDataSize();
|
char * max_p = p + getDataSize();
|
||||||
r << std::string(indent+1, ' ') << "ES ID: " << (unsigned int)(((unsigned int)p[0] << 8) | (unsigned int)p[1]) << std::endl;
|
r << std::string(indent+1, ' ') << "ES ID: " << (unsigned int)(((unsigned int)p[0] << 8) | (unsigned int)p[1]) << std::endl;
|
||||||
bool dep = (p[2] & 0x80);
|
bool dep = (p[2] & 0x80);//check pagina 28 ISO 1449-1 2001
|
||||||
bool url = (p[2] & 0x40);
|
bool url = (p[2] & 0x40);
|
||||||
bool ocr = (p[2] & 0x20);
|
bool ocr = (p[2] & 0x20);
|
||||||
|
//6 & 86
|
||||||
r << std::string(indent+1, ' ') << "Priority: " << int(p[2] & 0x1f) << std::endl;
|
r << std::string(indent+1, ' ') << "Priority: " << int(p[2] & 0x1f) << std::endl;
|
||||||
p += 3;
|
p += 3;
|
||||||
if (dep){
|
if (dep){
|
||||||
|
@ -907,7 +908,7 @@ namespace MP4 {
|
||||||
ESDS::ESDS(std::string init) {
|
ESDS::ESDS(std::string init) {
|
||||||
///\todo Do this better, in a non-hardcoded way.
|
///\todo Do this better, in a non-hardcoded way.
|
||||||
memcpy(data + 4, "esds", 4);
|
memcpy(data + 4, "esds", 4);
|
||||||
reserve(payloadOffset, 0, init.size() ? init.size()+29 : 26);
|
reserve(payloadOffset, 0, init.size() ? init.size()+28 : 26);
|
||||||
unsigned int i = 12;
|
unsigned int i = 12;
|
||||||
data[i++] = 3;//ES_DescrTag
|
data[i++] = 3;//ES_DescrTag
|
||||||
data[i++] = init.size() ? init.size()+23 : 21;//size
|
data[i++] = init.size() ? init.size()+23 : 21;//size
|
||||||
|
@ -941,7 +942,7 @@ namespace MP4 {
|
||||||
}
|
}
|
||||||
data[i++] = 6;//SLConfigDescriptor
|
data[i++] = 6;//SLConfigDescriptor
|
||||||
data[i++] = 1;//size
|
data[i++] = 1;//size
|
||||||
data[i++] = 2;//predefined, reserverd for use in MP4 files
|
data[i++] = 2;//predefined, reserved for use in MP4 files
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ESDS::isAAC(){
|
bool ESDS::isAAC(){
|
||||||
|
@ -967,14 +968,108 @@ namespace MP4 {
|
||||||
return r.str();
|
return r.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
FTYP::FTYP() {
|
DAC3::DAC3(unsigned int rate, unsigned int channels){
|
||||||
|
memcpy(data + 4, "dac3", 4);
|
||||||
|
setInt24(0,0);
|
||||||
|
|
||||||
|
setBitStreamIdentification(8);///\todo This is right now a default value. check the docs, this is a weird property
|
||||||
|
setBitStreamMode(0);//main, mixed audio
|
||||||
|
setAudioConfigMode(2);
|
||||||
|
|
||||||
|
switch (rate) {
|
||||||
|
case 48000:
|
||||||
|
setSampleRateCode(0);
|
||||||
|
break;
|
||||||
|
case 44100:
|
||||||
|
setSampleRateCode(1);
|
||||||
|
break;
|
||||||
|
case 32000:
|
||||||
|
setSampleRateCode(2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
setSampleRateCode(3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channels > 4) {
|
||||||
|
setLowFrequencyEffectsChannelOn(1);
|
||||||
|
} else {
|
||||||
|
setLowFrequencyEffectsChannelOn(0);
|
||||||
|
}
|
||||||
|
setFrameSizeCode(20);//should be OK, but test this.
|
||||||
|
}
|
||||||
|
|
||||||
|
char DAC3::getSampleRateCode(){
|
||||||
|
return getInt8(0) >> 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DAC3::setSampleRateCode(char newVal){
|
||||||
|
setInt8(((newVal << 6) & 0xC0) | (getInt8(0) & 0x3F), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char DAC3::getBitStreamIdentification(){
|
||||||
|
return (getInt8(0) >> 1) & 0x1F;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DAC3::setBitStreamIdentification(char newVal){
|
||||||
|
setInt8(((newVal << 1) & 0x3E) | (getInt8(0) & 0xC1), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char DAC3::getBitStreamMode(){
|
||||||
|
return (getInt16(0) >> 6) & 0x7;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DAC3::setBitStreamMode(char newVal){
|
||||||
|
setInt16(((newVal & 0x7) << 6) | (getInt16(0) & 0xFE3F), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char DAC3::getAudioConfigMode(){
|
||||||
|
return (getInt8(1) >> 3) & 0x7;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DAC3::setAudioConfigMode(char newVal){
|
||||||
|
setInt8(((newVal & 0x7) << 3) | (getInt8(1) & 0x38),1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DAC3::getLowFrequencyEffectsChannelOn(){
|
||||||
|
return (getInt8(1) >> 2) & 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DAC3::setLowFrequencyEffectsChannelOn(bool newVal){
|
||||||
|
setInt8(((unsigned int)(newVal & 0x1) << 2) | (getInt8(1) & 0x4),1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char DAC3::getFrameSizeCode(){
|
||||||
|
return ((getInt8(1) & 0x3) << 4) | ((getInt8(2) & 0xF0) >> 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DAC3::setFrameSizeCode(char newVal){
|
||||||
|
setInt16(((newVal & 0x3F) << 4) | (getInt16(1) & 0x03F0),1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string DAC3::toPrettyString(uint32_t indent){
|
||||||
|
std::stringstream r;
|
||||||
|
r << std::string(indent, ' ') << "[dac3] D-AC3 box (" << boxedSize() << ")" << std::endl;
|
||||||
|
r << std::string(indent + 1, ' ') << "FSCOD: " << (int)getSampleRateCode() << std::endl;
|
||||||
|
r << std::string(indent + 1, ' ') << "BSID: " << (int)getBitStreamIdentification() << std::endl;
|
||||||
|
r << std::string(indent + 1, ' ') << "BSMOD: " << (int)getBitStreamMode() << std::endl;
|
||||||
|
r << std::string(indent + 1, ' ') << "ACMOD: " << (int)getAudioConfigMode() << std::endl;
|
||||||
|
r << std::string(indent + 1, ' ') << "LFEON: " << (int)getLowFrequencyEffectsChannelOn() << std::endl;
|
||||||
|
r << std::string(indent + 1, ' ') << "FrameSizeCode: " << (int)getFrameSizeCode() << std::endl;
|
||||||
|
return r.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
FTYP::FTYP(bool fillDefaults){
|
||||||
memcpy(data + 4, "ftyp", 4);
|
memcpy(data + 4, "ftyp", 4);
|
||||||
setMajorBrand("mp41");
|
if (fillDefaults){
|
||||||
setMinorVersion("Mist");
|
setMajorBrand("isom");
|
||||||
setCompatibleBrands("isom", 0);
|
setMinorVersion("\000\000\002\000");
|
||||||
setCompatibleBrands("iso2", 1);
|
setCompatibleBrands("isom",0);
|
||||||
setCompatibleBrands("avc1", 2);
|
setCompatibleBrands("iso2",1);
|
||||||
setCompatibleBrands("mp41", 3);
|
setCompatibleBrands("avc1",2);
|
||||||
|
setCompatibleBrands("mp41",3);
|
||||||
|
setCompatibleBrands("Mist",4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FTYP::setMajorBrand(const char * newMajorBrand) {
|
void FTYP::setMajorBrand(const char * newMajorBrand) {
|
||||||
|
@ -1043,48 +1138,53 @@ namespace MP4 {
|
||||||
memcpy(data + 4, "mvex", 4);
|
memcpy(data + 4, "mvex", 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
TREX::TREX() {
|
TREX::TREX(unsigned int trackId){
|
||||||
memcpy(data + 4, "trex", 4);
|
memcpy(data + 4, "trex", 4);
|
||||||
|
setTrackID(trackId);
|
||||||
|
setDefaultSampleDescriptionIndex(1);
|
||||||
|
setDefaultSampleDuration(0);
|
||||||
|
setDefaultSampleSize(0);
|
||||||
|
setDefaultSampleFlags(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TREX::setTrackID(uint32_t newTrackID) {
|
void TREX::setTrackID(uint32_t newTrackID) {
|
||||||
setInt32(newTrackID, 0);
|
setInt32(newTrackID, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t TREX::getTrackID() {
|
uint32_t TREX::getTrackID() {
|
||||||
return getInt32(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TREX::setDefaultSampleDescriptionIndex(uint32_t newDefaultSampleDescriptionIndex) {
|
|
||||||
setInt32(newDefaultSampleDescriptionIndex, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t TREX::getDefaultSampleDescriptionIndex() {
|
|
||||||
return getInt32(4);
|
return getInt32(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TREX::setDefaultSampleDuration(uint32_t newDefaultSampleDuration) {
|
void TREX::setDefaultSampleDescriptionIndex(uint32_t newDefaultSampleDescriptionIndex) {
|
||||||
setInt32(newDefaultSampleDuration, 8);
|
setInt32(newDefaultSampleDescriptionIndex,8);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t TREX::getDefaultSampleDuration() {
|
uint32_t TREX::getDefaultSampleDescriptionIndex() {
|
||||||
return getInt32(8);
|
return getInt32(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TREX::setDefaultSampleSize(uint32_t newDefaultSampleSize) {
|
void TREX::setDefaultSampleDuration(uint32_t newDefaultSampleDuration) {
|
||||||
setInt32(newDefaultSampleSize, 12);
|
setInt32(newDefaultSampleDuration,12);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t TREX::getDefaultSampleSize() {
|
uint32_t TREX::getDefaultSampleDuration() {
|
||||||
return getInt32(12);
|
return getInt32(12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TREX::setDefaultSampleSize(uint32_t newDefaultSampleSize) {
|
||||||
|
setInt32(newDefaultSampleSize,16);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TREX::getDefaultSampleSize() {
|
||||||
|
return getInt32(16);
|
||||||
|
}
|
||||||
|
|
||||||
void TREX::setDefaultSampleFlags(uint32_t newDefaultSampleFlags) {
|
void TREX::setDefaultSampleFlags(uint32_t newDefaultSampleFlags) {
|
||||||
setInt32(newDefaultSampleFlags, 16);
|
setInt32(newDefaultSampleFlags,20);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t TREX::getDefaultSampleFlags() {
|
uint32_t TREX::getDefaultSampleFlags() {
|
||||||
return getInt32(16);
|
return getInt32(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TREX::toPrettyString(uint32_t indent) {
|
std::string TREX::toPrettyString(uint32_t indent) {
|
||||||
|
@ -1448,7 +1548,7 @@ namespace MP4 {
|
||||||
memcpy(data + 4, "mvhd", 4);
|
memcpy(data + 4, "mvhd", 4);
|
||||||
|
|
||||||
//reserve an entire version 0 box
|
//reserve an entire version 0 box
|
||||||
if (!reserve(0, 8, 108)) {
|
if (!reserve(0, 9, 108)) {
|
||||||
return;//on fail, cancel all the things
|
return;//on fail, cancel all the things
|
||||||
}
|
}
|
||||||
memset(data + payloadOffset, 0, 100); //set all bytes (108 - 8) to zeroes
|
memset(data + payloadOffset, 0, 100); //set all bytes (108 - 8) to zeroes
|
||||||
|
@ -1577,9 +1677,9 @@ namespace MP4 {
|
||||||
int32_t MVHD::getMatrix(size_t index) {
|
int32_t MVHD::getMatrix(size_t index) {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
if (getVersion() == 0) {
|
if (getVersion() == 0) {
|
||||||
offset = 24 + 2 + 10;
|
offset = 36;
|
||||||
} else {
|
} else {
|
||||||
offset = 36 + 2 + 10;
|
offset = 48;
|
||||||
}
|
}
|
||||||
return getInt32(offset + index * 4);
|
return getInt32(offset + index * 4);
|
||||||
}
|
}
|
||||||
|
@ -1587,17 +1687,17 @@ namespace MP4 {
|
||||||
//24 bytes of pre-defined in between
|
//24 bytes of pre-defined in between
|
||||||
void MVHD::setTrackID(uint32_t newTrackID) {
|
void MVHD::setTrackID(uint32_t newTrackID) {
|
||||||
if (getVersion() == 0) {
|
if (getVersion() == 0) {
|
||||||
setInt32(newTrackID, 86);
|
setInt32(newTrackID, 96);
|
||||||
} else {
|
} else {
|
||||||
setInt32(newTrackID, 98);
|
setInt32(newTrackID, 108);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t MVHD::getTrackID() {
|
uint32_t MVHD::getTrackID() {
|
||||||
if (getVersion() == 0) {
|
if (getVersion() == 0) {
|
||||||
return getInt32(86);
|
return getInt32(96);
|
||||||
} else {
|
} else {
|
||||||
return getInt32(98);
|
return getInt32(108);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1829,26 +1929,41 @@ namespace MP4 {
|
||||||
return r.str();
|
return r.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TKHD::TKHD(uint32_t trackId, uint64_t duration, uint32_t width, uint32_t height) {
|
TKHD::TKHD(uint32_t trackId, uint64_t duration, uint32_t width, uint32_t height) {
|
||||||
|
initialize();
|
||||||
|
setTrackID(trackId);
|
||||||
|
setDuration(duration);
|
||||||
|
setWidth(width << 16);
|
||||||
|
setHeight(height << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
TKHD::TKHD(DTSC::Track & track, bool fragmented) {
|
||||||
|
initialize();
|
||||||
|
setTrackID(track.trackID);
|
||||||
|
setDuration(-1);
|
||||||
|
if (!fragmented) {
|
||||||
|
setDuration(track.lastms - track.firstms);
|
||||||
|
}
|
||||||
|
if (track.type == "video") {
|
||||||
|
setWidth(track.width << 16);
|
||||||
|
setHeight(track.height << 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TKHD::initialize(){
|
||||||
memcpy(data + 4, "tkhd", 4);
|
memcpy(data + 4, "tkhd", 4);
|
||||||
|
|
||||||
//reserve an entire version 0 box
|
//reserve an entire version 0 box
|
||||||
if (!reserve(0, 8, 92)) {
|
if (!reserve(0, 9, 92)) {
|
||||||
return;//on fail, cancel all the things
|
return;//on fail, cancel all the things
|
||||||
}
|
}
|
||||||
memset(data + payloadOffset, 0, 84); //set all bytes (92 - 8) to zeroes
|
memset(data + payloadOffset, 0, 84); //set all bytes (92 - 8) to zeroes
|
||||||
|
setFlags(3);//ENABLED | IN_MOVIE
|
||||||
setFlags(15);//ENABLED | IN_MOVIE | IN_PREVIEW | IN_POSTER
|
|
||||||
setTrackID(trackId);
|
|
||||||
setDuration(duration);
|
|
||||||
if (width == 0 || height == 0) {
|
|
||||||
setVolume(0x0100);
|
|
||||||
}
|
|
||||||
setMatrix(0x00010000, 0);
|
setMatrix(0x00010000, 0);
|
||||||
setMatrix(0x00010000, 4);
|
setMatrix(0x00010000, 4);
|
||||||
setMatrix(0x40000000, 8);
|
setMatrix(0x40000000, 8);
|
||||||
setWidth(width << 16);
|
setVolume(0x0100);
|
||||||
setHeight(height << 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TKHD::setCreationTime(uint64_t newCreationTime) {
|
void TKHD::setCreationTime(uint64_t newCreationTime) {
|
||||||
|
@ -2046,7 +2161,7 @@ namespace MP4 {
|
||||||
MDHD::MDHD(uint64_t duration) {
|
MDHD::MDHD(uint64_t duration) {
|
||||||
memcpy(data + 4, "mdhd", 4);
|
memcpy(data + 4, "mdhd", 4);
|
||||||
//reserve an entire version 0 box
|
//reserve an entire version 0 box
|
||||||
if (!reserve(0, 8, 32)) {
|
if (!reserve(0, 9, 32)) {
|
||||||
return;//on fail, cancel all the things
|
return;//on fail, cancel all the things
|
||||||
}
|
}
|
||||||
memset(data + payloadOffset, 0, 24); //set all bytes (32 - 8) to zeroes
|
memset(data + payloadOffset, 0, 24); //set all bytes (32 - 8) to zeroes
|
||||||
|
@ -2250,6 +2365,12 @@ namespace MP4 {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STSCEntry::STSCEntry(unsigned int _first, unsigned int _count, unsigned int _index){
|
||||||
|
firstChunk = _first;
|
||||||
|
samplesPerChunk = _count;
|
||||||
|
sampleDescriptionIndex = _index;
|
||||||
|
}
|
||||||
|
|
||||||
STSC::STSC(char v, uint32_t f) {
|
STSC::STSC(char v, uint32_t f) {
|
||||||
memcpy(data + 4, "stsc", 4);
|
memcpy(data + 4, "stsc", 4);
|
||||||
setVersion(v);
|
setVersion(v);
|
||||||
|
@ -2574,6 +2695,8 @@ namespace MP4 {
|
||||||
|
|
||||||
PASP::PASP() {
|
PASP::PASP() {
|
||||||
memcpy(data + 4, "pasp", 4);
|
memcpy(data + 4, "pasp", 4);
|
||||||
|
setHSpacing(1);
|
||||||
|
setVSpacing(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PASP::setHSpacing(uint32_t newVal) {
|
void PASP::setHSpacing(uint32_t newVal) {
|
||||||
|
@ -2601,6 +2724,25 @@ namespace MP4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
VisualSampleEntry::VisualSampleEntry() {
|
VisualSampleEntry::VisualSampleEntry() {
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
VisualSampleEntry::VisualSampleEntry(DTSC::Track & track){
|
||||||
|
initialize();
|
||||||
|
setDataReferenceIndex(1);
|
||||||
|
setWidth(track.width);
|
||||||
|
setHeight(track.height);
|
||||||
|
if (track.codec == "H264") {
|
||||||
|
setCodec("avc1");
|
||||||
|
MP4::AVCC avccBox;
|
||||||
|
avccBox.setPayload(track.init);
|
||||||
|
setCLAP(avccBox);
|
||||||
|
}
|
||||||
|
MP4::PASP paspBox;
|
||||||
|
setPASP(paspBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisualSampleEntry::initialize(){
|
||||||
memcpy(data + 4, "erro", 4);
|
memcpy(data + 4, "erro", 4);
|
||||||
setHorizResolution(0x00480000);
|
setHorizResolution(0x00480000);
|
||||||
setVertResolution(0x00480000);
|
setVertResolution(0x00480000);
|
||||||
|
@ -2654,7 +2796,9 @@ namespace MP4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualSampleEntry::setCompressorName(std::string newCompressorName) {
|
void VisualSampleEntry::setCompressorName(std::string newCompressorName) {
|
||||||
|
if (newCompressorName.size() > 32){
|
||||||
newCompressorName.resize(32, ' ');
|
newCompressorName.resize(32, ' ');
|
||||||
|
}
|
||||||
setString(newCompressorName, 42);
|
setString(newCompressorName, 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2683,6 +2827,15 @@ namespace MP4 {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VisualSampleEntry::setPASP(Box & pasp) {
|
||||||
|
int writePlace = 78;
|
||||||
|
Box tmpBox = getBox(78);
|
||||||
|
if (tmpBox.getType () != "erro"){
|
||||||
|
writePlace = 78 + getBoxLen(78);
|
||||||
|
}
|
||||||
|
setBox(pasp, writePlace);
|
||||||
|
}
|
||||||
|
|
||||||
Box & VisualSampleEntry::getPASP() {
|
Box & VisualSampleEntry::getPASP() {
|
||||||
static Box ret = Box((char *)"\000\000\000\010erro", false);
|
static Box ret = Box((char *)"\000\000\000\010erro", false);
|
||||||
if (payloadSize() < 84) { //if the EntryBox is not big enough to hold a CLAP/PASP
|
if (payloadSize() < 84) { //if the EntryBox is not big enough to hold a CLAP/PASP
|
||||||
|
@ -2717,6 +2870,31 @@ namespace MP4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioSampleEntry::AudioSampleEntry() {
|
AudioSampleEntry::AudioSampleEntry() {
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioSampleEntry::AudioSampleEntry(DTSC::Track & track) {
|
||||||
|
initialize();
|
||||||
|
if (track.codec == "AAC" || track.codec == "MP3") {
|
||||||
|
setCodec("mp4a");
|
||||||
|
}
|
||||||
|
if (track.codec == "AC3") {
|
||||||
|
setCodec("ac-3");
|
||||||
|
}
|
||||||
|
setDataReferenceIndex(1);
|
||||||
|
setSampleRate(track.rate);
|
||||||
|
setChannelCount(track.channels);
|
||||||
|
setSampleSize(track.size);
|
||||||
|
if (track.codec == "AC3") {
|
||||||
|
MP4::DAC3 dac3Box(track.rate, track.channels);
|
||||||
|
setCodecBox(dac3Box);
|
||||||
|
} else { //other codecs use the ESDS box
|
||||||
|
MP4::ESDS esdsBox(track.init);
|
||||||
|
setCodecBox(esdsBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioSampleEntry::initialize() {
|
||||||
memcpy(data + 4, "erro", 4);
|
memcpy(data + 4, "erro", 4);
|
||||||
setChannelCount(2);
|
setChannelCount(2);
|
||||||
setSampleSize(16);
|
setSampleSize(16);
|
||||||
|
@ -2947,67 +3125,75 @@ namespace MP4 {
|
||||||
memcpy(data + 4, "elst", 4);
|
memcpy(data + 4, "elst", 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ELST::setSegmentDuration(uint64_t newVal) {
|
void ELST::setCount(uint32_t newVal){
|
||||||
if (getVersion() == 1) {
|
|
||||||
setInt64(newVal, 4);
|
|
||||||
} else {
|
|
||||||
setInt32(newVal, 4);
|
setInt32(newVal, 4);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t ELST::getSegmentDuration() {
|
uint32_t ELST::getCount(){
|
||||||
if (getVersion() == 1) {
|
|
||||||
return getInt64(4);
|
|
||||||
} else {
|
|
||||||
return getInt32(4);
|
return getInt32(4);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void ELST::setMediaTime(uint64_t newVal) {
|
void ELST::setSegmentDuration(uint64_t newVal) {
|
||||||
if (getVersion() == 1) {
|
if (getVersion() == 1) {
|
||||||
setInt64(newVal, 12);
|
setInt64(newVal, 8);
|
||||||
} else {
|
} else {
|
||||||
setInt32(newVal, 8);
|
setInt32(newVal, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t ELST::getMediaTime() {
|
uint64_t ELST::getSegmentDuration() {
|
||||||
if (getVersion() == 1) {
|
if (getVersion() == 1) {
|
||||||
return getInt64(12);
|
return getInt64(8);
|
||||||
} else {
|
} else {
|
||||||
return getInt32(8);
|
return getInt32(8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ELST::setMediaTime(uint64_t newVal) {
|
||||||
|
if (getVersion() == 1) {
|
||||||
|
setInt64(newVal, 16);
|
||||||
|
} else {
|
||||||
|
setInt32(newVal, 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t ELST::getMediaTime() {
|
||||||
|
if (getVersion() == 1) {
|
||||||
|
return getInt64(16);
|
||||||
|
} else {
|
||||||
|
return getInt32(12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ELST::setMediaRateInteger(uint16_t newVal) {
|
void ELST::setMediaRateInteger(uint16_t newVal) {
|
||||||
if (getVersion() == 1) {
|
if (getVersion() == 1) {
|
||||||
setInt16(newVal, 20);
|
setInt16(newVal, 24);
|
||||||
} else {
|
} else {
|
||||||
setInt16(newVal, 12);
|
setInt16(newVal, 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ELST::getMediaRateInteger() {
|
uint16_t ELST::getMediaRateInteger() {
|
||||||
if (getVersion() == 1) {
|
if (getVersion() == 1) {
|
||||||
return getInt16(20);
|
return getInt16(24);
|
||||||
} else {
|
} else {
|
||||||
return getInt16(12);
|
return getInt16(16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ELST::setMediaRateFraction(uint16_t newVal) {
|
void ELST::setMediaRateFraction(uint16_t newVal) {
|
||||||
if (getVersion() == 1) {
|
if (getVersion() == 1) {
|
||||||
setInt16(newVal, 22);
|
setInt16(newVal, 26);
|
||||||
} else {
|
} else {
|
||||||
setInt16(newVal, 14);
|
setInt16(newVal, 18);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ELST::getMediaRateFraction() {
|
uint16_t ELST::getMediaRateFraction() {
|
||||||
if (getVersion() == 1) {
|
if (getVersion() == 1) {
|
||||||
return getInt16(22);
|
return getInt16(26);
|
||||||
} else {
|
} else {
|
||||||
return getInt16(14);
|
return getInt16(18);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3015,6 +3201,7 @@ namespace MP4 {
|
||||||
std::stringstream r;
|
std::stringstream r;
|
||||||
r << std::string(indent, ' ') << "[elst] Edit List Box (" << boxedSize() << ")" << std::endl;
|
r << std::string(indent, ' ') << "[elst] Edit List Box (" << boxedSize() << ")" << std::endl;
|
||||||
r << fullBox::toPrettyString(indent);
|
r << fullBox::toPrettyString(indent);
|
||||||
|
r << std::string(indent + 1, ' ') << "Count: " << getCount() << std::endl;
|
||||||
r << std::string(indent + 1, ' ') << "SegmentDuration: " << getSegmentDuration() << std::endl;
|
r << std::string(indent + 1, ' ') << "SegmentDuration: " << getSegmentDuration() << std::endl;
|
||||||
r << std::string(indent + 1, ' ') << "MediaTime: " << getMediaTime() << std::endl;
|
r << std::string(indent + 1, ' ') << "MediaTime: " << getMediaTime() << std::endl;
|
||||||
r << std::string(indent + 1, ' ') << "MediaRateInteger: " << getMediaRateInteger() << std::endl;
|
r << std::string(indent + 1, ' ') << "MediaRateInteger: " << getMediaRateInteger() << std::endl;
|
||||||
|
|
|
@ -182,9 +182,27 @@ namespace MP4 {
|
||||||
std::string toPrettyString(uint32_t indent = 0);
|
std::string toPrettyString(uint32_t indent = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DAC3: public Box {
|
||||||
|
public:
|
||||||
|
DAC3(unsigned int rate, unsigned int channels);
|
||||||
|
char getSampleRateCode();//2bits
|
||||||
|
void setSampleRateCode(char newVal);//2bits
|
||||||
|
char getBitStreamIdentification();//5bits
|
||||||
|
void setBitStreamIdentification(char newVal);//5bits
|
||||||
|
char getBitStreamMode();//3 bits
|
||||||
|
void setBitStreamMode(char newVal);//3 bits
|
||||||
|
char getAudioConfigMode();//3 bits
|
||||||
|
void setAudioConfigMode(char newVal);//3 bits
|
||||||
|
bool getLowFrequencyEffectsChannelOn();//1bit
|
||||||
|
void setLowFrequencyEffectsChannelOn(bool newVal);//1bit
|
||||||
|
char getFrameSizeCode();//6bits
|
||||||
|
void setFrameSizeCode(char newVal);//6bits
|
||||||
|
std::string toPrettyString(uint32_t indent = 0);
|
||||||
|
};
|
||||||
|
|
||||||
class FTYP: public Box {
|
class FTYP: public Box {
|
||||||
public:
|
public:
|
||||||
FTYP();
|
FTYP(bool fillDefaults = true);
|
||||||
void setMajorBrand(const char * newMajorBrand);
|
void setMajorBrand(const char * newMajorBrand);
|
||||||
std::string getMajorBrand();
|
std::string getMajorBrand();
|
||||||
void setMinorVersion(const char * newMinorVersion);
|
void setMinorVersion(const char * newMinorVersion);
|
||||||
|
@ -195,6 +213,12 @@ namespace MP4 {
|
||||||
std::string toPrettyString(uint32_t indent = 0);
|
std::string toPrettyString(uint32_t indent = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class STYP: public FTYP {
|
||||||
|
public:
|
||||||
|
STYP(bool fillDefaults = true);
|
||||||
|
std::string toPrettyString(uint32_t indent = 0);
|
||||||
|
};
|
||||||
|
|
||||||
class MOOV: public containerBox {
|
class MOOV: public containerBox {
|
||||||
public:
|
public:
|
||||||
MOOV();
|
MOOV();
|
||||||
|
@ -205,9 +229,9 @@ namespace MP4 {
|
||||||
MVEX();
|
MVEX();
|
||||||
};
|
};
|
||||||
|
|
||||||
class TREX: public Box {
|
class TREX: public fullBox {
|
||||||
public:
|
public:
|
||||||
TREX();
|
TREX(unsigned int trackId = 0);
|
||||||
void setTrackID(uint32_t newTrackID);
|
void setTrackID(uint32_t newTrackID);
|
||||||
uint32_t getTrackID();
|
uint32_t getTrackID();
|
||||||
void setDefaultSampleDescriptionIndex(uint32_t newDefaultSampleDescriptionIndex);
|
void setDefaultSampleDescriptionIndex(uint32_t newDefaultSampleDescriptionIndex);
|
||||||
|
@ -397,6 +421,8 @@ namespace MP4 {
|
||||||
class TKHD: public fullBox {
|
class TKHD: public fullBox {
|
||||||
public:
|
public:
|
||||||
TKHD(uint32_t trackId, uint64_t duration, uint32_t width, uint32_t height);
|
TKHD(uint32_t trackId, uint64_t duration, uint32_t width, uint32_t height);
|
||||||
|
TKHD(DTSC::Track & track, bool fragmented);
|
||||||
|
|
||||||
void setCreationTime(uint64_t newCreationTime);
|
void setCreationTime(uint64_t newCreationTime);
|
||||||
uint64_t getCreationTime();
|
uint64_t getCreationTime();
|
||||||
void setModificationTime(uint64_t newModificationTime);
|
void setModificationTime(uint64_t newModificationTime);
|
||||||
|
@ -422,6 +448,8 @@ namespace MP4 {
|
||||||
void setHeight(uint32_t newHeight);
|
void setHeight(uint32_t newHeight);
|
||||||
uint32_t getHeight();
|
uint32_t getHeight();
|
||||||
std::string toPrettyString(uint32_t indent = 0);
|
std::string toPrettyString(uint32_t indent = 0);
|
||||||
|
protected:
|
||||||
|
void initialize();
|
||||||
};
|
};
|
||||||
|
|
||||||
class MDHD: public fullBox {
|
class MDHD: public fullBox {
|
||||||
|
@ -471,7 +499,9 @@ namespace MP4 {
|
||||||
std::string toPrettyString(uint32_t indent = 0);
|
std::string toPrettyString(uint32_t indent = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct STSCEntry {
|
class STSCEntry {
|
||||||
|
public:
|
||||||
|
STSCEntry(unsigned int _first = 0, unsigned int _count = 0, unsigned int _index = 0);
|
||||||
uint32_t firstChunk;
|
uint32_t firstChunk;
|
||||||
uint32_t samplesPerChunk;
|
uint32_t samplesPerChunk;
|
||||||
uint32_t sampleDescriptionIndex;
|
uint32_t sampleDescriptionIndex;
|
||||||
|
@ -563,6 +593,8 @@ namespace MP4 {
|
||||||
///\todo set default values
|
///\todo set default values
|
||||||
public:
|
public:
|
||||||
VisualSampleEntry();
|
VisualSampleEntry();
|
||||||
|
VisualSampleEntry(DTSC::Track & track);
|
||||||
|
void initialize();
|
||||||
void setCodec(const char * newCodec);
|
void setCodec(const char * newCodec);
|
||||||
void setWidth(uint16_t newWidth);
|
void setWidth(uint16_t newWidth);
|
||||||
uint16_t getWidth();
|
uint16_t getWidth();
|
||||||
|
@ -581,6 +613,7 @@ namespace MP4 {
|
||||||
Box & getCLAP();
|
Box & getCLAP();
|
||||||
void setCLAP(Box & clap);
|
void setCLAP(Box & clap);
|
||||||
Box & getPASP();
|
Box & getPASP();
|
||||||
|
void setPASP(Box & pasp);
|
||||||
std::string toPrettyVisualString(uint32_t index = 0, std::string = "");
|
std::string toPrettyVisualString(uint32_t index = 0, std::string = "");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -588,6 +621,8 @@ namespace MP4 {
|
||||||
public:
|
public:
|
||||||
///\todo set default values
|
///\todo set default values
|
||||||
AudioSampleEntry();
|
AudioSampleEntry();
|
||||||
|
AudioSampleEntry(DTSC::Track & track);
|
||||||
|
void initialize();
|
||||||
void setCodec(const char * newCodec);
|
void setCodec(const char * newCodec);
|
||||||
void setChannelCount(uint16_t newChannelCount);
|
void setChannelCount(uint16_t newChannelCount);
|
||||||
uint16_t getChannelCount();
|
uint16_t getChannelCount();
|
||||||
|
@ -666,6 +701,8 @@ namespace MP4 {
|
||||||
class ELST: public fullBox {
|
class ELST: public fullBox {
|
||||||
public:
|
public:
|
||||||
ELST();
|
ELST();
|
||||||
|
void setCount(uint32_t newVal);
|
||||||
|
uint32_t getCount();
|
||||||
void setSegmentDuration(uint64_t newVal);
|
void setSegmentDuration(uint64_t newVal);
|
||||||
uint64_t getSegmentDuration();
|
uint64_t getSegmentDuration();
|
||||||
void setMediaTime(uint64_t newVal);
|
void setMediaTime(uint64_t newVal);
|
||||||
|
|
Loading…
Add table
Reference in a new issue