1 /*****************************************************************************
2  * summary.c
3  *****************************************************************************
4  * Copyright (C) 2010-2017 L-SMASH project
5  *
6  * Authors: Takashi Hirata <silverfilain@gmail.com>
7  *
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.
11  *
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  *****************************************************************************/
20 
21 /* This file is available under an ISC license. */
22 
23 #include "common/internal.h" /* must be placed first */
24 
25 #include <stdlib.h>
26 #include <string.h>
27 
28 #include "box.h"
29 
30 #include "codecs/mp4a.h"
31 #include "codecs/mp4sys.h"
32 #include "codecs/description.h"
33 
34 /***************************************************************************
35     summary and AudioSpecificConfig relative tools
36 ***************************************************************************/
37 
38 /* create AudioSpecificConfig as memory block from summary, and set it into that summary itself */
lsmash_setup_AudioSpecificConfig(lsmash_audio_summary_t * summary)39 int lsmash_setup_AudioSpecificConfig( lsmash_audio_summary_t *summary )
40 {
41     if( !summary || !summary->opaque )
42         return LSMASH_ERR_FUNCTION_PARAM;
43     /* Remove an old one. */
44     for( lsmash_entry_t *entry = summary->opaque->list.head; entry; )
45     {
46         lsmash_entry_t *old_entry = entry;
47         entry = entry->next;
48         lsmash_codec_specific_t *cs = (lsmash_codec_specific_t *)old_entry->data;
49         if( !cs || cs->type != LSMASH_CODEC_SPECIFIC_DATA_TYPE_MP4SYS_DECODER_CONFIG )
50             continue;
51         lsmash_list_remove_entry_direct( &summary->opaque->list, old_entry );
52     }
53     /* Create and add a new one. */
54     uint32_t data_length;
55     uint8_t *data = mp4a_export_AudioSpecificConfig( summary->aot,
56                                                      summary->frequency,
57                                                      summary->channels,
58                                                      summary->sbr_mode,
59                                                      NULL,  /* FIXME */
60                                                      0,     /* FIXME */
61                                                      &data_length );
62     if( !data )
63         return LSMASH_ERR_NAMELESS;
64     lsmash_codec_specific_t *cs = lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_MP4SYS_DECODER_CONFIG,
65                                                                      LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED );
66     if( !cs )
67     {
68         lsmash_free( data );
69         return LSMASH_ERR_MEMORY_ALLOC;
70     }
71     lsmash_mp4sys_decoder_parameters_t *param = (lsmash_mp4sys_decoder_parameters_t *)cs->data.structured;
72     param->objectTypeIndication = MP4SYS_OBJECT_TYPE_Audio_ISO_14496_3;
73     param->streamType           = MP4SYS_STREAM_TYPE_AudioStream;
74     int err = lsmash_set_mp4sys_decoder_specific_info( param, data, data_length );
75     lsmash_free( data );
76     if( err < 0 || (err = lsmash_list_add_entry( &summary->opaque->list, cs )) < 0 )
77     {
78         lsmash_destroy_codec_specific_data( cs );
79         return err;
80     }
81     return 0;
82 }
83 
summary_allocate_opaque(void)84 static lsmash_codec_specific_list_t *summary_allocate_opaque( void )
85 {
86     lsmash_codec_specific_list_t *opaque = (lsmash_codec_specific_list_t *)lsmash_malloc_zero( sizeof(lsmash_codec_specific_list_t) );
87     if( opaque )
88         lsmash_list_init( &opaque->list, lsmash_destroy_codec_specific_data );
89     return opaque;
90 }
91 
summary_deallocate_opaque(lsmash_codec_specific_list_t * opaque)92 static void summary_deallocate_opaque
93 (
94     lsmash_codec_specific_list_t *opaque
95 )
96 {
97     if( !opaque )
98         return;
99     lsmash_list_remove_entries( &opaque->list );
100     lsmash_free( opaque );
101 }
102 
lsmash_create_summary(lsmash_summary_type summary_type)103 lsmash_summary_t *lsmash_create_summary( lsmash_summary_type summary_type )
104 {
105     size_t summary_size;
106     switch( summary_type )
107     {
108         case LSMASH_SUMMARY_TYPE_VIDEO :
109             summary_size = sizeof(lsmash_video_summary_t);
110             break;
111         case LSMASH_SUMMARY_TYPE_AUDIO :
112             summary_size = sizeof(lsmash_audio_summary_t);
113             break;
114         default :
115             /* 'summary_size = sizeof(lsmash_summary_t);' is a dead assignment here. */
116             return NULL;
117     }
118     lsmash_summary_t *summary = (lsmash_summary_t *)lsmash_malloc_zero( summary_size );
119     if( !summary )
120         return NULL;
121     summary->opaque = summary_allocate_opaque();
122     if( !summary->opaque )
123     {
124         lsmash_free( summary );
125         return NULL;
126     }
127     summary->summary_type   = summary_type;
128     summary->data_ref_index = 1;
129     return summary;
130 }
131 
lsmash_cleanup_summary(lsmash_summary_t * summary)132 void lsmash_cleanup_summary( lsmash_summary_t *summary )
133 {
134     if( !summary )
135         return;
136     summary_deallocate_opaque( summary->opaque );
137     lsmash_free( summary );
138 }
139 
lsmash_add_codec_specific_data(lsmash_summary_t * summary,lsmash_codec_specific_t * specific)140 int lsmash_add_codec_specific_data( lsmash_summary_t *summary, lsmash_codec_specific_t *specific )
141 {
142     if( !summary || !summary->opaque || !specific )
143         return LSMASH_ERR_FUNCTION_PARAM;
144     lsmash_codec_specific_t *dup = isom_duplicate_codec_specific_data( specific );
145     if( !dup )
146         return LSMASH_ERR_NAMELESS;
147     if( lsmash_list_add_entry( &summary->opaque->list, dup ) < 0 )
148     {
149         lsmash_destroy_codec_specific_data( dup );
150         return LSMASH_ERR_MEMORY_ALLOC;
151     }
152     return 0;
153 }
154 
lsmash_count_summary(lsmash_root_t * root,uint32_t track_ID)155 uint32_t lsmash_count_summary( lsmash_root_t *root, uint32_t track_ID )
156 {
157     if( isom_check_initializer_present( root ) < 0 || track_ID == 0 )
158         return 0;
159     isom_trak_t *trak = isom_get_trak( root->file->initializer, track_ID );
160     if( LSMASH_IS_NON_EXISTING_BOX( trak )
161      || LSMASH_IS_NON_EXISTING_BOX( trak->mdia->mdhd )
162      || LSMASH_IS_NON_EXISTING_BOX( trak->mdia->hdlr ) )
163         return 0;
164     return trak->mdia->minf->stbl->stsd->list.entry_count;
165 }
166 
lsmash_get_summary(lsmash_root_t * root,uint32_t track_ID,uint32_t description_number)167 lsmash_summary_t *lsmash_get_summary( lsmash_root_t *root, uint32_t track_ID, uint32_t description_number )
168 {
169     if( isom_check_initializer_present( root ) < 0 || track_ID == 0 || description_number == 0 )
170         return NULL;
171     isom_trak_t *trak = isom_get_trak( root->file->initializer, track_ID );
172     if( LSMASH_IS_NON_EXISTING_BOX( trak->mdia->mdhd )
173      || LSMASH_IS_NON_EXISTING_BOX( trak->mdia->hdlr ) )
174         return NULL;
175     isom_minf_t *minf = trak->mdia->minf;
176     isom_stsd_t *stsd = minf->stbl->stsd;
177     uint32_t i = 1;
178     for( lsmash_entry_t *entry = stsd->list.head; entry; entry = entry->next )
179     {
180         if( i != description_number )
181         {
182             ++i;
183             continue;
184         }
185         isom_sample_entry_t *sample_entry = entry->data;
186         if( LSMASH_IS_NON_EXISTING_BOX( sample_entry ) )
187             return NULL;
188         if( LSMASH_IS_EXISTING_BOX( minf->vmhd ) )
189             return isom_create_video_summary_from_description( sample_entry );
190         else if( LSMASH_IS_EXISTING_BOX( minf->smhd ) )
191             return isom_create_audio_summary_from_description( sample_entry );
192         else
193             return NULL;
194     }
195     return NULL;
196 }
197 
lsmash_compare_summary(lsmash_summary_t * a,lsmash_summary_t * b)198 int lsmash_compare_summary( lsmash_summary_t *a, lsmash_summary_t *b )
199 {
200     if( !a || !b )
201         return LSMASH_ERR_FUNCTION_PARAM;
202     if( a->summary_type != b->summary_type
203      || !lsmash_check_box_type_identical( a->sample_type, b->sample_type ) )
204         return 1;
205     if( a->summary_type == LSMASH_SUMMARY_TYPE_VIDEO )
206     {
207         lsmash_video_summary_t *in_video  = (lsmash_video_summary_t *)a;
208         lsmash_video_summary_t *out_video = (lsmash_video_summary_t *)b;
209         if( in_video->width  != out_video->width
210          || in_video->height != out_video->height
211          || in_video->depth  != out_video->depth
212          || in_video->par_h  != out_video->par_h
213          || in_video->par_v  != out_video->par_v
214          || memcmp( in_video->compressorname, out_video->compressorname, strlen( in_video->compressorname ) )
215          || in_video->clap.width.n             != out_video->clap.width.n
216          || in_video->clap.width.d             != out_video->clap.width.d
217          || in_video->clap.height.n            != out_video->clap.height.n
218          || in_video->clap.height.d            != out_video->clap.height.d
219          || in_video->clap.horizontal_offset.n != out_video->clap.horizontal_offset.n
220          || in_video->clap.horizontal_offset.d != out_video->clap.horizontal_offset.d
221          || in_video->clap.vertical_offset.n   != out_video->clap.vertical_offset.n
222          || in_video->clap.vertical_offset.d   != out_video->clap.vertical_offset.d
223          || in_video->color.primaries_index != out_video->color.primaries_index
224          || in_video->color.transfer_index  != out_video->color.transfer_index
225          || in_video->color.matrix_index    != out_video->color.matrix_index
226          || in_video->color.full_range      != out_video->color.full_range )
227             return 1;
228     }
229     else if( a->summary_type == LSMASH_SUMMARY_TYPE_AUDIO )
230     {
231         lsmash_audio_summary_t *in_audio  = (lsmash_audio_summary_t *)a;
232         lsmash_audio_summary_t *out_audio = (lsmash_audio_summary_t *)b;
233         if( in_audio->frequency        != out_audio->frequency
234          || in_audio->channels         != out_audio->channels
235          || in_audio->sample_size      != out_audio->sample_size
236          || in_audio->samples_in_frame != out_audio->samples_in_frame )
237             return 1;
238     }
239     return isom_compare_opaque_extensions( a, b );
240 }
241 
lsmash_check_codec_support(lsmash_codec_type_t sample_type)242 lsmash_codec_support_flag lsmash_check_codec_support( lsmash_codec_type_t sample_type )
243 {
244     static struct codec_support_table_tag
245     {
246         lsmash_codec_type_t       type;
247         lsmash_codec_support_flag flags;
248     } codec_support_table[160] = { { LSMASH_CODEC_TYPE_INITIALIZER, LSMASH_CODEC_SUPPORT_FLAG_NONE } };
249     if( lsmash_check_codec_type_identical( codec_support_table[0].type, LSMASH_CODEC_TYPE_UNSPECIFIED ) )
250     {
251         /* Initialize the table. */
252         int i = 0;
253 #define ADD_CODEC_SUPPORT_TABLE_ELEMENT( type, flags ) \
254     codec_support_table[i++] = (struct codec_support_table_tag){ type, flags }
255         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_AC_3_AUDIO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
256         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_ALAC_AUDIO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
257         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_DTSC_AUDIO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
258         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_DTSE_AUDIO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
259         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_DTSH_AUDIO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
260         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_DTSL_AUDIO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
261         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_DTSX_AUDIO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
262         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_EC_3_AUDIO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
263         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_MP4A_AUDIO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
264         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_SAMR_AUDIO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
265         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_SAWB_AUDIO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
266         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_23NI_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
267         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_MAC3_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
268         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_MAC6_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
269         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_NONE_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
270         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_QCLP_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_DEMUX );
271         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_AGSM_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
272         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_ALAC_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
273         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_ALAW_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
274         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_FL32_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
275         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_FL64_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
276         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_IN24_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
277         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_IN32_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
278         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_LPCM_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
279         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_MP4A_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
280         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_RAW_AUDIO,       LSMASH_CODEC_SUPPORT_FLAG_REMUX );
281         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_SOWT_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
282         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_TWOS_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
283         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_ULAW_AUDIO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
284         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_FULLMP3_AUDIO,   LSMASH_CODEC_SUPPORT_FLAG_REMUX );
285         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_ADPCM2_AUDIO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
286         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_ADPCM17_AUDIO,   LSMASH_CODEC_SUPPORT_FLAG_REMUX );
287         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_GSM49_AUDIO,     LSMASH_CODEC_SUPPORT_FLAG_REMUX );
288         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_NOT_SPECIFIED,   LSMASH_CODEC_SUPPORT_FLAG_REMUX );
289         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_AVC1_VIDEO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
290         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_AVC3_VIDEO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
291         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_HVC1_VIDEO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
292         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_HEV1_VIDEO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
293         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_MP4V_VIDEO,    LSMASH_CODEC_SUPPORT_FLAG_MUX );
294         ADD_CODEC_SUPPORT_TABLE_ELEMENT( ISOM_CODEC_TYPE_VC_1_VIDEO,    LSMASH_CODEC_SUPPORT_FLAG_REMUX );
295         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_2VUY_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
296         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_DV10_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
297         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_DVOO_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
298         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_APCH_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
299         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_APCN_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
300         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_APCS_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
301         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_APCO_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
302         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_AP4H_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
303         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_AP4X_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
304         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_DVC_VIDEO,       LSMASH_CODEC_SUPPORT_FLAG_REMUX );
305         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_DVCP_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
306         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_DVPP_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
307         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_DV5N_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
308         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_DV5P_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
309         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_DVH2_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
310         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_DVH3_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
311         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_DVH5_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
312         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_DVH6_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
313         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_DVHP_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
314         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_DVHQ_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
315         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_FLIC_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
316         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_H261_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
317         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_H263_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
318         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_JPEG_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
319         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_MJPA_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
320         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_MJPB_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
321         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_PNG_VIDEO,       LSMASH_CODEC_SUPPORT_FLAG_REMUX );
322         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_RAW_VIDEO,       LSMASH_CODEC_SUPPORT_FLAG_REMUX );
323         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_RLE_VIDEO,       LSMASH_CODEC_SUPPORT_FLAG_REMUX );
324         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_RPZA_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
325         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_TGA_VIDEO,       LSMASH_CODEC_SUPPORT_FLAG_REMUX );
326         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_TIFF_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
327         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_ULRA_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
328         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_ULRG_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
329         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_ULY0_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
330         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_ULY2_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
331         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_ULH0_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
332         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_ULH2_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
333         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_UQY2_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
334         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_V210_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
335         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_V216_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
336         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_V308_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
337         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_V408_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
338         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_V410_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
339         ADD_CODEC_SUPPORT_TABLE_ELEMENT( QT_CODEC_TYPE_YUV2_VIDEO,      LSMASH_CODEC_SUPPORT_FLAG_REMUX );
340         ADD_CODEC_SUPPORT_TABLE_ELEMENT( LSMASH_CODEC_TYPE_UNSPECIFIED, LSMASH_CODEC_SUPPORT_FLAG_NONE );
341     }
342     for( int i = 0; !lsmash_check_codec_type_identical( codec_support_table[i].type, LSMASH_CODEC_TYPE_UNSPECIFIED ); i++ )
343         if( lsmash_check_codec_type_identical( sample_type, codec_support_table[i].type ) )
344             return codec_support_table[i].flags;
345     return LSMASH_CODEC_SUPPORT_FLAG_NONE;
346 }
347