Added copy constructors for MP4 boxes
This commit is contained in:
parent
1018622d95
commit
a56f13bf8c
2 changed files with 104 additions and 7 deletions
105
lib/mp4.cpp
105
lib/mp4.cpp
|
@ -7,6 +7,8 @@
|
||||||
#include "mp4_generic.h"
|
#include "mp4_generic.h"
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
|
|
||||||
|
#include "defines.h"
|
||||||
|
|
||||||
/// Contains all MP4 format related code.
|
/// Contains all MP4 format related code.
|
||||||
namespace MP4 {
|
namespace MP4 {
|
||||||
|
|
||||||
|
@ -15,6 +17,7 @@ namespace MP4 {
|
||||||
/// If the datapointer is NULL, manage is assumed to be true even if explicitly given as false.
|
/// If the datapointer is NULL, manage is assumed to be true even if explicitly given as false.
|
||||||
/// If managed, the pointer will be free'd upon destruction.
|
/// If managed, the pointer will be free'd upon destruction.
|
||||||
Box::Box(char * datapointer, bool manage){
|
Box::Box(char * datapointer, bool manage){
|
||||||
|
|
||||||
data = datapointer;
|
data = datapointer;
|
||||||
managed = manage;
|
managed = manage;
|
||||||
payloadOffset = 8;
|
payloadOffset = 8;
|
||||||
|
@ -24,6 +27,31 @@ namespace MP4 {
|
||||||
data_size = ntohl(((int*)data)[0]);
|
data_size = ntohl(((int*)data)[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Box::Box(const Box & rs){
|
||||||
|
data = rs.data;
|
||||||
|
managed = false;
|
||||||
|
payloadOffset = rs.payloadOffset;
|
||||||
|
if (data == 0){
|
||||||
|
clear();
|
||||||
|
}else{
|
||||||
|
data_size = ntohl(((int*)data)[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Box& Box::operator = (const Box & rs){
|
||||||
|
clear();
|
||||||
|
data = rs.data;
|
||||||
|
managed = false;
|
||||||
|
payloadOffset = rs.payloadOffset;
|
||||||
|
if (data == 0){
|
||||||
|
clear();
|
||||||
|
}else{
|
||||||
|
data_size = ntohl(((int*)data)[0]);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// If managed, this will free the data pointer.
|
/// If managed, this will free the data pointer.
|
||||||
Box::~Box(){
|
Box::~Box(){
|
||||||
|
@ -43,6 +71,72 @@ namespace MP4 {
|
||||||
return !memcmp(boxType, data + 4, 4);
|
return !memcmp(boxType, data + 4, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reads the first 8 bytes and returns
|
||||||
|
std::string readBoxType(FILE * newData){
|
||||||
|
char retVal[8] = {0, 0, 0, 0, 'e', 'r', 'r', 'o'};
|
||||||
|
long long unsigned int pos = ftell(newData);
|
||||||
|
fread(retVal,8,1,newData);
|
||||||
|
fseek (newData,pos,SEEK_SET);
|
||||||
|
return std::string(retVal+4,4);
|
||||||
|
}
|
||||||
|
|
||||||
|
///\todo make good working calcBoxSize with size and payloadoffset calculation
|
||||||
|
unsigned long int calcBoxSize(char readVal[16]){
|
||||||
|
return (readVal[0] << 24) | (readVal[1] << 16) | (readVal[2] << 8) | (readVal[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool skipBox(FILE * newData){
|
||||||
|
char readVal[16];
|
||||||
|
long long unsigned int pos = ftell(newData);
|
||||||
|
if (fread(readVal,4,1,newData)){
|
||||||
|
uint64_t size = calcBoxSize(readVal);
|
||||||
|
if (size==1){
|
||||||
|
if (fread(readVal+4,12,1,newData)){
|
||||||
|
size = 0 + ntohl(((int*)readVal)[2]);
|
||||||
|
size <<= 32;
|
||||||
|
size += ntohl(((int*)readVal)[3]);
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else if (size==0){
|
||||||
|
fseek(newData, 0, SEEK_END);
|
||||||
|
}
|
||||||
|
DEBUG_MSG(DLVL_DEVEL,"skipping size 0x%0.8X",size);
|
||||||
|
if (fseek(newData, pos + size, SEEK_SET)==0){
|
||||||
|
return true;
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Box::read(FILE* newData){
|
||||||
|
char readVal[16];
|
||||||
|
long long unsigned int pos = ftell(newData);
|
||||||
|
if (fread(readVal,4,1,newData)){
|
||||||
|
payloadOffset = 8;
|
||||||
|
uint64_t size = calcBoxSize(readVal);
|
||||||
|
if (size==1){
|
||||||
|
if (fread(readVal+4,12,1,newData)){
|
||||||
|
size = 0 + ntohl(((int*)readVal)[2]);
|
||||||
|
size <<= 32;
|
||||||
|
size += ntohl(((int*)readVal)[3]);
|
||||||
|
payloadOffset = 16;
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fseek (newData,pos,SEEK_SET);
|
||||||
|
data = (char*)realloc(data, size);
|
||||||
|
data_size = size;
|
||||||
|
return (fread(data,size,1,newData) == 1);
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Reads out a whole box (if possible) from newData, copying to the internal data storage and removing from the input string.
|
/// Reads out a whole box (if possible) from newData, copying to the internal data storage and removing from the input string.
|
||||||
/// \returns True on success, false otherwise.
|
/// \returns True on success, false otherwise.
|
||||||
bool Box::read(std::string & newData){
|
bool Box::read(std::string & newData){
|
||||||
|
@ -63,13 +157,9 @@ namespace MP4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newData.size() >= size){
|
if (newData.size() >= size){
|
||||||
void * ret = malloc(size);
|
data = (char*)realloc(data, size);
|
||||||
if ( !ret){
|
data_size = size;
|
||||||
return false;
|
memcpy(data, newData.data(), size);
|
||||||
}
|
|
||||||
free(data);
|
|
||||||
data = (char*)ret;
|
|
||||||
memcpy(data, newData.c_str(), size);
|
|
||||||
newData.erase(0, size);
|
newData.erase(0, size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -568,6 +658,7 @@ namespace MP4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fullBox::fullBox(){
|
fullBox::fullBox(){
|
||||||
|
setVersion(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fullBox::setVersion(char newVersion){
|
void fullBox::setVersion(char newVersion){
|
||||||
|
|
|
@ -15,13 +15,19 @@
|
||||||
|
|
||||||
/// Contains all MP4 format related code.
|
/// Contains all MP4 format related code.
|
||||||
namespace MP4 {
|
namespace MP4 {
|
||||||
|
std::string readBoxType(FILE * newData);
|
||||||
|
bool skipBox(FILE * newData);
|
||||||
|
|
||||||
|
|
||||||
class Box{
|
class Box{
|
||||||
public:
|
public:
|
||||||
Box(char * datapointer = 0, bool manage = true);
|
Box(char * datapointer = 0, bool manage = true);
|
||||||
|
Box(const Box & rs);
|
||||||
|
Box& operator = (const Box & rs);
|
||||||
~Box();
|
~Box();
|
||||||
std::string getType();
|
std::string getType();
|
||||||
bool isType(const char* boxType);
|
bool isType(const char* boxType);
|
||||||
|
bool read(FILE* newData);
|
||||||
bool read(std::string & newData);
|
bool read(std::string & newData);
|
||||||
uint64_t boxedSize();
|
uint64_t boxedSize();
|
||||||
uint64_t payloadSize();
|
uint64_t payloadSize();
|
||||||
|
|
Loading…
Add table
Reference in a new issue