box: Initialize predefined children by non-existing box constants whenever
[L-SMASH.git] / codecs / alac.c
blobba866018264ec37850f086d8e825ba5aa0b633cd
1 /*****************************************************************************
2 * alac.c
3 *****************************************************************************
4 * Copyright (C) 2012-2017 L-SMASH project
6 * Authors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *****************************************************************************/
21 /* This file is available under an ISC license. */
23 #include "common/internal.h" /* must be placed first */
25 #include <stdlib.h>
26 #include <string.h>
27 #include <inttypes.h>
29 #include "core/box.h"
31 #define ALAC_SPECIFIC_BOX_LENGTH 36
33 uint8_t *lsmash_create_alac_specific_info( lsmash_alac_specific_parameters_t *param, uint32_t *data_length )
35 uint8_t buffer[ALAC_SPECIFIC_BOX_LENGTH];
36 lsmash_bs_t bs = { 0 };
37 bs.buffer.data = buffer;
38 bs.buffer.alloc = ALAC_SPECIFIC_BOX_LENGTH;
39 lsmash_bs_put_be32( &bs, ALAC_SPECIFIC_BOX_LENGTH ); /* box size */
40 lsmash_bs_put_be32( &bs, ISOM_BOX_TYPE_ALAC.fourcc ); /* box type: 'alac' */
41 lsmash_bs_put_be32( &bs, 0 ); /* version + flags */
42 lsmash_bs_put_be32( &bs, param->frameLength );
43 lsmash_bs_put_byte( &bs, 0 ); /* compatibleVersion */
44 lsmash_bs_put_byte( &bs, param->bitDepth );
45 lsmash_bs_put_byte( &bs, 40 ); /* pb */
46 lsmash_bs_put_byte( &bs, 14 ); /* mb */
47 lsmash_bs_put_byte( &bs, 10 ); /* kb */
48 lsmash_bs_put_byte( &bs, param->numChannels );
49 lsmash_bs_put_be16( &bs, 255 ); /* maxRun */
50 lsmash_bs_put_be32( &bs, param->maxFrameBytes );
51 lsmash_bs_put_be32( &bs, param->avgBitrate );
52 lsmash_bs_put_be32( &bs, param->sampleRate );
53 return lsmash_bs_export_data( &bs, data_length );
56 int alac_construct_specific_parameters( lsmash_codec_specific_t *dst, lsmash_codec_specific_t *src )
58 assert( dst && dst->data.structured && src && src->data.unstructured );
59 if( src->size < ALAC_SPECIFIC_BOX_LENGTH )
60 return LSMASH_ERR_INVALID_DATA;
61 lsmash_alac_specific_parameters_t *param = (lsmash_alac_specific_parameters_t *)dst->data.structured;
62 uint8_t *data = src->data.unstructured;
63 uint64_t size = LSMASH_GET_BE32( data );
64 data += ISOM_BASEBOX_COMMON_SIZE;
65 if( size == 1 )
67 size = LSMASH_GET_BE64( data );
68 data += 8;
70 if( size != src->size )
71 return LSMASH_ERR_INVALID_DATA;
72 data += 4; /* Skip version and flags. */
73 param->frameLength = LSMASH_GET_BE32( &data[0] );
74 param->bitDepth = LSMASH_GET_BYTE( &data[5] );
75 param->numChannels = LSMASH_GET_BYTE( &data[9] );
76 param->maxFrameBytes = LSMASH_GET_BE32( &data[12] );
77 param->avgBitrate = LSMASH_GET_BE32( &data[16] );
78 param->sampleRate = LSMASH_GET_BE32( &data[20] );
79 return 0;
82 int alac_print_codec_specific( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
84 assert( box->manager & LSMASH_BINARY_CODED_BOX );
85 int indent = level;
86 lsmash_ifprintf( fp, indent++, "[%s: ALAC Specific Box]\n", isom_4cc2str( box->type.fourcc ) );
87 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", box->pos );
88 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", box->size );
89 if( box->size < ALAC_SPECIFIC_BOX_LENGTH )
90 return LSMASH_ERR_INVALID_DATA;
91 uint8_t *data = box->binary;
92 isom_skip_box_common( &data );
93 lsmash_ifprintf( fp, indent, "version = %"PRIu8"\n", LSMASH_GET_BYTE( &data[0] ) );
94 lsmash_ifprintf( fp, indent, "flags = 0x%06"PRIx32"\n", LSMASH_GET_BE24( &data[1] ) );
95 data += 4;
96 lsmash_ifprintf( fp, indent, "frameLength = %"PRIu32"\n", LSMASH_GET_BE32( &data[0] ) );
97 lsmash_ifprintf( fp, indent, "compatibleVersion = %"PRIu8"\n", LSMASH_GET_BYTE( &data[4] ) );
98 lsmash_ifprintf( fp, indent, "bitDepth = %"PRIu8"\n", LSMASH_GET_BYTE( &data[5] ) );
99 lsmash_ifprintf( fp, indent, "pb = %"PRIu8"\n", LSMASH_GET_BYTE( &data[6] ) );
100 lsmash_ifprintf( fp, indent, "mb = %"PRIu8"\n", LSMASH_GET_BYTE( &data[7] ) );
101 lsmash_ifprintf( fp, indent, "kb = %"PRIu8"\n", LSMASH_GET_BYTE( &data[8] ) );
102 lsmash_ifprintf( fp, indent, "numChannels = %"PRIu8"\n", LSMASH_GET_BYTE( &data[9] ) );
103 lsmash_ifprintf( fp, indent, "maxRun = %"PRIu16"\n", LSMASH_GET_BE16( &data[10] ) );
104 lsmash_ifprintf( fp, indent, "maxFrameBytes = %"PRIu32"\n", LSMASH_GET_BE32( &data[12] ) );
105 lsmash_ifprintf( fp, indent, "avgBitrate = %"PRIu32"\n", LSMASH_GET_BE32( &data[16] ) );
106 lsmash_ifprintf( fp, indent, "sampleRate = %"PRIu32"\n", LSMASH_GET_BE32( &data[20] ) );
107 return 0;
110 int alac_update_bitrate( isom_stbl_t *stbl, isom_mdhd_t *mdhd, uint32_t sample_description_index )
112 isom_audio_entry_t *alac = (isom_audio_entry_t *)lsmash_get_entry_data( &stbl->stsd->list, sample_description_index );
113 if( LSMASH_IS_NON_EXISTING_BOX( alac ) )
114 return LSMASH_ERR_INVALID_DATA;
115 uint8_t *exdata = NULL;
116 uint32_t exdata_size = 0;
117 isom_box_t *alac_ext = isom_get_extension_box( &alac->extensions, QT_BOX_TYPE_WAVE );
118 if( LSMASH_IS_EXISTING_BOX( alac_ext ) )
120 /* Apple Lossless Audio inside QuickTime file format
121 * Though average bitrate field we found is always set to 0 apparently,
122 * we set up maxFrameBytes and avgBitRate fields. */
123 if( alac_ext->manager & LSMASH_BINARY_CODED_BOX )
124 exdata = isom_get_child_box_position( alac_ext->binary, alac_ext->size, QT_BOX_TYPE_ALAC, &exdata_size );
125 else
127 isom_wave_t *wave = (isom_wave_t *)alac_ext;
128 isom_box_t *wave_ext = isom_get_extension_box( &wave->extensions, QT_BOX_TYPE_ALAC );
129 if( !(wave_ext->manager & LSMASH_BINARY_CODED_BOX) )
130 return LSMASH_ERR_INVALID_DATA;
131 exdata = wave_ext->binary;
132 exdata_size = wave_ext->size;
135 else
137 /* Apple Lossless Audio inside ISO Base Media file format */
138 isom_box_t *ext = isom_get_extension_box( &alac->extensions, ISOM_BOX_TYPE_ALAC );
139 if( !(ext->manager & LSMASH_BINARY_CODED_BOX) )
140 return LSMASH_ERR_INVALID_DATA;
141 exdata = ext->binary;
142 exdata_size = ext->size;
144 if( !exdata || exdata_size < 36 )
145 return LSMASH_ERR_INVALID_DATA;
146 uint32_t bufferSizeDB;
147 uint32_t maxBitrate;
148 uint32_t avgBitrate;
149 int err = isom_calculate_bitrate_description( stbl, mdhd, &bufferSizeDB, &maxBitrate, &avgBitrate, sample_description_index );
150 if( err < 0 )
151 return err;
152 exdata += 24;
153 /* maxFrameBytes */
154 LSMASH_SET_BE32( &exdata[0], bufferSizeDB );
155 /* avgBitRate */
156 LSMASH_SET_BE32( &exdata[4], avgBitrate );
157 return 0;
160 #undef ALAC_SPECIFIC_BOX_LENGTH