@@ -32,14 +32,16 @@ class MP4Parser {
32
32
*/
33
33
struct Box {
34
34
friend class MP4Parser ; // /< Allow MP4Parser to access private members
35
- friend class MP4ParserExt ; // /< Allow MP4ParserExt to access private members
35
+ friend class MP4ParserExt ; // /< Allow MP4ParserExt to access private
36
+ // /< members
36
37
size_t id = 0 ; // /< Unique box ID
37
38
char type[5 ]; // /< 4-character box type (null-terminated)
38
- const uint8_t * data = nullptr ; // /< Pointer to box payload (not including header)
39
- size_t data_size = 0 ; // /< Size of payload (not including header)
40
- size_t size = 0 ; // /< Size of payload (not including header)
41
- int level = 0 ; // /< Nesting depth
42
- uint64_t offset = 0 ; // /< File offset where box starts
39
+ const uint8_t * data =
40
+ nullptr ; // /< Pointer to box payload (not including header)
41
+ size_t data_size = 0 ; // /< Size of payload (not including header)
42
+ size_t size = 0 ; // /< Size of payload (not including header)
43
+ int level = 0 ; // /< Nesting depth
44
+ uint64_t offset = 0 ; // /< File offset where box starts
43
45
bool is_complete = false ; // /< True if the box data is complete
44
46
bool is_container = false ; // /< True if the box is a container
45
47
};
@@ -52,7 +54,8 @@ class MP4Parser {
52
54
struct CallbackEntry {
53
55
char type[5 ]; // /< 4-character box type
54
56
BoxCallback cb; // /< Callback function
55
- bool callGeneric = true ; // /< If true, also call the generic callback after this one
57
+ bool callGeneric =
58
+ true ; // /< If true, also call the generic callback after this one
56
59
};
57
60
58
61
/* *
@@ -71,7 +74,8 @@ class MP4Parser {
71
74
* @brief Defines a specific callback for a box type.
72
75
* @param type 4-character box type (e.g. "moov", "mdat").
73
76
* @param cb Callback function for this box type.
74
- * @param callGeneric If true, the generic callback will also be called after the type-specific callback.
77
+ * @param callGeneric If true, the generic callback will also be called after
78
+ * the type-specific callback.
75
79
*/
76
80
void setCallback (const char * type, BoxCallback cb, bool callGeneric = true ) {
77
81
CallbackEntry entry;
@@ -179,24 +183,24 @@ class MP4Parser {
179
183
}
180
184
181
185
protected:
182
- BoxCallback callback = defaultCallback; // /< Generic callback for all boxes
183
- Vector<CallbackEntry> callbacks; // /< List of type-specific callbacks
184
- SingleBuffer<uint8_t > buffer; // /< Buffer for incoming data
185
- Vector<size_t > levelStack; // /< Stack for container box levels
186
- size_t parseOffset = 0 ; // /< Current parse offset in buffer
187
- uint64_t fileOffset = 0 ; // /< Current file offset
188
- void * ref = this ; // /< Reference pointer for callbacks
189
- Box box; // /< Current box being processed
190
- bool is_error = false ; // /< True if an error occurred
186
+ BoxCallback callback = defaultCallback; // /< Generic callback for all boxes
187
+ Vector<CallbackEntry> callbacks; // /< List of type-specific callbacks
188
+ SingleBuffer<uint8_t > buffer; // /< Buffer for incoming data
189
+ Vector<size_t > levelStack; // /< Stack for container box levels
190
+ size_t parseOffset = 0 ; // /< Current parse offset in buffer
191
+ uint64_t fileOffset = 0 ; // /< Current file offset
192
+ void * ref = this ; // /< Reference pointer for callbacks
193
+ Box box; // /< Current box being processed
194
+ bool is_error = false ; // /< True if an error occurred
191
195
192
196
/* *
193
197
* @brief Structure for container box information.
194
198
*/
195
199
struct ContainerInfo {
196
- const char * name = nullptr ; // /< Name of the container box
197
- int start = 0 ; // /< Offset of child boxes
200
+ const char * name = nullptr ; // /< Name of the container box
201
+ int start = 0 ; // /< Offset of child boxes
198
202
};
199
- Vector<ContainerInfo> containers; // /< List of container box info
203
+ Vector<ContainerInfo> containers; // /< List of container box info
200
204
201
205
/* *
202
206
* @brief Returns the current file offset (absolute position in file).
@@ -292,10 +296,10 @@ class MP4Parser {
292
296
box.is_complete = (parseOffset + boxSize <= bufferSize);
293
297
box.is_container = is_container;
294
298
295
- // Special logic for container: no data
299
+ // Special logic for container: usually no data
296
300
if (box.is_container ) {
297
- box.data = nullptr ;
298
- box.data_size = 0 ;
301
+ box.data_size = getContainerDataLength (box. type ) ;
302
+ if ( box.data_size == 0 ) box. data = nullptr ;
299
303
box.is_complete = true ;
300
304
}
301
305
@@ -305,7 +309,7 @@ class MP4Parser {
305
309
// Recurse into container
306
310
if (box.is_container ) {
307
311
levelStack.push_back (absBoxOffset + boxSize);
308
- parseOffset += headerSize;
312
+ parseOffset += ( headerSize + box. data_size ) ;
309
313
continue ;
310
314
}
311
315
@@ -334,7 +338,8 @@ class MP4Parser {
334
338
335
339
/* *
336
340
* @brief Processes the callback for a box.
337
- * Calls the type-specific callback if present, and the generic callback if allowed.
341
+ * Calls the type-specific callback if present, and the generic callback if
342
+ * allowed.
338
343
* @param box The box being processed.
339
344
*/
340
345
void processCallback (Box& box) {
@@ -360,15 +365,18 @@ class MP4Parser {
360
365
// fill with default values if nothing has been defined
361
366
if (containers.empty ()) {
362
367
static const char * containers_str[] = {
363
- " moov" , " trak" , " mdia" , " minf" , " stbl" , " edts" ,
364
- " dinf" , " udta" , " meta" , " ilst" , " moof" , " traf" ,
365
- " mfra" , " tref" , " iprp" , " sinf" , " schi" };
368
+ " moov" , " trak" , " mdia" , " minf" , " stbl" , " edts" , " dinf" , " udta" ,
369
+ " ilst" , " moof" , " traf" , " mfra" , " tref" , " iprp" , " sinf" , " schi" };
366
370
for (const char * c : containers_str) {
367
371
ContainerInfo info;
368
372
info.name = c;
369
373
info.start = 0 ;
370
374
containers.push_back (info);
371
375
}
376
+ ContainerInfo info;
377
+ info.name = " meta" ;
378
+ info.start = 4 ; // 4 bytes: version (1 byte) + flags (3 bytes)
379
+ containers.push_back (info);
372
380
}
373
381
// find the container by name
374
382
for (auto & cont : containers) {
@@ -382,7 +390,7 @@ class MP4Parser {
382
390
* @param type Box type string.
383
391
* @return Offset of the subcontainer.
384
392
*/
385
- int getSubcontainerStart (const char * type) {
393
+ int getContainerDataLength (const char * type) {
386
394
for (auto & cont : containers) {
387
395
if (StrView (type) == cont.name ) return cont.start ;
388
396
}
@@ -407,11 +415,11 @@ class MP4Parser {
407
415
* @param offset Offset in the string.
408
416
* @return true if valid, false otherwise.
409
417
*/
410
- bool isValidType (const char * type, int offset= 0 ) const {
418
+ bool isValidType (const char * type, int offset = 0 ) const {
411
419
// Check if the type is a valid 4-character string
412
- return (type != nullptr &&
413
- isalnum (type[offset]) && isalnum (type[offset+ 1 ]) &&
414
- isalnum (type[offset+ 2 ]) && isalnum (type[offset+ 3 ]));
420
+ return (type != nullptr && isalnum (type[offset]) &&
421
+ isalnum (type[offset + 1 ]) && isalnum (type[offset + 2 ]) &&
422
+ isalnum (type[offset + 3 ]));
415
423
}
416
424
417
425
/* *
0 commit comments