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 "json.h"
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/// Contains all MP4 format related code.
|
||||
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 managed, the pointer will be free'd upon destruction.
|
||||
Box::Box(char * datapointer, bool manage){
|
||||
|
||||
data = datapointer;
|
||||
managed = manage;
|
||||
payloadOffset = 8;
|
||||
|
@ -25,6 +28,31 @@ namespace MP4 {
|
|||
}
|
||||
}
|
||||
|
||||
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.
|
||||
Box::~Box(){
|
||||
if (managed && data != 0){
|
||||
|
@ -43,6 +71,72 @@ namespace MP4 {
|
|||
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.
|
||||
/// \returns True on success, false otherwise.
|
||||
bool Box::read(std::string & newData){
|
||||
|
@ -63,13 +157,9 @@ namespace MP4 {
|
|||
}
|
||||
}
|
||||
if (newData.size() >= size){
|
||||
void * ret = malloc(size);
|
||||
if ( !ret){
|
||||
return false;
|
||||
}
|
||||
free(data);
|
||||
data = (char*)ret;
|
||||
memcpy(data, newData.c_str(), size);
|
||||
data = (char*)realloc(data, size);
|
||||
data_size = size;
|
||||
memcpy(data, newData.data(), size);
|
||||
newData.erase(0, size);
|
||||
return true;
|
||||
}
|
||||
|
@ -568,6 +658,7 @@ namespace MP4 {
|
|||
}
|
||||
|
||||
fullBox::fullBox(){
|
||||
setVersion(0);
|
||||
}
|
||||
|
||||
void fullBox::setVersion(char newVersion){
|
||||
|
|
|
@ -15,13 +15,19 @@
|
|||
|
||||
/// Contains all MP4 format related code.
|
||||
namespace MP4 {
|
||||
std::string readBoxType(FILE * newData);
|
||||
bool skipBox(FILE * newData);
|
||||
|
||||
|
||||
class Box{
|
||||
public:
|
||||
Box(char * datapointer = 0, bool manage = true);
|
||||
Box(const Box & rs);
|
||||
Box& operator = (const Box & rs);
|
||||
~Box();
|
||||
std::string getType();
|
||||
bool isType(const char* boxType);
|
||||
bool read(FILE* newData);
|
||||
bool read(std::string & newData);
|
||||
uint64_t boxedSize();
|
||||
uint64_t payloadSize();
|
||||
|
|
Loading…
Add table
Reference in a new issue