@@ -28,8 +28,8 @@ class M4AAudioDemuxer : public M4ACommonDemuxer {
28
28
* @brief Initializes the demuxer and resets state.
29
29
*/
30
30
bool begin () {
31
- codec = Codec::Unknown;
32
- alacMagicCookie.clear ();
31
+ audio_config. codec = Codec::Unknown;
32
+ audio_config. alacMagicCookie .clear ();
33
33
resize (default_size);
34
34
35
35
stsz_processed = false ;
@@ -58,51 +58,32 @@ class M4AAudioDemuxer : public M4ACommonDemuxer {
58
58
* @brief Returns the ALAC magic cookie (codec config).
59
59
* @return Reference to the ALAC magic cookie vector.
60
60
*/
61
- Vector<uint8_t >& getALACMagicCookie () { return alacMagicCookie; }
61
+ Vector<uint8_t >& getALACMagicCookie () { return audio_config. alacMagicCookie ; }
62
62
63
63
/* *
64
64
* @brief Sets a reference pointer for callbacks.
65
65
* @param ref Reference pointer.
66
66
*/
67
67
void setReference (void * ref) { this ->ref = ref; }
68
68
69
- /* *
70
- * @brief Resizes the internal buffer.
71
- * @param size New buffer size.
72
- */
73
- void resize (int size) {
74
- default_size = size;
75
- if (buffer.size () < size) {
76
- buffer.resize (size);
77
- }
69
+ void copyFrom (M4ACommonDemuxer& source) {
70
+ audio_config = source.getM4AAudioConfig ();
78
71
}
79
72
80
73
protected:
81
- SingleBuffer<uint8_t > buffer; // /< Buffer for incremental data.
82
- void * ref = nullptr ; // /< Reference pointer for callbacks.
83
- size_t default_size = 2 * 1024 ; // /< Default buffer size.
74
+ void * ref = nullptr ; // /< Reference pointer for callbacks.
84
75
85
76
/* *
86
77
* @brief Setup all parser callbacks
87
78
*/
88
- virtual void setupParser () {
79
+ void setupParser () override {
89
80
// global box data callback to get sizes
90
81
parser.setReference (this );
91
- parser.setCallback (boxDataSetupCallback);
92
82
93
- // incremental data callback
94
- parser.setIncrementalDataCallback (incrementalBoxDataCallback);
95
-
96
- // Register a specific incremental data callback for mdat
97
- parser.setIncrementalDataCallback (
98
- " mdat" ,
99
- [](MP4Parser::Box& box, const uint8_t * data, size_t len, bool is_final,
100
- void * ref) {
101
- auto * self = static_cast <M4AAudioDemuxer*>(ref);
102
- LOGI (" *Box: %s, size: %u bytes" , box.type , (unsigned )len);
103
- self->sampleExtractor .write (data, len, is_final);
104
- },
105
- false );
83
+ // parsing for content of stsd (Sample Description Box)
84
+ parser.setCallback (" stsd" , [](MP4Parser::Box& box, void * ref) {
85
+ static_cast <M4AAudioDemuxer*>(ref)->onStsd (box);
86
+ });
106
87
107
88
// parsing for content of stsd (Sample Description Box)
108
89
parser.setCallback (" esds" , [](MP4Parser::Box& box, void * ref) {
@@ -114,107 +95,37 @@ class M4AAudioDemuxer : public M4ACommonDemuxer {
114
95
parser.setCallback (" alac" , [](MP4Parser::Box& box, void * ref) {
115
96
static_cast <M4AAudioDemuxer*>(ref)->onAlac (box);
116
97
});
98
+
99
+ // mdat
117
100
parser.setCallback (
118
101
" mdat" ,
119
102
[](MP4Parser::Box& box, void * ref) {
120
103
M4AAudioDemuxer& self = *static_cast <M4AAudioDemuxer*>(ref);
121
104
// mdat must not be buffered
122
- LOGI (" Box: %s, size: %u bytes" , box.type , (unsigned )box.size );
123
- self.sampleExtractor .setMaxSize (box.size );
105
+ LOGI (" #%d Box: %s, size: %u of %u bytes" , (unsigned ) box.seq , box.type ,(unsigned ) box.available , (unsigned )box.size );
106
+ if (box.seq == 0 ) self.sampleExtractor .setMaxSize (box.size );
107
+ size_t written = self.sampleExtractor .write (box.data , box.available , box.is_complete );
108
+ assert (written == box.available );
124
109
},
125
110
false ); // 'false' prevents the generic callback from being executed
126
- }
127
-
128
- /* *
129
- * @brief Checks if a box type is relevant for audio demuxing.
130
- * @param type Box type string.
131
- * @return True if relevant, false otherwise.
132
- */
133
- static bool isRelevantBox (const char * type) {
134
- // Check if the box is relevant for audio demuxing
135
- return (StrView (type) == " stsd" || StrView (type) == " stsz" ||
136
- StrView (type) == " stco" );
137
- }
138
-
139
- /* *
140
- * @brief Callback for box data setup. If we contain data we add
141
- * it to the buffer. If there is no data we set up the buffer to
142
- * receive incremental data.
143
- * @param box MP4 box.
144
- * @param ref Reference pointer.
145
- */
146
- static void boxDataSetupCallback (MP4Parser::Box& box, void * ref) {
147
- M4AAudioDemuxer& self = *static_cast <M4AAudioDemuxer*>(ref);
148
-
149
- bool is_relevant = isRelevantBox (box.type );
150
- if (is_relevant) {
151
- LOGI (" Box: %s, size: %u bytes" , box.type , (unsigned )box.size );
152
- if (box.data_size == 0 ) {
153
- // setup for incremental processing
154
- self.resize (box.size );
155
- self.buffer .clear ();
156
- } else {
157
- // we have the complete box data
158
- self.processBox (box);
159
- }
160
- }
161
- }
162
111
163
- /* *
164
- * @brief Callback for incremental box data.
165
- * @param box MP4 box.
166
- * @param data Pointer to data.
167
- * @param len Length of data.
168
- * @param is_final True if this is the last chunk.
169
- * @param ref Reference pointer.
170
- */
171
- static void incrementalBoxDataCallback (MP4Parser::Box& box,
172
- const uint8_t * data, size_t len,
173
- bool is_final, void * ref) {
174
- M4AAudioDemuxer& self = *static_cast <M4AAudioDemuxer*>(ref);
175
-
176
- // mdat is now handled by its specific incremental callback, so remove logic
177
- // here
178
-
179
- // only process relevant boxes
180
- if (!isRelevantBox (box.type )) return ;
181
-
182
- LOGI (" *Box: %s, size: %u bytes" , box.type , (unsigned )len);
183
-
184
- // others fill buffer incrementally
185
- if (len > 0 ) {
186
- size_t written = self.buffer .writeArray (data, len);
187
- if (written != len) {
188
- LOGE (" Failed to write all data to buffer, written: %zu, expected: %zu" ,
189
- written, len);
190
- }
191
- }
192
-
193
- // on last chunk, call the specific box handler
194
- if (is_final) {
195
- MP4Parser::Box complete_box = box;
196
- complete_box.data = self.buffer .data ();
197
- complete_box.data_size = self.buffer .size ();
198
- self.processBox (complete_box);
199
- // The buffer might be quite large, so we resize it to the default size
200
- self.resize (self.default_size );
201
- }
202
- }
112
+ // stsz
113
+ parser.setCallback (
114
+ " stsz" ,
115
+ [](MP4Parser::Box& box, void * ref) {
116
+ M4AAudioDemuxer& self = *static_cast <M4AAudioDemuxer*>(ref);
117
+ self.onStsz (box);
118
+ },
119
+ false ); // 'false' prevents the generic callback from being executed
203
120
204
- /* *
205
- * @brief Processes a parsed MP4 box.
206
- * @param box MP4 box.
207
- */
208
- void processBox (MP4Parser::Box& box) {
209
- if (StrView (box.type ) == " stsd" ) {
210
- onStsd (box);
211
- } else if (StrView (box.type ) == " stsz" ) {
212
- onStsz (box);
213
- } else if (StrView (box.type ) == " stco" ) {
214
- // onStco(box); // currently not supported
215
- }
121
+ // parser.setCallback(
122
+ // "stco",
123
+ // [](MP4Parser::Box& box, void* ref) {
124
+ // M4AAudioDemuxer& self = *static_cast<M4AAudioDemuxer*>(ref);
125
+ // self.onStco(box);
126
+ // },
127
+ // false); // 'false' prevents the generic callback from being executed
216
128
}
217
-
218
129
};
219
130
220
131
} // namespace audio_tools
0 commit comments