2 * Copyright (C) 2013 nu774
3 * For conditions of distribution and use, see copyright notice in COPYING
17 # include <inttypes.h>
18 #elif defined _MSC_VER
19 # define PRId64 "I64d"
22 #include "m4af_endian.h"
24 #define m4af_realloc(memory,size) realloc(memory, size)
25 #define m4af_free(memory) free(memory)
26 #define m4af_max(a,b) ((a)<(b)?(b):(a))
28 #define M4AF_ATOM_WILD 0xffffffff
30 typedef struct m4af_sample_entry_t
{
33 } m4af_sample_entry_t
;
35 typedef struct m4af_chunk_entry_t
{
38 uint32_t samples_per_chunk
;
42 typedef struct m4af_track_t
{
45 uint16_t num_channels
;
46 int64_t creation_time
;
47 int64_t modification_time
;
49 uint32_t frame_duration
;
50 uint32_t encoder_delay
;
52 uint8_t *decSpecificInfo
;
53 uint32_t decSpecificInfoSize
;
54 uint32_t bufferSizeDB
;
59 m4af_sample_entry_t
*sample_table
;
61 uint32_t sample_table_capacity
;
63 m4af_chunk_entry_t
*chunk_table
;
65 uint32_t chunk_table_capacity
;
67 uint8_t *chunk_buffer
;
69 uint32_t chunk_capacity
;
71 /* temporary, to help parsing */
81 int64_t creation_time
;
82 int64_t modification_time
;
88 m4af_itmf_entry_t
*itmf_table
;
90 uint32_t itmf_table_capacity
;
92 m4af_io_callbacks_t io
;
96 m4af_track_t track
[2];
98 m4af_itmf_entry_t current_tag
;
101 typedef struct m4af_box_parser_t
{
103 int (*handler
)(m4af_ctx_t
*ctx
, uint32_t name
, uint64_t size
);
107 int64_t m4af_timestamp(void)
109 return (int64_t)(time(0)) + (((1970 - 1904) * 365) + 17) * 24 * 60 * 60;
113 * http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
116 uint32_t m4af_roundup(uint32_t n
)
129 int64_t m4af_tell(m4af_ctx_t
*ctx
)
132 if ((pos
= ctx
->io
.tell(ctx
->io_cookie
)) < 0)
133 ctx
->last_error
= M4AF_IO_ERROR
;
138 int m4af_set_pos(m4af_ctx_t
*ctx
, int64_t pos
)
141 if ((rc
= ctx
->io
.seek(ctx
->io_cookie
, pos
, SEEK_SET
)) < 0)
142 ctx
->last_error
= M4AF_IO_ERROR
;
147 int m4af_write(m4af_ctx_t
*ctx
, const void *data
, uint32_t size
)
150 if ((rc
= ctx
->io
.write(ctx
->io_cookie
, data
, size
)) < 0)
151 ctx
->last_error
= M4AF_IO_ERROR
;
156 int m4af_write16(m4af_ctx_t
*ctx
, uint32_t data
)
158 data
= m4af_htob16(data
);
159 return m4af_write(ctx
, &data
, 2);
163 int m4af_write32(m4af_ctx_t
*ctx
, uint32_t data
)
165 data
= m4af_htob32(data
);
166 return m4af_write(ctx
, &data
, 4);
170 int m4af_write64(m4af_ctx_t
*ctx
, uint64_t data
)
172 data
= m4af_htob64(data
);
173 return m4af_write(ctx
, &data
, 8);
177 int m4af_write24(m4af_ctx_t
*ctx
, uint32_t data
)
179 data
= m4af_htob32(data
<< 8);
180 return m4af_write(ctx
, &data
, 3);
184 void m4af_write32_at(m4af_ctx_t
*ctx
, int64_t pos
, uint32_t value
)
186 int64_t current_pos
= m4af_tell(ctx
);
187 m4af_set_pos(ctx
, pos
);
188 m4af_write32(ctx
, value
);
189 m4af_set_pos(ctx
, current_pos
);
192 m4af_ctx_t
*m4af_create(uint32_t codec
, uint32_t timescale
,
193 m4af_io_callbacks_t
*io
, void *io_cookie
)
198 if (codec
!= M4AF_FOURCC('m','p','4','a') &&
199 codec
!= M4AF_FOURCC('a','l','a','c'))
201 if ((ctx
= m4af_realloc(0, sizeof(m4af_ctx_t
))) == 0)
203 memset(ctx
, 0, sizeof(m4af_ctx_t
));
204 memcpy(&ctx
->io
, io
, sizeof(m4af_io_callbacks_t
));
205 ctx
->io_cookie
= io_cookie
;
206 ctx
->timescale
= timescale
;
207 timestamp
= m4af_timestamp();
208 ctx
->creation_time
= timestamp
;
209 ctx
->modification_time
= timestamp
;
211 ctx
->track
[0].codec
= codec
;
212 ctx
->track
[0].timescale
= timescale
;
213 ctx
->track
[0].creation_time
= timestamp
;
214 ctx
->track
[0].modification_time
= timestamp
;
215 ctx
->track
[0].num_channels
= 2;
220 void m4af_free_itmf_table(m4af_ctx_t
*ctx
)
223 m4af_itmf_entry_t
*entry
= ctx
->itmf_table
;
224 for (i
= 0; i
< ctx
->num_tags
; ++i
, ++entry
) {
225 if (entry
->fcc
== M4AF_FOURCC('-','-','-','-'))
226 m4af_free(entry
->name
);
227 m4af_free(entry
->data
);
229 m4af_free(ctx
->itmf_table
);
233 void m4af_clear_track(m4af_ctx_t
*ctx
, int track_idx
)
235 m4af_track_t
*track
= ctx
->track
+ track_idx
;
236 if (track
->decSpecificInfo
)
237 m4af_free(track
->decSpecificInfo
);
238 if (track
->sample_table
)
239 m4af_free(track
->sample_table
);
240 if (track
->chunk_table
)
241 m4af_free(track
->chunk_table
);
242 if (track
->chunk_buffer
)
243 m4af_free(track
->chunk_buffer
);
244 memset(track
, 0, sizeof(m4af_track_t
));
247 void m4af_teardown(m4af_ctx_t
**ctxp
)
250 m4af_ctx_t
*ctx
= *ctxp
;
251 for (i
= 0; i
< ctx
->num_tracks
; ++i
)
252 m4af_clear_track(ctx
, i
);
254 m4af_free_itmf_table(ctx
);
259 void m4af_set_num_channels(m4af_ctx_t
*ctx
, uint32_t track_idx
,
262 ctx
->track
[track_idx
].num_channels
= channels
;
265 void m4af_set_fixed_frame_duration(m4af_ctx_t
*ctx
, uint32_t track_idx
,
268 ctx
->track
[track_idx
].frame_duration
= length
;
271 int m4af_set_decoder_specific_info(m4af_ctx_t
*ctx
, uint32_t track_idx
,
272 uint8_t *data
, uint32_t size
)
274 m4af_track_t
*track
= &ctx
->track
[track_idx
];
275 if (size
> track
->decSpecificInfoSize
) {
276 uint8_t *memory
= m4af_realloc(track
->decSpecificInfo
, size
);
278 ctx
->last_error
= M4AF_NO_MEMORY
;
281 track
->decSpecificInfo
= memory
;
284 memcpy(track
->decSpecificInfo
, data
, size
);
285 track
->decSpecificInfoSize
= size
;
287 return ctx
->last_error
;
290 void m4af_set_vbr_mode(m4af_ctx_t
*ctx
, uint32_t track_idx
, int is_vbr
)
292 m4af_track_t
*track
= &ctx
->track
[track_idx
];
293 track
->is_vbr
= is_vbr
;
296 void m4af_set_priming(m4af_ctx_t
*ctx
, uint32_t track_idx
,
297 uint32_t encoder_delay
, uint32_t padding
)
299 m4af_track_t
*track
= &ctx
->track
[track_idx
];
300 track
->encoder_delay
= encoder_delay
;
301 track
->padding
= padding
;
304 void m4af_set_priming_mode(m4af_ctx_t
*ctx
, int mode
)
306 ctx
->priming_mode
= mode
;
310 int m4af_add_sample_entry(m4af_ctx_t
*ctx
, uint32_t track_idx
,
311 uint32_t size
, uint32_t delta
)
313 m4af_track_t
*track
= &ctx
->track
[track_idx
];
314 m4af_sample_entry_t
*entry
;
318 if (track
->num_samples
== track
->sample_table_capacity
) {
319 uint32_t new_size
= track
->sample_table_capacity
;
320 new_size
= new_size
? new_size
* 2 : 1;
321 entry
= m4af_realloc(track
->sample_table
, new_size
* sizeof(*entry
));
323 ctx
->last_error
= M4AF_NO_MEMORY
;
326 track
->sample_table
= entry
;
327 track
->sample_table_capacity
= new_size
;
329 entry
= track
->sample_table
+ track
->num_samples
;
331 entry
->delta
= delta
;
332 ++track
->num_samples
;
337 int m4af_flush_chunk(m4af_ctx_t
*ctx
, uint32_t track_idx
)
339 m4af_track_t
*track
= &ctx
->track
[track_idx
];
340 m4af_chunk_entry_t
*entry
;
341 if (!track
->num_chunks
|| !track
->chunk_size
)
343 entry
= &track
->chunk_table
[track
->num_chunks
- 1];
344 entry
->offset
= m4af_tell(ctx
);
345 m4af_write(ctx
, track
->chunk_buffer
, track
->chunk_size
);
346 ctx
->mdat_size
+= track
->chunk_size
;
347 track
->chunk_size
= 0;
348 return ctx
->last_error
? -1 : 0;
352 int m4af_add_chunk_entry(m4af_ctx_t
*ctx
, uint32_t track_idx
)
354 m4af_track_t
*track
= &ctx
->track
[track_idx
];
355 m4af_chunk_entry_t
*entry
;
356 if (track
->num_chunks
== track
->chunk_table_capacity
) {
357 uint32_t new_size
= track
->chunk_table_capacity
;
358 new_size
= new_size
? new_size
* 2 : 1;
359 entry
= m4af_realloc(track
->chunk_table
, new_size
* sizeof(*entry
));
361 ctx
->last_error
= M4AF_NO_MEMORY
;
364 track
->chunk_table
= entry
;
365 track
->chunk_table_capacity
= new_size
;
367 memset(&track
->chunk_table
[track
->num_chunks
++], 0,
368 sizeof(m4af_chunk_entry_t
));
373 int m4af_update_chunk_table(m4af_ctx_t
*ctx
, uint32_t track_idx
,
374 uint32_t size
, uint32_t delta
)
376 m4af_track_t
*track
= &ctx
->track
[track_idx
];
377 m4af_chunk_entry_t
*entry
;
378 int add_new_chunk
= 0;
382 if (track
->num_chunks
== 0)
385 entry
= &track
->chunk_table
[track
->num_chunks
- 1];
386 if (entry
->duration
+ delta
> track
->timescale
/ 2)
390 m4af_flush_chunk(ctx
, track_idx
);
391 if (m4af_add_chunk_entry(ctx
, track_idx
) < 0)
394 entry
= &track
->chunk_table
[track
->num_chunks
- 1];
396 ++entry
->samples_per_chunk
;
397 entry
->duration
+= delta
;
402 void m4af_update_max_bitrate(m4af_ctx_t
*ctx
, uint32_t track_idx
)
404 m4af_track_t
*track
= &ctx
->track
[track_idx
];
405 uint32_t duration
= 0, size
= 0, bitrate
;
406 m4af_sample_entry_t
*ent
= track
->sample_table
+ track
->num_samples
- 1;
408 for (; ent
>= track
->sample_table
&& duration
< track
->timescale
; --ent
) {
409 duration
+= ent
->delta
;
412 bitrate
= (uint32_t)(size
* 8.0 * track
->timescale
/ duration
+ .5);
413 if (bitrate
> track
->maxBitrate
)
414 track
->maxBitrate
= bitrate
;
418 int m4af_append_sample_to_chunk(m4af_ctx_t
*ctx
, uint32_t track_idx
,
419 const void *data
, uint32_t size
)
421 m4af_track_t
*track
= &ctx
->track
[track_idx
];
422 uint32_t newsize
= track
->chunk_size
+ size
;
426 if (track
->chunk_capacity
< newsize
) {
427 uint32_t capacity
= m4af_roundup(newsize
);
428 uint8_t *memory
= realloc(track
->chunk_buffer
, capacity
);
430 ctx
->last_error
= M4AF_NO_MEMORY
;
433 track
->chunk_buffer
= memory
;
434 track
->chunk_capacity
= capacity
;
436 memcpy(track
->chunk_buffer
+ track
->chunk_size
, data
, size
);
437 track
->chunk_size
= newsize
;
441 int m4af_write_sample(m4af_ctx_t
*ctx
, uint32_t track_idx
, const void *data
,
442 uint32_t size
, uint32_t duration
)
444 m4af_track_t
*track
= &ctx
->track
[track_idx
];
445 if (track
->frame_duration
)
446 duration
= track
->frame_duration
;
447 if (size
> track
->bufferSizeDB
)
448 track
->bufferSizeDB
= size
;
449 track
->duration
+= duration
;
450 m4af_add_sample_entry(ctx
, track_idx
, size
, duration
);
451 m4af_update_chunk_table(ctx
, track_idx
, size
, duration
);
452 m4af_update_max_bitrate(ctx
, track_idx
);
453 m4af_append_sample_to_chunk(ctx
, track_idx
, data
, size
);
454 return ctx
->last_error
;
458 m4af_itmf_entry_t
*m4af_find_itmf_slot(m4af_ctx_t
*ctx
, uint32_t fcc
,
461 m4af_itmf_entry_t
*entry
= ctx
->itmf_table
;
464 fcc
= M4AF_FOURCC('-','-','-','-');
466 if (fcc
!= M4AF_TAG_ARTWORK
)
467 for (; entry
!= ctx
->itmf_table
+ ctx
->num_tags
; ++entry
)
468 if (fcc
== entry
->fcc
&& (!name
|| !strcmp(name
, entry
->name
)))
471 if (ctx
->num_tags
== ctx
->itmf_table_capacity
) {
472 uint32_t new_size
= ctx
->itmf_table_capacity
;
473 new_size
= new_size
? new_size
* 2 : 1;
474 entry
= m4af_realloc(ctx
->itmf_table
, new_size
* sizeof(*entry
));
476 ctx
->last_error
= M4AF_NO_MEMORY
;
479 ctx
->itmf_table
= entry
;
480 ctx
->itmf_table_capacity
= new_size
;
482 entry
= &ctx
->itmf_table
[ctx
->num_tags
++];
483 memset(entry
, 0, sizeof(m4af_itmf_entry_t
));
486 char *name_copy
= m4af_realloc(0, strlen(name
) + 1);
488 ctx
->last_error
= M4AF_NO_MEMORY
;
492 strcpy(name_copy
, name
);
493 entry
->name
= name_copy
;
498 int m4af_add_itmf_long_tag(m4af_ctx_t
*ctx
, const char *name
,
501 m4af_itmf_entry_t
*entry
;
503 size_t name_len
= strlen(name
);
504 size_t data_len
= strlen(data
);
505 if (!name_len
|| !data_len
)
508 if ((entry
= m4af_find_itmf_slot(ctx
, 0, name
)) == 0)
510 entry
->type_code
= M4AF_UTF8
;
511 if ((data_copy
= m4af_realloc(entry
->data
, data_len
)) == 0) {
512 ctx
->last_error
= M4AF_NO_MEMORY
;
515 memcpy(data_copy
, data
, data_len
);
516 entry
->data
= data_copy
;
517 entry
->data_size
= data_len
;
520 return ctx
->last_error
;
523 int m4af_add_itmf_short_tag(m4af_ctx_t
*ctx
, uint32_t fcc
,
524 uint32_t type_code
, const void *data
,
527 m4af_itmf_entry_t
*entry
;
532 if ((entry
= m4af_find_itmf_slot(ctx
, fcc
, 0)) == 0)
534 entry
->type_code
= type_code
;
535 if ((data_copy
= m4af_realloc(entry
->data
, data_size
)) == 0) {
536 ctx
->last_error
= M4AF_NO_MEMORY
;
539 memcpy(data_copy
, data
, data_size
);
540 entry
->data
= data_copy
;
541 entry
->data_size
= data_size
;
544 return ctx
->last_error
;
547 int m4af_add_itmf_string_tag(m4af_ctx_t
*ctx
, uint32_t fcc
, const char *data
)
549 return m4af_add_itmf_short_tag(ctx
, fcc
, M4AF_UTF8
, data
, strlen(data
));
552 int m4af_add_itmf_int8_tag(m4af_ctx_t
*ctx
, uint32_t fcc
, int value
)
554 uint8_t data
= value
;
555 return m4af_add_itmf_short_tag(ctx
, fcc
, M4AF_INTEGER
, &data
, 1);
558 int m4af_add_itmf_int16_tag(m4af_ctx_t
*ctx
, uint32_t fcc
, int value
)
560 uint16_t data
= m4af_htob16(value
);
561 return m4af_add_itmf_short_tag(ctx
, fcc
, M4AF_INTEGER
, &data
, 2);
564 int m4af_add_itmf_int32_tag(m4af_ctx_t
*ctx
, uint32_t fcc
, uint32_t value
)
566 uint32_t data
= m4af_htob32(value
);
567 return m4af_add_itmf_short_tag(ctx
, fcc
, M4AF_INTEGER
, &data
, 4);
570 int m4af_add_itmf_int64_tag(m4af_ctx_t
*ctx
, uint32_t fcc
, uint64_t value
)
572 uint64_t data
= m4af_htob64(value
);
573 return m4af_add_itmf_short_tag(ctx
, fcc
, M4AF_INTEGER
, &data
, 8);
576 int m4af_add_itmf_track_tag(m4af_ctx_t
*ctx
, int track
, int total
)
578 uint16_t data
[4] = { 0 };
579 data
[1] = m4af_htob16(track
);
580 data
[2] = m4af_htob16(total
);
581 return m4af_add_itmf_short_tag(ctx
, M4AF_FOURCC('t','r','k','n'),
582 M4AF_IMPLICIT
, &data
, 8);
585 int m4af_add_itmf_disk_tag(m4af_ctx_t
*ctx
, int disk
, int total
)
587 uint16_t data
[3] = { 0 };
588 data
[1] = m4af_htob16(disk
);
589 data
[2] = m4af_htob16(total
);
590 return m4af_add_itmf_short_tag(ctx
, M4AF_FOURCC('d','i','s','k'),
591 M4AF_IMPLICIT
, &data
, 6);
594 int m4af_add_itmf_genre_tag(m4af_ctx_t
*ctx
, int genre
)
596 uint16_t data
= m4af_htob16(genre
);
597 return m4af_add_itmf_short_tag(ctx
, M4AF_FOURCC('g','n','r','e'),
598 M4AF_IMPLICIT
, &data
, 2);
602 int m4af_set_iTunSMPB(m4af_ctx_t
*ctx
)
604 const char *fmt
= " 00000000 %08X %08X %08X%08X 00000000 00000000 "
605 "00000000 00000000 00000000 00000000 00000000 00000000";
606 m4af_track_t
*track
= &ctx
->track
[0];
608 uint64_t length
= track
->duration
- track
->encoder_delay
- track
->padding
;
609 sprintf(buf
, fmt
, track
->encoder_delay
, track
->padding
,
610 (uint32_t)(length
>> 32), (uint32_t)length
);
611 return m4af_add_itmf_long_tag(ctx
, "iTunSMPB", buf
);
615 uint32_t m4af_update_box_size(m4af_ctx_t
*ctx
, int64_t pos
)
617 int64_t current_pos
= m4af_tell(ctx
);
618 m4af_set_pos(ctx
, pos
);
619 m4af_write32(ctx
, current_pos
- pos
);
620 m4af_set_pos(ctx
, current_pos
);
621 return current_pos
- pos
;
625 void m4af_write_descriptor(m4af_ctx_t
*ctx
, uint32_t tag
, uint32_t size
)
629 buf
[1] = ((size
>> 21) | 0x80);
630 buf
[2] = ((size
>> 14) | 0x80);
631 buf
[3] = ((size
>> 7) | 0x80);
632 buf
[4] = (size
& 0x7f);
633 m4af_write(ctx
, buf
, 5);
637 void m4af_write_ftyp_box(m4af_ctx_t
*ctx
)
639 m4af_write(ctx
, "\0\0\0\040""ftypM4A \0\0\0\0M4A mp42isom\0\0\0\0", 32);
643 void m4af_write_free_box(m4af_ctx_t
*ctx
, uint32_t size
)
645 int64_t pos
= m4af_tell(ctx
);
646 m4af_write32(ctx
, size
+ 8);
647 m4af_write(ctx
, "free", 4);
649 m4af_set_pos(ctx
, pos
+ size
+ 8);
652 int m4af_begin_write(m4af_ctx_t
*ctx
)
654 m4af_write_ftyp_box(ctx
);
655 m4af_write_free_box(ctx
, 0);
656 m4af_write(ctx
, "\0\0\0\0mdat", 8);
657 ctx
->mdat_pos
= m4af_tell(ctx
);
658 return ctx
->last_error
;
662 void m4af_write_stco_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
664 m4af_track_t
*track
= &ctx
->track
[track_idx
];
666 m4af_chunk_entry_t
*index
= track
->chunk_table
;
667 int is_co64
= (ctx
->mdat_pos
+ ctx
->mdat_size
> UINT32_MAX
);
668 int64_t pos
= m4af_tell(ctx
);
670 m4af_write32(ctx
, 0); /* size */
671 m4af_write(ctx
, is_co64
? "co64" : "stco", 4);
672 m4af_write32(ctx
, 0); /* version and flags */
673 m4af_write32(ctx
, track
->num_chunks
);
674 for (i
= 0; i
< track
->num_chunks
; ++i
, ++index
) {
676 m4af_write64(ctx
, index
->offset
);
678 m4af_write32(ctx
, index
->offset
);
680 m4af_update_box_size(ctx
, pos
);
684 void m4af_write_stsz_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
686 m4af_track_t
*track
= &ctx
->track
[track_idx
];
687 m4af_sample_entry_t
*index
= track
->sample_table
;
689 int64_t pos
= m4af_tell(ctx
);
691 "\0\0\0\0" /* size */
695 "\0\0\0\0" /* sample_size: 0(variable) */
697 m4af_write32(ctx
, track
->num_samples
);
698 for (i
= 0; i
< track
->num_samples
; ++i
, ++index
)
699 m4af_write32(ctx
, index
->size
);
700 m4af_update_box_size(ctx
, pos
);
704 void m4af_write_stsc_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
706 m4af_track_t
*track
= &ctx
->track
[track_idx
];
707 m4af_chunk_entry_t
*index
= track
->chunk_table
;
708 uint32_t i
, prev_samples_per_chunk
= 0, entry_count
= 0;
709 int64_t pos
= m4af_tell(ctx
);
711 "\0\0\0\0" /* size */
715 "\0\0\0\0" /* entry_count */
718 for (i
= 0; i
< track
->num_chunks
; ++i
, ++index
) {
719 if (index
->samples_per_chunk
!= prev_samples_per_chunk
) {
721 m4af_write32(ctx
, i
+ 1);
722 m4af_write32(ctx
, index
->samples_per_chunk
);
723 m4af_write32(ctx
, 1); /* sample_description_index */
724 prev_samples_per_chunk
= index
->samples_per_chunk
;
727 m4af_write32_at(ctx
, pos
+ 12, entry_count
);
728 m4af_update_box_size(ctx
, pos
);
732 void m4af_write_stts_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
734 m4af_track_t
*track
= &ctx
->track
[track_idx
];
735 m4af_sample_entry_t
*index
= track
->sample_table
;
736 uint32_t i
, prev_delta
= 0, entry_count
= 0, sample_count
= 0;
737 int64_t pos
= m4af_tell(ctx
);
739 "\0\0\0\0" /* size */
743 "\0\0\0\0" /* entry_count */
746 for (i
= 0; i
< track
->num_samples
; ++i
, ++index
) {
747 if (index
->delta
== prev_delta
)
752 m4af_write32(ctx
, sample_count
);
753 m4af_write32(ctx
, prev_delta
);
755 prev_delta
= index
->delta
;
760 m4af_write32(ctx
, sample_count
);
761 m4af_write32(ctx
, prev_delta
);
763 m4af_write32_at(ctx
, pos
+ 12, entry_count
);
764 m4af_update_box_size(ctx
, pos
);
768 void m4af_write_esds_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
770 m4af_track_t
*track
= &ctx
->track
[track_idx
];
771 int64_t pos
= m4af_tell(ctx
);
772 m4af_write(ctx
, "\0\0\0\0esds", 8);
773 m4af_write32(ctx
, 0); /* version + flags */
776 m4af_write_descriptor(ctx
, 3, 32 + track
->decSpecificInfoSize
);
777 m4af_write(ctx
, "\0\0\0", 3);
778 /* DecoderConfigDescriptor */
779 m4af_write_descriptor(ctx
, 4, 18 + track
->decSpecificInfoSize
);
781 "\x40" /* objectTypeIndication: 0x40(Audio ISO/IEC 14496-3)*/
782 "\x15" /* streamType(6): 0x05(AudioStream)
787 m4af_write24(ctx
, track
->bufferSizeDB
);
788 m4af_write32(ctx
, track
->maxBitrate
);
789 m4af_write32(ctx
, track
->is_vbr
? 0: track
->avgBitrate
);
790 /* DecoderSpecificInfo */
791 m4af_write_descriptor(ctx
, 5, track
->decSpecificInfoSize
);
792 m4af_write(ctx
, track
->decSpecificInfo
, track
->decSpecificInfoSize
);
793 /* SLConfigDescriptor */
794 m4af_write_descriptor(ctx
, 6, 1);
795 m4af_write(ctx
, "\002", 1); /* predefined */
797 m4af_update_box_size(ctx
, pos
);
801 void m4af_write_alac_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
803 m4af_track_t
*track
= &ctx
->track
[track_idx
];
804 int64_t pos
= m4af_tell(ctx
);
806 "\0\0\0\0" /* size */
811 m4af_write(ctx
, track
->decSpecificInfo
, track
->decSpecificInfoSize
);
812 m4af_update_box_size(ctx
, pos
);
816 void m4af_write_mp4a_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
818 m4af_track_t
*track
= &ctx
->track
[track_idx
];
819 int64_t pos
= m4af_tell(ctx
);
820 m4af_write32(ctx
, 0); /* size */
821 m4af_write32(ctx
, track
->codec
); /* mp4a or alac */
823 "\0\0\0\0\0\0" /* reserved */
824 "\0\001" /* data_reference_index: 1 */
825 "\0\0\0\0" /* reserved[0] */
826 "\0\0\0\0" /* reserved[1] */
828 m4af_write16(ctx
, track
->num_channels
);
830 "\0\020" /* samplesize: 16 */
831 "\0\0" /* pre_defined */
832 "\0\0" /* reserved */
834 if (track
->codec
== M4AF_FOURCC('m','p','4','a')) {
835 m4af_write32(ctx
, track
->timescale
<< 16);
836 m4af_write_esds_box(ctx
, track_idx
);
838 m4af_write32(ctx
, 44100 << 16);
839 m4af_write_alac_box(ctx
, track_idx
);
841 m4af_update_box_size(ctx
, pos
);
845 void m4af_write_stsd_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
847 int64_t pos
= m4af_tell(ctx
);
848 m4af_write(ctx
, "\0\0\0\0stsd", 8);
852 "\0\0\0\001" /* entry_count: 1 */
854 m4af_write_mp4a_box(ctx
, track_idx
);
855 m4af_update_box_size(ctx
, pos
);
859 void m4af_write_sbgp_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
861 m4af_track_t
*track
= &ctx
->track
[track_idx
];
863 "\0\0\0\034" /* size: 28 */
867 "roll" /* grouping_type */
868 "\0\0\0\001" /* entry_count: 1 */
870 m4af_write32(ctx
, track
->num_samples
);
871 m4af_write32(ctx
, 1); /* group_description_index */
875 void m4af_write_sgpd_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
878 "\0\0\0\026" /* size: 22 */
882 "roll" /* grouping_type */
883 "\0\0\0\001" /* entry_count: 1 */
884 "\377\377" /* payload_data: -1 */
889 void m4af_write_stbl_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
891 m4af_track_t
*track
= &ctx
->track
[track_idx
];
892 int64_t pos
= m4af_tell(ctx
);
893 m4af_write(ctx
, "\0\0\0\0stbl", 8);
894 m4af_write_stsd_box(ctx
, track_idx
);
895 if ((ctx
->priming_mode
& M4AF_PRIMING_MODE_EDTS
) &&
896 (track
->encoder_delay
|| track
->padding
)) {
897 m4af_write_sbgp_box(ctx
, track_idx
);
898 m4af_write_sgpd_box(ctx
, track_idx
);
900 m4af_write_stts_box(ctx
, track_idx
);
901 m4af_write_stsc_box(ctx
, track_idx
);
902 m4af_write_stsz_box(ctx
, track_idx
);
903 m4af_write_stco_box(ctx
, track_idx
);
904 m4af_update_box_size(ctx
, pos
);
908 void m4af_write_url_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
911 "\0\0\0\014" /* size */
914 "\0\0\001" /* flags: 1(in the same file) */
919 void m4af_write_dref_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
921 int64_t pos
= m4af_tell(ctx
);
922 m4af_write(ctx
, "\0\0\0\0dref", 8);
926 "\0\0\0\001" /* entry_count: 1 */
928 m4af_write_url_box(ctx
, track_idx
);
929 m4af_update_box_size(ctx
, pos
);
933 void m4af_write_dinf_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
935 int64_t pos
= m4af_tell(ctx
);
936 m4af_write(ctx
, "\0\0\0\0dinf", 8);
937 m4af_write_dref_box(ctx
, track_idx
);
938 m4af_update_box_size(ctx
, pos
);
942 void m4af_write_smhd_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
945 "\0\0\0\020" /* size */
950 "\0\0" /* reserved */
955 void m4af_write_minf_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
957 m4af_track_t
*track
= &ctx
->track
[track_idx
];
958 int64_t pos
= m4af_tell(ctx
);
959 m4af_write(ctx
, "\0\0\0\0minf", 8);
960 /* TODO: add TEXT support */
961 if (track
->codec
!= M4AF_CODEC_TEXT
)
962 m4af_write_smhd_box(ctx
, track_idx
);
963 m4af_write_dinf_box(ctx
, track_idx
);
964 m4af_write_stbl_box(ctx
, track_idx
);
965 m4af_update_box_size(ctx
, pos
);
969 void m4af_write_mdhd_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
971 m4af_track_t
*track
= &ctx
->track
[track_idx
];
972 int64_t pos
= m4af_tell(ctx
);
973 uint8_t version
= (track
->creation_time
> UINT32_MAX
||
974 track
->modification_time
> UINT32_MAX
||
975 track
->duration
> UINT32_MAX
);
977 m4af_write(ctx
, "\0\0\0\0mdhd", 8);
978 m4af_write(ctx
, &version
, 1);
979 m4af_write(ctx
, "\0\0\0", 3); /* flags */
981 m4af_write64(ctx
, track
->creation_time
);
982 m4af_write64(ctx
, track
->modification_time
);
983 m4af_write32(ctx
, track
->timescale
);
984 m4af_write64(ctx
, track
->duration
);
986 m4af_write32(ctx
, track
->creation_time
);
987 m4af_write32(ctx
, track
->modification_time
);
988 m4af_write32(ctx
, track
->timescale
);
989 m4af_write32(ctx
, track
->duration
);
992 "\x55\xc4" /* language: und */
993 "\0\0" /* pre_defined */
995 m4af_update_box_size(ctx
, pos
);
999 void m4af_write_hdlr_box(m4af_ctx_t
*ctx
, uint32_t track_idx
, const char *type
)
1001 int64_t pos
= m4af_tell(ctx
);
1002 static const char reserved_and_name
[10] = { 0 };
1005 "\0\0\0\0" /* size */
1008 "\0\0\0" /* flags */
1009 "\0\0\0\0" /* pre_defined */
1011 m4af_write(ctx
, type
, 4); /* handler_type */
1013 m4af_write(ctx
, !strcmp(type
, "mdir") ? "appl" : "\0\0\0\0", 4);
1014 /* reserved[1], reserved[2], name */
1015 m4af_write(ctx
, reserved_and_name
, (pos
& 1) ? 9 : 10);
1016 m4af_update_box_size(ctx
, pos
);
1020 void m4af_write_mdia_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
1022 m4af_track_t
*track
= &ctx
->track
[track_idx
];
1024 (track
->codec
== M4AF_CODEC_TEXT
) ? "text" : "soun";
1025 int64_t pos
= m4af_tell(ctx
);
1026 m4af_write(ctx
, "\0\0\0\0mdia", 8);
1027 m4af_write_mdhd_box(ctx
, track_idx
);
1028 m4af_write_hdlr_box(ctx
, track_idx
, hdlr
);
1029 m4af_write_minf_box(ctx
, track_idx
);
1030 m4af_update_box_size(ctx
, pos
);
1034 void m4af_write_elst_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
1036 m4af_track_t
*track
= &ctx
->track
[track_idx
];
1038 int64_t duration
= track
->duration
- track
->encoder_delay
- track
->padding
;
1039 int64_t pos
= m4af_tell(ctx
);
1040 duration
= (double)duration
/ track
->timescale
* ctx
->timescale
+ .5;
1041 version
= (duration
> UINT32_MAX
);
1043 m4af_write(ctx
, "\0\0\0\0elst", 8);
1044 m4af_write(ctx
, &version
, 1);
1045 m4af_write(ctx
, "\0\0\0", 3); /* flags */
1046 m4af_write32(ctx
, 1); /* entry_count: 1 */
1048 m4af_write64(ctx
, duration
);
1049 m4af_write64(ctx
, track
->encoder_delay
);
1051 m4af_write32(ctx
, duration
);
1052 m4af_write32(ctx
, track
->encoder_delay
);
1054 m4af_write16(ctx
, 1); /* media_rate_integer */
1055 m4af_write16(ctx
, 0); /* media_rate_fraction */
1056 m4af_update_box_size(ctx
, pos
);
1060 void m4af_write_edts_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
1062 int64_t pos
= m4af_tell(ctx
);
1063 m4af_write(ctx
, "\0\0\0\0edts", 8);
1064 m4af_write_elst_box(ctx
, track_idx
);
1065 m4af_update_box_size(ctx
, pos
);
1069 void m4af_write_tkhd_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
1071 m4af_track_t
*track
= &ctx
->track
[track_idx
];
1072 int64_t pos
= m4af_tell(ctx
);
1074 (double)track
->duration
/ track
->timescale
* ctx
->timescale
+ .5;
1075 uint8_t version
= (track
->creation_time
> UINT32_MAX
||
1076 track
->modification_time
> UINT32_MAX
||
1077 duration
> UINT32_MAX
);
1078 m4af_write(ctx
, "\0\0\0\0tkhd", 8);
1079 m4af_write(ctx
, &version
, 1);
1080 m4af_write(ctx
, "\0\0\007", 3); /* flags */
1082 m4af_write64(ctx
, track
->creation_time
);
1083 m4af_write64(ctx
, track
->modification_time
);
1084 m4af_write32(ctx
, track_idx
+ 1);
1085 m4af_write(ctx
, "\0\0\0\0" /* reserved */
1087 m4af_write64(ctx
, duration
);
1089 m4af_write32(ctx
, track
->creation_time
);
1090 m4af_write32(ctx
, track
->modification_time
);
1091 m4af_write32(ctx
, track_idx
+ 1);
1092 m4af_write(ctx
, "\0\0\0\0" /* reserved */
1094 m4af_write32(ctx
, duration
);
1097 "\0\0\0\0" /* reserved[0] */
1098 "\0\0\0\0" /* reserved[1] */
1100 "\0\0" /* alternate_group */
1101 "\001\0" /* volume: 1.0 */
1102 "\0\0" /* reserved */
1103 "\0\001\0\0" /* matrix[0] */
1104 "\0\0\0\0" /* matrix[1] */
1105 "\0\0\0\0" /* matrix[2] */
1106 "\0\0\0\0" /* matrix[3] */
1107 "\0\001\0\0" /* matrix[4] */
1108 "\0\0\0\0" /* matrix[5] */
1109 "\0\0\0\0" /* matrix[6] */
1110 "\0\0\0\0" /* matrix[7] */
1111 "\100\0\0\0" /* matrix[8] */
1112 "\0\0\0\0" /* width */
1113 "\0\0\0\0" /* height */
1115 m4af_update_box_size(ctx
, pos
);
1119 void m4af_write_trak_box(m4af_ctx_t
*ctx
, uint32_t track_idx
)
1121 m4af_track_t
*track
= &ctx
->track
[track_idx
];
1122 int64_t pos
= m4af_tell(ctx
);
1123 m4af_write(ctx
, "\0\0\0\0trak", 8);
1124 m4af_write_tkhd_box(ctx
, track_idx
);
1125 if ((ctx
->priming_mode
& M4AF_PRIMING_MODE_EDTS
) &&
1126 (track
->encoder_delay
|| track
->padding
))
1127 m4af_write_edts_box(ctx
, track_idx
);
1128 m4af_write_mdia_box(ctx
, track_idx
);
1129 m4af_update_box_size(ctx
, pos
);
1133 int64_t m4af_movie_duration(m4af_ctx_t
*ctx
)
1135 int64_t movie_duration
= 0;
1137 for (i
= 0; i
< ctx
->num_tracks
; ++i
) {
1138 double x
= ctx
->track
[i
].duration
;
1139 int64_t duration
= x
/ ctx
->track
[i
].timescale
* ctx
->timescale
+ .5;
1140 if (duration
> movie_duration
)
1141 movie_duration
= duration
;
1143 return movie_duration
;
1147 void m4af_write_mvhd_box(m4af_ctx_t
*ctx
)
1149 int64_t pos
= m4af_tell(ctx
);
1150 int64_t movie_duration
= m4af_movie_duration(ctx
);
1151 uint8_t version
= (ctx
->creation_time
> UINT32_MAX
||
1152 ctx
->modification_time
> UINT32_MAX
||
1153 movie_duration
> UINT32_MAX
);
1155 m4af_write(ctx
, "\0\0\0\0mvhd", 8);
1156 m4af_write(ctx
, &version
, 1);
1157 m4af_write(ctx
, "\0\0\0", 3); /* flags */
1159 m4af_write64(ctx
, ctx
->creation_time
);
1160 m4af_write64(ctx
, ctx
->modification_time
);
1161 m4af_write32(ctx
, ctx
->timescale
);
1162 m4af_write64(ctx
, movie_duration
);
1164 m4af_write32(ctx
, ctx
->creation_time
);
1165 m4af_write32(ctx
, ctx
->modification_time
);
1166 m4af_write32(ctx
, ctx
->timescale
);
1167 m4af_write32(ctx
, movie_duration
);
1170 "\0\001\0\0" /* rate: 1.0 */
1171 "\001\0" /* volume: 1.0 */
1172 "\0\0" /* reserved */
1173 "\0\0\0\0" /* reserved[0] */
1174 "\0\0\0\0" /* reserved[1] */
1175 "\0\001\0\0" /* matrix[0] */
1176 "\0\0\0\0" /* matrix[1] */
1177 "\0\0\0\0" /* matrix[2] */
1178 "\0\0\0\0" /* matrix[3] */
1179 "\0\001\0\0" /* matrix[4] */
1180 "\0\0\0\0" /* matrix[5] */
1181 "\0\0\0\0" /* matrix[6] */
1182 "\0\0\0\0" /* matrix[7] */
1183 "\100\0\0\0" /* matrix[8] */
1184 "\0\0\0\0" /* pre_defined[0] */
1185 "\0\0\0\0" /* pre_defined[1] */
1186 "\0\0\0\0" /* pre_defined[2] */
1187 "\0\0\0\0" /* pre_defined[3] */
1188 "\0\0\0\0" /* pre_defined[4] */
1189 "\0\0\0\0" /* pre_defined[5] */
1191 m4af_write32(ctx
, ctx
->num_tracks
+ 1);
1192 m4af_update_box_size(ctx
, pos
);
1196 void m4af_write_mean_box(m4af_ctx_t
*ctx
)
1199 "\0\0\0\034" /* size */
1202 "\0\0\0" /* flags */
1203 "com.apple.iTunes" /* meaning-string */
1208 void m4af_write_name_box(m4af_ctx_t
*ctx
, const char *name
)
1210 int64_t pos
= m4af_tell(ctx
);
1212 "\0\0\0\0" /* size */
1215 "\0\0\0" /* flags */
1217 m4af_write(ctx
, name
, strlen(name
));
1218 m4af_update_box_size(ctx
, pos
);
1222 void m4af_write_data_box(m4af_ctx_t
*ctx
, uint32_t type_code
,
1223 const char *data
, uint32_t data_size
)
1225 int64_t pos
= m4af_tell(ctx
);
1226 uint8_t code
= type_code
;
1228 "\0\0\0\0" /* size */
1230 "\0\0" /* reserved */
1231 "\0" /* type_set_indifier */
1233 m4af_write(ctx
, &code
, 1);
1234 m4af_write(ctx
, "\0\0\0\0", 4); /* locale */
1235 m4af_write(ctx
, data
, data_size
);
1236 m4af_update_box_size(ctx
, pos
);
1240 void m4af_write_metadata(m4af_ctx_t
*ctx
, m4af_itmf_entry_t
*entry
)
1242 int64_t pos
= m4af_tell(ctx
);
1243 m4af_write(ctx
, "\0\0\0\0", 4);
1244 m4af_write32(ctx
, entry
->fcc
);
1245 if (entry
->fcc
!= M4AF_FOURCC('-','-','-','-'))
1246 m4af_write_data_box(ctx
, entry
->type_code
,
1247 entry
->data
, entry
->data_size
);
1249 m4af_write_mean_box(ctx
);
1250 m4af_write_name_box(ctx
, entry
->name
);
1251 m4af_write_data_box(ctx
, 1, entry
->data
, entry
->data_size
);
1253 m4af_update_box_size(ctx
, pos
);
1257 void m4af_write_ilst_box(m4af_ctx_t
*ctx
)
1260 int64_t pos
= m4af_tell(ctx
);
1261 m4af_write(ctx
, "\0\0\0\0ilst", 8);
1262 for (i
= 0; i
< ctx
->num_tags
; ++i
)
1263 m4af_write_metadata(ctx
, &ctx
->itmf_table
[i
]);
1264 m4af_update_box_size(ctx
, pos
);
1268 void m4af_write_meta_box(m4af_ctx_t
*ctx
)
1270 int64_t pos
= m4af_tell(ctx
);
1272 "\0\0\0\0" /* size */
1275 "\0\0\0" /* flags */
1277 m4af_write_hdlr_box(ctx
, 0, "mdir");
1278 m4af_write_ilst_box(ctx
);
1279 m4af_update_box_size(ctx
, pos
);
1283 void m4af_write_udta_box(m4af_ctx_t
*ctx
)
1285 int64_t pos
= m4af_tell(ctx
);
1286 m4af_write(ctx
, "\0\0\0\0udta", 8);
1287 m4af_write_meta_box(ctx
);
1288 m4af_update_box_size(ctx
, pos
);
1292 uint32_t m4af_write_moov_box(m4af_ctx_t
*ctx
)
1295 int64_t pos
= m4af_tell(ctx
);
1296 m4af_write(ctx
, "\0\0\0\0moov", 8);
1297 m4af_write_mvhd_box(ctx
);
1298 for (i
= 0; i
< ctx
->num_tracks
; ++i
)
1299 m4af_write_trak_box(ctx
, i
);
1301 m4af_write_udta_box(ctx
);
1302 return m4af_update_box_size(ctx
, pos
);
1306 void m4af_finalize_mdat(m4af_ctx_t
*ctx
)
1308 if (ctx
->mdat_size
+ 8 > UINT32_MAX
) {
1309 m4af_set_pos(ctx
, ctx
->mdat_pos
- 16);
1310 m4af_write32(ctx
, 1);
1311 m4af_write(ctx
, "mdat", 4);
1312 m4af_write64(ctx
, ctx
->mdat_size
+ 16);
1314 m4af_set_pos(ctx
, ctx
->mdat_pos
- 8);
1315 m4af_write32(ctx
, ctx
->mdat_size
+ 8);
1317 m4af_set_pos(ctx
, ctx
->mdat_pos
+ ctx
->mdat_size
);
1321 void m4af_shift_mdat_pos(m4af_ctx_t
*ctx
, uint32_t offset
)
1327 end
= ctx
->mdat_pos
+ ctx
->mdat_size
;
1328 for (; (begin
= m4af_max(ctx
->mdat_pos
, end
- 8192)) < end
; end
= begin
) {
1329 m4af_set_pos(ctx
, begin
);
1330 ctx
->io
.read(ctx
->io_cookie
, buf
, end
- begin
);
1331 m4af_set_pos(ctx
, begin
+ offset
);
1332 m4af_write(ctx
, buf
, end
- begin
);
1334 for (i
= 0; i
< ctx
->num_tracks
; ++i
)
1335 for (j
= 0; j
< ctx
->track
[i
].num_chunks
; ++j
)
1336 ctx
->track
[i
].chunk_table
[j
].offset
+= offset
;
1337 ctx
->mdat_pos
+= offset
;
1338 m4af_set_pos(ctx
, ctx
->mdat_pos
- 16);
1339 m4af_write_free_box(ctx
, 0);
1340 m4af_write(ctx
, "\0\0\0\0mdat", 8);
1341 m4af_finalize_mdat(ctx
);
1344 int m4af_finalize(m4af_ctx_t
*ctx
, int optimize
)
1347 m4af_track_t
*track
;
1350 for (i
= 0; i
< ctx
->num_tracks
; ++i
) {
1351 track
= ctx
->track
+ i
;
1352 if (track
->duration
) {
1353 int64_t track_size
= 0;
1355 for (j
= 0; j
< track
->num_chunks
; ++j
)
1356 track_size
+= track
->chunk_table
[j
].size
;
1358 8.0 * track_size
* track
->timescale
/ track
->duration
+ .5;
1360 m4af_flush_chunk(ctx
, i
);
1363 if ((ctx
->priming_mode
& M4AF_PRIMING_MODE_ITUNSMPB
) &&
1364 (track
->encoder_delay
|| track
->padding
))
1365 m4af_set_iTunSMPB(ctx
);
1366 m4af_finalize_mdat(ctx
);
1367 moov_size
= m4af_write_moov_box(ctx
);
1370 m4af_shift_mdat_pos(ctx
, moov_size
+ 1024);
1371 m4af_set_pos(ctx
, 32);
1372 m4af_write_moov_box(ctx
);
1373 pos
= m4af_tell(ctx
);
1374 m4af_write_free_box(ctx
, ctx
->mdat_pos
- pos
- 24);
1376 return ctx
->last_error
;